Debugging
Debugging Is the search for the cause of problems, ‘bugs’, in code and fixing them. The term comes from The origin of the term “debugging.”
Stack Trace
Is bunch of printed text that appears in your console/terminal when things go bad. As the name implies, it’s a Stack (data structure) that shows a trace of the steps executed in your program leading to the crash. It’s often enough to see where the error lies, as most stack traces inform us of the line where the code crashes as well as the Exception or Error that occurred. The very first line of the stack trace will generally provide the most useful information about the error your program encountered.
Debugging by ‘printing’
This is Noob behavior, BUT it’s also practical and real. By printing statements at certain junctures in our code we can be certain of how our code behaves and what it’s doing, enabling us to confirm if it runs as expected. In the REAL WORLD and Production environments this should be avoided and removed immediately after confirming suspicions if used! It will signal out rookies from experienced programmers.
A flaw of this debugging method is that when printing nil
we simply get a blank line… so use p
instead of puts
to print when you use this debugging method as p
yields more information and provides a string representation of whatever it’s called on.
Debugging with Pry-byebug
Pry is a Ruby gem that provides you with an interactive REPL while your program is running. The REPL provided by Pry is very similar to IRB but has added functionality. The recommended Ruby gem for debugging is Pry-byebug and it includes Pry as a dependency. Pry-byebug
adds step-by-step debugging and stack navigation.
To use Pry-byebug
:
- Install it in your terminal by running
gem install pry-byebug
. - Make it available in your program by requiring it at the top of your file with
require 'pry-byebug'
. - To use it, call
binding.pry
at any point in your program. - Then run ruby
your_program.rb
and it’ll open a debugging session in your terminal that resembles IRB. - Via
pry
you can check values of all variables up to the point where you placedbinding.pry
. - Enter
next
to skip over to the next line…
For example:
require 'pry-byebug'
# Isogram is a word with no repeating letters
def isogram?(string)
original_length = string.length
string_array = string.downcase.split
binding.pry
unique_length = string_array.uniq.length # Not included in pry's scope...
original_length == unique_length
end
isogram?("Odin")
when the program hits binding.pry
it opens an IRB-like session in the terminal. This session allows us to check values of anything within the scope of where it’s included, but not anything written or evaluated after…
This practically makes adding binding.pry
similar to a breakpoint in other languages when debugging.
// In wish this was simply the case TBH
How to Debug
- You encounter an error or exception. If there’s a stack trace, follow it, and see where it went wrong and try to figure out why. Sometimes it’s obvious sometimes you’ll need to do some digging. Use the debugger if available.
- If the program runs but doesn’t execute as expected or the result isn’t what you want, you’ll need to do some investigating to understand why.