用于+ =的Ruby方法

有没有办法让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 

+=运算符不与任何方法相关联,它只是语法糖,当你写a += b ,Ruby解释器将它转换为a = a + b ,同样适用于转换为ab = ab + c ab += c ab = ab + c 。 因此,您只需根据需要定义方法x=x

 class Plane def initialize @moved = 0 @x = 0 end attr_reader :x def x=(x) @x = x @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 
  1. 你不能在Ruby中覆盖复合赋值运算符。 作业在内部处理。 而不是+= ,你应该覆盖+plane.a += bplane.a = plane.a + bplane.a=(plane.a.+(b)) 。 因此,您还应该在Plane覆盖a=
  2. 当你写plane.x += 5+消息被发送到plane.x ,而不是plane 。 所以你应该在x的类中覆盖+方法,而不是Plane
  3. 当你提到@variable ,你应该注意当前的self 。 在class Plane; @variable; end class Plane; @variable; end class Plane; @variable; end@variable的是类实例变量 。 这与class Plane; def initialize; @variable; end; end的一个不同class Plane; def initialize; @variable; end; end class Plane; def initialize; @variable; end; end class Plane; def initialize; @variable; end; end ,这是类实例的实例变量 。 因此,您可以将初始化部分放入initialize方法中。
  4. 应谨慎对待操作员覆盖。 有时它具有生产力和表现力,但有时则不然。 在这里,我认为最好为平面定义一个方法(例如fly ),而不是使用某个运算符。
 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