From: Wejn Date: 2002-09-30T07:31:04+09:00 Subject: Inheritance tree -- how to improve this piece of code? Hi, yesterday I was lazy to work so I toyed with Ruby a while ... the result is proggie which draws ancestors for any class found in ObjectSpace as graph. I think the code is not-so-badly written and I'm no longer able to shorten it. Is there anybody (more experienced) who can show me (I'm just another Ruby newbie) how to write such proggie in both readable and efficient way? Thanks in advance, W. # -- cut here ---------------------------------------------------------------- #!/usr/bin/env ruby =begin Descr: Pretty prints (or returns) object hierarchy Methods: get_class_hierarchies_in_hash -- returns class hierarchies in hash (used by pretty_print) get_object_hierarchy(klass) -- returns array with sorted ancestors for specified class: A < B < C ====> [C, B, A] pretty_print(what = nil) -- pretty prints class hierarchies (what==nil) or specified data ObjectPrettyPrint.new(4).pretty_print({1=>{}, 1=>{1=>{}, 2=>{2=>{}, 3=>{}}}}) # => # 1 # |-- 1 # `-- 2 # |-- 2 # `-- 3 Author: Wejn License: Same as Ruby's =end class ObjectPrettyPrint def initialize(increment = 4) raise RuntimeError, "Increment must be at least 4 !" if increment < 4 @pfx_f = "|" + " " * (increment - 1) @pfx_e = " " * increment @pfx_n = "|" + "-" * (increment - 2) + " " @pfx_l = "`" + "-" * (increment - 2) + " " @increment = 4 end private def recursive_print(what, dir = [], root = false) pfx = "" dir.each { |x| pfx << (x ? @pfx_f : @pfx_e) } sarr = what.sort{ |x, y| x[0].to_s <=> y[0].to_s } sarr.each do |x, y| if root puts x.to_s recursive_print(y, []) unless y.empty? else print pfx, sarr[-1][0] == x ? @pfx_l : @pfx_n, x.to_s, "\n" recursive_print(y, dir + [sarr[-1][0] != x]) unless y.empty? end end puts pfx what end public def pretty_print(what = nil) recursive_print(what.nil? ? get_class_hierarchies_in_hash : what, [], \ true) end def get_object_hierarchy(klass) one = [] begin one << klass klass = klass.superclass end while klass one.reverse end def get_class_hierarchies_in_hash hierarchy = {} ObjectSpace.each_object(Class) do |klass| h = hierarchy get_object_hierarchy(klass).each do |cl| h[cl] = {} if h[cl].nil? h = h[cl] end end hierarchy end end # Let the fun begin ... if __FILE__ == $0 ObjectPrettyPrint.new(8).pretty_print #ObjectPrettyPrint.new(4).pretty_print({1=>{}, 1=>{1=>{}, 2=>{2=>{}, 3=>{}}}}) end # -- cut here ---------------------------------------------------------------- -- Wejn (svamberk.net's Linux section, fi.muni.cz student, linuxfan) >>> Bored? Want hours of entertainment? <<< >>> Just set the initdefault to 6! <<<