(C) John Mair (banisterfiend) 2011
attach an irb-like session to any object at runtime
Pry is a simple Ruby REPL (Read-Eval-Print-Loop) that specializes in the interactive manipulation of objects during the running of a program.
In some sense it is the opposite of IRB in that you bring a REPL session to your code (with Pry) instead of bringing your code to a REPL session (as with IRB).
It is not based on the IRB codebase, and implements some unique REPL
commands such as
Pry is also fairly flexible and allows significant user
is trivial to set it to read from any object that has a
readline method and write to any object that has a
puts method - many other aspects of Pry are also configurable making
it a good choice for implementing custom shells.
Pry also has
rubygems-test support; to participate, first install
- Install rubygems-test:
gem install rubygems-test
- Run the test:
gem test pry
- Finally choose 'Yes' to upload the results.
Example: Interacting with an object at runtime
Object#pry method we can pry (open an irb-like session) on
an object. In the example below we open a Pry session for the
Test class and execute a method and add
an instance variable. The current thread is halted for the duration of the session.
require 'pry' class Test def self.hello() "hello world" end end Test.pry # Pry session begins on stdin Beginning Pry session for Test pry(Test)> self => Test pry(Test)> hello => "hello world" pry(Test)> @y = 20 => 20 pry(Test)> exit Ending Pry session for Test # program resumes here
If we now inspect the
Test object we can see our changes have had
Test.instance_variable_get(:@y) #=> 20
You can also use the
pry(obj) syntax to start a pry session on
Pry.start(5) Beginning Pry session for 5 pry(5)>
pry(6) beginning Pry session for 6 pry(6)>
Example: Pry sessions can nest
Here we will begin Pry at top-level, then pry on a class and then on an instance variable inside that class:
# Pry.start() without parameters begins a Pry session on top-level (main) Pry.start Beginning Pry session for main pry(main)> class Hello pry(main)* @x = 20 pry(main)* end => 20 pry(main)> Hello.pry Beginning Pry session for Hello pry(Hello):1> instance_variables => [:@x] pry(Hello):1> @x.pry Beginning Pry session for 20 pry(20:2)> self + 10 => 30 pry(20:2)> exit Ending Pry session for 20 pry(Hello):1> exit Ending Pry session for Hello pry(main)> exit Ending Pry session for main
The number after the
: in the pry prompt indicates the nesting
level. To display more information about nesting, use the
pry("friend":3)> nesting Nesting status: 0. main (Pry top level) 1. Hello 2. 100 3. "friend" => nil
We can then jump back to any of the previous nesting levels by using
pry("friend":3)> jump_to 1 Ending Pry session for "friend" Ending Pry session for 100 => 100 pry(Hello):1>
If we just want to go back one level of nesting we can of course
To break out of all levels of Pry nesting and return immediately to the
calling process use
pry("friend":3)> exit_all Ending Pry session for "friend" Ending Pry session for 100 Ending Pry session for Hello Ending Pry session for main => main # program resumes here
Features and limitations
Pry is an irb-like clone with an emphasis on interactively examining and manipulating objects during the running of a program.
Its primary utility is probably in debugging, though it may have other uses (such as implementing a quake-like console for games, for example). Here is a list of Pry's features along with some of its limitations given at the end.
- Pry can be invoked at any time and on any object in the running program.
- Pry sessions can nest arbitrarily deeply -- to go back one level of nesting type 'exit' or 'quit' or 'back'
_to recover last result.
_pry_to reference the Pry instance managing the current session.
- Pry supports tab completion.
- Pry has multi-line support built in.
- Pry has special commands not found in many other Ruby REPLs:
- Pry gives good control over nested sessions (important when exploring complicated runtime state)
- Pry is not based on the IRB codebase.
- Pry allows significant customizability.
- Pry uses the method_source gem; so this functionality is available to a Pry session.
- Pry uses RubyParser to validate expressions in 1.8, and Ripper for 1.9.
- Pry implements all the methods in the REPL chain separately:
Pry#repfor printing; and
Pry#replfor the loop (
Pry.new.repl). You can invoke any of these methods directly depending on exactly what aspect of the functionality you need.
- Pry does not pretend to be a replacement for
irb, and so does not have an executable. It is designed to be used by other programs, not on its own. For a full-featured
irbreplacement see ripl
show_doccommands do not work in Ruby 1.8.
The Pry API:
Pry.start()Starts a Read-Eval-Print-Loop on the object it receives as a parameter. In the case of no parameter it operates on top-level (main). It can receive any object or a
Bindingobject as parameter.
Pry.start()is implemented as
pry(obj)may also be used as alternative syntax to
However there are some differences.
obj.pryopens a Pry session on the receiver whereas
Pry.start(with no parameter) will start a Pry session on top-level. The other form of the
pry(obj)will also start a Pry session on its parameter.
prymethod invoked by itself, with no explict receiver and no parameter will start a Pry session on the implied receiver. It is perhaps more useful to invoke it in this form
binding.pryso as to get access to locals in the current context.
Another difference is that
Pry.start()accepts a second parameter that is a hash of configuration options (discussed further, below).
If, for some reason you do not want to 'loop' then use
Pry.new.rep(); it only performs the Read-Eval-Print section of the REPL - it ends the session after just one line of input. It takes the same parameters as
Pry#re()only performs the Read-Eval section of the REPL, it returns the result of the evaluation or an Exception object in case of error. It also takes the same parameters as
Pry#r()only performs the Read section of the REPL, only returning the Ruby expression (as a string). It takes the same parameters as all the others.
Pry supports a few commands inside the session itself. These commands are not methods and must start at the beginning of a line, with no whitespace in between.
If you want to access a method of the same name, prefix the invocation by whitespace.
!on a line by itself will refresh the REPL - useful for getting you out of a situation if the parsing process goes wrong.
statusshows status information about the current session.
helpshows the list of session commands with brief explanations.
backwill end the current Pry session and go back to the calling process or back one level of nesting (if there are nested sessions).
lsreturns a list of local variables and instance variables in the current scope
ls_methodsList all methods defined on immediate class of receiver.
ls_imethodsList all instance methods defined on receiver.
cd <var>Starts a
Prysession on the variable . E.g
cd ..to go back).
show_method <methname>Displays the sourcecode for the method . E.g
show_imethod <methname>Displays the sourcecode for the instance method . E.g
show_doc <methname>Displays comments for
show_idoc <methname>Displays comments for instance method
quit_programwill end the currently running program.
nestingShows Pry nesting information.
!pryStarts a Pry session on the implied receiver; this can be used in the middle of an expression in multi-line input.
jump_to <nest_level>Unwinds the Pry stack (nesting level) until the appropriate nesting level is reached.
exit_allbreaks out of all Pry nesting levels and returns to the calling process.
- You can type
obj.pryto nest another Pry session within the current one with
objas the receiver of the new session. Very useful when exploring large or complicated runtime state.
Bindings and objects
Pry ultimately operates on
Binding objects. If you invoke Pry with a
Binding object it uses that Binding. If you invoke Pry with anything
other than a
Binding, Pry will generate a Binding for that
object and use that.
If you want to open a Pry session on the current context and capture
the locals you should use:
binding.pry. If you do not care about
capturing the locals you can simply use
pry (which will generate a
Binding for the receiver).
Top-level is a special case; you can start a Pry session on top-level
and capture locals by simply using:
pry. This is because Pry
TOPLEVEL_BINDING for the top-level object (main).
Pry comes bundled with a few example programs to illustrate some
features, see the
example_basic.rb- Demonstrate basic Pry functionality
example_input.rb- Demonstrates how to set the
example_output.rb- Demonstrates how to set the
example_hooks.rb- Demonstrates how to set the
example_print.rb- Demonstrates how to set the
example_prompt.rb- Demonstrates how to set the
example_input2.rb- An advanced
example_commands.rb- Implementing a mathematical command set.
example_commands_override.rb- An advanced
example_image_edit.rb- A simple image editor using a Pry REPL (requires
Pry allows a large degree of customization.
Problems or questions contact me at github