2017-06-09 118 views
2

示例代碼:如何覆蓋擴展方法?

module B 
    def f2 
    puts "B::f2" 
    end 
end 

class C 
    def initialize 
    extend B 
    end 

    def f2 
    puts "C::f2" 
    end 
end 

c = C.new 
c.f2 

上面的示例代碼是我的問題的抽象。 Class C延伸module B在飛行(B實際上延伸到C的實例)。方法f2 from B不符合我的需要,所以我想覆蓋f2。如何實現?

+2

好,你_are_覆蓋'C#有一個從'B' f2'。爲什麼你做這個動態擴展而不是通常的任何原因包括? –

+0

因爲在我的真實代碼中,'B'是一個可配置的插件。 – TieDad

回答

2

我其實不喜歡在initialize中擴展。以不同的方式實現「插件」有很多原因。 但是,如果你想通過這種方式來「的腳開槍」,OK,只是做一個更擴展:

module B 
    def f2 
    puts 'B::f2' 
    end 
end 

class C 
    attr_reader :parent_state 

    def initialize 
    extend B 
    extend BOverrides 

    @parent_state = 'Parent State' 
    end 

    module BOverrides 
    def f2 
     puts 'C::f2' 
     puts 'Yes, I have access to %s' % parent_state 
    end 
    end 
end 

c = C.new 
c.f2 
+0

感謝您的回答。在我的真實代碼中,我沒有在初始化中進行擴展,我有一個load_plugin方法,它在initialize中也沒有被調用。 – TieDad

+0

我的意思是「延長」是不是最好的主意。您可以更標準的方式實施'策略'設計模式。例如,你可以將你的插件作爲具有相同接口的類來實現,並將其類名或實例放到'C''initialize'中。或者你可以創建DSL,它可以在代碼加載時提供擴展,而不是在運行時。它是爲Rails和其他框架和寶石配置代碼的非常標準的方法。 –