在Ruby中动态填充对象的属性,其属性名称与散列键相同

时间:2013-05-30 14:35:14

标签: ruby

我有以下哈希:

row = {:id => 1, :name => "Altus Raizen", :email => "altus@blarg.com"}

现在我有Person个结构,其属性与row中的键相同:

Person = Struct.new(:id, :name, :email)

我想使用Person哈希中的值动态填充row对象,如下所示:

person = Person.new
person.id = row[:id]
person.name = row[:name]
person.email = row[:email]

上面的代码可行,但必须有更优雅的方法,即动态填充属性。我该怎么做呢? (实际上我有9个属性,因此通过考虑将值设置为其他属性(如电话,地址等),上面的代码变得更长并且更“丑陋”。

2 个答案:

答案 0 :(得分:7)

person = Person.new
row.each_pair { |key, value| person.send("#{key}=", value) }

答案 1 :(得分:2)

在ruby> = 1.9。你可以这样做:

row = {:id => 1, :name => "Altus Raizen", :email => "altus@blarg.com"}
Person = Struct.new(:id, :name, :email)

p person = Person.new(*row.values)
# => <struct Person id=1, name="Altus Raizen", email="altus@blarg.com">

这恰好工作,因为一切都是正确的顺序。更多控制提供values_at,这也适用于较旧的红宝石:

row = {:id => 1, :name => "Altus Raizen", :email => "altus@blarg.com"}
Person = Struct.new(:id, :name, :email)
p person = Person.new(*row.values_at(:id, :name, :email))

另一个选项是OpenStruct:

require 'ostruct'
row = {:id => 1, :name => "Altus Raizen", :email => "altus@blarg.com"}
person = OpenStruct.new(row)
p person  #=><OpenStruct id=1, name="Altus Raizen", email="altus@blarg.com">
puts person.name #=> Altus Raizen