requireとincludeとextend

requireについて調べたら、includeとextendも気になったので調べた。

require

引数のファイルの内容を読み込んで実行する。

include

selfがクラスの時には、モジュールのインスタンスメソッドをクラスでも、 そのまま使えるようにする。実際には、クラスとスーパークラスの間にモジュールを挟むように 継承ツリーを変更しているらしい。

module M
  def instance_m
  end

  def self.class_m
  end
end

class C
  include M
end

C.new.instance_m
#C.new.class_m #=> NoMethodError
#C.class_m #=> NoMethodError

includeメソッドはselfがインスタンスの時には呼び出せない。
ただし、トップレベルではincludeメソッドを呼ぶ出すことができる。トップレベルでのselfはmainで、 mainの特異メソッドにincludeがある。 このincludeを呼び出すと、引数のモジュールのインスタンスメソッドがObjectクラスのインスタンスメソッドに追加される。
Objectクラスにインスタンスメソッドを追加するとObjectクラスのクラスメソッドにも追加される。

module M
  def instance_m
    puts "call instance_m"
  end

  def self.class_m
    puts "call class_m"
  end
end

include M
instance_m #=> "call instance_m"
#class_m #=> NoMethodError
Object.instance_m #=> "call instance_m"


class Sample;end
sample = Sample.new
sample.instance_m #=> "call instance_m"
#Sample.class_m #=> NoMethodError
Sample.instance_m #=> "call instance_m"

extend

引数のモジュールのインスタンスメソッドをselfの特異クラスのインスタンスメソッドに追加する。

module M
  def instance_m
    puts "call instance_m"
  end

  def self.class_m
  end
end

class C
  extend M
end

#C.new.instance_m #=> NoMethodError
#C.class_m #=> NoMethodError
C.instance_m #=> "call instance_m"

c = C.new
c.extend M #cに特異メソッドを追加
c.instance_m #=> "call instance_m"

#C.new.instance_m #=> NoMethodError