Monday, September 15, 2008

Class_tree

クラスの一覧をクラス階層に従ってソートしたいんだけど
もう一歩のところでやり方が分からない
いい線行ってると思うんだけれどだめだ


   1  #!/usr/local/bin/ruby

   2  # encoding: utf-8

   3  def get_klasses(obj)

   4    klasses = obj.constants.sort.map{ |c| eval(c.to_s) }.select{ |c| c.class.to_s =~ /^(Class|Module)$/ }

   5    normal_class, module_class, error_class, erb_class = [],[],[],[]

   6    klasses.each do |klass|

   7      case

   8      when klass.to_s =~/ERB|StringScanner/

   9        erb_class << klass

  10      when klass.to_s =~ /Error/

  11        error_class << klass

  12      when klass.class == Module

  13        module_class << klass

  14      else

  15        normal_class << klass

  16      end

  17    end

  18    return normal_class, module_class, error_class

  19  end

  20  

  21  def get_methods(klass)

  22    result = []

  23    meths = %w(public_methods protected_methods private_methods public_instance_methods protected_instance_methods private_instance_methods)

  24    begin

  25      meths.each do |m|

  26        meth = klass.send(m,false)

  27        meth.delete_if { |m| m =~ /get_klasses|get_methods|get_supers/ } if klass == Object

  28        result << {m => meth.sort} unless meth.empty?

  29      end

  30    rescue Exception => e

  31  

  32    end

  33    result

  34  end

  35  

  36  def get_supers(klass)

  37    (klass.superclass ? get_supers(klass.superclass) : []).unshift(klass)

  38  end

  39  

  40  klasses, modules, errors = get_klasses(Object)

  41  all_klasses = klasses + modules + errors

  42  

  43  klasses = (klasses).sort_by { |k| k.superclass.to_s }

  44  

  45  class Array

  46    def class_tree(parents)

  47      result = []

  48      parents.each do |parent|

  49        s_class = select{ |this| this.superclass == parent }

  50        result << class_tree(s_class) << s_class

  51      end

  52      result

  53    end

  54  end

  55  

  56  klasses = [Object, Integer, File, Numeric, IO, String]

  57  p klasses.class_tree([BasicObject])

No comments: