2011-11-05 93 views
4

當在一個Ruby類定義中聲明private/protected時實際發生了什麼?它們不是keywords,所以這意味着它們必須是方法調用,但我無法找到它們被定義的位置。他們似乎沒有記錄。兩種不同的方式聲明private/protected方法(如下所示)的實現方式不同嗎? (第二種方法顯然是一個方法調用,但這不是在第一種方式如此明顯。)在Ruby中聲明「private」/「protected」時實際發生了什麼?

class Foo 
    private 
    def i_am_private; end 
    def so_am_i; end 
end 

class Foo 
    def i_am_private; end 
    def so_am_i; end 
    private :i_am_private, :so_am_i 
end 
+1

你看過http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Classes#Private? – jtbandes

+0

是的,但是這並沒有說明方法在哪裏或如何實際執行。我完全知道什麼是'private'&'protected',我對Ruby的內部(* how *&* where *)很好奇。 –

回答

9

兩者都是方法調用。從docs引用:

每個函數都可以以兩種不同的方式使用。

  1. 如果在沒有參數的情況下使用,則三個函數設置後續定義的方法的默認訪問控制。
  2. 使用參數,函數設置命名方法和常量的訪問控制。

查看文檔在這裏:

  1. Module.private
  2. Access Control

你要找的Module.private方法是如何開始存在。 Here is where that happens。關於它的here is some more information。您需要詳細閱讀,從class.c中定義的rb_define_private_method開始。

希望有幫助!

+0

我很好奇爲什麼這裏不顯示:http://www.ruby-doc.org/core-1.9.2/Module.html –

+0

我同意它應該在那裏,但我不知道爲什麼不是。我不太喜歡這些文檔 - 它可能會有很大的改進! – Zabba

+0

您是否知道該方法實際定義的位置?這是我真正想要的一部分。我想它可能在'class.c'中,但我似乎無法找到它。 –

0

我想補充一些有關自己關鍵字樣行爲,因爲答案已經比較瞭解其中如何;答案在於Ruby的複雜元編程功能。 有可能使用它們作爲關鍵字使用method_added鉤子; Ruby中的一個鉤子是一個在特定事件(即鉤子名稱)發生時被調用的函數。 重要的是,method_added掛鉤接收已定義方法的名稱作爲其參數:這樣,可以修改它的行爲。例如,你可以使用這個鉤子來定義類似於Python的裝飾器的行爲;重要的部分是,不同於privateprotected方法,這個裝飾類的方法應該定義一個method_added即取消定義本身:

class Module 
    def simple_decorator 
    eigenclass = class << self; self; end 
    eigenclass.class_eval do 
     define_method :method_added do |name| 
     eigenclass.class_eval { remove_method :method_added } 
     old_name = 'old_' + name.to_s 
     alias_method old_name, name 
     class_eval %Q{ 
      def #{name}(*args, &block) 
      p 'Do something before call...' 
      #{old_name}(*args, &block) 
      p '... and something after call.' 
      end 
     } 
     end 
    end 
    end 
end 

class UsefulClass 
    simple_decorator 
    def print_something 
    p "I'm a decorated method :)" 
    end 

    def print_something_else 
    p "I'm not decorated :(" 
    end 
end 

a = UsefulClass.new 
a.print_something 
a.print_something_else 

simple_decorator看起來像一個語言的關鍵字,並且表現得像private;但是,因爲它刪除了method_added鉤子,它僅適用於緊隨其後的方法定義。

+0

我憐憫那些不得不維護這樣的代碼的可憐人。只因爲你可以,並不意味着你應該。 – mastaBlasta

相關問題