Search code examples
rubyoverwrite

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


I am trying to create a quick set method for my multi component variable (in my real code it is a Vector2d).

I would like to use an overwritten version of the = method.

For example:

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

But it is not working because when I try to call this method I receive an error:

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)

This is my test suite:

# 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

Solution

  • As @eugen correctly says, you cannot pass two arguments to a setter like

    self.my_vector = 1, 2
    

    The nearest thing you can achieve is to unpack the argument using pattern matching:

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

    An alternative is to define a simple helper method v so you can write

    foo.my_vector = v 1, 2