문제

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 ')'
도움이 되었습니까?

해결책

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> 

다른 팁

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top