Debugging Ruby on Rails with the ruby-debug gem
September 28th, 2007
Remember the breakpointer? It was based on a bug in ruby that was closed in ruby 1.8.5 - when the bug was closed, the handy dandy breakpointer functionality went away. That's a drag, but there's an even better way available.
Ok. Lets get going - the first thing we do is install the ruby-debug gem. This uses a ruby C extension, so you'll need to have your compiler tool chain installed for your platform. (You're on your own for that one boyo, I ain't gonna help you).
[shell]
gem install ruby-debug
Need to update 40 gems from http://gems.rubyforge.org
........................................
complete
Install required dependency ruby-debug-base? [Yn] y
Select which gem to install for your platform (i686-darwin)
1. ruby-debug-base 0.9.3 (ruby)
2. ruby-debug-base 0.9.3 (mswin32)
3. Skip this gem
4. Cancel installation
> 1
Building native extensions. This could take a while...
Successfully installed ruby-debug-0.9.3
Successfully installed ruby-debug-base-0.9.3
Installing ri documentation for ruby-debug-0.9.3...
Installing ri documentation for ruby-debug-base-0.9.3...
Installing RDoc documentation for ruby-debug-0.9.3...
Installing RDoc documentation for ruby-debug-base-0.9.3...
[/shell]
Ok. Now we have the ruby-debug gem installed we're gonna rawk it an' sock it into our rails app. Go and stand in your rails directory and add the following to config/environments/development.rb (and config/test.rb if you want to use it during testing too).
-
require 'ruby-debug'
Now it gets even easier. Just slam a "debugger" statement wherever you think you need one. Let's experiment with this broken code below:
-
class PeopleController <ApplicationController
-
-
def create
-
@person = Person.new(params[:personage])
-
if @person.save
-
flash[:notice] = 'Person was successfully created.'
-
redirect_to :action => 'list'
-
else
-
render :action => 'new'
-
end
-
end
-
-
end
Obviously we should be looking for params[:person] here instead of params[:personage]. Instead of saving the parameters that we expect here, we're going to be saving empty fields, since we're not passing in any personage hash.
So we'll just slam in a "debugger" statement:
-
class PeopleController <ApplicationController
-
-
def create
-
@person = Person.new(params[:personage])
-
debugger
-
if @person.save
-
flash[:notice] = 'Person was successfully created.'
-
redirect_to :action => 'list'
-
else
-
render :action => 'new'
-
end
-
end
-
-
end
Now when we try and create a new patient we're going to see that the request doesn't return in the browser. (I think that's how the old breakpointer client worked too - I can't remember). But if we go to the window where our server is running we'll see something like this:
-
Completed in 0.02870 (34 reqs/sec) | Rendering: 0.01762 (61%) | DB: 0.00000 (0%) | 200 OK [http://127.0.0.1/people/new]
-
./script/../config/../app/controllers/people_controller.rb:26 if @person.save
-
(rdb:1)
That debugger is open right in the context of where we put the debugger statement. To see what we can do with the debugger we just have to say 'help' at the prompt
-
(rdb:1) help
-
ruby-debug help v0.9.3
-
Type 'help <command-name>' for help on a specific command
-
-
Available commands:
-
backtrace break catch cont delete display down eval exit finish frame
-
help irb list method next p pp quit reload restart save script set
-
step thread tmate trace undisplay up var where
-
-
(rdb:1)
Try them out! Some neeto ones are "tmate" which opens the context in textmate, "irb" which opens an irb session just right in the context just like the old breakpointer client. The other ones mostly work like you'd expect too. You can find a more detailed explanation of the methods here.





Leave a Reply