Ruby の include, extend まとめ

by tanabe on March 26, 2007

この前の話の続き。

include, extend わかった。つか、自分で写した説明のとおりとしか言いようがない。

  • self.include(other) とすると、Mixinにより self に other のインタフェースが実装される。
  • self.extend(other) とすると、 other のインスタンスメソッドを self の特異メソッドとして追加する。

Module はインスタンス化されないから、Module のインスタンスメソッドは extend するか、 include するかしないと使うことができないってだけだった。いったい何が理解できずにはまってたのか、自分でもよくわからず。。

てことで、まとめ。

  • self.include(other) とすると、Mixinにより self に other のインタフェースが実装される。
    • 特異メソッドは実装されない
    • インスタンスメソッドは実装される。public, private, protected もそれぞれの扱いとして実装される
  • self.extend(other) とすると、 other のインスタンスメソッドを self の特異メソッドとして追加する
    • 特異メソッドは実装されない
    • private なインスタンスメソッドは特異メソッドとしては実装されない。private な呼び出しは可能。
module Foo
  def self.a # 特異メソッド
    puts "a"
  end

  def self.b # 特異メソッドからインスタンスメソッドを呼出
    d
  end

  def self.c # 特異メソッドから特異メソッドを呼出
    a
  end

  def self.c_self # 特異メソッドから特異メソッドを呼出
    self.a
  end

  def self.c_foo # 特異メソッドから特異メソッドを呼出
    Foo.a
  end

  def d # インスタンスメソッド
    puts "d"
  end

  def e # インスタンスメソッドから特異メソッドを呼出
    a
  end

  def e_self # インスタンスメソッドから特異メソッドを呼出
    self.a
  end

  def e_foo # インスタンスメソッドから特異メソッドを呼出
    Foo.a
  end

  def f # インスタンスメソッドからインスタンスメソッドを呼出
    d
  end

  def g # インスタンスメソッドから private なインスタンスメソッドを呼出
    h
  end

  def h # private なインスタンスメソッド
    puts "h"
  end
  private :h
end

class Bar
  include Foo
end

class Baz
  extend Foo
end

BarBazFoo
ClassName.method_nameすべてエラーd,e_foo,f,g は問題なく動作a,c,c_self,c_foo は問題なく動作
ClassName.new.method_named,e_foo,f,g は問題なく動作すべてエラー

インスタンス変数の動作。

module Hoge
  def self.set_value
    @hoge = "hoge"
  end

  def self.puts_value
    puts @hoge
  end
end

module Hoge
  def set_instance_value
    @hoge = "hogehoge"
  end

  def puts_instance_value
    puts @hoge
  end
end

class HogeHoge
  include Hoge
end

Hoge.set_value
Hoge.puts_value  #=> hoge

HogeHoge.new.puts_instance_value  #=> nil

ここに書くのが遅くなったから、エントリ上の日付だけ追ってると一週間これに悩んでたみたいだな。ま、いいか。