2013-10-24 65 views
3

下面的代碼導致我的問題:紅寶石增量(+ =)引發錯誤未定義的方法 '+' 的零:NilClass

class Foo 
    def initialize(n=0) 
    @n = n 
    end 

    attr_accessor :n 

    def inc 
    n+=1 
    end 
end 

調用Foo.new.inc提高NoMethodError: undefined method '+' for nil:NilClass 調用Foo.new.n回報0

爲什麼Foo.new.inc提出錯誤?我可以做Foo.new.n+=1沒有問題。

+1

那麼用'@ n'呢?或者'self.n'? – Ryan

+1

'n + = x'擴展爲'n = n + x',其中* n被綁定爲局部變量*,因爲它出現在左側。 – user2864740

回答

10

tldr;某種形式的self.n = x必須總是可用於分配給設置器

考慮到n += x擴展到n = n + x其中n被綁定爲一個局部變量,因爲它出現在賦值的左手側。本地變量的這種「引入」抵消了隱式方法調用的正常回退行爲(例如,nself.n)。

因此,由於n尚未分配(但它是綁定作爲局部變量現在),則表達式評估爲n = nil + x這是什麼原因造成的異常上升。

+0

,你會從哪裏讀取? 'ReferenceError'。 –

+1

@JanDvorak哎呀,如果在任何*任務之前使用了'n',將會是NameError。我刪除了不正確的最後一段。 – user2864740

+0

「隱式自我方法調用的正常回退行爲」 - 請參考?我很確定這隻適用於'Kernel'。 –

4

使用此

def inc 
    self.n += 1 
end 

或本

def inc 
    @n += 1 
end 

在你的情況,赤裸裸的名字 「N」 被解釋爲一個局部變量(不存在)。您需要明確指定它是一種方法(self.n)或使用基礎實例變量。

+0

'self.n'只有在'@ n'有一個閱讀器_和一個作者(他們的行爲如預期)時纔會起作用。我認爲後者的形式是首選嗎? –

+1

@JanDvorak:'attr_accessor'就是這樣,對吧? – Ryan

+1

在這種情況下確實有讀者。 –

相關問題