2013-01-01 79 views
2

在紅寶石1.9.3,爲什麼Foo.explicit_receiver產生錯誤「稱爲保護法」?受保護的方法錯誤

我引用這些教程:

哪個州:

您可以隨時撥打一個受保護的方法有一個隱含的接收器,只需 像私人,但除此之外,你可以打電話給親只要這個接收者是自己或者是一個與自己相同的對象,就可以使用明確的接收者。

我打電話給一個Foo實例,它應該允許我調用受保護的方法。我確實失去了一些東西:)

代碼示例

class Foo 
    def implicit_receiver 
    protected_method 
    end 

    def explicit_receiver 
    self.protected_method 
    end 

    def self.explicit_receiver 
    Foo.new.tap do |foo| 
     foo.protected_method 
    end 
    end 

protected 

    def protected_method 
    p "called protected method!" 
    end 
end 

foo = Foo.new 
foo.implicit_receiver 
foo.explicit_receiver 
Foo.explicit_receiver 

# output 
# "called protected method!" 
# "called protected method!" 
# protected.rb:12:in `explicit_receiver': protected method `protected_method' called for #<Foo:0x10a280978> (NoMethodError) 
+0

(忽略,手機上無法刪除客戶端將在稍後刪除。) –

回答

3

受保護的方法可用於同一類或子類的其他實例的實例方法。然而,也就是引發錯誤的explicit_receiver是類的單一方法(實際上是元類)本身並沒有訪問類的受保護的實例方法。

您可以通過簡單的運行看到這一點:

class Foo 
    def self.test 
    Foo.new.protected_method 
    end 
end 

Foo.test 

你會得到一個類似的錯誤。

是什麼使得它在這種情況下,混亂的是,你在你創建,仍然可以得到這個錯誤實例調用tap。這是因爲對於tap塊的結合仍處於無法訪問其類的保護實例方法元類的背景下 - 你可以檢查self該塊裏面看到這一點。

+0

那麼你的意思是'self.explicit_receiver'是對「eigenclass」因此它不具有訪問定義的' Foo的受保護成員? – austen

+0

是的。在簡單地說的原因是,元類是類的子類不是富。 – PinnyM