Динамически установить атрибут объекта Ruby - PullRequest
41 голосов
/ 21 октября 2011

Как я могу динамически установить атрибут объекта в Ruby, например

def set_property(obj, prop_name, prop_value)
    #need to do something like > obj.prop_name = prop_value 

    #we can use eval but I'll prefer a faster/cleaner alternative:
    eval "obj.#{prop_name} = #{prop_value}"
end

Ответы [ 4 ]

77 голосов
/ 21 октября 2011

Использовать отправить :

def set_property(obj, prop_name, prop_value)
    obj.send("#{prop_name}=",prop_value)
end
11 голосов
/ 21 декабря 2015

Object#instance_variable_set() - это то, что вы ищете, и более чистая версия того, что вы хотели.

Пример:

your_object = Object.new
your_object.instance_variable_set(:@attribute, 'value')
your_object
# => <Object:0x007fabda110408 @attribute="value">

Рубиновая документация о Object#instance_variable_set

3 голосов
/ 21 августа 2016

Если обстоятельства позволяют использовать метод экземпляра, следующее не слишком оскорбительно:

class P00t
  attr_reader :w00t

  def set_property(name, value)
    prop_name = "@#{name}".to_sym # you need the property name, prefixed with a '@', as a symbol
    self.instance_variable_set(prop_name, value)
  end
end

Использование:

p = P00t.new
p.set_property('w00t', 'jeremy')
2 голосов
/ 23 августа 2016

Этот ответ (https://stackoverflow.com/a/7466385/6094965) работал для меня:

Object.send(attribute + '=', value)

attribute должен быть String. Поэтому, если вы выполняете итерацию по массиву Symbol s (как я), вы можете использовать to_s.

Object.send(attribute.to_s + '=', value) 
...