用于+ =的Ruby方法

Kok*_*zzu 5 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
Run Code Online (Sandbox Code Playgroud)

Ari*_*iao 6

  1. 你不能在Ruby中覆盖复合赋值运算符.分配在内部处理.而不是+=,你应该覆盖+.plane.a += bplane.a = plane.a + bor一样plane.a=(plane.a.+(b)).因此,你也应该重写a=Plane.
  2. 在您编写时plane.x += 5,+会将消息发送给plane.x,而不是plane.所以你应该覆盖+类中的方法x,而不是Plane.
  3. 当你提到时@variable,你应该注意当前的self情况.在class Plane; @variable; end,@variable的是类实例变量.这与in的不同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
Run Code Online (Sandbox Code Playgroud)


tor*_*o2k 5

+=运营商没有关联的任何方法,它只是语法糖,当你写a += b的Ruby解释器改造它a = a + b,这同样适用于a.b += c被变换到a.b = a.b + 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
Run Code Online (Sandbox Code Playgroud)