2014-02-14 19 views
0

我需要一個很重的aspect oriented programming library鴨式方法與前後連接點的建議,或者我可以做幾行Ruby嗎?在Ruby中簡單的面向方面的duck-typing?

例如,我有以下功能:

def add_them(a,b) 
    a + b 
end 

我想鴨式add_them()與之前的連接點,因此在執行主體之前類型檢查:

if (a.class != b.class) 
    puts "DANGER" 
end 

鴨子打字的天真方式破壞了原始的add_them()。理想情況下,我想最終:

def foo 
    #before join point code 
    #original body of foo 
    #after join point code 
end 

回答

3

有兩種方法可以做到這一點。

首先,如果你是混合模塊到你的類,你可以簡單地調用super調用覆蓋的方法:

class Foo 
    def bar(a, b) 
    a + b 
    end 
end 

module TypeEnforcer 
    def bar(a, b) 
    raise "Wrong type!" unless a.is_a? Fixnum && b.is_a? Fixnum 
    super 
    end 
end 

Foo.send :include, TypeEnforcer 

如果通過重新打開同一個類是猴子打補丁,但是,你將使用alias_method來創建你覆蓋方法的「備份」:

class Foo 
    alias_method :orig_bar, :bar 
    def bar(a, b) 
    raise "Wrong type!" unless a.is_a? Fixnum && b.is_a? Fixnum 
    orig_bar(a, b) 
    end 
end 

最後,雖然這並不能回答你的問題,你可能有興趣在contracts.ruby其中使用了Ruby元編程魔法加合型ntracts方法。它確實有一些性能開銷,但它是表達這種行爲的一種非常乾淨的方式。

+1

'include'會使'TypeEnforcer'成爲'Foo'的一個*超類*。你需要使用'prepend'。 –

+0

啊,是的,這是正確的。我的錯! –

+0

alias_method正是我所期待的。謝謝!它看起來也非常適用於備忘錄,並且它適用於Ruby1.9 –