Pry

Ruby ships with an interactive shell, or REPL (Read-Eval-Print Loop) called irb. It’s pretty handy for quick ruby evaluations, or running rails console commands.

You can also require files or gems to do more complicated stuff, you can bundle exec irb to run your shell with the local gemset installed.

I’ll assume you know about it and what it does.

Pry is like irb, but better. The big benefits include:

Combining it with plugins like pry-byebug and pry-remote allows you to step through code, or debug through a network connection.

Source code and documentation browsing

Using this code:

pry example pry_example.rb

require 'pry'
require 'pry-byebug'

# This class stores a value when initialized, and provides a multiply method
# to multiply a given value by the initial value
class SimpleTest
  def initialize(v)
    binding.pry
    @v = v
  end

  def multiply m
    @v * m
  end
end

binding.pry

t = SimpleTest.new(3)
t.multiply 7

You can spelunk around the code, inspect classes and methods and view their source code or documentation.

Breakpoint debugging

The best use for pry, is with binding.pry Add this to your code, and when executed, you will drop straight into the pry REPL at that point in the code. You can then inspect objects, and navigate through the stack and step through the code.

These features are shown in the playthough below:

$ ruby pry_example.rb

From: .../blog_code_examples/pry_example.rb:19 :

    14:   end
    15: end
    16:
    17: binding.pry
    18:
 => 19: t = SimpleTest.new(3)
    20: t.multiply 7
    21:

[1] pry(main)> ls
self.methods: inspect  to_s
locals: _  __  _dir_  _ex_  _file_  _in_  _out_  pry_instance  t
[2] pry(main)> cd SimpleTest
[3] pry(SimpleTest):1> show-source

From: pry_example.rb:4
Class name: SimpleTest
Number of lines: 10

class SimpleTest
  def initialize(v)
    binding.pry
    @v = v
  end

  def multiply m
    @v * m
  end
end
[4] pry(SimpleTest):1> show-doc

From: pry_example.rb:4
Class name: SimpleTest
Number of lines: 2

This class stores a value when initialized, and provides a multiply method
to multiply a given value by the initial value

WARNING: the show-doc command is deprecated. It will be removed from future Pry versions.
Please use 'show-source' with the -d (or --doc) switch instead
Example: show-source  -d
[5] pry(SimpleTest):1> nesting
Nesting status:
--
0. main (Pry top level)
1. SimpleTest
[6] pry(SimpleTest):1> cd ..
[7] pry(main)> next

From: .../blog_code_examples/pry_example.rb:9 SimpleTest#initialize:

     7: def initialize(v)
     8:   binding.pry
 =>  9:   @v = v
    10: end

[7] pry(#<SimpleTest>)> v
=> 3
[8] pry(#<SimpleTest>)> next


From: .../blog_code_examples/pry_example.rb:20 :

    15: end
    16:
    17: binding.pry
    18:
    19: t = SimpleTest.new(3)
 => 20: t.multiply 7
    21:

[9] pry(main)> t.interesting_methods
=> [:multiply]
[10] pry(main)>continue

Customisation

You can add features and configurations in $HOME/.pryrc. This is a ruby file, mine currently looks like this:

.pryrc .pryrc

class Object
  def interesting_methods
    case self.class
    when Class
      self.public_methods.sort - Object.public_methods
    when Module
      self.public_methods.sort - Module.public_methods
    else
      self.public_methods.sort - Object.new.public_methods
    end
  end
end

if defined?(PryDebugger) || defined?(PryByebug)
  Pry.commands.alias_command 'c', 'continue'
  Pry.commands.alias_command 's', 'step'
  Pry.commands.alias_command 'n', 'next'
  Pry.commands.alias_command 'f', 'finish'
end

Extra

You can also edit an object, open your configured editor. w 20 shows 20 lines of context around your current breakpoint. Type help at any point to get a whole bunch of useful information.

Tagged: | software-development | pry | ruby | debugging |
Cover Image: Kalea Jerielle, via Unsplash