Ruby 大规模方法调用

Ruby 大规模方法调用,ruby,Ruby,因此,在Ruby中,可以大量分配如下变量: a, b, c = [1, 2, 3] 但是,如果我想对对象方法做同样的操作,但不必像这样写出整个过程,该怎么办呢 foo.a, foo.b, foo.c = [1, 2, 3] 有没有一种干巴巴的方法可以做到这一点?我不确定你会喜欢它,但我能想到的最干巴巴的方法是: [:a, :b, :c].zip([1, 2, 3]).each { |k, v| foo.public_send "#{k}=", v } # or vice versa [1,

因此,在Ruby中,可以大量分配如下变量:

a, b, c = [1, 2, 3]
但是,如果我想对对象方法做同样的操作,但不必像这样写出整个过程,该怎么办呢

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

有没有一种干巴巴的方法可以做到这一点?

我不确定你会喜欢它,但我能想到的最干巴巴的方法是:

[: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 }
或者,以更面向对象的方式:

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])

从上面的评论来看,我认为海报的意思是,它实际上不是
foo
,而是一个更复杂的表达;不仅有3个赋值(方法调用),还有很多

我想到了两种技术:
点击
发送

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\u hash
只包含有效/正常/允许的名称)。

没有特定的语法,但是可以为作为hash传递的多个属性实现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>
class-Foo
属性存取器:a,:b,:c
def属性=(属性)
属性。每个do |名称、值|
public_send(“#{name}=”,value)
结束
结束
结束
foo=foo.new
#=> #
foo.attributes={a:1,b:2,c:3}
#=> #

实例变量的质量分配也可以按如下方式完成:

foo.instance_eval { @a, @b, @c = [1, 2, 3] }

我也是这么想的。我想这里显式的比隐式的好。你是什么意思?这仍然会重复三次。这是你不想做的那种“干巴巴的”。该代码具有非常高的“wtf是这吗?”评级。只需键入作业。很清楚。很明显。它是可读的。“没有必要用一个类把它抽象出来。”是的,我有点同意,但这要视情况而定。如果要在json生成器和这个
massible\u assign
之间进行选择,我会选择后者。@mudasobwa使用散列和循环似乎更好。这样可读性更强,更容易修改。如果您有50个键,并且您想要修改键27(或者想要在位置27添加一个键),那么您将如何使用此代码进行修改?这两个例子都让人觉得很尴尬,因为你需要两次找到正确的位置,而且很容易计算错误。如果出于任何原因必须使用数组,那么我会按照
[:a,1],:b,2],…]
的方式来做。讽刺的是,第一个示例中的
zip实际上就是这样产生的!我不明白你为什么这样写,“整件事”比这个短(甚至包括换行),所以我真的看不出这有什么好处。在Ruby中,
foo.c=1
这不是赋值。这是一种方法,为什么要投否决票?只是检查它是否存在。@SergioTulentsev:如果名称比
foo
长,并且您还有一些,那么它就不干了。如果您经常需要这种情况,那么这表明您应该将它们作为一个单独的属性保存在一起。