DRY方式将哈希值分配给对象
我正在寻找一种优雅的方法将存储在Hash中的值分配给预先存在的对象。 为了清楚起见,如果我有一个对象,说obj有两个属性,比如名字和年龄,我想分配来自哈希的这些值而不做类似的事情:
obj.name = hash[:name] obj.age = hash[:age]
感谢您的关注。 西蒙娜
最好的办法可能是简单地定义一个像update_attributes
这样的方法,它接受一个哈希并在类的实例方法中进行。
扩展其他人写的东西和你似乎需要的东西我认为你最好的选择是:
hash.keys.each do |key| m = "#{key}=" obj.send( m, hash[key] ) if obj.respond_to?( m ) end
这将占:
- 并不总是在哈希中拥有类的所有属性
- 哈希中的任意数量的键(不仅仅是:名称等)
这是我多年来使用的一种非常易于使用的模式:
{ first_name: "John", last_name: "Smith", ... }.each {|k, v| send("#{k}=", v)}
不知道优雅,但你可以这样做:
[:name, :age].each do |att| obj.send("#{att}=", hash[att]) end
使用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 # => #
唯一的技巧是instance_variable_set需要一个以@
开头的符号:@name
有效但是:name
不是。
obj.methods.grep(/[^!=]=$/).each {|attr| obj.send(attr, hash[attr]) }
您可以直接在对象上调用assign_attributes方法。
obj.assign_attributes(hash)