如何获得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