クラス階層を書き出す

突然Rubyのクラス階層を厳密に知りたくなった。Rubyリファレンスマニュアルはアテにならないので、せっかくなのでRubyに訊いてみた。

Ruby 1.8.7の場合。

RUBY_VERSION    # => "1.8.7"
# まず、スーパークラス=>サブクラスのHashを作成する。
table = {}.tap{|h| ObjectSpace.each_object(Class){|c| (h[c.superclass] ||= []) << c}}
table[nil]      # => [Object]
table[Integer]  # => [Bignum, Fixnum]
table[NilClass] # => nil

def class_hierarchy(table, indent=0, sup=nil)
  excepts = [Exception]         # 詳細を省略するクラス
  return unless table[sup]
  table[sup].sort_by{|c| c.name}.each do |c|
    puts "#{'  '*indent}#{c}"
    class_hierarchy(table, indent+1, c) unless excepts.include? c
  end
end
class_hierarchy(table)
# >> Object
# >>   Array
# >>   Binding
# >>   Continuation
# >>   Data
# >>     NameError::message
# >>   Dir
# >>   Enumerable::Enumerator
# >>   Exception
# >>   FalseClass
# >>   File::Stat
# >>   Hash
# >>   IO
# >>     File
# >>   MatchData
# >>   Method
# >>   Module
# >>     Class
# >>   NilClass
# >>   Numeric
# >>     Float
# >>     Integer
# >>       Bignum
# >>       Fixnum
# >>   Proc
# >>   Process::Status
# >>   Range
# >>   Regexp
# >>   String
# >>   Struct
# >>     Struct::Tms
# >>   Symbol
# >>   Thread
# >>   ThreadGroup
# >>   Time
# >>   TrueClass
# >>   UnboundMethod

Ruby 1.9.0の場合。

RUBY_VERSION    # => "1.9.0"
# まず、スーパークラス=>サブクラスのHashを作成する。
table = {}.tap{|h| ObjectSpace.each_object(Class){|c| (h[c.superclass] ||= []) << c}}
table[nil]      # => [BasicObject]
table[Integer]  # => [Bignum, Fixnum]
table[NilClass] # => nil

def class_hierarchy(table, indent=0, sup=nil)
  excepts = [Exception]         # 詳細を省略するクラス
  return unless table[sup]
  table[sup].sort_by{|c| c.name}.each do |c|
    puts "#{'  '*indent}#{c}"
    class_hierarchy(table, indent+1, c) unless excepts.include? c
  end
end
class_hierarchy(table)
# >> BasicObject
# >>   Object
# >>     ARGF.class
# >>     Array
# >>     Binding
# >>     Data
# >>       NameError::message
# >>     Dir
# >>     Encoding
# >>     Enumerable::Enumerator
# >>     Exception
# >>     FalseClass
# >>     Fiber
# >>     File::Stat
# >>     Hash
# >>     IO
# >>       File
# >>     MatchData
# >>     Method
# >>     Module
# >>       Class
# >>     Mutex
# >>     NilClass
# >>     Numeric
# >>       Complex
# >>       Float
# >>       Integer
# >>         Bignum
# >>         Fixnum
# >>       Rational
# >>     Proc
# >>     Process::Status
# >>     Range
# >>     Regexp
# >>     String
# >>     Struct
# >>       Struct::Tms
# >>     Symbol
# >>     Thread
# >>     ThreadGroup
# >>     Time
# >>     TrueClass
# >>     UnboundMethod
# >>     VM
# >>     VM::Env
# >>     VM::InstructionSequence