ravelll の日記

よしなに

Module#prepend と Module#include

Module#prepend をあまり知らなかったので Module#include と比較しつつコードを書いて確かめた。


Module#prepend はモジュールを継承チェーンの先頭に追加するメソッド
一方で Module#include はモジュールを継承チェーンのひとつ手前に追加する。

module A
end

module B
end

class C
  prepend A
  include B
end

p C.ancestors # => [A, C, B, Object, Kernel, BasicObject]

複数のモジュールを prepend すると最後に prepend したモジュールが先頭になる。
一方で include は最後に include したモジュールがひとつ手前に置かれる。
つまり、どちらも最後に加えたモジュールの振る舞いが優先される。

module A
  def include_test
    'A'
  end
end

module B
  def include_test
    'B'
  end
end

module C
  def prepend_test
    'C'
  end
end

module D
  def prepend_test
    'D'
  end
end

class E
  include A
  include B
  prepend C
  prepend D
end

e = E.new
p e.class.ancestors # => [D, C, E, B, A, Object, Kernel, BasicObject]
p e.include_test # => B
p e.prepend_test # => D

なるほど〜。
学びがありました。よかったですね。