2011-05-30 118 views
5

鑑於這種代碼:爲什麼不解決這些方法?

class Something 
    attr_accessor :my_variable 

    def initialize 
    @my_variable = 0 
    end 

    def foo 
    my_variable = my_variable + 3 
    end 
end 

s = Something.new 
s.foo 

我得到這個錯誤:

test.rb:9:in `foo': undefined method `+' for nil:NilClass (NoMethodError) 
    from test.rb:14:in `<main>' 

如果attr_accessor創建一個名爲my_variable方法(和.. =),爲什麼不能foo找到方法?如果我將其更改爲self.my_variable,它會起作用,但爲什麼?是不是self的默認接收器?

回答

7

你不是在那裏調用方法,而是實際上引用了你正在定義的同一個變量!這是Ruby中的一個小問題。

什麼是更好的是,如果你引用和設置實例變量,而不是:

@my_variable = @my_variable + 3 

或更短:

@my_variable += 3 

或者你可以調用setter方法,因爲你發現了(和Jits pointed )out:

self.my_variable += 3 

最後一個會打電話給my_variable=方法由attr_accessor定義,其他兩個只會修改一個變量。如果你這樣做了,你可以覆蓋my_variable=做不同的事情來傳遞的價值:

def my_variable=(value) 
    # do something here 
    @my_variable = value 
end 

BONUS

或者你可以通過傳遞一個空的參數集通過顯式調用方法:

my_variable = my_variable() + 3 

這不是「Ruby之道」去了解它,但它仍然是有趣的知道,你仍然可以調用一個方法,這樣,如果你有相同名稱的局部變量。

+1

WRT獎勵:您仍然需要直接設置伊娃或使用setter。這只是設置本地。 – Chuck 2011-05-30 04:06:46

5
my_variable = my_variable + 3 

...是一個局部變量賦值,其優先級。

因此需要self - 爲了將其範圍限定在對象範圍內。

2

我認爲在這種情況下,變量的範圍只在函數內,除非您在self.之前加上@

相關問題