我正在寻找一种优雅的方法将存储在Hash中的值分配给预先存在的对象。 为了清楚起见,如果我有一个对象,说obj有两个属性,比如姓名和年龄,我想分配这个来自哈希值的值而不做类似的事情:
obj.name = hash[:name]
obj.age = hash[:age]
感谢您的关注。 西蒙
答案 0 :(得分:11)
最好的办法可能是简单地定义像update_attributes
这样的方法,它接受一个哈希并在类的实例方法中进行。
扩展其他人所写的内容以及您似乎需要的内容我认为您最好的选择是:
hash.keys.each do |key|
m = "#{key}="
obj.send( m, hash[key] ) if obj.respond_to?( m )
end
这将解释:
答案 1 :(得分:3)
这是我多年来使用的一种非常易于使用的模式:
{
first_name: "John",
last_name: "Smith",
...
}.each {|k, v| send("#{k}=", v)}
答案 2 :(得分:2)
不知道优雅,但你可以这样做:
[:name, :age].each do |att|
obj.send("#{att}=", hash[att])
end
答案 3 :(得分:2)
使用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
不是。
答案 4 :(得分:1)
obj.methods.grep(/[^!=]=$/).each {|attr| obj.send(attr, hash[attr]) }
答案 5 :(得分:1)
You can directly call the assign_attributes method on the object.
obj.assign_attributes(hash)