用于+ =的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
- 你不能在Ruby中覆盖复合赋值运算符。 作业在内部处理。 而不是
+=
,你应该覆盖+
。plane.a += b
与plane.a = plane.a + b
或plane.a=(plane.a.+(b))
。 因此,您还应该在Plane
覆盖a=
。 - 当你写
plane.x += 5
,+
消息被发送到plane.x
,而不是plane
。 所以你应该在x
的类中覆盖+
方法,而不是Plane
。 - 当你提到
@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
方法中。 - 应谨慎对待操作员覆盖。 有时它具有生产力和表现力,但有时则不然。 在这里,我认为最好为平面定义一个方法(例如
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