この前買った「Pro Active Record」を読んでいたら、どストライクな説明を見つけてバチッときたのでその部分を翻訳して大引用。
includeされたメソッドとextendされたメソッドには微妙な違いがあります。
モジュールをクラスにincludeすると、モジュール内に定義されたメソッドはそのクラス内に定義されたものとして扱われます。
つまりモジュールをincludeすると、それらのメソッドはそのクラスのすべてのインスタンスからアクセスできます。
対して、オブジェクトにモジュールをextendすると、モジュール内に定義されているメソッドはそのオブジェクトに対してのみ有効となります。
クラスにincludeされたメソッドはそのクラスのすべてのインスタンスに、extendされたメソッドはそのオブジェクトにのみ影響します。—– P.120 Pro Active Record (Apress, 2007) by Kevin Marshall, Chad Pytel, Jon Yurek
Rubyリファレンスマニュアルと言っていることは同じなんだけど、言い回しがきた原因なんだと思う。
で、問題の場所はプラグインの参考元から持ってきたこの部分
module ActMethods
def acts_as_fortuned
self.extend ClassMethods
self.instance_eval {include InstanceMethods}
before_save :cast
end
end
なんでClassMethodsがextendでInstanceMethodsがincludeなのかってことだった。
これはClassMethodsはクラスオブジェクトだけにしか追加したくないからextendを、InstanceMethodsはクラス定義に追加したいからincludeってことか。
「クラスオブジェクト」とその構造を表す「クラス定義」としっかり分けて考えればよかったんだ。
[ref.] extendとincludeについて。
[ref.] プラグインを作ってみた。
Pro Active Record: Databases with Ruby and Rails (Pro) Apress(2007-09-10)
Apress |