2017-06-09 179 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和其他框架和宝石配置代码的非常标准的方法。 –