Ruby Metaprogramming:dynamic实例variables名称
假设我有以下哈希:
{ :foo => 'bar', :baz => 'qux' }
我怎样才能dynamic地设置键和值成为对象的实例variables…
class Example def initialize( hash ) ... magic happens here... end end
…所以我最终在模型里面
@foo = 'bar' @baz = 'qux'
?
你正在寻找的方法是instance_variable_set
。 所以:
hash.each { |name, value| instance_variable_set(name, value) }
或者更简单地说,
hash.each &method(:instance_variable_set)
如果你的实例variables名缺less“@”(就像在OP的例子中那样),你需要添加它们,所以它更像是:
hash.each { |name, value| instance_variable_set("@#{name}", value) }
h = { :foo => 'bar', :baz => 'qux' } o = Struct.new(*h.keys).new(*h.values) o.baz => "qux" o.foo => "bar"
你让我们想哭:)
在任何情况下,请参阅Object#instance_variable_get
和Object#instance_variable_set
。
快乐的编码。
你也可以使用send
来防止用户设置不存在的实例variables:
def initialize(hash) hash.each { |key, value| send("#{key}=", value) } end
在你的类中使用send
时,有一个像attr_accessor
这样的setter用于你的实例variables:
class Example attr_accessor :foo, :baz def initialize(hash) hash.each { |key, value| send("#{key}=", value) } end end