用于+ =的Ruby方法

时间:2013-05-29 05:09:22

标签: ruby operator-overloading

有没有办法让Ruby能够做到这样的事情?

class Plane
  @moved = 0
  @x = 0
  def x+=(v) # this is error
    @x += v
    @moved += 1
  end
  def to_s
    "moved #{@moved} times, current x is #{@x}"
  end
end

plane = Plane.new
plane.x += 5
plane.x += 10
puts plane.to_s # moved 2 times, current x is 15

2 个答案:

答案 0 :(得分:6)

  1. 您不能在Ruby中覆盖复合赋值运算符。分配在内部处理。您应该覆盖+=,而不是+plane.a += bplane.a = plane.a + bplane.a=(plane.a.+(b))相同。因此,您还应该覆盖a=。{/ li>中的Plane
  2. 当您撰写plane.x += 5时,+消息将发送至plane.x,而非plane。因此,您应该在+类中覆盖x方法,而不是Plane
  3. 当您引用@variable时,您应该注意当前的self是什么。在class Plane; @variable; end中,@variable指的是的实例变量。这与class Plane; def initialize; @variable; end; end中的那个不同,后者是类的实例的实例变量。因此,您可以将初始化部分放入initialize方法。
  4. 应谨慎对待操作员覆盖。有时它具有生产力和表现力,但有时则不然。在这里,我认为最好为平面定义一个方法(例如fly)而不是使用某个运算符。
  5. class Plane
      def initialize
        @x = 0
        @moved = 0
      end
      def fly(v)
        @x += v
        @moved += 1
      end
      def to_s
        "moved #{@moved} times, current x is #{@x}"
      end
    end
    
    plane = Plane.new
    plane.fly(5)
    plane.fly(10)
    puts plane.to_s
    

答案 1 :(得分:5)

+=运算符与任何方法都没有关联,它只是语法糖,当你编写a += b Ruby解释器将其转换为a = a + b时,同样适用于{{1}转换为a.b += c。因此,您只需根据需要定义方法a.b = a.b + cx=

x