几天前我想要类似的东西,最终使用了 Hashie 2.0.0.beta,它为您提供了可以与您自己的子类一起使用的扩展Hash
:
require 'hashie'
require 'hashie/hash_extensions'
class Lash < Hash
include Hashie::Extensions::MethodAccess
def [](key)
val = super(key)
if val.respond_to?(:call) and val.arity.zero?
val.call
else
val
end
end
end
这使您可以执行以下操作:
l = Lash.new
#=> {}
l.foo = 123
#=> 123
l.bar = ->{ Time.now }
#=> #<Proc:0x007ffab3915f18@(irb):58 (lambda)>
l.baz = ->(x){ 10 * x }
#=> #<Proc:0x007ffab38fb4d8@(irb):59 (lambda)>
l.foo
#=> 123
l.bar
#=> 2013-01-26 15:36:50 +0100
l.baz
#=> #<Proc:0x007ffab38fb4d8@(irb):59 (lambda)>
l.baz[5]
#=> 50
注意:这仅适用于 Hashie 2.0.0.beta,您可以通过 Bundler 将这一行添加到您的 Gemfile 中来安装它:
gem 'hashie', :git => 'git://github.com/intridea/hashie.git'
或者,没有 Bundler,使用specific_install
gem:
gem install specific_install
gem specific_install -l git://github.com/intridea/hashie.git