Four things about Pry
Tags: commandline, programming, ruby, debugging
Published: 2018-12-28 17:35:04

---
title: Four things about Pry
published: true
tags: command-line,programming,ruby,debugging
canonical_url: https://revs.runtime-revolution.com/four-things-about-pry-a0ebb10c6c2e
---

![](https://cdn-images-1.medium.com/max/819/1*QTCgxaIflO13BjErDm69nw.png)<figcaption>Pry is ready for action.</figcaption>

I love **REPL** s. It’s a great development tool. Any decent language has a REPL. **Lisp** has it. **Python** has it. So does **Haskell**. And **Ruby** , obviously, has it!

REPL stands for **R** ead **E** val **P** rint **L** oop. It’s a command line interface to interact with a programming language. Most interactive programming languages have a REPL. (I didn’t check.) This nomenclature derives from Lisp’s implementation which, in its most basic form, can be a one-liner:

```
(loop (print (eval (read))))
```

Lisp REPLs are very powerful. We can inspect the stack tree, (re-)execute a frame (usually a function call), change frame arguments and re-execute it, change a function definition and re-execute the frame calling it.

With such high expectations, it’s no wonder that [**IRB**](https://ruby-doc.org/stdlib/libdoc/irb/rdoc/IRB.html) (Ruby’s default REPL) doesn’t look that powerful. (I think you’ll agree with me on this.) [**Pry**](http://pryrepl.org/) is a pretty powerful alternative to IRB and packs a lot of new functionality. But still… it can’t be compared with Lisp’s. Nevertheless, there are a few features which (I think) will appeal to newcomers. I intend to go over them in this post.

### Previous evaluation value

When learning Ruby, one of the things I was constantly needing to do was using the value of the previous evaluation. Let’s say I had calculated the tax value of a product and now wanted to get the final price:

```
pry(main)\> price, tax\_rate = 34, 0.08
=\> [34, 0.08]
pry(main)\> price \* tax\_rate
=\> 2.72
pry(main)\> final\_price = price + # damn! -\_-
```

It took me ages to find out we can access the previous value with **\_** (underscore). With two underscores **\_\_** we access the second from last value.

```
pry(main)\> price, tax\_rate = 34, 0.08
=\> [34, 0.08]
pry(main)\> price \* tax\_rate
=\> 2.72
pry(main)\> final\_price = price + \_
=\> 36.72
pry(main)\> \_\_
=\> 2.72
```

### Where am I?

One debug methodology is to put breakpoints in our code. With Pry we do that with the **binding.pry** expression. This causes the execution to stop on that line. When that happens ruby’s console will show something like this:

```
pry(main)\> Grid.generate(6, 6)

From: /Users/bjacquet/Projects/gol/gol.rb @ line 27 Grid.generate:

25: def self.generate(width, height)
 26: self.new(Array.new(height).collect do
 =\> 27: binding.pry
 28: Array.new(width).collect { rand(2) }
 29: end
[1] pry(Grid)\>
```

It shows the line of code where the execution stopped, indicated with =\>. (Being the 27th line.) Also some code context with surrounding lines. We can also infer that it stopped inside the method Grid.generate and it’s defined in file  **gol.rb**.

This information is also available at any time by typing in the **whereami**  command.

Were this method twice its size, we could still see its full content by using the **show-source** command as such:

```
pry(main)\> show-source Grid.generate

From: gol.rb @ line 25:
Owner: #\<Class:Grid\>
Visibility: public
Number of lines: 7

def self.generate(width, height)
 self.new(Array.new(height).collect do
 binding.pry
 Array.new(width).collect { rand(2) }
 end
 )
end
pry(Grid)\>
```

### Replaying history

Pry’s **hist** command is really something. It enables you to view, search, and replay history, among other things. When invoked with no options it displays all of Pry’s history, that is, all the inputs we’ve given it.

```
pry(main)\> hist
1: price, tax\_rate = 34, 0.08
2: price \* tax\_rate
3: price, tax\_rate = 34, 0.08
4: price \* tax\_rate
5: final\_price = price + \_
6: \_\_
7: Grid.generate(6, 6)
8: show-command Grid.generate
pry(main)\>
```

With the **--replay** option we can re-evaluate expression(s):

```
pry(main)\> hist --replay 3..4
=\> [34, 0.08]
=\> 2.72
```

I find it faster to use this command than revolving previous inputs with the up arrow.

### Let me fix that right now

Quite often we are typing in multiple-line expressions into Pry. More often than we would like we type in a line with an error. To fix it we use the **amend-line** command. It takes a line number and the replacement code as arguments.

```
pry(main)\> def hello
pry(main)\* puts “hello #{name}”
pry(main)\* amend-line 1 def hello(name)
1: def hello(name)
2: puts “hello #{name}”
pry(main)\* end
=\> :hello
```

In this example I realised that I forgot to specify name as a method argument. Thus I correct that by calling the amend-line command on line **1** with the new code. Pry then shows all input lines provided so far and waits for more. I type in end and the method is defined.

### Going further

Off by one error, sorry about that! It’s worth it.

Pry also gives us the possibility of changing methods on the fly. To do so we need to use two commands. First we change the method using the **edit**  command.

```
pry(main)\> edit Grid.generate
```

This will open an editor with the cursor on the first line of the method definition. When we’re done, we save the changes and exit the editor.

Next we need to evaluate the new definition. Command **reload-method** does just that.

```
pry(main)\> reload-method Grid.generate
```

From now on it will use the new version of Grid.generate.

### Further reading

Pry has a lot more features to discover. Whilst preparing this post I discovered the amend-line command. It is so useful that I had to include it. Other commands you should know about include:

- **show-model** , lists the model attributes and class associations.
- **show-stack** , shows the frames call stack. (More often than not, this takes a lot of time to display anything.)

[Pry's wiki](https://github.com/pry/pry/wiki) is well documented and also has links to other resources.

Pry’s help command is also very useful. I learned most of these features through there. (RTFM syndrome)

That’s all for now. Have fun and be nice! :-)

_I work at_ [_Runtime Revolution_](http://www.runtime-revolution.com/) _as a Rails developer. We also work with Python, JavaScript… both of which have REPL! We also help startups reach the next level._

* * *