Help us understand the problem. What is going on with this article?

Ruby のオブジェクトの継承関係を tree コマンドっぽく表示する

More than 1 year has passed since last update.

ruby のオブジェクトの継承関係を tree っぽく表示することが出来るようになります。

class ObjectTree
  SPACE_SIZE = 8
  T_LINE = '├─────'
  I_LINE = '│'
  L_LINE = '└─────'

  def self.create(klass)
    new(klass)
  end

  def initialize(klass)
    @queue = []
    walk(klass)
  end

  def to_s
    @queue.join
  end

  private

  def output_node(klass)
    klass.instance_of?(Class) ? "<C> #{klass}\n" : "<M> #{klass}\n"
  end

  def get_line(end_line: nil, space: '')
    end_line ? "#{space}#{L_LINE} " : "#{space}#{T_LINE} "
  end

  def get_space(end_line: nil)
    end_line ? ' ' * SPACE_SIZE : I_LINE + ' ' * (SPACE_SIZE - 1)
  end

  def walk(klass, space = '', path: [])
    path << klass
    @queue << output_node(klass)
    modules = get_modules(klass, path.reverse)

    while sub = modules.shift
      @queue << get_line(end_line: modules.empty?, space: space)
      walk(sub, space + get_space(end_line: modules.empty?), path: path.dup)
    end
  end

  def get_modules(klass, path)
    ObjectSpace.each_object(Module).map do |k|
      l = k.ancestors
      if l.each_cons(path.size).include?(path)
        (l[l.index(k)..l.index(klass)] - path).last
      end
    end.compact.uniq.sort_by(&:to_s)
  end
end

puts ObjectTree.create(Numeric)

実行結果

<C> Numeric
├───── <C> Complex
├───── <C> Float
├───── <C> Integer
└───── <C> Rational

Ruby のバージョンが 2.4 以前だと結果が異なります。(Integer に統一される前)

<C> Numeric
├───── <C> Complex
├───── <C> Float
├───── <C> Integer
│       ├───── <C> Bignum
│       └───── <C> Fixnum
└───── <C> Rational

BasicObject の結果はちょっと大きかったので gist に貼り付けておきます

https://gist.github.com/siman-man/eb696cea856bffb9fc18dc668756c1d1

Gem にしました

gem のほうは結果に色がついてちょっとだけ見やすくなっています。

https://github.com/siman-man/object_tree

こんな感じで使えるようになります

sample.rb
require "object_tree"

module D
end

module E
end

class A
  include D
end

class B < A
end

class C < A
  include E
end

class F < B
  include E
end

puts ObjectTree.create(D)

結果

<M> D
└───── <C> A
        ├───── <C> B
        │       └───── <M> E
        │               └───── <C> F
        └───── <M> E
                └───── <C> C
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away