継承チェーン
継承チェーンとは、そのオブジェクトがなんのオブジェクトを継承しているかのこと。
Rubyではオブジェクトの大元はBasicObject
というオブジェクトです。継承しているオブジェクトをたどっていくと行き着く先はBasicObject
になります。
その過程で継承しているクラスが様々なメソッドをもっていて、それらを僕たちが使っているというイメージです。
コンソールでirbをつかって確認 # Stringのスーパークラスを確認 String.superclass => Object # StringのスーパークラスであるObjectのスーパークラスを確認 Object.superclass => BasicObject # BasicObjectのスーパークラスを確認するがnilとなるのでここが大元となる BasicObject.superclass => nil
これでスーパークラスが何かをたどることができました。 あのメソッドを使いたいが、どのクラスがもっていたかや、このクラスにあるはずのメソッドが使えないときに、継承もとをたどるとミスや勘違いを発見することができるかもです。
2.継承チェーン上のモジュールについて
ancestors
メソッドを使うと親クラスすべてが確認できます。
String.ancestors => [String, Comparable, Object, Kernel, BasicObject] 「Comparable」と「Kernel」はさっきのsuperclassにはなかったが、この2つはモジュールです。 ・ KernelはObjectクラスにインクルードされていて、ComparableはStringにインクルードされています。
- モジュールとクラスの読み込みのタイミング
module A end module B end # クラスC に モジュールAとBをincludeする class C include A include B end p C.ancestors [C, B, A, Object, Kernel, BasicObject] というように、クラスCが読み込まれたあとに、モジュールを下から順に読み込んでいます。 なので、モジュールBがモジュールAのメソッドを使おうとすると読み込む順番的に method_missing が発生します。 # prependメソッドを使用すると読み込む順番が変わる module A end module B end class C prepend A #includeをprependに変更 include B end p C.ancestors [A, C, B, Object, Kernel, BasicObject] となり、クラスよりも先にモジュールAが読み込まれる順に変わりました。 先に予め読み込ませて置くのを『preload』ともいうので覚えておくといいかも!!