2016-04-22 35 views
1

我有一個Ruby類C,其中包括一些第三方模塊,說AB在Ruby中,是否可以將模塊移到祖先鏈上?

模塊A通過C的類繼承鏈間接包含;假設我無法控制A的位置。現在,C包括B直接,但B包括另一模塊D這恰好提供也由A提供的功能,例如:

class C < Base 

    # Base includes A 

    include B # includes D 

    # methods in A overridden by D 

end  

祖先鏈是這樣的(其中...表示零個或多個其它這是不相關的討論祖先):

C ... B ... D ... A 

我想要的A功能採取precdence超過D:我想移動A所以它是在祖先鏈的D前,像這樣:

C ... A ... B ... D 

我已經嘗試只是包括A再次但這並沒有工作。有沒有辦法做到這一點?

+0

你看過嗎[莫獨樂#prepend'(http://ruby-doc.org/core-2.3.0/Module.html#method-i-prepend)? – Myst

+0

P.S.我的意思是,預先加上'A',然後加上'B' ....另外 - 不會改變破壞'B'的實現(可能依賴於原始繼承流程)的層次結構風險? – Myst

+0

會有這種風險,但在這種特殊情況下,我知道風險不存在。我只有這個問題,因爲B包括了它不應該的東西。 – starfry

回答

2

一旦建立了mixin層次就不可能改變。只有包含順序決定了層次結構。你必須包括AC(首次),您包括BC後,或者,如果你在前面加上AC,而不是包括它的,那麼它將優先於D即使B被納入C以後。

+0

我已經爲該問題添加了一個類示例。我已經嘗試了很多'include A'和'prepend A'的排列,但沒有成功。 – starfry

+1

您不能在同一個類中多次包含或預先添加一個模塊。正如我寫的,第一次包含/預先**的時間很重要。 – sawa

+0

啊我得到你,這是**第一次**的事情。這就是我的想法,最後我得出了你確認的結論,即不能做到。 – starfry

1

當然可以。我每天都做,每週星期兩次。嗯,有點...

module A 
    def hiya(str) 
    puts "ho #{str}" 
    end 
    def if_what? 
    end 
end 

module D 
    def hiya(str) 
    puts "hi #{str}" 
    end 
    def what_if? 
    end 
end 

module B 
    include D 
end 

class C 
    include A 
    include B 
end 

正如預期的那樣:

C.ancestors 
    #=> [C, B, D, A, Object, Kernel, BasicObject] 
a = C.new 
    #=> #<C:0x007fc56324ed40> 
a.hiya("Lois") 
hi Lois 

要調用A的實例方法,而不是D的,我們可以這樣寫:

(A.instance_methods & D.instance_methods).each { |m| D.send(:remove_method, m) } 

讓我們來看看:

D.instance_methods 
    #=> [:hiya, :what_if?] 
(A.instance_methods & D.instance_methods).each { |m| D.send(:remove_method, m) } 
    #=> [:hiya] 
D.instance_methods 
    #=> [:what_if?] 
C.instance_methods.include?(:hiya) 
    #=> true 
a.hiya("Lois") 
ho Lois 
+0

我試過這個,它確實有效,但它不會改變祖先鏈 - 它將從模塊中移除該方法,這會影響使用它的其他任何方法。有沒有在'C'類範圍內達到效果的方法,以便包括'D'的其他類不受影響? – starfry

+0

這就是我的意思,「好吧,有點......」。 @sawa已經解釋說,祖先鏈不能重新排列(對你的問題的答案),所以沒有什麼可說的。我只是告訴你一些東西可以做到這一點,會有同樣的效果,你想要什麼去做。我不明白你在'C'類範圍內的其他類是什麼意思。類不能包含類。 –

+0

我的意思是從'D'l中刪除的方法被限制在它包含在'C'類中,以便包括'D'在內的其他類不受影響。我只是想知道如果你知道某些東西,但我意識到在所有類別的祖先鏈中都是相同的'D',並且對'D'的改變會影響所有具有'D'作爲祖先的類。 – starfry

相關問題