2017-03-28 129 views
2

幾乎所有關於Ruby中面向對象的體面資源都聲明訪問修飾符的存在 - 關鍵字public,privateprotected - 並展示如何正確使用它們。更少的解釋是這些修飾符是而不是關鍵字,但它們是實際的方法,並且調用它們會修改此特定類中未來定義的所有方法的可見性。但是,我找不到任何關於的信息,他們實際上是如何做到這一點的。他們是否改變了一個特殊的內部變量,或者他們改變了當前範圍/綁定的屬性,還是他們設置了一些特定的解釋器標誌,或者......或者什麼?「公共」,「私人」和「受保護」方法的確切做法是什麼?

我自己做了一些小小的研究,但這讓我更加困惑。請看下面的代碼片段:

class Test 
    public 
    define_method :public_define_method do 
     puts 'Public define_method' 
    end 

    private 
    define_method :private_define_method do 
     puts 'Private define_method' 
    end 

    public 
    def public_def 
     puts 'Public def' 
    end 

    private 
    def private_def 
     puts 'Private def' 
    end 
end 

t = Test.new 

t.public_define_method 
t.private_define_method 
t.public_def 
t.private_def 

#Output: 
#> Public define_method 
#> Private define_method 
#> Public def 
#> sandbox.rb:29:in `<main>': private method `private_def' called for #<Test:0x00000001cdfd38> (NoMethodError) 

我始終認爲,def作爲一種優化的語法糖define_method與創建新的變量能見度範圍的額外的怪癖,但很明顯,似乎有更多的東西 - 使用def創建的方法受private/public修飾符的影響,而使用define_method創建的方法不受此影響。此外,define_methoddoesn't have所有與改變方法的可見性有關的參數,這導致了我的結論:關於它的信息必須存儲在類中,而不是方法本身 - 所以應該是訪問修飾符設置的標誌。但爲什麼defdefine_method有所不同呢?在後臺發生了什麼?它是否檢查通過訪問修飾符方法設置的標誌,然後將其自身添加到類'私有/受保護的方法的一些特殊的隱藏的註冊?..

總之,我很困惑,並會非常高興,如果comeone可以請澄清問題。提前致謝!

回答

1

是嗎?

公共 http://apidock.com/ruby/Module/public

不帶任何參數,設置了隨後定義的方法來公開默認可見性。使用參數,可以將命名方法設置爲公開可見性。

來源:

static VALUE 
rb_mod_public(int argc, VALUE *argv, VALUE module) 
{ 
    secure_visibility(module); 
    if (argc == 0) { 
     SCOPE_SET(NOEX_PUBLIC); 
    } 
    else { 
     set_method_visibility(module, argc, argv, NOEX_PUBLIC); 
    } 
    return module; 
} 

私人http://apidock.com/ruby/Module/private

不帶任何參數,設置了隨後 定義的方法,以私人默認可見性。通過參數,將指定方法設置爲 具有私密可見性。

來源:

static VALUE 
rb_mod_private(int argc, VALUE *argv, VALUE module) 
{ 
    secure_visibility(module); 
    if (argc == 0) { 
     SCOPE_SET(NOEX_PRIVATE); 
    } 
    else { 
     set_method_visibility(module, argc, argv, NOEX_PRIVATE); 
    } 
    return module; 
} 

保護http://apidock.com/ruby/Module/protected

不帶任何參數,設置了隨後 定義方法的默認能見度保護。使用參數,將命名方法 設置爲具有受保護的可見性。

static VALUE 
rb_mod_protected(int argc, VALUE *argv, VALUE module) 
{ 
    secure_visibility(module); 
    if (argc == 0) { 
     SCOPE_SET(NOEX_PROTECTED); 
    } 
    else { 
     set_method_visibility(module, argc, argv, NOEX_PROTECTED); 
    } 
    return module; 
} 

這並沒有真正與該信息的實際應用有所幫助,但是。您可能會在What are the differences between "private", "public", and "protected methods"?Why does Ruby have both private and protected methods?等問題上找到更多真實世界的適用信息。

+0

謝謝你的答案,但它不完全是我要找的。我已經知道Ruby中的封裝是如何工作的以及調用這些方法的結果,我試圖理解他們在底層*所做的事情。請重讀這個問題。我不太瞭解C++,所以自己挖掘解釋器的源代碼只會導致更多的混淆。代碼片段確實有幫助,但是您能否詳細解釋一下'SCOPE_SET'和'set_method_visibility'的作用?例如,「public」/'protected' /'private'的效果是否可以在純Ruby中複製,或者是否是硬編碼的?謝謝! – DeFazer

相關問題