Debugging Using the Output to the Console
Learn to debug a Ruby program using the output to our console.
We'll cover the following
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 1400+ tech skills courses.