如何获得JavaScript样式的哈希访问?
我知道ActiveSupport提供的这个function。
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。
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
您正在寻找OpenStruct
$ require 'ostruct' $ large_hash_obj = OpenStruct.new large_hash $ large_hash_obj.boy => "John"
我为此创建了自己的gem ,我一直在我的所有项目中使用它。 似乎只做你需要的:
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
会喜欢一些反馈。
如果它只是一个小脚本,那么扩展Hash
本身就是安全的
class Hash def method_missing sym,* fetch(sym){fetch(sym.to_s){super}} end end
method_missing
是一种魔术方法,只要您的代码尝试调用不存在的方法,就会调用该方法。 Ruby将在运行时拦截失败的调用,让您处理它,以便您的程序可以正常恢复。 上面的实现尝试使用方法名称作为符号访问哈希,使用方法名称作为字符串,并最终失败,Ruby的内置方法丢失错误。
对于更复杂的应用程序,将此行为添加到所有哈希可能会破坏其他代码或第三方gem,使用模块并扩展每个实例
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