2015-08-27 36 views
6

this answer提到的,在紅寶石2.1或更高,這樣的代碼:是否可以動態檢查方法可見性範圍(private/public/protected)?

class SimpleTest 
    private 

    define_method :foo do 
    42 
    end 
end 

將定義foo作爲SimpleTest實例的私有方法。 (在Ruby 2.0及更早的版本中,它不會是私有的。)但是,我期待着做一些不重要的事情。我想定義類可以擴展的DSL,並且希望DSL在內部定義的方法能夠尊重調用上下文的私有/受保護的可見性。這可能不是很清楚,所以這裏有一個例子:

module Dsl 
    def has_a(name) 
    define_method name do 
     42 
    end 
    end 
end 

class Test 
    extend Dsl 

    private 

    has_a :thing 
end 

書面,該代碼將定義上Test實例一公共thing方法。相反,我希望has_a能夠反映其調用方法的可見性(本例中爲private),並在該方法可見性下定義thing

我對Ruby的C源代碼並不熟悉,但我快速瀏覽了一下,發現this function看起來好像可以做我想做的事,但我認爲它不能從Ruby訪問。 (這似乎只能用here)。我也查閱了文檔define_method(因爲第一個示例根據需要),here而且好像宣稱,在這裏設置noex變量:

int noex = NOEX_PUBLIC; 
const NODE *cref = rb_vm_cref_in_context(mod, mod); 

if (cref) { 
    noex = (int)cref->nd_visi; 
} 

可能是我想要的值,但是我不知道如何在Ruby中獲得這個值,或者即使它能夠反射回調用範圍(在Test中)。假設我有知名度,那麼我可以簡單地裏has_adefine_method調用後調用private name(或protected name),如果它不是在public上下文調用。

想法?有沒有辦法做到這一點,或者我運氣不好?

回答

1

我認爲這個問題有一個類似的答案,你在找什麼:https://stackoverflow.com/a/28075865/5129208

它看起來像的是,筆者做了一個自定義模塊讓你以後的行爲。

+0

謝謝你的指點。我在查詢之前沒有看到它。這是一個有趣的解決方案,但我寧願不必在「Module」中添加某些內容。 – rmacklin