Classの特異クラス
疑問:クラスメソッドのメソッド探索では、最終地点はClassだというが、Classの特異メソッドはどういう位置づけか?
「メタプログラミングRuby」では直接書かれていたわけではないので確かめてみた。
- 作者: Paolo Perrotta,角征典
- 出版社/メーカー: KADOKAWA/アスキー・メディアワークス
- 発売日: 2010/08/28
- メディア: 大型本
- 購入: 18人 クリック: 533回
- この商品を含むブログ (125件) を見る
メタプログラミングRubyに書かれていた図は以下のような感じだった。
- "c"は、カレントクラス
- "s"は、スーパークラス
- "#"は、特異クラス
- 緑の矢印は、以下のサンプルコードでのメソッド探索経路
- Classの特異メソッドを作っても、経路の最終地点はClassに収束するというのが面白い。
class Class def hoge puts "Class:hoge" end def hoge_not_eigen puts "Class:hoge_not_eigen" end class << self def hoge puts "EigenClass:hoge" end def hoge_eigen_only puts "EigenClass:hoge_eigen_only" end end end class MyClass end class << MyClass def hoge_my puts "ClassA:hoge_my" end end # (1)の経路を試すメソッド呼び出し MyClass.hoge MyClass.hoge_not_eigen puts MyClass.method_defined?(:hoge_eigen_only) MyClass.hoge_my puts "" # (2)の経路を試すメソッド呼び出し class << MyClass hoge hoge_not_eigen hoge_eigen_only end
標準出力は以下。
Class:hoge Class:hoge_not_eigen false ClassA:hoge_my EigenClass:hoge Class:hoge_not_eigen EigenClass:hoge_eigen_only
しかし、本当のところ、#Classのスーパークラスは図のように単純ではなくて、
#Class → #Module → #Object → #BasicObject → Class
となっている。(ruby 1.9.1p378 で確認)
ただし、通常#Object, #BasicObjectはすでに探索済みなので気にする必要はないので図からは省略した。
(恐らく「メタプログラミングRuby」の図もClassの上階層は省略しているのだと思われる)
class Class p superclass p superclass.superclass p superclass.superclass.superclass p superclass.superclass.superclass.superclass puts "" class << self p superclass p superclass.superclass p superclass.superclass.superclass p superclass.superclass.superclass.superclass end end puts "" class MyClass class << self p superclass p superclass.superclass p superclass.superclass.superclass end end
Module Object BasicObject nil #<Class:Module> #<Class:Object> #<Class:BasicObject> Class #<Class:Object> #<Class:BasicObject> Class