2017-03-21 54 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允許。