Hammertime: An interactive error console for Ruby

Users of Lisp and Smalltalk environments are used to having some pretty powerful tools for debugging exceptions in their code. For instance, here’s the dialog I see when I try to do execute some bad code in Squeak:

squeak-error

Ruby users are not so lucky. Our first indication of an error is either the code not working or a stack trace, depending on whether the error is handled somewhere. Either way, we don’t get an opportunity to investigate the circumstances of the error when it is raised. All we get to see is the aftermath.

Ruby exceptions are raised with the raise method, or with fail, which is an alias for raise. I use the term “method” deliberately. raise is not a keyword; it’s a method on Kernel just like puts and exit.

The fact that raise is just an ordinary method has some interesting implications. For instance, we can modify it to trace the location of every error raised in a program:

Since MyRaise is included in Object after the default Kernel, our definition of raise takes precedence.

Obviously, if we can intercept errors at the moment they are raised, there’s a lot more we can do beyond mere tracing. Introducing Hammertime.

stop-hammertime

Hammertime is an interactive error console for Ruby. Using it is simple: just gem install hammertime and require the library:

Now when an error is raised, we’re be presented with a menu:

With Hammertime we can diagnose and fix errors at the point where they occur. Let’s walk through an example Hammertime session using the following highly contrived script:

We start the code with Hammertime enabled:

The code raises an error, and we see the Hammertime menu:

We choose “Backtrace” to see the full trace leading up to the error:

Note that Hammertime returns us to the menu after showing the stack trace. Next we choose “Console” to drop into an IRB session. From there, we do a little snooping around:

Well that seems to be the problem, someone left the “more magic” switch off. Let’s fix that:

And now we’ll choose to Ignore the error and proceed:

We’ve fixed the “bug”, so successive runs execute without problems.

Hammertime has other features, including the ability to specify certain errors which won’t trigger the menu to be presented. If you want to learn more about it I suggest installing it, playing around with it, and reading the code.

The biggest limitation of Hammertime is that it can only catch errors which are raised within Ruby code, not those raised in native code. I threw it together in an afternoon, so it probably has other bugs as well. Please let me know if you get some use out of the tool. Patches, bug reports, and suggestions are welcome.

UPDATE: Magnus Holm was inspired by this post to create an Exception#continue method. With a little more work I think this could be the basis for a Lisp-style conditions system, something I’d love to see implemented in Ruby.
[ad#PostInline]