Mass方法调用

时间:2016-03-11 08:05:45

标签: ruby

所以在Ruby中,可以像这样大量分配变量:

a, b, c = [1, 2, 3]

但是,如果我想对对象方法做同样的事情,但不必写出像这样的整个事情:

foo.a, foo.b, foo.c = [1, 2, 3]

有没有干嘛的方法来实现这个目标?

4 个答案:

答案 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个作业(方法调用),还有很多。

有两种技巧可供考虑:tapsend

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仅包含有效/合理/允许的名称)。