2013-05-29 66 views
4

有沒有辦法讓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 
+4

只需將您的方法重命名爲其他內容? – oldergod

+0

是的,我想這樣..因爲+ =不能重載(我知道這只是現在)從http://stackoverflow.com/questions/3331962/list-of-ruby-operators-that-c​​an-be-overloaded – Kokizzu

+2

對類和它的實例使用相同的變量名「@ moved」和「@ x」是令人困惑的。 – sawa

回答

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 
+0

'a + = b'被稱爲*縮寫賦值*。當Ruby的解析器看到她所做的第一件事就是將它轉換爲'a = a + b'。 Ruby有13個操作符(主要是方法),可以表示爲縮寫賦值。所有的形式都是'o =',其中'o'是一個操作符,'a o = b'擴展爲'a = a o b'。這些運算符是'''','''''','''''''','''''','&','''','&','''''' <<' and '>>'。 (來源:The Ruby Programming Language,1st ed。,Flanagan和Matsumoto,96頁) –

6
  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,@variable指的是類的實例變量。這與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