includeとextendの違いについて

ふとActionController::TestCaseを読んでいたときに以下のような書き方を見つけた。

  class TestCase < ActiveSupport::TestCase
    module Behavior
      extend ActiveSupport::Concern
      include ActionDispatch::TestProcess
  :

勉強不足だ。。とりあえず調べてみると、以下の記事が見つかった。

http://rubyist.g.hatena.ne.jp/yamaz/20060722

どうやらincludeはインスタンスメソッドとして、extendはクラスメソッドとしてmodule内の記述を追加できるようだ。
試しに以下を書いてみた。

module Test
  def self.func1
    puts "func1"
  end

  def func2
    puts "func2"
  end
end

Test.func1 #=> Module functionとしての使い方

class A
  include Test
end

a = A.new; a.func2
#A.func2 #=> error

class B
  extend Test
end

B.func2
#b = B.new; b.func2 #=> error

出力結果は以下

func1
func2
func2

確かにmodule TestのMixin用関数func2が以下のように定義されることが確認できた。

  • includeではインスタンスメソッドとして定義される。
  • extendではクラスメソッドとして定義される。

ちなみにModule内のインスタンス(?)変数についてはinclude、extendされたクラス内でインスタンス変数として使えるようだ。
この辺りはよくわからん。