2013-10-24 51 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

在这种情况下确实有读者。 –

相关问题