Debugging Ruby Code with Pry

Your comprehensive guide to Pry and how to use it .

Debugging: the process of identifying and removing errors from code

Every programmer has faced a situation where they go to execute their code and get an error message they’re confused by, or even worse, the code runs successfully but nothing is output. This was me, and before I learned about Pry I would do things like combing through my code, line by line, trying to guess where the error could be. I even had a phase of inserting puts statements (puts “The error is here!”) hoping to figure out where the error was originating from. Once I learned about Pry, I never looked back. I truly believe it is one of the most important tools for beginning Ruby programmers.

What is Pry?

Pry is a REPL (Read, Evaluate, Print, Loop) that pauses your code wherever inserted and allows you to test/debug. When your code gets to the ‘pry’ it will freeze and your terminal will turn into a REPL right in the middle of your program.

How do I use Pry?

The first step is to make sure you have the pry gem installed by typing the following into your terminal:

Once it’s installed, you will have to require it at the top of any file you plan on using it in like so:

Now it's time to actually install a pry break into your code using the following snippet:
binding.pry

Let’s create a file called ‘practice.rb’ and insert the following code into it:

Now, when you call “my_fancy_method” before the code finishes fully executing, it will run into the “binding.pry” and kick out into the REPL before it gets to the end. Inside the REPL, you will have everything that was defined before binding.pry, but not anything afterwards. Your terminal should look something like this:

At the bottoms you will see the pry(main)> prompt indicating you are currently inside the pry REPL. Let’s test it out. Since the variable inside_method was defined before binding.pry, it should be known to Pry.

It worked!! Now, lets try calling the variable frozen which isn’t defined until after the binding.pry on line 8:

It doesn’t know what frozen is, because as far as its concerned it hasn’t gotten to that definition yet so it does not exist. Make sense?

When you type ‘exit’ to leave Pry, it will continue executing the rest of the code, as seen here.

Using Pry to Debug

Ok. Now that we understand how to install, and use pry, we’ll see how it helps us debug code. Here are the most common uses of Pry for me so far in my early journey through the coding world.

Use Case #1: Checking Variables

One common mistake for early coders is improperly assigning values to variables. For example, let's say you had the following code:

It takes in an integer as an argument and multiplies it times itself 3 times. Then it returns a statement giving you your number cubed. Now in a simple case like this you may see the problem already, but let’s take a look at when we run our method with the input of 4.

4?? But 4 cubed is 64 not 4. Lets see what happened by using Pry:

If we type number into pry, even after line four: (number * number * number) has been executed, we see the value of number is still 4. Oops! we forgot to assign number*number*number value to a variable. How do we fix this?

Ok now lets run it again.

Perfect! Now you see how to use Pry to check the value of variables at different stages of your program.

Use Case #2: Seeing where you are in a nested Hash/Array

Let’s say we have an array of hashes (AOH) defined as follows:

Our goal here is to iterate through this hash and return all of the basketball teams for each city in the form of:

“The basketball teams for (city name) are (basketball team names).”

Now, this may seem complicated, but using our friend Pry, we should be able to take this step by step.

When we run this code we get a NoMethodError — undefined method ‘pry’… hmm..

Oops! we forgot to require ‘pry’ at the top of our code!!!! (I actually made this mistake while writing this so figured I would keep it in)

Much better!! Now based on our code, we can see we are two levels into our nested hash array, and on the first loop of each. We can confirm this by plugging outer_key and outer_value into our pry terminal:

Good, but we still need some work. We won’t get to the :teams hash until the 3rd loop of our inner each loop and then we still need to dive in 2 levels deeper to return the array of baseball team names. Let’s keep going and add some logic. (Remember: use “exit!” to back all the way out of PRY)

We should now be inside of the :teams hash and on the first iteration of our cities hash within :teams which would be :new_york.

We can check this again with pry by entering “city” and “sports_hash” into PRY.

Looks good! We’re getting close to the desired output! Lets bring it home.

Oh no!! So close but something is wrong. Lets use pry to figure out what happened.

There are a couple of errors here. If we check the sport it returns :baseball, but we’re looking for basketball teams for each city. The error is on line 44 in our if statement, where we say if sport ==:baseball instead of :basketball.

Then, we returned the wrong variable in our puts statement. We want to return the array of basketball team names for that city, which is defined as “team_name_array” yet we entered puts The basketball teams for #{city} are #{sport}.

Here is the final debugged code with these corrections added:

You can work on this code even further to make the output “prettier” but as you can see, Pry was extremely helpful in helping us get to the correct output.

Use Case #3: Anywhere else you need to debug your Code!!!

You can use Pry in any application that you seem fit where you need to debug errors in your code. Now that you’re a Pry wizard get out there and test it on your own!

NYC based SWE

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store