Ruby Metaprogramming: имена переменных динамического экземпляра
Скажем, у меня следующий хэш:
{ :foo => 'bar', :baz => 'qux' }
Как я могу динамически установить ключи и значения, чтобы стать переменными экземпляра в объекте...
class Example
def initialize( hash )
... magic happens here...
end
end
... так что я получаю следующее внутри модели...
@foo = 'bar'
@baz = 'qux'
?
Ответы
Ответ 1
Метод, который вы ищете, 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) }
Ответ 2
h = { :foo => 'bar', :baz => 'qux' }
o = Struct.new(*h.keys).new(*h.values)
o.baz
=> "qux"
o.foo
=> "bar"
Ответ 3
Ты хочешь плакать:)
В любом случае см. Object#instance_variable_get
и Object#instance_variable_set
.
Счастливое кодирование.
Ответ 4
Вы также можете использовать 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