当我经常使用 Ruby 时,我有一个坏习惯,就是将所有内容都公开并忽略隐私。不幸的是,这种无知又回来困扰着我。这是我的问题的一个更简单的版本:
class Something
private
attr_accessor :sneaky
public
def initialize
@sneaky = 0
end
def test
while sneaky < 10
puts "#{sneaky}"
sneaky = (sneaky + 1)
end
end
end
test = Something.new
test.test
这会打印 sneaky 的正确值 ( 0
),然后在 sneaky = (sneaky + 1)
处出错,说 sneaky
是nil
:
0
test.rb:13:in `test': undefined method `+' for nil:NilClass (NoMethodError)
from test.rb:19:in `<main>'
这是怎么回事? @sneaky
在构造函数中已设置为 0。如果它真的是零,那不应该是puts
吗?打印一个空行而不是 0
?
编辑:是的,替换 sneaky = (sneaky + 1)
与 self.sneaky = sneaky + 1
解决了问题,即使 self.sneaky=
看起来像是侵犯隐私,因为它有一个明确的接收者。显然,二传手是个异常(exception)。但是与隐私的奇怪互动意味着你不能说 self.sneaky += 1
(你最终得到 test.rb:14:in 'test': private method 'sneaky' called for #<Something:0x000001019004c8 @sneaky=0> (NoMethodError)
)。还好我是not the only one who thinks that's weird .
最佳答案
foo = bar
的一种形式分配给名为 foo
的局部变量。如果要调用 attr_writer
,则需要使用显式接收器:self.sneaky += 1
。
这与 private
无关,它只是局部变量赋值的基本 Ruby 语法。
关于Ruby 私有(private) attr_accessor 和意外的 nil,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27262620/