Метапрограммирование Ruby: имена динамических переменных экземпляра
допустим, у меня есть следующий хэш:
{ :foo => 'bar', :baz => 'qux' }
как я могу динамически установить ключи и значения, чтобы стать переменными экземпляра в объекте...
class Example
def initialize( hash )
... magic happens here...
end
end
... так что я в конечном итоге со следующим внутри модели...
@foo = 'bar'
@baz = 'qux'
?
4 ответов:
метод, который вы ищете является
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) }
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
что не позволяет пользователю устанавливать несуществующие переменные экземпляра: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
Comments