この前の話の続き。
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
| Bar | Baz | Foo | |
|---|---|---|---|
| ClassName.method_name | すべてエラー | d,e_foo,f,g は問題なく動作 | a,c,c_self,c_foo は問題なく動作 |
| ClassName.new.method_name | d,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
ここに書くのが遅くなったから、エントリ上の日付だけ追ってると一週間これに悩んでたみたいだな。ま、いいか。