2017-03-21 17 views
7

这是一个我似乎无法解释的有趣案例。它看起来像私人定员是'私人的',但有时也有例外。定期私有方法似乎表现不同私人setter方法:为什么私人制定者的行为与其他私人方法有所不同?

class TestClass 
    def do 
    self.foo = :bar # fine 
    self.baz  # error 
    end 

    private 

    def foo=(other) 
    @foo = other 
    end 

    def baz 
    end 
end 

TestClass.new.do 

上述代码设置@foo就好了,尽管被称为上明确self。然后它不能拨打#baz,因为#baz是一种私人方法。

这是怎么回事?

+1

通常我会叫'baz'不使用前缀'self',以及应在这种情况下工作。但我意识到这并不能回答你的直接问题。 – moveson

回答

4

私人setter方法是特殊的,因为否则他们无法在全称为:

foo = :bar 

分配给本地变量foo,它不会发送消息foo=

请注意,setter不是唯一的东西,没有一个明确的接收器不能被调用。 [email protected][email protected]!~[][]=+-*/%&|^**<<>>======~!~!=<><=>=,<=>和其他我忘记的其他人可能没有一个明确的接收器也不能被调用。然后有像+=<<=等等。

所有这些都需要例外。不幸的是,其中一些只有例外。

有人建议从

只能被称为改变private规则没有明确的接收器,除了[这漫长的例外列表,它是非常复杂,并且仍然没有完成。

只能被称为没有明确接收器或字面特殊变量self作为接收器。

它保留了定义的所有当前属性(最重要的是它可以在解析时静态确定)。

But so far, nothing has come of it.

1

如果在使用setter方法时不使用self,则它会将该值分配给局部变量。 More details

在下面的代码,我已经移除分配给FOO self,你可以看到不被使用的setter B/C @foonil

def do 
    foo = :bar # fine 
    baz  # error 
    puts @foo # prints nil 
    puts foo # prints 'bar' 
    end 
1

这几乎是怎么private的作品,它是红宝石中privateprotected方法的主要区别。您不能在类的实例上调用private方法,即使在该类中也是如此,而protected允许。