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

Time:02-17

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

CodePudding user response:

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

CodePudding user response:

Slight modification to the supplied code to use an array argument instead:

 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

CodePudding user response:

You're defining a method named my_vector= (or my_other_var= in your 2nd example).

If you're just trying to call it with

my_vector = 1, 2

ruby will interpret that as an assignment to the my_vector variable.

You'll have to use send in order to call the method you've defined, as in

self.send :my_vector=, 1, 2

That's kind of ugly, but I don't see another way around this.

  • Related