вопрос по переопределению + оператор в ruby - PullRequest
7 голосов
/ 30 декабря 2010

Последнее преобразование в Ruby здесь.Следующий вопрос не очень практичен;это больше вопрос о том, как работает внутренняя часть Ruby.Можно ли переопределить стандартный оператор сложения для приема нескольких входов?Я предполагаю, что ответ отрицательный, учитывая, что оператор сложения является стандартным, но я хотел убедиться, что ничего не пропустил.

Ниже приведен код, который я написал быстро, чтобы проверить своймысли.Обратите внимание, это совершенно тривиально / надумано.

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 ')'

Ответы [ 3 ]

11 голосов
/ 30 декабря 2010

Вы не должны изменять объект при реализации оператора +.Вместо этого верните новый точечный объект:

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> 
4 голосов
/ 30 декабря 2010

Вы можете определить метод + таким образом, но вы сможете вызывать его только с помощью обычного синтаксиса вызова метода:

pt1.+(1,1)
0 голосов
/ 30 декабря 2010

Вы можете добиться чего-то подобного, используя массивы:

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

и позже используйте его как:

pt1 + [1, 1]

Вы также можете комбинировать его с решением Чандры, чтобы принимать в качестве аргументов и массивы, и точки.

...