如何获得JavaScript样式的哈希访问?

时间:2022-09-11 15:08:51

I am aware of this feature provided by ActiveSupport.

我知道ActiveSupport提供的这个功能。

h = ActiveSupport::OrderedOptions.new
h.boy = 'John'
h.girl = 'Mary'
h.boy  # => 'John'
h.girl # => 'Mary'

However I already have a large hash and I want to access that hash using dot notation. This is what I tried:

但是我已经有一个大哈希,我想使用点表示法访问该哈希。这是我试过的:

large_hash = {boy: 'John', girl: 'Mary'}
h = ActiveSupport::OrderedOptions.new(large_hash)
h.boy # => nil

That did not work. How can I make this work.

那没用。我怎样才能做到这一点。

I am using ruby 1.9.2

我正在使用ruby 1.9.2

Update:

更新:

Sorry I should have mentioned that I can't use openstruct because it does not have each_pair method which Struct has. I do not know keys beforehand so I can't use openstruct.

对不起我应该提到我不能使用openstruct,因为它没有Struct所具有的each_pair方法。我事先不知道密钥所以我不能使用openstruct。

4 个解决方案

#1


9  

OpenStruct should work nicely for this.

OpenStruct应该很好地为此工作。

If you want to see how it works, or perhaps make a customized version, start with something like this:

如果您想了解它的工作原理,或者想要制作自定义版本,请从以下内容开始:

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

#2


6  

You are looking for OpenStruct

您正在寻找OpenStruct

$ require 'ostruct'
$ large_hash_obj = OpenStruct.new large_hash
$ large_hash_obj.boy
=> "John"

#3


4  

I created my own gem for this, and I've been using it in all my projects. Seems to do just what you need:

我为此创建了自己的宝石,我一直在我的所有项目中使用它。似乎只做你需要的:

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

Would love some feedback.

会喜欢一些反馈。

#4


3  

If it’s just a small script it’s safe to extend Hash itself

如果它只是一个小脚本,那么扩展Hash本身就是安全的

class Hash
  def method_missing sym,*
    fetch(sym){fetch(sym.to_s){super}}
  end
end

method_missing is a magic method that is called whenever your code tries to call a method that does not exist. Ruby will intercept the failing call at run time and let you handle it so your program can recover gracefully. The implementation above tries to access the hash using the method name as a symbol, the using the method name as a string, and eventually fails with Ruby's built-in method missing error.

method_missing是一种魔术方法,只要您的代码尝试调用不存在的方法,就会调用该方法。 Ruby将在运行时拦截失败的调用,让您处理它,以便您的程序可以正常恢复。上面的实现尝试使用方法名称作为符号访问哈希,使用方法名称作为字符串,并最终失败,Ruby的内置方法丢失错误。

For a more complex application, where adding this behavior to all hashes might break other code or third0party gems, use a module and extend each instance

对于更复杂的应用程序,将此行为添加到所有哈希可能会破坏其他代码或第三方宝石,使用模块并扩展每个实例

module H
  def method_missing sym,*
    fetch(sym){fetch(sym.to_s){super}}
  end
end

the = { answer: 42 }
the.extend(H)
the.answer # => 42

and for greater convenience you can even propagate the module down to nested hashes

为了更方便,您甚至可以将模块传播到嵌套哈希

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

#1


9  

OpenStruct should work nicely for this.

OpenStruct应该很好地为此工作。

If you want to see how it works, or perhaps make a customized version, start with something like this:

如果您想了解它的工作原理,或者想要制作自定义版本,请从以下内容开始:

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

#2


6  

You are looking for OpenStruct

您正在寻找OpenStruct

$ require 'ostruct'
$ large_hash_obj = OpenStruct.new large_hash
$ large_hash_obj.boy
=> "John"

#3


4  

I created my own gem for this, and I've been using it in all my projects. Seems to do just what you need:

我为此创建了自己的宝石,我一直在我的所有项目中使用它。似乎只做你需要的:

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

Would love some feedback.

会喜欢一些反馈。

#4


3  

If it’s just a small script it’s safe to extend Hash itself

如果它只是一个小脚本,那么扩展Hash本身就是安全的

class Hash
  def method_missing sym,*
    fetch(sym){fetch(sym.to_s){super}}
  end
end

method_missing is a magic method that is called whenever your code tries to call a method that does not exist. Ruby will intercept the failing call at run time and let you handle it so your program can recover gracefully. The implementation above tries to access the hash using the method name as a symbol, the using the method name as a string, and eventually fails with Ruby's built-in method missing error.

method_missing是一种魔术方法,只要您的代码尝试调用不存在的方法,就会调用该方法。 Ruby将在运行时拦截失败的调用,让您处理它,以便您的程序可以正常恢复。上面的实现尝试使用方法名称作为符号访问哈希,使用方法名称作为字符串,并最终失败,Ruby的内置方法丢失错误。

For a more complex application, where adding this behavior to all hashes might break other code or third0party gems, use a module and extend each instance

对于更复杂的应用程序,将此行为添加到所有哈希可能会破坏其他代码或第三方宝石,使用模块并扩展每个实例

module H
  def method_missing sym,*
    fetch(sym){fetch(sym.to_s){super}}
  end
end

the = { answer: 42 }
the.extend(H)
the.answer # => 42

and for greater convenience you can even propagate the module down to nested hashes

为了更方便,您甚至可以将模块传播到嵌套哈希

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