Classの特異クラス

疑問:クラスメソッドのメソッド探索では、最終地点はClassだというが、Classの特異メソッドはどういう位置づけか?
メタプログラミングRuby」では直接書かれていたわけではないので確かめてみた。

メタプログラミングRuby

メタプログラミングRuby


メタプログラミングRubyに書かれていた図は以下のような感じだった。

調べた結果このようになっていた。

  • 緑の矢印は、以下のサンプルコードでのメソッド探索経路
  • 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