Debugging Using the Output to the Console

Learn to debug a Ruby program using the output to our console.

The inspect method

This is one of the easiest and most efficient ways to debug a program.

puts something.inspect

We can implement the inspect method for every object in any part of a program. It then returns a string representation of the object. Here, we may ask why we need to use puts something.inspect while we could use puts something.

The answer is that inspect is more verbose, and its primary purpose is to inspect. For example, puts nil and puts "" statements return an empty output on the screen, while .inspect gives us a better idea of what the object is:

$ pry
> puts nil

> puts nil.inspect
nil
> puts ""

> puts "".inspect
""

For programs that produce a lot of information to our terminal, e.g., all Ruby on Rails applications, we can use the following trick:

puts '=' * 80
puts something.inspect
puts '=' * 80

The above code will print = eighty times, with the inspection of the variable on the next line. We can easily spot this debugging statement in a lengthy output of other unrelated debug messages. The following is such an example, where we can see that our something variables equal 123:

The raise method

To “stop the world” at a certain point, we can use the raise statement. Ruby will generate a “standard error” exception and the program will terminate, while the Rails framework will terminate only the current request:

puts '=' * 80
puts something.inspect
puts '=' * 80
raise

Ruby is a dynamically typed language. It is not always possible to determine where exactly the raise method or another method is defined until we run a program. RubyMine IDE from Jetbrains (subscription-based) has the fantastic “Go to declaration” feature we can usually use through the Cmd+B shortcut on macOS, and Ctrl+B on other operating systems. It allows us to jump to the place where the method is defined. However, even sophisticated IDEs sometimes can’t understand where the method is defined due to the dynamic nature of Ruby runtime.

In this case, we can use the following trick:

puts method(:something).source_location

If an object has the something method, the path will be displayed alongside the line number.

When code gets executed multiple times, a single debugging statement can pollute our screen. Therefore, having the puts conditional is useful:

puts something.inspect if i == 100

Using stack trace

Sometimes, we may need to print a stack trace. A stack trace is the exact picture and evidence of how and why a particular line got executed. Using Ruby’s caller statement, the following program returns the exponentiation for a random number:

Get hands-on with 1200+ tech skills courses.