メソッド探索の注意点

メタプログラミングRuby、「月曜日」の最後のクイズから。

module Printable
  def print 
    p "Print in Printable Module!"
  end

  def prepare_cove
    p "Prepare Cover!"
  end
end

module Document
  def print_to_screen
    prepare_cove
    format_for_screen
    print
  end

  def format_for_screen
    p "Format for Screen!"
  end

  def print
    p "Print in Document module."
  end
end

class Book
  include Document
  include Printable
end

b = Book.new
b.print_to_screen

Bookクラスの継承関係は以下のようになっており、includeした順番を素直に反映している。(あとにincludeしたモジュールが後ろに来ている。)

[Book, Printable, Document, Object, Kernel, BasicObject]

Bookクラスのインスタンスに対して、「print_to_screen」を実行した時点で、まずはメソッドが存在する「Document」モジュールのメソッドを実行する。

Documentモジュールの「print_to_screen」メソッドが実行された後、すべてのモジュール探索は「self」に戻って行われる。つまり、メソッド探索はすべて継承関係の一番下から開始される。

Documentモジュールの「print_to_screen」メソッドが実行されると、最後に「print」というメソッドが呼び出される。これは、Documentモジュールにも存在するメソッド名だが、Documentモジュールは継承関係の一番下にはいない。

継承関係の一番下は「Printable」モジュールであり、「Printable」モジュールのメソッドが実行される。Documentモジュールのprintメソッドを実行したい場合は、includeの順番を逆にすればよい