Article

Debug Your Rails App With ruby-debug

Page: 1 2 3

Manually Setting Breakpoints

While using the next command can be useful if you know exactly where in your application to go poking around, it can be less useful in a Rails application. The level at which the stepping occurs can in some circumstances be far too granular, and can result in your stepping through multiple lines of core library files instead of your own code.

To gain a little more control over where the debugger halts execution, you can manually set breakpoints at the locations you desire. Breakpoints can be set by specifying either:

  • a combination of filename and line number
  • a class name and the name of an instance method or class method

As a practical example of setting manual breakpoints, we're going to move the halt point from its current location (inside the vote action of StoryController) to the RJS template that's rendered when that same action is requested to render a JavaScript response. We'll do all of this without ever opening a text editor, or stepping over every line between the current point of execution and the code of the RJS template.

The last line of the RJS template at app/views/story/vote.rjs reads:

vote.rjs (excerpt)  
 
page[:vote_history].replace_html :partial => 'vote',  
 :collection => @story.latest_votes

It therefore makes sense to choose the latest_votes instance method of a Story object as our new breakpoint. To do so, execute the following command in the ruby-debug shell:

(rdb) break Story#latest_votes

You can now let go of the current breakpoint by typing the cont command in the ruby-debug shell. Execution will resume until the @story.latest_votes call is executed, at which point the application will pause again. To verify that we're paused exactly where we expect to be, type list. Figure 11 confirms that I've stopped my application at the beginning of the latest_votes method.

Stopping at a breakpoint that was set by specifying class and method name

Source-code Reloading

A Rails application, when run in development mode, automatically adopts all changes that are made to the source files without requiring you to restart the application server. ruby-debug includes a similar feature to avoid stale code passages from being displayed in the stack traces and listings output by the list command. If you can afford it (performance-wise), type the following at the ruby-debug prompt:

(rdb) set autoreload

With this setting, ruby-debug will automatically reload your Ruby scripts from disk whenever necessary. If this appears to slow down your development progress significantly, you can instead periodically invoke the reload command whenever you think you're getting stale representations of your code.

TextMate Integration

Those developers who develop their Rails applications on a Mac using the TextMate editor will be pleased to know that the author of ruby-debug happens to be a fan of TextMate as well. Fortunately, ruby-debug ships with some nice hooks that you can use to integrate the debugger with the editor.

First of all, you can open the file in which your application is currently paused using the tmate command. This eases the round-trips between your terminal window and your editor quite a bit.

I'd also recommend that you install the Ruby Debug Bundle for TextMate. This package gives you ultimate control over setting breakpoints from within TextMate itself.

After you've installed the bundle, you'll need to launch your application a little differently. Here's how to start your application server to take advantage of ruby-debug's remote debugging facilities (the $ indicates that we're typing this in an operating system shell):

$ rdebug -sn ./script/server

Unlike the local debugging facility that we've been using thus far, you can safely minimize the terminal window in which you started your application server -- we need to fire up a separate debugging client (from a new command prompt) to enable communication between TextMate and ruby-debug.

Open a new terminal window and type the following command:

$ rdebug -c

You should see the message "Connected", as shown in Figure 12.

You'll need to leave this window open and accessible, as this will be the window that displays the ruby-debug console output once a breakpoint is encountered.

Using the TextMate Ruby bundle to connect to ruby-debug’s remote debugging tool

As soon as that's accomplished, you can use the bundle's only keyboard shortcut, Cmd-Shift-B, to open up a menu of all the available commands, shown in Figure 13.

Displaying the TextMate Ruby bundle's menu options

You can use this menu to set a breakpoint at the position of the cursor in the current TextMate editing window. You can also show or delete all breakpoints that have been set, or even interrupt or quit the debugging shell right from the convenience of your text editing window.

Conclusion

ruby-debug is a worthy successor to the old (and admittedly hackish) technique of debugging your Ruby application using the breakpoint library. Better yet, it's compatible with all the most recent releases of the Ruby language interpreter. ruby-debug comes packed with many welcome shortcuts and powerful navigation commands that make debugging Ruby scripts and Rails applications a joyful and rewarding experience.

For further reading on ruby-debug and many helpful articles and links to Ruby resources, I thoroughly recommend you subscribe to Kent Sibilev's weblog.

If you liked this article, share the love:
Print-Friendly Version Suggest an Article

Sponsored Links

Rate This Article

  • 1
    Poor
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
    Great

Comment on This Article

Have something to say?

Post A Comment

You need to be a member of the SitePoint Forums to comment on this post. Sign Up

Already a member? Post using your SitePoint Forums account: