用本地变量创建新哈希:Ruby

3
我正在尝试从本地变量创建哈希表(丢弃不存在的变量)。类似这样:
foo = "bar"
baz = "qiz"

["foo", "baz", "nothing"].something_awesome

#=>
{"foo" => "bar", "baz" => "qiz"}

我尝试了很多不同的Array和Enumerable组合,但找不到正确的组合。有什么想法吗?

谢谢你的帮助!


我会只写{"foo" => foo, "bar" => bar},但这可能是实用主义(而不是缺乏“完整上下文”)在说话... - user166390
不能将foo和baz作为键/值存储在哈希表中吗?玩弄变量和eval函数是如此不愉快... - tokland
3个回答

3

在Jin的回答基础上,有一种稍微更惯用的版本可以抑制异常:

ree-1.8.7-2011.03 :042 > foo, bar = 'bar', 'quz'
=> ["bar", "quz"] 
ree-1.8.7-2011.03 :043 > %w(foo bar nothing).reduce({}) { |acc, item| acc[item] = eval(item) rescue nil; acc }.reject { |k, v| v.nil? }
=> {"foo"=>"bar", "bar"=>"quz"} 

个人认为使用eval会感觉很不安全,您可能需要重新考虑一下您的方法。


3

这是一种通用的从本地变量获取哈希值的方式,您甚至不需要知道变量名:

foo, bar = 'baz', 'qux'
local_names = binding.send(:local_variables)
locals = local_names.reduce({}) do |acc, v| 
  acc[v] = binding.eval(v.to_s) unless v == :_
  acc
end
p locals # {:foo => 'baz', :bar => 'qux'}

这将获取您所有的本地内容,因此如果您希望,在执行减少操作之前可以筛选列表。

2
尝试使用 eval
ruby-1.9.2-p290 :001 > foo = "bar"
 => "bar" 
ruby-1.9.2-p290 :002 > baz = "qiz"
 => "qiz" 
ruby-1.9.2-p290 :003 > ["foo", "baz", "nothing"].each { |x| puts eval(x) }
bar
qiz
NameError: undefined local variable or method `nothing' for main:Object
    from (irb):3:in `eval'
    from (irb):3:in `eval'
    from (irb):3:in `block in irb_binding'
    from (irb):3:in `each'
    from (irb):3
    from /Users/jin/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>'

将此与某种形式的异常处理相结合,您就可以开始了。 示例:
foo = "bar"
baz = "qiz"

local_vars = Hash.new(0)

["foo", "baz", "nothing"].each do |x|
  begin
    local_vars[x] = eval(x)
  rescue NameError
    puts "No local var named: " + x # No local var named: nothing
  end
end

puts local_vars # {"foo"=>"bar", "baz"=>"qiz"}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接