Ruby,如何覆盖setter("=")方法允许2个参数?

Ruby, how to overwrite the setter ("=") method to allow 2 parameters?

我正在尝试为我的多分量变量创建一个快速 set 方法(在我的实际代码中它是一个 Vector2d)。

我想使用 = 方法的覆盖版本。

例如:

def my_vector=(x, y)
  @my_vector = Vector2d.new(x, y)
end

但它不起作用,因为当我尝试调用此方法时收到错误消息:

my_vector=1, 2 # => wrong number of arguments (given 1, expected 2)
my_vector=(1, 2) # => syntax error, unexpected ',', expecting ')'
my_vector=[1, 2] # => wrong number of arguments (given 1, expected 2)

这是我的测试套件:

# With one param it works
def my_var=(value)
  @var = value
end

self.my_var=1
puts "var: " + @var.to_s


# With 2 params it doesn't work
def my_other_var=(value1, value2)
  @other_var_component_1 = value1
  @other_var_component_2 = value2
end

# Nothing works:
# self.my_other_var=1, 2
# self.my_other_var=(1, 2)
# self.my_other_var=[1, 2]
puts "other_var_component_1: " + @other_var_component_1.to_s
puts "other_var_component_2: " + @other_var_component_2.to_s

您正在定义一个名为 my_vector= 的方法(或在您的第二个示例中为 my_other_var=)。

如果您只是想用

调用它
my_vector = 1, 2

ruby 会将其解释为对 my_vector 变量的赋值。

您必须使用 send 才能调用您定义的方法,如

self.send :my_vector=, 1, 2

这有点丑陋,但我看不到其他解决方法。

正如@eugen 正确所说的那样,您不能将两个参数传递给 setter 之类的

self.my_vector = 1, 2

您最接近的做法是使用模式匹配解压参数:

def myvector=(arg)
  arg => [x, y]
  @my_vector = Vector2d.new(x, y)
end

foo.my_vector = [1, 2]

另一种方法是定义一个简单的辅助方法v,这样您就可以编写

foo.my_vector = v 1, 2

对提供的代码稍作修改以改为使用数组参数:

 def my_other_var=(values)
   @other_var_component_1 = values[0]
   @other_var_component_2 = values[1]
 end
    
 self.my_other_var=[1, 2]
    
"other_var_component_1: " + @other_var_component_1.to_s
#=>  other_var_component_1: 1
"other_var_component_2: " + @other_var_component_2.to_s
#=>  other_var_component_2: 2