Ruby私有attr_访问器和意外的nil

Ruby私有attr_访问器和意外的nil,ruby,Ruby,当我经常使用Ruby的时候,我有一个坏习惯,就是把所有的事情都公开,而忽略隐私。不幸的是,这种无知再次困扰着我。以下是我的问题的简单版本: class Something private attr_accessor :sneaky public def initialize @sneaky = 0 end def test while sneaky < 10 puts "#{snea

当我经常使用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
怎么回事<代码>@skilly已在构造函数中设置为0。如果它真的是零,那么
不应该把
打印成一个空行而不是
0


编辑:是的,将
skilly=(skilly+1)
替换为
self.skilly=skilly+1
解决了这个问题,尽管
self.skilly=
看起来像是侵犯隐私,因为它有一个明确的接收器。显然,二传手是个例外。但是与隐私的奇怪交互意味着你不能说
self.skilly+=1
(你最终得到了
test.rb:14:in'test':私有方法'skilly'调用了#(nomethoderor)
)。幸运的是,我是。

一种形式的
foo=bar
赋值给一个名为
foo
的局部变量。如果要调用
attr\u writer
,则需要使用显式接收器:
self.skilly+=1


这与
private
无关,它只是局部变量赋值的基本Ruby语法。

private
与此相关,因为这是一个私有访问器,通常不能使用显式接收器调用私有方法。因此,
self.skilly+=1
不起作用。但是,
self.skilly=skilly+1
虽然看起来很难看,但仍然有效。不过,感谢你让我尝试忽略直观的隐私规则!是的,这是Ruby规范中的一个疏忽。我在6个月前报告了它,它可能会包含在Ruby 2.3中,因此
self.skilly+=1
可以工作。我完全忘记了我正在运行一个版本的2.2-trunk,应用了bugreport中的补丁,这样我就不会出错。啊,我看到你找到了我的bugreport:-D
0
test.rb:13:in `test': undefined method `+' for nil:NilClass (NoMethodError)
    from test.rb:19:in `<main>'