与常规方法相比,Splat 参数对于属性编写器的行为不同



我有以下两种方法,我认为它们应该具有相同的行为,而不考虑它们的名称:

def a=(*params)
params
end
def b(*params)
params
end

但是实际上当我使用它们时:

a=(1) # => 1
b(1) # => [1]
(a=1) == b(1) # => false

而有趣的是:

(a=1,2) == b(1,2) # => true

为什么他们的行为不一样?

编辑:忘记将上述内容包装在与self.的类/调用中,该类/调用意外产生相同的行为,但出于不同的原因。答案中已经指出了这一点。

它与 splat 无关。它是赋值运算符。在 ruby 中,赋值运算符返回分配的值。该方法的返回值将被忽略。

所以a=1返回1,而不是[1]

但是,正如@mudasobwa所提到的,您甚至没有在这里调用该方法。但如果是,就会发生这种情况(忽略返回值)。

class Foo
def a=(*params)
params
end
end
f = Foo.new
f.a = 1 # => 1
f.a = 1,2 # => [1, 2]

若要不忽略返回值,请在不使用赋值运算符的情况下调用该 setter。

f.send 'a=', 1 # => [1]

问题是

a = 1

设置局部变量,根本不调用您的方法。尝试使用

def a=(*param)
puts "I AM HERE"
end

var=方法都需要显式接收器。若要调用方法,请使用显式接收器调用它:

self.a = 1

仍然不会返回除1之外的任何内容,因为赋值方法返回值(与通过MyClass.new调用initialize返回实例的方式相同,无论如何。但您可以检查 splat 是否适用于:

def a=(*param)
puts param.inspect
end
self.a = 1
# [1]
#⇒ 1

最新更新