It’s My Party (..I mean Program) and I’ll Pry if I Want To

How to debug your Ruby code using Pry

Roy Flores
6 min readAug 21, 2020
image source: twitter.com/TheOnion

Learning how to code is pretty much like being a child learning the complexities of a language in order to communicate with everyone you interact with; in our case as programmers, a computer. When I started learning Ruby, one of the beautiful things I immediately noticed is how nice Ruby is to us. As much as it can, Ruby will let us know if there is something wrong with our code; what the error is, and where. Take the code below for example:

When we try to run this code, Ruby will bang the pots and pans and start hollering at us, letting us know that there is something wrong with what we just wrote!

Want to read this story later? Save it in Journal.

In the given example, Ruby threw (programmatically speaking) an error at us. Here, ruby tells us that there is a syntax error (an unexpected semicolon) in line 5 of our code. Wonderful! We can quickly fix that, and have our code up and running. As I have said earlier, Ruby is really nice to us that way. And very specific!

A syntax error is just one kind of error that Ruby can point out to us. There are many other errors that you’ll probably run into for the rest of your programming life. For more information about that, check out this documentation => Ruby Exceptions.

There are times though, when we get in situations that are beyond Ruby’s capabilities to help us. I mean… Ruby can’t do most of the heavy lifting for us. Sometimes the problem is in the logic we are telling our computer to evaluate. Take this code, for instance:

Ruby didn’t see any error, and ran our code. However, our code is not performing the way we designed it to. Calling on our find_young_cats method, and passing in our array_of_cats as an argument, we expected our method to give us the names “mojo”, “Savanah”, and “Willow”. But we got nothing. Not a single cat!

One way we could search for the gap in our logic is by puts-ing certain variables within our code. This is a simple way of debugging our code, but not the most ideal. We could end up sprinkling puts statements all over our code. And when we are dealing with more complex programs than the given example, our program could end up behaving in strange ways. We definitely don’t want that.

This is the perfect time for our dear friend, Pry, to make an appearance! If you’re not quite acquainted yet, allow me. Pry is a library or gem created by a guy named John Mair. It is a runtime developer console and an IRB alternative that we can install. Unlike IRB, Pry offers more flexibility and can be quite dynamic in a sense that you can inject it in your program and literally “pry” into your code, and figure out why it is acting funky.

How exciting! So how do we take advantage of the beautifully wrapped gift that Pry came with?

First thing we need to do is install Pry. We can do that by running gem install pry in our terminal, or adding this line to your application’s Gemfile:

gem ‘pry’, ‘~> 0.12.2’

Then executing:

bundle

Next thing to do is require Pry at the very top of whatever file you are woking in, like so:

Now that we are all set up, let’s put a binding.pry inside our method.

This should pause the execution of our code right when we hit line 13, and bring us into a new interactive environment where we can access and call on variables within that scope.

But wait. When we run our code, nothing happens! It didn’t pause the execution. Let’s throw another binding.pry outside of our if statement.

Let’s run the file again.

Hurray! Our code paused execution! We finally went into our interactive environment, which I like to call “Pry-land” . It’s quite exciting being in “Pry-land”. Here we can do some investigating or “prying around” and connect the dots as to why our code is not behaving the way we wanted it to.

Looking at the image above, we know that our code got paused at line 15. Do you notice the arrow to the very left? That is our indicator as to which line gets executed next (once we un-pause). Remember that we also put a binding.pry at line 13, but somehow, our code didn’t get paused there. With that observation, we can assume that our execution never went inside our if statement. Why is that? Let’s find out…

When we call on our younger_cats variable, we get a return of an empty array. So this means that line 12 of our code (where we are supposed to push names of cats into our younger_cats array) never gets executed. This information combined with our earlier observation about our binding.pry on line 13, solidifies our suspicion that we never went inside our if statement. Not even once. I think we found our culprit! The condition of our if statement!

We are looking for young cats. The way we’ve written our conditional statement, we are telling our program to only enter the code block of our if statement if the age of the cat in the current iteration, is greater than 3. We meant to say less than 3!

Now that we’ve traced where our mistake is, we can change the > to a < , remove our binding.pry’s, leave “Pry-land” (using !!! + ENTER), run our file again, and VOILA! We got “Mojo”, “Savanah”, and “Willow”.

Thank you Pry! And thank you John Mair!

📝 Save this story in Journal.

👩‍💻 Wake up every Sunday morning to the week’s most noteworthy stories in Tech waiting in your inbox. Read the Noteworthy in Tech newsletter.

--

--