ナスカブログ

未来の自分へのドキュメント

ruby tips (include, prepend, extend)

rubyのinclude, prepend, extendについての理解が曖昧だったのでそれぞれの違いをまとめていく

include prepend extend
メソッドの種類 インスタンスメソッド インスタンスメソッド クラスメソッド
メソッド探索 対象のクラスの後 対象のクラスの前 対象のクラスの後

include

module Fuga
  def hello
    p "Hello Fuga"
  end
end

module Fuga2
  def hello
    p "Hello Fuga2"
  end
end

class Hoge1
  include Fuga, Fuga2
  p self.ancestors #=> [Hoge1, Fuga, Fuga2, Object, Kernel, BasicObject]

  def hello
    p "Hello Hoge1"
  end
end

Hoge1.new.hello #=> "Hello Hoge1"
Hoge1.hello #=> undefined method `hello' for Hoge1:Class (NoMethodError)

prepend

module Fuga
  def hello
    p "Hello Fuga"
  end
end

module Fuga2
  def hello
    p "Hello Fuga2"
  end
end

class Hoge3
  prepend Fuga, Fuga2
  p self.ancestors #=> [Fuga, Fuga2, Hoge3, Object, Kernel, BasicObject]
  def hello
    p "Hello Hoge3"
  end
end

Hoge3.new.hello #=> "Hello Fuga"
Hoge3.hello #=> undefined method `hello' for Hoge3:Class (NoMethodError)

extend

module Fuga
  def hello
    p "Hello Fuga"
  end
end

module Fuga2
  def hello
    p "Hello Fuga2"
  end
end

class Hoge2
  extend Fuga, Fuga2
  p self.ancestors #=> [Hoge2, Object, Kernel, BasicObject]
  def hello
    p "Hello Hoge2"
  end
end

Hoge2.new.hello #=> "Hello Hoge2"
Hoge2.hello #=> "Hello Fuga"

まとめ

  • インスタンスメソッドとして使用したい場合はincludeprepend
  • クラスメソッドとして使用したい場合はextend
  • 読み込むモジュールのメソッドを優先して使用したい場合はprepend