Manera SECA de asignar valores hash a un objeto

Estoy buscando una forma elegante de asignar el valor almacenado dentro de un Hash a un objeto preexistente. Solo para ser claro, si tengo un objeto, digamos obj con dos atributos, digamos nombre y edad, quiero asignar estos valores provenientes de un hash sin hacer algo como:

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

Gracias por tu atención. Simone

Lo mejor es probablemente definir simplemente un método como update_attributes que toma un hash y lo hace dentro de un método de instancia de la clase.

Ampliando lo que otros han escrito y lo que parece necesitar, creo que lo mejor sería:

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

Esto tendrá en cuenta:

  • no tener todos los atributos de la clase en el hash en todo momento, y
  • cualquier número de claves en el hash (no solo: nombre, etc.)

Aquí hay un patrón bastante fácil de escribir que uso durante años:

 { first_name: "John", last_name: "Smith", ... }.each {|k, v| send("#{k}=", v)} 

No sé de elegante, pero puedes hacer:

 [:name, :age].each do |att| obj.send("#{att}=", hash[att]) end 

Usar instance_variable_set es otra opción. Aquí hay un ejemplo:

 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 # => # 

El único truco es que instance_variable_set espera un símbolo que comience con @ por lo que :@name es válido pero :name no.

 obj.methods.grep(/[^!=]=$/).each {|attr| obj.send(attr, hash[attr]) } 

Puede llamar directamente al método assign_attributes en el objeto.

 obj.assign_attributes(hash)