2015-01-09 62 views
3

鑑於紅寶石一類:如何訪問Ruby中的私有類方法?

class MyClass 
    def self.my_class_method 
    puts "class method" 
    end 

    private 

    def my_method 
    puts "regular method" 
    end 

    private_class_method :my_class_method 
end 

要訪問私有方法我可以調用類對象.send(:my_method),但如何做類方法的工作?

回答

9

你應該這樣做:

class MyClass 
    def self.my_class_method 
    puts "class method" 
    end 

    private 

    def my_method 
    puts "regular method" 
    end 

    private_class_method :my_class_method 
end 

# to call class method 
MyClass.send :my_class_method # => class method 
# to call instance method 
MyClass.new.send :my_method # => regular method 

在Ruby中,類(S)也是對象,所以你也可以撥打#send方法的類。

在Ruby中,你可以定義私有類方法作爲

class MyClass 
    class << self 
    private 

    def my_class_method 
     puts "class method" 
    end 
    end 
end 

或者使用thhis 宏觀類似方法:private_class_method

+0

謝謝你的提示! – Severin

1

僅供參考,這不是你如何創建一個私有的類方法。

class A 
    private 

    def self.foo 
    "foo" 
    end 
end 

A.foo # => "foo" 

要創建私有類方法,您需要使用private_class_method

class A 
    def self.foo 
    "foo" 
    end 

    private_class_method :foo 
end 

A.foo # => private method `foo' called for A:Class 
+0

謝謝,我沒有注意到..現在我補充說。但這不是問題。 –

+0

謝謝指出!相應地更新了問題。 – Severin

1

首先,MyClass.send(:my_method)不起作用。您必須將其發送到實例:MyClass.new.send(:my_method)

然後,你的my_class_method是不是真的私人。
Ruby的語義private與您在其他語言中可能會使用的有所不同。由於Ruby允許您選擇跳過封裝,因此private僅意味着只能在不向實際對象發送消息的情況下隱式調用

例如:

class Example 
    def test 
    'foobar' 
    end 

    def hello 
    puts test  # implicit receiver 
    puts self.test # explicit receiver 
    end 
end 

這一切都不錯,但爲什麼是你的問題很重要?
因爲您在self上明確聲明my_class_method。這樣做繞過private修飾符,並且該方法是公開的。這意味着,你可以把它用:

MyClass.my_class_method 

如果你真的需要private類的方法,那麼你可以將它們定義在元類:

class MyClass 

    class << self 

    private 

    def my_class_method 
     puts "class method" 
    end 
    end 


    private 

    def my_method 
    puts "regular method" 
    end 

end 

這將使my_class_method實際上私人,並迫使你用以下任何一種方式調用它:

MyClass.send :my_class_method 
MyClass.class_exec { my_class_method } 
MyClass.class_eval { my_class_method } 
MyClass.class_eval "my_class_method" 
2

沒有類方法這樣的事情。類方法只是該類的單例方法。但是沒有單身方法這樣的事情。單例方法只是單例類的實例方法。所以,類方法只是類的單例類的實例方法。

因爲有作爲一類方法沒有這樣的事情,只有實例方法,你已經知道該怎麼做:

訪問私有方法,我可以在類對象調用.send(:my_method),但是這是如何工作的對於類方法?