所以在Ruby中,可以像这样大量分配变量:
a, b, c = [1, 2, 3]
但是,如果我想对对象方法做同样的事情,但不必写出像这样的整个事情:
foo.a, foo.b, foo.c = [1, 2, 3]
有没有干嘛的方法来实现这个目标?
答案 0 :(得分:2)
我不确定你会喜欢它,但我能想到的DRYest方式是:
[:a, :b, :c].zip([1, 2, 3]).each { |k, v| foo.public_send "#{k}=", v }
# or vice versa
[1, 2, 3].zip([:a, :b, :c]).each { |v, k| foo.public_send "#{k}=", v }
或者,更多OO方式:
class Foo
attr_accessor :a, :b, :c
def massive_assign attrs, values
attrs.zip(values).each { |k, v| public_send "#{k}=", v }
end
end
foo = Foo.new
foo.massive_assign([:a, :b, :c], [1, 2, 3])
答案 1 :(得分:2)
实例变量的质量分配也可以像下面那样完成:
foo.instance_eval { @a, @b, @c = [1, 2, 3] }
答案 2 :(得分:1)
没有特定的语法,但您可以为作为哈希传递的多个属性实现setter。 Rails使用类似的方法:
class Foo
attr_accessor :a, :b, :c
def attributes=(attrs)
attrs.each do |name, value|
public_send("#{name}=", value)
end
end
end
foo = Foo.new
#=> #<Foo:0x007fc6d8a1e950>
foo.attributes = { a: 1, b: 2, c: 3 }
#=> #<Foo:0x007fc6d8a1e950 @a=1, @b=2, @c=3>
答案 3 :(得分:0)
从评论那里我假设海报意味着它实际上不是foo
而是更复杂的表达;而且不仅仅是3个作业(方法调用),还有很多。
有两种技巧可供考虑:tap
和send
:
some.complex[expression].which.evaluates.to.the.receiving.object.tap do |obj|
value_hash.each_pair do |key,value|
obj.send("#{key}=", value)
end
end
希望有所帮助。
当然,通常的安全警告适用(更好地确保value_hash
仅包含有效/合理/允许的名称)。