class Moduledef m'm'endendModule.new.m # => "m"Enumerable.m # => "m"Math.m # => "m"Kernel.m # => "m"Class.new.m # => "m"Object.m # => "m"Array.m # => "m"class MyClassendMyClass.m # => "m"Module.m # => "m"Class.m # => "m"
Moduleクラスはモジュールの生成クラスである
だからModuleクラスにinstanceメソッドmを定義すると
すべてのモジュールで定義されたモジュールメソッドself.mになる
KernelモジュールもModuleクラスで生成されるから
当然そのモジュールメソッドself.mになる
一方ModuleクラスはClassクラスのスーパークラスである
だからModuleクラスに定義されたinstanceメソッドmは
Classクラスで定義されたinstanceメソッドmになる
Classクラスはすべてのクラスの生成クラスだから
Classクラスのinstanceメソッドmは
すべてのクラスのクラスメソッドself.mになる
その中にはModuleクラスも含まれるから
Moduleクラスのクラスメソッドself.mにもなる
ここでModuleクラスはClassクラスのスーパークラスだから
Moduleクラスのクラスメソッドself.mは
Classクラスのクラスメソッドself.mになる
こうしてModuleクラスに定義されたinstanceメソッドmは
すべてのクラスにおけるクラスメソッドself.mになる
ここでKernelモジュールはObjectクラスにincludeされているので
そこに定義されたinstanceメソッドはObjectクラスに定義されたメソッドとなる
Objectクラスはすべてのクラスのスーパークラスだから
結果Kernelモジュールに定義されたinstanceメソッドは
すべてのクラスに定義されたinstanceメソッドとなる
ところがModuleクラスからKernelモジュールに渡された先のメソッドmは
Kernelモジュールにおいてモジュールメソッドself.mになるから
Objectクラスには渡されない
Objectクラス(およびKernelモジュール)に定義されたinstanceメソッドoは
すべてのクラスのクラスメソッド(モジュールメソッドを含む)となると共に
すべてのクラスのinstanceメソッドとなる
これはクラスから生成されるすべてのオブジェクトで
instanceメソッドoが使えることを意味している
一方でModuleクラスに定義されたinstanceメソッドmは
すべてのクラスのクラスメソッド(モジュールメソッドを含む)となるが
それらのinstanceメソッドになることはない
これらのことから
すべてのオブジェクトの挙動に影響を与えたいときは
Objectクラスにinstanceメソッドを定義すれば良く
すべてのクラスの挙動に影響を与えたいときは
Moduleクラスにinstanceメソッドを定義すればいい
No comments:
Post a Comment