Rubyでinclude/prependがそれぞれ連続したときの継承ツリー
Ruby Association Certified Ruby Programmer Gold version 2.1取得に向けてincludeとprependの動きを確認。
include
クラスの上に、最後に定義された順でモジュールが積み上がっていくイメージと覚える。
module M1; end module M2; end module M3; end class C1 include M1 include M2 include M3 end C1.ancestors # [C1, M3, M2, M1, Object, Kernel, BasicObject]
prepend
クラスの下に、最初に定義された順でモジュールがぶら下がっていくイメージと覚える。
module M1; end module M2; end module M3; end class C1 prepend M1 prepend M2 prepend M3 end C1.ancestors # [M3, M2, M1, C1, Object, Kernel, BasicObject]
親子クラスで同じモジュールをinclude / prependした場合
継承ツリー上、同じモジュールは複数セットされない。 親クラスのモジュールの定義が優先される。
include
module M1; end class P1 include M1 end class C1 < P1 include M1 end C1.ancestors # [C1, P1, M1, Object, Kernel, BasicObject]
prepend
module M1; end class P1 prepend M1 end class C1 < P1 prepend M1 end C1.ancestors # [C1, M1, P1, Object, Kernel, BasicObject]
include / prepend混合
module M1; end module M2; end module M3; end class P1 include M1 include M2 include M3 end class C1 < P1 prepend M2 end C1.ancestors # [C1, P1, M3, M2, M1, Object, Kernel, BasicObject]