web-dev-qa-db-ja.com

Rubyメタプログラミング:動的インスタンス変数名

私は次のハッシュを持っているとしましょう:

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

オブジェクトのインスタンス変数になるようにキーと値を動的に設定するにはどうすればよいですか...

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

...モデル内で次のようになります...

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

88
Andrew

探しているメソッドは 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) }
164
Chuck
h = { :foo => 'bar', :baz => 'qux' }

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

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

あなたは私たちが泣きたいようにします:)

いずれにせよ、 Object#instance_variable_get および Object#instance_variable_set

ハッピーコーディング。

7
user166390

sendを使用して、ユーザーが存在しないインスタンス変数を設定できないようにすることもできます。

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

クラスにattr_accessorのようなセッターがインスタンス変数にある場合、sendを使用します。

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