鉴于此代码:
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
不是默认收件人吗?
答案 0 :(得分:7)
你没有在那里调用方法,实际上你正在引用你正在定义的同一个变量!这是Ruby中的一个小问题。
如果您引用并设置实例变量,那会更好:
@my_variable = @my_variable + 3
或更短:
@my_variable += 3
或者你可以调用setter方法,就像你找到的那样(和Jits pointed):
self.my_variable += 3
最后一个将调用my_variable=
定义的attr_accessor
方法,其他两个方法只会修改变量。如果你这样做,你可以覆盖my_variable=
来做与传入的值不同的东西:
def my_variable=(value)
# do something here
@my_variable = value
end
<强>奖金强>
或者你可以通过传递一组空参数来显式调用方法:
my_variable = my_variable() + 3
这不是“红宝石之路”,但是如果你有一个同名的局部变量,你仍然可以通过这种方式调用方法,这仍然很有趣。
答案 1 :(得分:5)
my_variable = my_variable + 3
...是一个局部变量赋值,它优先。
因此需要self
- 以便将其范围扩展到对象。
答案 2 :(得分:3)
如果您在my_variable
中执行了foo
,那就是分配给本地变量 my_variable
,而不是调用方法my_variable=
。
要根据需要分配值,您需要在发现时使用self
。
另请参阅此问题:Why do ruby setters need “self.” qualification within the class?
答案 3 :(得分:2)
我认为在这种情况下,变量的范围仅在函数内,除非您使用self.
的{{1}}作为前缀。