class A
attr_accessor :rank
def change_rank
rank = rank + 1
end
end
a = A.new
a.rank = 5
p a.rank
a.change_rank
p a.rank
为rank = rank + 1产生错误(未定义的方法+为nil:Nilclass)。不应该对“rank”方法的隐式调用返回实例变量@rank的值吗?出于某种原因,如果我将第4行更改为:
,则此代码有效self.rank = self.rank + 1
为什么对rank方法的显式调用有效,而隐式方法没有?
答案 0 :(得分:4)
def change_rank
rank = rank + 1
end
在此上下文中,名称rank
会将不解析为attr_accessor
生成的方法之一。红宝石大致认为这是:
def change_rank
rank = nil
rank = rank + 1
end
当ruby看到对“裸”名称的赋值时,它会创建一个具有此名称的局部变量。它将影响外部方法。由于本地变量已使用nil
初始化,因此它解释了您遇到的错误。
您可以这样做以避免错误(明确您要修改的内容):
def change_rank
self.rank += 1
end
这里有更多代码说明了这个
defined?(x) # => nil # name x is unidentified yet
defined?(x = x) # => "assignment" # local var x is created by assignment
defined?(x) # => "local-variable" # now local var x exists
x # => nil # and its value is nil
答案 1 :(得分:0)
我重写你的代码如下。你可以看到Ruby如何以不同的方式对待rank =和排名。
class A
attr_accessor :rank
def change_rank
self.rank = rank + 1
end
end
a = A.new
a.rank = 5
p a.rank
a.change_rank
p a.rank
执行结果:
5
6