Skip to content

Instantly share code, notes, and snippets.

@danielfone
Created May 27, 2013 00:58
Show Gist options
  • Save danielfone/5654633 to your computer and use it in GitHub Desktop.
Save danielfone/5654633 to your computer and use it in GitHub Desktop.
Ruby class to build and print a class hierarchy.
class ClassHierarchy
def initialize(root_class)
@root_class = root_class
@parent_class = @root_class.superclass
@tree = {}
generate_tree
end
def to_s
@tree.collect { |class_name, subclasses| branch_to_s class_name, subclasses }.join
end
private
def generate_tree
subclasses.each { |subclass| subclass.insert_into_tree @tree, @parent_class }
end
def subclasses
@subclasses ||= all_classes.select { |klass| klass < @root_class }.collect { |klass| ClassHierarchy::Subclass.new klass }
end
def all_classes
@all_classes ||= ObjectSpace.each_object(::Class)
end
def branch_to_s(class_name, subclasses, indent=0)
string = (" " * indent)
string << class_name
string << "\n"
string << subclasses.collect { |subclass_name, subsubclasses| branch_to_s subclass_name, subsubclasses, indent + 2 }.join
end
class Subclass < Struct.new(:subclass)
def superclasses
@superclasses ||= subclass.ancestors - subclass.included_modules
end
def insert_into_tree(tree, root_class)
classes = superclasses.take_while { |klass| klass != root_class }
classes.reverse.collect(&:name).compact.inject(tree) { |memo,name| memo[name] ||= {} }
end
end
end
> Dir[File.join Rails.root, "/app/controllers/*"].each {|file| require file }
> puts ClassHierarchy.new ActionController::Base
ActionController::Base
ApplicationController
UsersController
UserSessionsController
OrdersController
...
@vassilevsky
Copy link

I used this class in our project and I added sorting because the tree looked rather chaotic without it:

   def branch_to_s(class_name, subclasses, indent=0)
     string = (" " * indent)
     string << class_name
     string << "\n"
-    string << subclasses.collect { |subclass_name, subsubclasses| branch_to_s subclass_name, subsubclasses, indent + 2 }.join
+    string << subclasses.sort.collect { |subclass_name, subsubclasses| branch_to_s subclass_name, subsubclasses, indent + 2 }.join
   end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment