demolog

備忘録. 雑なあまりにも雑な

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]