Are the "Two Ps" (print statements and prayer) all that comprise your debugging strategy? It's time you were introduced to the Interactive Ruby Debugger.
I often ask other developers for advice. At times, the counsel reinforces my approach; at other times, the guidance challenges my thinking, leading me to refine my code or even pursue a wholly different solution.
Out of curiosity, I also ask other coders about debugging techniques, and more often than not, I am surprised by the answer. Believe it or not, the vast majority relies on liberal “print” statements sprinkled throughout code. Of course, “print” takes many forms—dump pertinent data structures, emit trace statements to standard error, and log interim results in a separate file—and there are cases where these methods are mandated. Still, it puzzles me why more skilled developers do not use a debugger. Extensions to PHP allow for interactive forensics; Perl running within mod_perl supports debugging; and Ruby on Rails’s Mongrel provides the --debugger option to interrupt execution and drop to a debug console.
In my Rails work, I use the debugger extensively. The debugger combines the power of the Rails console and the Interactive Ruby Debugger, irb, and peers into running code responding to incoming requests. Better yet, I can yield to the debugger console anywhere—in a controller, a view, a plug-in or helper. Within the debugger, I can inspect the stack, variables, the params hash, and more.
Installing the Debugger
The debugger, ruby-debug, is provided as a Ruby gem and installs just as easily as any other extension.
$ sudo gem install ruby-debug
Once installed, you can invoke the debugger anywhere in your code with a call to debugger.
class ExampleController < ApplicationController
def index
# ...
debugger
# ...
end
end
By default, Rails's script/server ignores calls to the debugger (and instead emits a message such as Debugger requested, but was not available). To enable the debugger and temporarily halt execution at each call, launch Mongrel with the option --debugger.
$ ruby ./script/server --debugger
=> Booting Mongrel
=> Rails 2.3.2 application starting on http://0.0.0.0:3001
=> Debugger enabled
=> Call with -d to detach
=> Ctrl-C to shutdown server
Once the debugger is enabled, each call to debugger generates a command prompt. The prompt is prefaced by the file name and line number where the call occurred and the next line of code to execute.
/Users/supergiantrobot/Projects/dc/trunk/app/controllers/search_controller.rb:32
@results = Part.uniqify( @results ) if logged_in?
(rdb:3)
(The 3 in the prompt is the thread number, which you can safely ignore if you're not juggling multiple threads.) At the prompt, you can type a number of commands to help ferret out your mistake. When in doubt, simply type help for a list of available commands or help command for hints about a specific command.
Commands to Query State
Like gdb (the Linux debugger for many languages) and Firebug (the Firefox debugger for JavaScript), rdb provides instructions to march through code and examine state. Here's an example using some of the most common commands.
The sample code prints the catalog of revisions made to records in the database. The controller is standard; the view is written in HAML, but could just as well be any other format. A call to debugger has been added at the start of the index action.
class RevisionController < ApplicationController
before_filter :login_required
def index
debugger
@revisions = Revision.paginate :page => params[:page],
:order => 'created_at DESC'
end
end
%table
- @revisions.each do |revision|
%tr
%td
= revision.author.capitalize
%td
= revision.field
%td
= revision.value
The first command is list (which can be abbreviated to simple l, or lowercase L). It prints the ten lines of code surrounding the breakpoint to provide context.
.../app/controllers/revision_controller.rb:7
@revisions = Revision.paginate :page => params[:page],
(rdb:20) list
[2, 11] in .../app/controllers/revision_controller.rb
2 before_filter :login_required
3
4 def index
5 debugger
6
=> 7 @revisions = Revision.paginate :page => params[:page],
8 :order => 'created_at DESC'
9 end
10 end
The arrow (=>) reflects the program counter, or the statement about to execute. If you type list again, it shows the next ten lines of code.
The next command is print or p. It reveals the value of its argument, and formats the output as inspect would.
(rdb:20) p params
{"action"=>"index", "controller"=>"revision"}
(rdb:20) params
{"action"=>"index", "controller"=>"revision"}
Inspecting a variable is so common, there's a shortcut: omit print and simply type the name of the variable. That's the latter command above.
The backtrace command displays the call stack. The current frame—that is, the frame where you called debugger&mdashlis numbered 0. Commands such print and list always apply to the current frame.
Preceding call frames are numbered 1, 2, and so on. Use the frame n command, where n is a frame number, to move to a specific frame. Again, an arrow (-->indicates your current frame.
(rdb:20) backtrace
--> #0 RevisionController.index
at line .../app/controllers/revision_controller.rb:7
#1 Kernel.send(e#NilClass)
at line .../actionpack-2.3.2/lib/action_controller/base.rb:1322
...
#44 Mongrel::HttpServer.run
at line .../mongrel-1.1.5/lib/mongrel.rb:285
(rdb:20) frame 44
(rdb:20) list
[280, 289] in /opt/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb
280 if worker_list.length >= @num_processors
281 STDERR.puts "Server overloaded with #{worker_list.length} processors (#@num_processors max). Dropping connection."
282 client.close rescue nil
283 reap_dead_workers("max processors")
284 else
=> 285 thread = Thread.new(client) {|c| process_client(c) }
286 thread[:started_on] = Time.now
287 @workers.add(thread)
288
289 sleep @throttle if @throttle > 0
(rdb:20) backtrace
#0 RevisionController.index
at line /Users/supergiantrobot/Projects/dc/trunk/app/controllers/revision_controller.rb:7
...
--> #44 Mongrel::HttpServer.run
at line .../mongrel-1.1.5/lib/mongrel.rb:285
By the way, if you want to know what instance variables are defined in the current frame, type instance_variables.
(rdb:20) frame 0
#0 RevisionController.index
at line .../app/controllers/revision_controller.rb:7
(rdb:20) instance_variables
["@_params", "@request_origin", "@_request", "@search_options", "@performed_render", "@_headers", "@template", "@action_name", "@_response", "@url", "@performed_redirect", "@before_filter_chain_aborted", "@target", "@_session"]
You can also use the var command to query global variables, local variables, and constants and instance variables in any object.
(rdb:20) var global
$! = nil
...
$tcp_defer_accept_opts = nil
$~ = nil
(rdb:20) var local
__dbg_verbose_save => false
const_name => :Revision
e => nil
parent_qualified_name => nil
qualified_name => nil
(rdb:20) var instance Inventory
@after_create_callbacks = [#<ActiveSupport::Callbacks::Callback:0x262f35c
@identifier=nil, @kind=:after...
...
@observer_peers = [#<StockObserver:0x25f4090>]
@parent_name = nil
Next: Commands to Control Execution
Comments on "Hey, Don’t Dump. Debug!"
I’m truly enjoying thhe design and layout off your
site. It’s a very easy on the eyes which makes it much mmore pleasant ffor me to come
here and visit mire often. Did you hire out a developer to create your theme?
Fantastiic work!
Allso visit my blog post; cheap car insurance
It is not my first time to visit this site, i am browsing this
website dailly and get good data from here every day.
my web blog; cheap car insurance california
It’s actually a cool and useful piece of info. I’m happy that
you simply shared tbis useful information with us.
Please keep us informed like this. Thank you for sharing.
my web site – cheap car insurance
When someone writes an article he/she retains the idea of a user
in his/her mind that how a user can know it. Therefore that’s whhy this article is great.
Thanks!
Feel free to visit my blog – cheap car insurance florida
Verry good article. I aam dealing with some of these issues as well..
Here is my web site – cheap car insurance for students
Thankls for a marvelous posting! I quite enjoyed
reading it, you may bee a great author.I will ensure that I bookmark your blog and will
eventually come back in the future. I want to encourage yourself to continue your great work, have a
nice evening!
Stop by my web site cheap car insurance online
Hey! Do you know if they make any plugins to help with SEO?
I’m trying tto get mmy bloog to rank for some targeted kehwords
but I’m not seeing very good success. If youu know of
any please share. Many thanks!
Check out my blog post: cheap car insurance in pa
Also visit my blog :: http://dioufy.com/groups/some-basics-for-consideration-with-straightforward-massage-programs/
Also visit my blog :: http://www.allindiasaltmaker.com
My web page :: ancientayurved.net
Quality content is the important to invite the viewers to visit the website, that’s what this
web page is providing.
Feel free to visit my blog post :: cheap car insurance
Together with every thing that appears to be building within this particular subject material, many of your opinions are actually rather exciting. Nonetheless, I am sorry, because I do not subscribe to your entire idea, all be it exhilarating none the less. It seems to us that your remarks are not completely rationalized and in reality you are yourself not totally certain of the point. In any case I did take pleasure in reading through it.
The crux of your writing whilst appearing agreeable in the beginning, did not really settle very well with me after some time. Somewhere within the sentences you actually were able to make me a believer but only for a while. I nevertheless have a problem with your jumps in assumptions and you might do nicely to fill in those breaks. When you can accomplish that, I could surely be fascinated.
Hello! I could have sworn I’ve been to this blog before but after
looking at many of the posts I realized it’s new to me.
Nonetheless, I’m definitely happy I discovered it and
I’ll be book-marking it and checking back regularly!
Here is my blog … Cheap car insurance
The very root of your writing whilst appearing agreeable originally, did not work properly with me personally after some time. Someplace throughout the sentences you were able to make me a believer but only for a while. I nevertheless have got a problem with your jumps in assumptions and one would do well to help fill in all those gaps. In the event that you can accomplish that, I will definitely end up being impressed.
Eveгүtthing iѕ vегʏ ореn witһ ɑ
ѵeгу сⅼеаг claгіfіcatіⲟn оf tɦе cһaⅼⅼеngеѕ.
Іt ᴡаѕ ɗefіnitеⅼү infօrmɑtiνе.
Ⲩоur ѕіtе іѕ
usᥱfսⅼ. ТҺаnkѕ
fⲟг ѕһaгіng!
My ѡᥱЬlоg …
is.gd/kSuBvD
I do like the way you have presented this issue plus it does indeed supply us a lot of fodder for consideration. On the other hand, coming from everything that I have experienced, I really wish when the actual feedback stack on that people stay on point and don’t start upon a soap box regarding the news of the day. Still, thank you for this fantastic piece and whilst I can not necessarily go along with the idea in totality, I value the perspective.
It was my pleasure finding your site this morning. I got here now hoping to uncover something new. I was not disappointed. Your ideas with new techniques on this thing were topical and a wonderful help to my family. Thank you for having time to create these things along with sharing your notions.
Awesome blog.Much thanks again. Awesome.
Throughout the awesome design of things you actually receive a B- with regard to hard work. Exactly where you actually confused everybody ended up being on your specifics. You know, people say, the devil is in the details… And it couldn’t be more accurate in this article. Having said that, let me say to you what did do the job. Your writing is definitely pretty convincing which is possibly the reason why I am making the effort to comment. I do not really make it a regular habit of doing that. Second, while I can easily see the jumps in reasoning you make, I am not necessarily convinced of just how you seem to unite your ideas which inturn help to make your conclusion. For right now I shall subscribe to your position but wish in the future you link your dots better.
I do love the manner in which you have framed this matter and it does indeed supply me some fodder for thought. Nevertheless, through just what I have seen, I only wish when the reviews stack on that people keep on issue and in no way get started on a soap box regarding some other news du jour. Yet, thank you for this superb point and although I can not really concur with this in totality, I respect the perspective.
A large percentage of of whatever you point out happens to be astonishingly appropriate and it makes me ponder why I hadn’t looked at this in this light before. This article truly did turn the light on for me as far as this issue goes. But at this time there is actually just one issue I am not necessarily too comfy with so while I make an effort to reconcile that with the actual core theme of your position, permit me observe just what the rest of your readers have to say.Well done.
I am so grateful for your article.Really thank you! Really Cool.
Throughout the grand design of things you actually secure a B+ for hard work. Where you confused me was first in all the facts. You know, people say, the devil is in the details… And it couldn’t be much more accurate in this article. Having said that, let me say to you exactly what did work. The authoring can be extremely convincing and that is possibly the reason why I am taking the effort in order to opine. I do not make it a regular habit of doing that. 2nd, although I can easily notice a leaps in reason you make, I am not necessarily certain of how you seem to unite your ideas which help to make your final result. For the moment I will yield to your issue however hope in the near future you link the facts better.
Most of the things you mention is supprisingly appropriate and it makes me wonder the reason why I had not looked at this in this light previously. This article truly did switch the light on for me as far as this specific issue goes. Nonetheless at this time there is one point I am not really too comfy with and while I try to reconcile that with the actual central idea of the issue, permit me observe exactly what the rest of your visitors have to point out.Well done.
The crux of your writing whilst appearing agreeable initially, did not really work properly with me personally after some time. Someplace throughout the paragraphs you were able to make me a believer unfortunately just for a short while. I still have got a problem with your jumps in logic and one might do nicely to fill in those gaps. If you actually can accomplish that, I would surely end up being amazed.
In this awesome scheme of things you actually get an A+ for effort. Exactly where you actually lost us was first in the facts. As as the maxim goes, details make or break the argument.. And that couldn’t be more accurate at this point. Having said that, allow me say to you what did deliver the results. The text can be very persuasive which is probably why I am taking the effort to opine. I do not really make it a regular habit of doing that. Next, while I can certainly see a leaps in reasoning you make, I am not necessarily sure of exactly how you seem to unite the points which produce the actual conclusion. For now I shall subscribe to your position however wish in the foreseeable future you link the facts much better.
The very core of your writing whilst sounding reasonable in the beginning, did not work properly with me personally after some time. Someplace within the paragraphs you managed to make me a believer unfortunately only for a short while. I however have a problem with your leaps in logic and one would do well to help fill in those breaks. If you can accomplish that, I could definitely end up being impressed.
The heart of your writing while appearing agreeable originally, did not work properly with me personally after some time. Somewhere within the sentences you managed to make me a believer but only for a while. I nevertheless have a problem with your leaps in assumptions and you would do nicely to help fill in those breaks. When you can accomplish that, I will definitely end up being fascinated.
Throughout this awesome scheme of things you secure an A for effort and hard work. Where you confused everybody ended up being on your specifics. You know, they say, the devil is in the details… And it couldn’t be more correct here. Having said that, allow me tell you exactly what did do the job. Your text is actually incredibly persuasive which is most likely why I am making the effort to opine. I do not really make it a regular habit of doing that. 2nd, despite the fact that I can easily notice a jumps in reasoning you make, I am not really certain of exactly how you appear to unite your points which inturn help to make your final result. For right now I will subscribe to your point but wish in the future you connect the facts better.
Just about all of what you claim is supprisingly precise and that makes me ponder why I had not looked at this in this light previously. This particular article really did turn the light on for me personally as far as this particular issue goes. Nonetheless there is actually one factor I am not too comfortable with and while I attempt to reconcile that with the actual core theme of the point, allow me observe just what the rest of your visitors have to say.Well done.
Throughout this awesome design of things you secure an A with regard to effort. Exactly where you actually misplaced me personally ended up being on the specifics. As as the maxim goes, details make or break the argument.. And it couldn’t be much more true here. Having said that, let me say to you just what did do the job. Your article (parts of it) is actually really engaging which is probably the reason why I am making the effort in order to comment. I do not really make it a regular habit of doing that. Next, whilst I can see a leaps in reason you come up with, I am not convinced of just how you appear to connect your points which inturn make the actual conclusion. For now I shall subscribe to your issue but hope in the future you link your facts much better.
I simply want to tell you that I am just all new to blogs and actually loved you’re blog site. Almost certainly I’m likely to bookmark your site . You definitely come with outstanding posts. Cheers for sharing your web page.
I will right away clutch your rss feed as I can not to find
your email subscription link or e-newsletter service.
Do you have any? Please permit me recognise in order that I
may just subscribe. Thanks.