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

时间:2017-09-08 12:30:37

标签: ruby 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.的类/调用中,这意外地会产生相同的行为,但原因不同。答案中已经指出了这一点。

2 个答案:

答案 0 :(得分:4)

它与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]

答案 1 :(得分:2)

事情是那个

a = 1

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

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

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

self.a = 1

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

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