Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 将散列值分配给对象的一种干燥方式_Ruby_Hash - Fatal编程技术网

Ruby 将散列值分配给对象的一种干燥方式

Ruby 将散列值分配给对象的一种干燥方式,ruby,hash,Ruby,Hash,我正在寻找一种优雅的方法,将散列中存储的值分配到预先存在的对象中。 需要明确的是,如果我有一个对象,比如有两个属性的obj,比如name和age,我想分配这个来自散列的值,而不需要执行以下操作: obj.name = hash[:name] obj.age = hash[:age] 谢谢你的关注。 西蒙妮不知道优雅,但你可以做到: [:name, :age].each do |att| obj.send("#{att}=", hash[att]) end 最好的办法可能是简单地定义一个

我正在寻找一种优雅的方法,将散列中存储的值分配到预先存在的对象中。 需要明确的是,如果我有一个对象,比如有两个属性的obj,比如name和age,我想分配这个来自散列的值,而不需要执行以下操作:

obj.name = hash[:name]
obj.age = hash[:age] 
谢谢你的关注。
西蒙妮不知道优雅,但你可以做到:

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

最好的办法可能是简单地定义一个方法,比如
update\u attributes
,它接受一个散列并在类的实例方法中执行

扩展其他人所写的内容以及您似乎需要的内容,我认为您最好的选择是:

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

  • 没有始终在哈希中包含该类的所有属性,以及
  • 散列中任意数量的键(不仅仅是:名称等)

使用
实例变量集是另一种选择。以下是一个例子:

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> 
类测试;属性访问器:名称,:年龄;结束
哈希={name:'John',年龄:52}
obj=测试。新
hash.each do | k,v|
obj.instance_variable_set(“@#{k}.”to_sym,v)#:name转换为:@name
结束
p obj#=>#

唯一的诀窍是,实例变量集需要一个以
@
开头的符号,因此
:@name
是有效的,但
:name
不是有效的。

这里有一个我多年来一直使用的非常容易键入的模式:

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

可以直接在对象上调用assign_attributes方法

obj.assign_attributes(hash)

如果hash.has_key?(attr)
,可能至少要在其中添加一个
,以防hash中没有对象的所有属性。@thenduks:据我所知,该对象有两个属性,它们总是在hash中。但当然,这个问题的措辞并不准确。它应该至少有一个规范和一个测试套件需要正确回答。你的方法看起来很整洁,但你能解释一下正则表达式代表什么吗?@user442622:我想得到所有setter方法,即所有以等号结尾的方法(这是
=$
部分),但是还有一些其他方法也以等号结尾(即
==
===
!=
),所以我只匹配那些没有
的方法
=
作为它们的倒数第二个字符(这是
[^!=]
部分)。你的方法看起来不错,但是如果我的名字和年龄都超过了怎么办?请你解释一下为什么你必须使用m=“{key}=”而不是m=“{key}”?这很难解释,但实际上很简单。首先,为了解释
key
是字符串
x
hash[key]
1
。。。现在,在Ruby中,代码
obj.x=1
实际上相当于
obj.x=(1)
。因此,在下一行中,当我执行
obj.send(m…)
时,我需要将其分配给该属性。换句话说,如果我没有在方法名中添加等号,它会调用
obj.x(1)
,并且
x
根本不接受参数(因为它是一个属性)。我想要的是
obj.x=(1)
这就是为什么我需要
{key}=
你也可以这样做:
hash.each do | key,value |
然后使用
value
而不是
hash[key]
。我会使用
public\u send
@kode,听起来很合理,但多年来,我从未遇到过
attr=
是私有的情况。这是一个活动记录特定的API,而不是Ruby标准库API。
obj.assign_attributes(hash)