2012-08-17 15 views
1
module B 
    def stub 
    extend() 
    end 

    def extend 
    puts "B:extend" 
    end 
end 

class A 
    include B 
    def extend 
    puts "A:extend" 
    end 
end 

a = A.new 

a.stub 
# output: A:extend 
# would like to have: B:extend 

的問題是:
如何使a.stub呼叫從模塊Bextend方法,而無需修改B的代碼和不重命名A的方法extendruby​​192:具體方法調用

回答

2

include BB的方法添加到A,因此您的方法定義覆蓋B的實現。

你可以使用alias方法保存到B的方法引用,並實現自己的stub方法A

class A 
    include B 
    alias :b_extend :extend 

    def stub 
    b_extend 
    end 

    def extend 
    puts "A:extend" 
    end 
end 

A.new.stub 
# B:extend 
1

也許猴子補丁可以解決這個問題。

module B 
    alias original_stub stub 
    alias b_extend extend 
    def stub 
    b_extend 
    end 
end 

但是,如果您的項目確實有很多調用原始存根......每個調用都應該修改。

+0

需要說明的是,'stub'來自RSpec gem,所以我已經詢問過有關'B'代碼未被修改的解決方案。 – ted 2012-08-17 09:53:56

1
def a.extend 
    self.class.ancestors[1].instance_method(:extend).bind(self).call 
end 
1

我只是一個嘗試。

A.class_eval do 
if self.include? B 
    def extend 
    super 
    end 
    end 
end 

A.new.stub 
#=> B:extend 

如果這是一個錯誤的方法,糾正我。