我知道ActiveSupport提供的这项功能。
h = ActiveSupport::OrderedOptions.new
h.boy = 'John'
h.girl = 'Mary'
h.boy # => 'John'
h.girl # => 'Mary'
但是我已经有一个大哈希,我想使用点表示法访问该哈希值。这就是我试过的:
large_hash = {boy: 'John', girl: 'Mary'}
h = ActiveSupport::OrderedOptions.new(large_hash)
h.boy # => nil
那不起作用。我怎样才能做到这一点。
我正在使用ruby 1.9.2
更新
很抱歉我应该提到我不能使用openstruct,因为它没有Struct所具有的each_pair方法。我事先不知道密钥所以我不能使用openstruct。
答案 0 :(得分:9)
OpenStruct应该很好地为此工作。
如果您想了解它的工作原理,或者想要制作自定义版本,请从以下内容开始:
h = { 'boy' => 'John', 'girl' => 'Mary' }
class << h
def method_missing m
self[m.to_s]
end
end
puts h.nothing
puts h.boy
puts h.girl
答案 1 :(得分:6)
您正在寻找OpenStruct
$ require 'ostruct'
$ large_hash_obj = OpenStruct.new large_hash
$ large_hash_obj.boy
=> "John"
答案 2 :(得分:4)
I created my own gem for this,我一直在我的所有项目中使用它。似乎只是做你需要的:
large_hash = { boy: 'John', girl: 'Mary' }
r = Ribbon.wrap large_hash
r.boy
=> "John"
r.girl
=> "Mary"
r.keys
=> [:boy, :girl]
r.each_pair { |key, value| puts "#{key} => #{value}" }
boy => John
girl => Mary
会喜欢一些反馈。
答案 3 :(得分:3)
如果它只是一个小脚本,那么扩展Hash
本身
class Hash
def method_missing sym,*
fetch(sym){fetch(sym.to_s){super}}
end
end
method_missing
是一种神奇的方法,只要您的代码尝试调用不存在的方法,就会调用该方法。 Ruby将在运行时拦截失败的调用,让你处理它,这样你的程序就可以优雅地恢复。上面的实现尝试使用方法名称作为符号访问哈希,使用方法名称作为字符串,并最终失败,Ruby的内置方法丢失错误。
对于更复杂的应用程序,将此行为添加到所有哈希值可能会破坏其他代码或第三方域,请使用模块并扩展每个实例
module H
def method_missing sym,*
fetch(sym){fetch(sym.to_s){super}}
end
end
the = { answer: 42 }
the.extend(H)
the.answer # => 42
为了更方便,您甚至可以将模块传播到嵌套哈希
module H
def method_missing sym,*
r = fetch(sym){fetch(sym.to_s){super}}
Hash === r ? r.extend(H) : r
end
end
the = { answer: { is: 42 } }
the.extend(H)
the.answer.is # => 42