Ruby中关于覆盖"+"操作符的问题。

11
一个最近学习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个回答

14

在实现+运算符时,不应该改变对象本身。相反,应该返回一个新的Point对象:

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> 

我同意那个实现方式,因为它最有意义,但这更像是一次工作中的慢日子实验。 - aosik

6
你可以像这样定义+方法,但是你只能使用普通的方法调用语法来调用它:
pt1.+(1,1)

1

你可以使用数组来实现类似的功能:

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

然后将其用作:

pt1 + [1, 1]

你也可以将它与 Chandra 的解决方案结合起来,接受数组和点作为参数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接