Ruby pry

From wikinotes

pry is an alternative interpreter for ruby (instead of ruby irb ).
It has powerful features like:

  • syntax highlighting
  • tab-completion


Documentation

github https://github.com/pry/pry

Install

gem install pry

Usage

interpreter

pry                           # start pry interpreter
ruby -r pry -e 'binding.pry'  # start pry interpreter from specific ruby interp
pry -r ./config/environment   # load rails from pry

debugger

# Use `pry` interpreter in debug mode.
ruby -r pry yourmodule.rb
# Add a breakpoint to your code
require 'pry'; binding.pry

Configuration

readline

gem install rb-readline  # pure ruby readline

Then you can customize readline within your ~/.inputrc

set editing-mode vi
set keymap vi

# meta+(hjkl) jumps into normal mode from insert mode
set keymap vi-insert
  M-h: vi-movement-mode
  M-j: vi-movement-mode
  M-k: vi-movement-mode
  M-l: vi-movement-mode
  C-l: clear-screen
 
# meta+(hjkl) from normal mode also moves characters
set keymap vi-move
  M-h: previous-char
  M-j: previous-history
  M-k: next-history
  M-l: next-char
  C-l: clear-screen

Commands

Overview

help                      # print available commands

load 'path/file.rb'       # execute file within pry (reload)

ls                        # list methods/attrs currently in scope (categorized by module/class)
ls <object>               # list methods/attrs on object (categorized by module/class)

whereami                  # print current location
show-source <method>      # show sourcecode
show-source -ld <method>  # show sourcecode with docstring
show-doc <method>         # show docstring

exit!                     # quit debugger

ls/find-method

ls -h       # print flags
ls -p Obj   # print protected/private/public methods
ls -i Obj   # print instance attributes
ls -G ^foo  # filter out results that do not start with 'foo' (has not worked for me)
find-method -c '^abc' Foo  # search for specific method (regex)

load (run file)

Execute a file within pry.

# file.rb
require 'pry'

users = User
  .where(last_name: "Guthrie")
  .limit(10)

binding.pry
puts users

By adding binding.pry (followed by another line of code), reloading the file will run up until the trace, and leave you an interactive console with all variables in scope.

[1] pry(main)> load 'file.rb'
# (runs test.rb, leaves you at trace)


Extensions

pry-byebug

NOTE:

pry-byebug does not have a post-mortem option

[1] pry(main)> break  --help
[1] pry(main)> break                                 # prints all current breakpoints
[1] pry(main)> break ::Namespace::MyClass#my_method  # add breakpoint at start of method
[1] pry(main)> break app/models/user.rb:222          # add breakpoint at line 222 in file
[1] pry(main)> break --delete 1                      # delete breakpoint at `break` result index 1 (1-indexed)
# add breakpoint in code
b = PryByebug::BreakCommand.new
b.send(:add_breakpoint, 'file.rb:222', nil)

You can enable gdb-style pry shortcuts by modifying your ~/.pryrc

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

  Pry::Commands.command /^$/, "repeat last command" do
    _pry_.run_command Pry.history.to_a.last  
  end
end

pry-rails

https://github.com/rweng/pry-rails

Adds useful commands related to rails introspection:

find-route
show-models  # list all models/attrs
show-routes  # show all routes

pry-editline

tim pope plugin to edit current line in vim.
pry ships with readline support, this plugin is kind of useless to me, actuall...

https://www.rubydoc.info/gems/pry-editline/1.1.2

Tips/Tricks

Vim Cursor Navigation

pry uses readline. Configure your ~/.inputrc and it will get used.

Time Travel

If testing a rails app, can use TimeHelpers.

require 'active_support/testing/time_helpers'

class FooBar
  include ActiveSupport::Testing::TimeHelpers
  def doit
    sunday = Date.new(2019, 7, 21)
    travel_to(sunday) do
      puts Time.now
    end
  end
end
FooBar.new.doit