Question

A recent convert to Ruby here. The following question isn't really practical; it's more of a question on how the internals of Ruby works. Is it possible to override the standard addition operator to accept multiple inputs? I'm assuming that the answer is no, given that the addition operator is a standard one, but i wanted to make sure i wasn't missing something.

Below is the code I wrote up quick to verify my thoughts. Note, it's completely trivial/contrived.

class Point
    attr_accessor :x, :y

    def initialize(x,y)
        @x, @y = x, y
    end


    def +(x,y)
        @x += x
        @y += y
    end


    def to_s
        "(#{@x}, #{@y})"
    end
end

pt1 = Point.new(0,0)
pt1 + (1,1) # syntax error, unexpected ',', expecting ')'
Was it helpful?

Solution

You should not mutate the object when implementing + operator. Instead return a new Point Object:

class Point
    attr_accessor :x, :y

    def initialize(x,y)
        @x, @y = x, y
    end


    def +(other)
      Point.new(@x + other.x, @y + other.y)
    end


    def to_s
        "(#{@x}, #{@y})"
    end
end

ruby-1.8.7-p302:
> p1 = Point.new(1,2)
=> #<Point:0x10031f870 @y=2, @x=1> 
> p2 = Point.new(3, 4)
=> #<Point:0x1001bb718 @y=4, @x=3> 
> p1 + p2
=> #<Point:0x1001a44c8 @y=6, @x=4> 
> p3 = p1 + p2
=> #<Point:0x1001911e8 @y=6, @x=4> 
> p3
=> #<Point:0x1001911e8 @y=6, @x=4> 
> p1 += p2
=> #<Point:0x1001877b0 @y=6, @x=4> 
> p1
=> #<Point:0x1001877b0 @y=6, @x=4> 

OTHER TIPS

You can define the + method like that, but you'll only be able to call it using normal method call syntax:

pt1.+(1,1)

You can achieve something similar using arrays:

def +(args)
  x, y = args
  @x += x
  @y += y
end

and later use it as:

pt1 + [1, 1]

You can also combine it with Chandra's solution, to accept both arrays and Points as arguments.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top