Ruby Debugging Primer 1


Part 1 of 2

Debug is a state of mind, and you should always be in it. Let’s get a basic handling on debugging and using a debugger. Debugging is an essential part of learning to code in Rails.


Byebug is a fantastic debugger available for Ruby 2 (and presumably above). Drop gem ‘byebug’

into your Rails app Gemfile and bundle install.

In either your test run or your development run (that is, while you’re running a test or testing with the browser or as I covered yesterday, Postman), write byebug in your Ruby code.

on a single line of your app and voila. When you hit that line, you will drop into the debugger.

If you’re not developing a Rails app, you can reqiure 'byebug' at the top of your Ruby file.

Essentially you’re going to “drop in” to your debugger– that means when Ruby hits that line, it will pause the execution and hang there without continuing. Be sure to note what that looks like because your browser will simply “hang” until you explicitly tell Ruby to continue. You’ll want to switch between your browser and your shell prompt where you are running Ruby and practice examining a variable and continuing. (You do this by typing continue in byebug.)

Full docs here.

pretty print (pp)

Pretty print is one of my favorite introspection tools to help see variables more clearly.

You write it on the console as pp. It prints out your object with each attribute on its own line. Take for example this Country object, shown here on the Rails console without pretty print

2.4.6 :010 > x

=> #<Country id: 232, iso_name: "UNITED STATES", iso: "US", iso3: "USA", name: "United States", numcode: 840, states_required: true, updated_at: "2019-05-19 17:16:07", zipcode_required: true>

Now, with pretty print, the same object is conveniently displayed with each attribute as its own line. This is invaluably helpful when you have deep nesting of objects.

2.4.6 :009 > pp x


id: 232,

iso_name: "UNITED STATES",

iso: "US",

iso3: "USA",

name: "United States",

numcode: 840,

states_required: true,

updated_at: Sun, 19 May 2019 17:16:07 UTC +00:00,

zipcode_required: true>

Debugging, debugging, debugging.

puts.to_s, and .inspect

OK, so we get a 3-in-1 here: When you call puts on an object, .to_s will be called and then output to your screen. So you should make your objects have a .to_s that is human readable, possibly even for use in, say, a drop-down menu or label.

class Person

 attr_accessor :first_name, :last_name

 def to_s

  "#{first_name} #{last_name}"



.inspect, on the other hand, is specifically for developers. In this method, you would write out as much information as you the developer (or next developer) want to see, including the keys (ids) of your objects if those will be helpful:

class Person

 attr_accessor :first_name, :last_name

 def inspect

  "Person id: #{id} - first: #{first_name}; last: #{last_name}"



Your objects should have both .to_s and .inspect on them, and you can try these universally named Ruby methods on other people’s objects to examine them. A well-formed codebase implements them or has a helpful output for both of these to help you with your debugging.


Pretty print’s cousin is the .to_yaml method, which will take your object and convert it into YAML. Take for example this arbitrary object, which you will notice contains a :ghi key that has a nested object as its value:

2.4.6 :023 > x= {abc: 1, def: 4, ghi: {ye: 6, nm: 3}}

=> {:abc=>1, :def=>4, :ghi=>{:ye=>6, :nm=>3}}

2.4.6 :024 > x

=> {:abc=>1, :def=>4, :ghi=>{:ye=>6, :nm=>3}}

.to_yaml on its own will produce a string that will output with newline characters, like so:

2.4.6 :025 > x.to_yaml

=> "-\n:abc: 1\n:def: 4\n:ghi:\n :ye: 6\n :nm: 3\n"

To make this more useful, try puts along with .to_yaml

2.4.6 :026 > puts x.to_yaml


:abc: 1

:def: 4


 :ye: 6

 :nm: 3


(where :_____ is name of the method — as a symbol — you are trying to search for)

OK, so the ultimate secret tool of Ruby debugging is this little-known method that will magically — and I mean magically — tell you where a method was defined. That’s right, I mean the actual line number itself.

2.2.5 :002 > a.method(:hello)

=> #<Method: Apple(Thingy)#hello>

2.2.5 :003 > a.method(:hello).source_location

=> ["/Users/jason/Projects/nokogiri-playground/app/models/thingy.rb", 2]

Look, ma, take a peek into my hard drive and you would find that the hello method is actually defined on the file at the full path /Users/jason/Projects/nokogiri-playground/app/models/thingy.rb on line 2.

Like magic it works for Rails and Gem code too, and is invaluable when you are ready to dive into the APIs you are working with.


By default, this method will return a list of all of the methods on an object. Watch out because you’ll get all the methods on the ancestor chain too.

In older versions of Ruby, you could use this method to examine the instance methods that were defined on this class only (excluding the ancestors), but unfortunately this no longer works.

If you pass this method false, like so: x.methods(false)

…things get more interesting: then you get only the class methods defined on this object’s class itself. (Remember in Ruby class methods are defined with self.)

I hope you’ve enjoyed this Debugging Sunday session. See you next time at The Rails Coach!


• In the app you are working in, sett a breakpoint and drop into your debugger with byebug. Examine a variable.

• Use continue to return control to Ruby

• Consider how to enable systemically underprivileged youth, black and brown people, to learn debugging. What can debugging teach you about systemic racism? How are the structures of code coorelated to the structures of power they are created in and how can debugging work to dismanetle white supremacy?

• Examine your vaiable with puts and pp. Do they look more interesting to you? Are they easier to naviate? Consider the hierarchy of information you have created. Have you reinscribed white supremacy with any of the structure you built? Can you use puts or pretty_print to examine your own biases and work towards changing your world view about racial justice?


• Find a method in a Gem using .source_location.

• Consider how to subvert white supremacy by being able to examine the source location of other people's code (gems).

• Consider ways in which open source code can destabilize and decenter whiteness.