Ruby Metaprogramming:动态实例变量名称

时间:2011-07-19 02:13:21

标签: ruby metaprogramming instance-variables

假设我有以下哈希:

{ :foo => 'bar', :baz => 'qux' }

如何动态设置键和值以成为对象中的实例变量...

class Example
  def initialize( hash )
    ... magic happens here...
  end
end

...所以我最终在模型中得到以下内容......

@foo = 'bar'
@baz = 'qux'

4 个答案:

答案 0 :(得分:161)

您要查找的方法是instance_variable_set。所以:

hash.each { |name, value| instance_variable_set(name, value) }

或者更简单地说,

hash.each &method(:instance_variable_set)

如果您的实例变量名称缺少“@”(因为它们在OP的示例中),您将需要添加它们,因此它更像是:

hash.each { |name, value| instance_variable_set("@#{name}", value) }

答案 1 :(得分:12)

h = { :foo => 'bar', :baz => 'qux' }

o = Struct.new(*h.keys).new(*h.values)

o.baz
 => "qux" 
o.foo
 => "bar" 

答案 2 :(得分:7)

你让我们想哭:)

无论如何,请参阅Object#instance_variable_getObject#instance_variable_set

快乐的编码。

答案 3 :(得分:5)

您还可以使用send来阻止用户设置不存在的实例变量:

def initialize(hash)
  hash.each { |key, value| send("#{key}=", value) }
end

在课堂上使用send时,您的实例变量会有attr_accessor这样的设置器:

class Example
  attr_accessor :foo, :baz
  def initialize(hash)
    hash.each { |key, value| send("#{key}=", value) }
  end
end