СУХОЙ способ присвоить хеш значения объекту - PullRequest
10 голосов
/ 08 сентября 2010

Я ищу элегантный способ присвоения значения, хранящегося в хэше, уже существующему объекту. Просто чтобы прояснить, если у меня есть объект, скажем, obj с двумя атрибутами, скажем, имя и возраст, я хочу присвоить это значение из хэша, не делая что-то вроде:

obj.name = hash[:name]
obj.age = hash[:age] 

Спасибо за ваше внимание. Simone

Ответы [ 6 ]

11 голосов
/ 08 сентября 2010

Лучше всего просто определить метод, подобный update_attributes, который берет хеш и делает это внутри экземпляра метода класса.

Расширяя то, что написали другие, и что вам, кажется, нужнодумаю, что ваша лучшая ставка была бы:

hash.keys.each do |key|
  m = "#{key}="
  obj.send( m, hash[key] ) if obj.respond_to?( m )
end

Это будет учитывать:

  • , не имеющий все атрибуты класса в хэше, и
  • любое количество ключей в хэше (не только: имя и т. Д.)
3 голосов
/ 22 мая 2014

Вот довольно простой шаблон, который я использую годами:

{
  first_name: "John",
  last_name: "Smith",
  ...
}.each {|k, v| send("#{k}=", v)}
2 голосов
/ 16 ноября 2012

Использование instance_variable_set - еще один вариант.Вот пример:

class Test; attr_accessor :name, :age; end

hash = {name: 'John', age: 52}

obj = Test.new
hash.each do |k,v|
  obj.instance_variable_set("@#{k}".to_sym, v) # :name is converted to :@name
end

p obj # => #<Test:0x007fd8cbb75b00 @name="John", @age=52> 

Единственная хитрость в том, что instance_variable_set ожидает символ, начинающийся с @, поэтому :@name допустимо, но :name - нет.

2 голосов
/ 08 сентября 2010

Не знаю, элегантно, но вы можете сделать:

[:name, :age].each do |att|
  obj.send("#{att}=", hash[att])
end
1 голос
/ 03 февраля 2018

Вы можете напрямую вызвать метод assign_attributes для объекта.

obj.assign_attributes(hash)
1 голос
/ 08 сентября 2010
obj.methods.grep(/[^!=]=$/).each {|attr| obj.send(attr, hash[attr]) }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...