Internetbureau Holder

Unroller

Jeroen Bulters ma 07 jun 10

When working with a new piece of code, being a new plugin, gem or just some code someone else wrote, and you want to familiarise yourself with the inner workings you can do a few things.

Play around with it in irb (or script/console) and try out different options, while keeping the code as a reference. Or you pull out the debugging-swiss-army-knife named Unroller (available as a gem with the same name).

Unroller is a custom tracing module designed with this kind of situations in mind and is very easy to use.

Image the following – useless – piece of Ruby code which calls the same function 4 times, followed by some other function.

require 'rubygems'
require 'unroller'

class Recurse
    def self.some_recursive_function(times, callback, depth=0)
        if depth == times
            self.send(callback)
            return
        else
            puts "Depth is #{depth}"
            some_recursive_function(times, callback, depth+1)    
        end
    end

    def self.end_of_recursion_callback
        puts "End of recursion"
    end
end

Recurse.some_recursive_function(3, :end_of_recursion_callback)

Of course, this example is quite trivial, but imagine for a second we do not understand how it works.

By wrapping the method call in a Unroller block we can easily generate an easily understandable stacktrace.

So, we replace the Recurse#some_recursive_function call with the following:

Unroller::trace do
    Recurse.some_recursive_function(3, :end_of_recursion_callback)
end

And run the file again.

This time, we are presented with a nice stack trace showing each step of the execution:

 |    Recurse.some_recursive_function(3, :end_of_recursion_callback)    | unroll.rb:23                                                                    
 |  \ calling Recurse::some_recursive_function                        

Recurse::some_recursive_function (unroll.rb:6) (line):
 |  |    (times = 3; callback = :end_of_recursion_callback; depth = 0)...
             def self.some_recursive_function(times, callback, depth=0)
      ->         if depth == times
                     self.send(callback)
                     return
                 else
                     puts "Depth is #{depth}"
                     some_recursive_function(times, callback, depth+1)    
                 end
             end
         
--- SNIP FOR BREVITY ---

                  Recurse.some_recursive_function(3, :end_of_recursion_callback)
                  
                  Unroller::trace do
                      Recurse.some_recursive_function(3, :end_of_recursion_callback)
                  end

 |  |  |  |  / returning from Recurse::some_recursive_function        
 |  |  |  / returning from Recurse::some_recursive_function           
 |  |  / returning from Recurse::some_recursive_function              
 |  / returning from Recurse::some_recursive_function    

Unroller shows us all the code being executed, the current line and the depth of the function in the stacktrace.

This kind of output can come quite in handy when debugging complicated situations like ActiveRecord filter chains.

More information on Unroller is found at http://unroller.rubyforge.org/.

Gepost in hor |  0 reacties

Plaats je reactie





Welcome to Holland On Rails

This weblog is the official Ruby techblog from the guys at Holder, a Ruby development company. Holder is also the company behind the RubyAndRails Europe Conference in Amsterdam.

Recente Jobs


Bekijk alle jobs »»

Gereedschapskist

Onmisbare tools voor
iedere developer!
Ruby On Rails
Framework voor de web 2.0 developer. Eindelijk vooruitgang!
TextMate
Editor for true pro's
Typ, tab, top :-)
Nee, niet voor Win.
Made On A Mac
En nou is het over met die saaie grijze Windows bak van je!

Auteurs op deze site

Chris Obdam

'Less is more' evangelist, past dit ook dagelijks toe op zijn tandenborstel.

Chiel Wester

Snelheidswonder op Ruby wielen. Leuk om mee te pair-programmen ;-) Recommend Me

Stephan Kaag

Het eerste Rails coreteam- member uit Nederland? Rails evangelist van het eerste uur.

Paul Engel

Én Rails programmeren én interfaces designen? Je zou hem superman kunnen noemen..

Dax Huiberts

Official Zip-Programmer, skinny code is helemaal zijn ding. Haalt meer code weg dan dat er bij komt.

Freek Monteban

Het nieuwste telg uit het Holland on Rails nest! Hij doet niets anders meer!

Johan Vermeulen

De stylesheet-koning uit de kop van Noord-Holland!