Skip to content

Instantly share code, notes, and snippets.

@gunn
Created November 27, 2009 04:11
Show Gist options
  • Save gunn/243817 to your computer and use it in GitHub Desktop.
Save gunn/243817 to your computer and use it in GitHub Desktop.
Crude ruby/IRB visualizer tool
%w[rubygems graphviz rbosa irb].each { |g| require g }
puts "==RubyViz==
For exploring the ruby language, draws a graph of ruby objects as they are instantiated.
Usage:
declare a top level instance-variable then set attributes one it
Example:
@dog = Object.new
@dog.name = 'Bess'
four = 4
@dog.age = four
four.description = 'the number four'
@dog.number_of_legs = 4
@dog.happiness = 9
Bugs / Limitations:
Too numerous to list here. Graph leaves a lot of deatil to be desired. The main limitation is that only instance variables are followed so Arrays for instance do not visualise well. Cannot be used to visualise any sizable application.
"
# This code - good for experimenting in IRB with, would break most apps:
class Object
def method_missing method_name, *args
case method_name.to_s
when /(.*)=/
self.instance_variable_set("@#{$1}", args[0])
when /(.*)/
self.instance_variable_get("@#{$1}")
end
end
end
module RubyViz
def self.plot base_object
g = GraphViz::new("structs", :type => 'digraph', :path => "/opt/local/bin/")
instances = Hash.new
nodes = []
create_nodes(base_object, g, instances, nodes)
nodes.each do |n|
n[:shape] = "Mrecord"
n[:color] = "lightblue"
end
g.output(:output => "png", :file => "/tmp/instances.png")
refresh_image
end
def self.create_nodes parent, g, instances, nodes
parent_node = g.add_node parent.object_id.to_s
nodes << parent_node
parent_label = "{#{parent.class}|#{parent.object_id}|#{parent}|"
parent.instance_variables.each do |child_name|
child = parent.instance_variable_get child_name
child_node = nil
parent_label << "#{child_name}: #{child.class}\\l"
if !instances[child.object_id]
child_node = create_nodes child, g, instances, nodes
instances[child.object_id] = [child_node, parent_node]
elsif instances[child.object_id].last != parent_node
child_node = instances[child.object_id].first
end
g.add_edge parent_node, child_node if child_node
end
parent_node[:label] = parent_label+"}"
parent_node
end
def self.refresh_image
current_safari_tab = OSA.app("Safari").windows.first.current_tab
current_safari_tab.url = current_safari_tab.url
OSA.app("Safari").open "/tmp/instances.png"
end
end
module IRB
class Irb
def output_value_with_ruby_vis
RubyViz::plot $main
output_value_without_ruby_vis
end
alias_method :output_value_without_ruby_vis, :output_value
alias_method :output_value, :output_value_with_ruby_vis
end
end
# start an interactive session
$main = self
IRB.start(__FILE__)
# or visualise a structure based on an object:
# RubyViz.plot object
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment