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_getObject#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