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)