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

Splat parameters behave differently for attribute writers compared to regular method

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

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

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

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

事情是这样的

a = 1

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

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

var= 方法需要显式接收者。要调用您的方法,请使用显式接收器调用它:

self.a = 1

仍然除了1不会return,因为赋值方法return值(与initialize 通过 MyClass.new return 调用了一个实例,无论如何。)但是您可以检查 splat 是否适用于:

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

与splat无关。它是赋值运算符。在 ruby 中,赋值运算符 return 是赋值。来自方法的 return 值被忽略。

所以a=1return1,不是[1]

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

class Foo

  def a=(*params)
    params
  end

end

f = Foo.new

f.a = 1 # => 1
f.a = 1,2 # => [1, 2]

为了不忽略 return 值,请在不使用赋值运算符的情况下调用 setter。

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