2

是否有一个像 Hashie 一样工作的 Ruby 库,除了它可以将 lambda 作为属性并在访问该属性时调用它?

例如,我想要这样的东西:

# Lash = Lambda-able hash
lash = Lash.new(
  someProperty:      "Some value",
  someOtherProperty: ->{ Time.now }
)

lash.someProperty      # => "Some value"
lash.someOtherProperty # => 2013-01-25 16:36:45 -0500
lash.someOtherProperty # => 2013-01-25 16:36:46 -0500
4

2 回答 2

0

这是我的实现:

class Lash < BasicObject
  def self.new hash
    ::Class.new do
      hash.each do |key, value|
        method_body = if value.respond_to? :call
                        ->(*args){ self.instance_exec(*args, &value) }
                      else
                        ->{ value }
                      end
        define_method(key, &method_body)
      end
    end.new
  end
end
于 2013-01-25T21:38:50.087 回答
0

几天前我想要类似的东西,最终使用了 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_installgem:

gem install specific_install
gem specific_install -l git://github.com/intridea/hashie.git
于 2013-01-26T14:41:07.147 回答