ルックアップ チェーンを壊さずに 2 つの Ruby モジュールをマージしたいと考えています。BothAnB
基本的に、A と B のテキスト ソース コードを連結し、新しい foo が古いものを置き換えたかのように、 の動作を正確に行いたいと考えています。この問題は、MRO が継承ダイヤモンドを線形化するときに発生します。
module O
def foo; puts "O" end
end
module A
include O
def foo; puts "A"; super end
def aaa; puts "aaa" end
end
module B
include O
def foo; puts "B"; super end
def bbb; puts "bbb" end
end
module BothAnB
#insert magic here such that a class C that includes BothAnB:
# C.new.foo => B O
# C.new.aaa => aaa
# C.new.bbb => bbb
end
module JustA
#insert magic here such that a class C that includes JustA:
# C.new.foo => A O
# C.new.aaa => aaa
# C.new.bbb => FAIL
end
#and similarly JustB
A と B はかなり複雑なモジュールであり、深い継承チェーンを持つことができます (これは、プログラマーがそれを行うことを可能にするメタプログラミング フレームワークのためのものです)。
Include B, A
ルックアップ BothAnB->B->A->O の代わりに、BothAnB->B->O (およびオプションで ->A) である必要があるため、機能しません。私は近くに来ました:
- A の継承ツリー全体のディープ クローニング (ダイヤモンドを削除するため)
undef_method
A のクローンで、B にあるメソッドを削除しますModule
この動作を反映するための新しいメソッドを作成する
これよりも良い解決策はありますか?を呼び出すときに少なくともいくつかのモジュールを認識できるようにしておくことが理想的ですBothAnB.ancestors
。
[注: Phrogz のフィードバックに基づいて 2 つの回答を得た後、質問を完全に変更しました。