Debugging is the process of finding the bugs in your code. This guide is a brief introduction to basic debugging techniques for Ruby.
Puts debugging
When you’re writing scripts or command line programs the easiest form of debugging is “puts debugging” (aka “printf debugging”). This is as simple as calling the puts method with a variable you want to know the value of, for example:
puts x
The string representation of an object might not give you enough information, so you’ll typically want to use one of a number of variations on this. Calling #inspect on the object will typically provide more information, for example:
puts x.inspect
The p method provides a useful shortcut to save your fingers some typing—this is equivalent to the previous example:
p x
You can also use the pp library to “pretty print” output, which is useful when you have more complex objects to debug:
require 'pp'
pp x
Not clear what kind of object you have? Call #class:
p x.class
Need to see what “interesting” methods the object has? Try this:
p x.methods - Object.instance_methods
(A little bit similar to Python’s dir function.)
Important to note that if you use this style of debugging it’s a good habit / best practice to remove the debugging statements before you commit/ship your code.
Debugging a web app
Puts style debugging doesn’t work as well in a web app. The debugging output will typically be interleaved with noisy logging output from elsewhere, and sometimes it won’t show up on your screen at all.
Generally it’s easier to send the output to your browser. This is similar in principle to puts debugging, but with the added concern of having to escape the debugging output before including it in the response.
Rails includes a debug helper method for displaying objects in your views:
<%= debug @user %>
Alternatively try the inspectbang gem which provides an #inspect! method you can call from anywhere inside your app, and works with Sinatra and Rails.
Again, it’s good practice to make sure these debugging statements don’t appear in code that you ship to production or share with your team.
Logging 101
Logging is a more structured approach to debugging, suitable for use in production environments and more complex applications. It neatly separates the what [to debug] from the how [to display the debugging output].
Rails and Sinatra will configure a logger for you automatically. For scripting or command line programs you can configure your own logger instance like this:
require 'logger'
logger = Logger.new(STDOUT)
To use the logger, call the #info method with the message/object you want to debug. So from a Rails controller or Sinatra action you might end up with something like this:
logger.info "user #{user.id} did something interesting!"
Unlike puts debugging, logging statements are intended to be present in production code—the logger(s) in your production environment can be configured to show different levels of detail and exactly where to send the logging output.