To start debugging in ruby 1.9, you need the gem debugger (see github repository)

Gemfile

source "https://rubygems.org"

gem "debugger"

yourcode.rb

require "debugger"

def my_function
  debugger    # <== place debug point by putting this in your code
  x = 1
end

You can also do it in one shot:

def my_function
  require "debugger"; debugger
  x = 1
end

Because the breakpoint is in your code, you can put logic around it

def my_function
  debugger if foo == 3 && !bar
  x = 1
end

You should put debugger before the desired breakpoint because it will stop on the next statement after a call to debugger. If you put it at the end of function, you may end up in a different file, wherever the stack frame happen to be after the function returns.

You run your code the same way as you did before, the difference is that you’ll be placed into a interactive ruby debugger.

People have injected pry into their code to put an interactive shell so they can look around (This is done by require "pry" and calling binding.pry in the code). pry is powerful and it can be used for some types of debugging, but it’s not a debugger. You are not able to step through your code. Within debugger, have access to the ruby interpreter so you have most of the functionality you need. So if you used pry in the past, you should try out debugger.

Once you’re inside the debugger, you can type “help” or just “h”.

(rdb:1) h
ruby-debug help v1.6.1
Type 'help <command-name>' for help on a specific command

Available commands:
backtrace  delete   enable  help  list    ps       save    start   undisplay
break      disable  eval    info  method  putl     set     step    up
catch      display  exit    irb   next    quit     show    thread  var
condition  down     finish  jump  p       reload   skip    tmate   where
continue   edit     frame   kill  pp      restart  source  trace

You can also type “h set” to see options available

(rdb:1) h set
Modifies parts of the ruby-debug environment. Boolean values take
on, off, 1 or 0.
You can see these environment settings with the "show" command.

--
List of set subcommands:
--
set annotate -- Set annotation level
set args -- Set argument list to give program being debugged when it is started
set autoeval -- Evaluate every unrecognized command
set autolist -- Execute 'list' command on every breakpoint
set autoirb -- Invoke IRB on every stop
set autoreload -- Reload source code when changed
set basename -- Report file basename only showing file names
set callstyle -- Set how you want call parameters displayed
set debuggertesting -- Used when testing the debugger
set forcestep -- Make sure 'next/step' commands always move to a new line
set fullpath -- Display full file names in frames
set history -- Generic command for setting command history parameters
set linetrace+ -- Set line execution tracing to show different lines
set linetrace -- Set line execution tracing
set listsize -- Set number of source lines to list by default
set trace -- Display stack trace when 'eval' raises exception
set width -- Number of characters the debugger thinks are in a line

You can put these commands into a .rdebugrc file. You can also require ruby files so it’ll load automatically when the debugger is run. I always have “autolist” set so I can see the code listing while I am stepping through the code. You should also set autoeval so you can type ruby code (e.g. “a = 2”) rather than typing “eval” (e.g. “eval a = 2”) or using “p” to print the value.

Some useful commands

  • n : to go to the next statement
  • s : to step into the statement
  • c : continue
  • fin : to finish the method and stop at the next stack trace
  • p : print out result of ruby expression
  • pp : pretty print result of ruby expression. It prints list and hashes in a more readable format
  • bt : a backtrace to tell you where you are (you can also use “where”)

You can exit by typing “exit”, “q”, or press Ctrl-d.

When you’re debugging something complicated, it’s a good idea to put some print statements to see what your program is doing, but you may not want to have to clean it up every time. I solve this by creating a Logger class that takes a debug method. It will only print if the debug flag is set. This is especially useful when you’re dealing with multiple threads or when you’re not sure where to put the breakpoint.

I think you should try debugger out. It’s worth learning.