Created
November 27, 2009 04:11
-
-
Save gunn/243817 to your computer and use it in GitHub Desktop.
Crude ruby/IRB visualizer tool
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%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