Good Byebug

A Guide

Arthur Torres
9 min readJan 24, 2019

If you’re a Ruby developer, or even if you’ve only casually toyed with Ruby on Rails, you’ve probably used the byebug gem to debug your code. If you haven’t, you should certainly read on; you have a lot to gain here, but even if you have used byebug, are you taking full advantage of its commands and features? If you’re unsure, this article was written with you in mind.

Is Byebug Just a REPL?

The quick answer is no, but if we’re going to talk about how byebug is more than just a REPL, first we must make sure we’re clear on what a REPL is.

REPL stands for Read — Eval — Print Loop, which is a fancy term for a tool that lets you run code right in your command line and see the results. You may have used other Ruby REPL tools such as irb or pry. Pry in particular is great for allowing you to stop your code at any point in its process and open a REPL session at the current state.

Byebug can give you this type of functionality, but honestly, if this is all you’re going to use it for, you’re better off using pry, because well, pry does it better. As a matter of fact, you can even call pry directly from within byebug with the pry command, but more on that later.

Before we set out on our adventure, I’ll show you the code we’re going to be working with in our examples. This is book_collector.rb, a simple program that generates random book titles and adds them to a collection.

book_collector.rb

Starting Byebug

Byebug is built into Rails, but if you’re not using Rails you’ll have to run gem install byebug and add require 'byebug' to your code before you can use it.

Once you’ve done that, there are two ways you can open byebug: directly from your terminal by typingbyebug app/modules/book_collector.rb, which will open byebug and start you at the first line of code, or when you’re working with a large file and you know exactly where you need to go to debug, you can type byebug into your code at the location you want to start, and then run the file normally.

When you’re finished, you can exit with the quit! command. The “!” prevents you from getting an annoying “are you sure” prompt.

Navigation Commands

Probably the greatest functional difference between byebug and REPL only debugging tools, is its ability to navigate around within your code while you debug. As invaluable as this feature is, it can also be a little unintuitive for someone who isn’t familiar with it, but with some understanding of a few deceptively simple commands, this type of debugging can become second nature.

next / step

Most of your navigation will be accomplished with these two commands, and it’s important to know the difference in the way they work. Let’s start at the top.

Byebug shows us exactly where we are in the file. We’re on the first line of code where we require faker, a gem that allows us to generate our random book names.

Let’s type next.

Now we’re at the start of our first method. Let’s go ahead and call that method and see what happens.

Uh oh, it says the method doesn’t exist. That’s because where we are in the file is directly before the #collection method, and in Ruby if you try to call a method before defining it, you won’t get the results you’re looking for.

Let’s type next again.

Ok, that drops us down to line 7 where the next method starts. It does not take us into the block of the method. That’s good to know. What happens now if we try to call #collection again?

Bingo! It worked this time because we’re past the point where our method was defined.

So the next command navigates us through the code one method at a time, and if you stop to type some Ruby code like you would in a REPL it will run it as if it’s being run directly before the line we are on. As it turns out, step would work much the same way here because we haven’t called any of our methods yet, but let’s jump on down to the line where we call our method from within the file to see how the two commands differ.

Did you see what I did there? I typed next 2, which is the same as using next twice, and that jumped us on down to line 19 where we call #show_collection.

Let’s type next again to see what happens.

It just moved down two lines to the next line of code. Ok that’s pretty simple. If we were to type next again here I bet you can guess what would happen. we’d jump down to line 23, the next line of code in the file…

…but what happens if we type step?

Now this is a different result. We’ve gone all the way up to line 8. That’s because we were at the line where we call #collect_books(n), and we stepped into the method, which is defined above.

That was fun. Let’s type step again.

It moved us down only one line. More specifically it stepped us into the n.times block. Now that we are inside of an iterative block, every time we type next it will take us to the next iteration within the block, but more on that later.

restart / break / continue

Let’s say we’ve made some changes to our code. We’ve made a change to #collect_books(n) and now we want byebug to reflect those changes.

We can do that easily by typing restart.

Here we are back at the start of the file, and if you look closely you’ll see it reflects the changes I made on line 8 telling the n.times block to track index. If we want to get back into the block, does that mean we have to go all the way to the bottom of the file where we called the method and step into it from there? Nope.

Here we can use the break command.

Great, I typed break 9 and it told me it created breakpoint 1 at line 9, but what does that get us? How do we make use of this breakpoint?

Well, continue is the only command named in the tittle of this section that we haven’t used yet, so let’s try that.

Yep, that did the trick. continue brought us all the way down to line 9 where our first breakpoint was. You can set as many breakpoints as you want this way, and work your way through them using the continue command, but keep in mind, this only works because we are calling our method at the bottom of the file. When you type continue, byebug reads the entire file stepping into each method when called. When it gets to the line collect_books(7), it calls the method and triggers the breakpoint on line 9.

Commands for Tracking Variables and Running Code

We’ve learned how to navigate around a Ruby file with byebug, and we know that we can type Ruby code at any point just like a REPL, but what if we want to see the value of a variable and it happens to have the same name of one of the byebug commands? There’s a command for that!

eval / display

Here we are on line 9 inside our n.times block, and let’s say we want to see what the value of n is. As it turns out n is an alias for next so if you just type n, byebug will not read it as Ruby code. Instead it will go to the next iteration.

The way around this is to use the eval command.

That was easy. Now maybe we want to see the value of index and of collection.

That’s pretty cool, notice how it even works with collection which is actually a method. Some of these values will change as we move through the iterations of the n.times block. Wouldn’t it be cool if we could automatically track the value of our variables as we go? Oh, but we can!

We can set this by using display.

We’ve set a display for each of our variables, now let’s type next to go to the next iteration.

Beautiful! We’re still on line 9, but because we are tracking our variables with display we can see that we are on the second iteration (index 1), and we now have one book title in our array called “Wildfire At Midnight”.

Just for fun let’s do it again.

I’m sure you’re not surprised that our variables changed again. You can bet that we could keep doing this until we’ve collected 7 books, and we know that because n = 7.

pry

I suspect you’re beginning to see the raw debugging power that byebug can give you, but you might recall I stated earlier that pry is still the better option when all you need is a REPL. You might also recall when I mentioned you can open pry from within byebug. That’s because byebug has a pry command, but remember pry is not built into Rails by default, so you’ll have to include it in your Gemfile for this to work.

We’ve gone through several iterations inside #collect_books(n), and the collection array is starting to get a bit long and difficult to read, and this is still a small array compared to the data you may have to work with.

Let’s see if we can hop into pry and get a better view.

Oh, pry you lovely creature, that is one good looking array!

When you’re working with complex nested arrays, or custom objects with numerous attributes, believe me, you’ll find that pry can display information in a much more readable fashion.

Bye Bye Byebug…

…for now.

I’ve given you an arsenal of commands to use in your war against bugs, and hopefully you’re starting to see just how powerful byebug can be. If you’d like to learn more about what byebug can do, type help to see the full list of commands that byebug has to offer. Thanks for reading, happy coding, and happy debugging!

--

--

Arthur Torres

I'm a former infrastructure engineers specializing in enterprise virtualization platforms, turned software engineer to follow my passion. Do what you love!