This was the tip of the week in the Jan 21, 2021 Ruby Weekly Newsletter.

There are many popular debugging gems or IRB alternatives. These are typically packed with features and can be extremely useful tools. The main caveat to using them, besides learning their unique syntax, is having to install (and sometimes configure) them. If we’re working in repos that don’t have our favorite debugging gems installed, we have to adopt certain workarounds.

Perhaps less well known than gems like pry and byebug is the binding.irb feature of irb (as available in Ruby 2.4 onward). It allows us to open an IRB console from within the current scope. In this IRB console, we can call any methods or variables defined within the current scope as well as mutate state. Since IRB is installed with Ruby, there’s no need to install any separate gems and it will work wherever we’re running Ruby.

Here’s an example of adding a binding.irb call to some simple code:

def func(input)
  a = 1
  a + input

puts func(0)
$ ruby example.rb

From: example.rb @ line 3 :

    1: def func(input)
    2:   a = 1
 => 3:   binding.irb
    4:   a + input
    5: end
  7: puts func(0)

irb(main):001:0> a
=> 1
irb(main):002:0> input
=> 0
irb(main):003:0> a = 2
=> 2
irb(main):004:0> input = 3
=> 3
irb(main):005:0> exit

Voila! We get an IRB console from within our code. Not only can we see the values of our local variables, we can also change their values (which leads this program to print 5 instead of 1 as it otherwise would have). Any methods or variables available within the current scope can be accessed from this IRB console. As we see above, binding.irb will pause execution of our code, and exiting the IRB console will resume execution.

Next time you’re debugging, give binding.irb a try!