217 lines
9.0 KiB
HTML
217 lines
9.0 KiB
HTML
<!DOCTYPE html>
|
||
<html lang='en'>
|
||
<head>
|
||
<meta charset='utf-8'>
|
||
<meta content='-L_V_27r8NmVJh-1OGyEhGcNVulPnxjfbma6m3SqNME' name='google-site-verification'>
|
||
<link href='http://yorickpeterse.com/feed.xml' rel='alternate' title='Yorick Peterse' type='application/atom+xml'>
|
||
<link href='http://yorickpeterse.com/articles/debugging-with-pry/' rel='canonical'>
|
||
<meta content='pry,repl,ruby,debugging,irb' name='keywords'>
|
||
<meta content='Pry is a REPL (Read Eval Print Loop) that was written as a better alternative to IRB.' name='description'>
|
||
<link href='/favicon.ico' rel='icon' type='image/x-icon'>
|
||
<link href='http://fonts.googleapis.com/css?family=Lato' rel='stylesheet'>
|
||
<link href='/stylesheets/application.css' rel='stylesheet'>
|
||
<!--[if lt IE 9]>
|
||
<script src='http://html5shim.googlecode.com/svn/trunk/html5.js'></script>
|
||
<![endif]-->
|
||
<title>Debugging With Pry</title>
|
||
|
||
</head>
|
||
<body>
|
||
<header id='top'>
|
||
<nav>
|
||
<ul class='clearfix'>
|
||
<li>
|
||
<a href='http://yorickpeterse.com'>
|
||
Homepage
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a href='http://yorickpeterse.com/feed.xml'>
|
||
Atom Feed
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</nav>
|
||
</header>
|
||
|
||
<div class='row' id='content'>
|
||
<section>
|
||
<header>
|
||
<h1>Debugging With Pry</h1>
|
||
<p class='meta'>
|
||
Published on: <time datetime="2011-11-26T23:00:00Z">November 26, 2011</time>
|
||
</p>
|
||
</header>
|
||
|
||
<p>Pry is a REPL (Read Eval Print Loop) that was written as a better alternative
|
||
to IRB. It comes with syntax highlighting, code indentation that actually works
|
||
and several other features that make it easier to debug code. I stumbled upon
|
||
Pry when looking for an alternative to both IRB and the way I was debugging my
|
||
code (placing <code>puts</code> all over the place, I think it’s called “Puts Driven
|
||
Development”).</p>
|
||
|
||
<p>Pry tries to do a lot of things and I was actually quite surprised how well it
|
||
does that. It might not stick to the Unix idea of only doing a single thing
|
||
(and doing that very well) but it makes my life (and the lifes of others) so
|
||
much easier that it’s easy to forget.</p>
|
||
|
||
<p>Pry is primarily meant to be used as a REPL. There are a lot of things that
|
||
make Pry so much more pleasant to use than IRB. One of the things almost any
|
||
Ruby programmer will notice when using IRB is that its indentation support is a
|
||
bit clunky. Indenting itself works fine most of the time but it fails to
|
||
un-indent code properly as illustrated in the code snippet below (pasted
|
||
directly from an IRB session):</p>
|
||
|
||
<div class="CodeRay"><div class="code"><pre><code class="language-text">ruby-1.9.3-p0 :001 > class User
|
||
ruby-1.9.3-p0 :002?> def greet
|
||
ruby-1.9.3-p0 :003?> puts "Hello world"
|
||
ruby-1.9.3-p0 :004?> end
|
||
ruby-1.9.3-p0 :005?> end</code></pre></div></div>
|
||
|
||
<p>Luckily Pry handles this just fine, whether you’re trying to indent a class or
|
||
a hash containing an array containing a proc and so on. Pry does this by
|
||
resetting the terminal output every time a new line is entered. The downside of
|
||
this approach is that it only works on terminals that understand ANSI escape
|
||
codes. In Pry the above example works like it should do:</p>
|
||
|
||
<div class="CodeRay"><div class="code"><pre><code class="language-text">[1] pry(main)> class User
|
||
[1] pry(main)* def greet
|
||
[1] pry(main)* puts "Hello world"
|
||
[1] pry(main)* end
|
||
[1] pry(main)* end</code></pre></div></div>
|
||
|
||
<p>Besides indentation Pry does a lot more. A feature that I think is very cool is
|
||
the ability to show documentation and source code of methods right in your REPL
|
||
(sadly this feature doesn’t work with classes or modules at the time of
|
||
writing). This means that you no longer have to use the <code>ri</code> command to
|
||
search documentation for methods. You also don’t need to install the RDoc
|
||
documentation as Pry pulls it directly from the source code. Showing the source
|
||
code of a method or its documentation can be done by using the <code>show-method</code>
|
||
and <code>show-doc</code> command. For example, invoking <code>show-method pry</code> in a Pry
|
||
session would give you the following output:</p>
|
||
|
||
<div class="CodeRay"><div class="code"><pre><code class="language-text">[1] pry(main)> show-method pry
|
||
|
||
From: /path/trimmed/for/readability/lib/pry/core_extensions.rb @ line 19:
|
||
Number of lines: 3
|
||
Owner: Object
|
||
Visibility: public
|
||
|
||
def pry(target=self)
|
||
Pry.start(target)
|
||
end</code></pre></div></div>
|
||
|
||
<p>Calling <code>show-doc pry</code> would instead show the following:</p>
|
||
|
||
<div class="CodeRay"><div class="code"><pre><code class="language-text">[2] pry(main)> show-doc pry
|
||
|
||
From: /path/trimmed/for/readability/lib/pry/core_extensions.rb @ line 19:
|
||
Number of lines: 17
|
||
Owner: Object
|
||
Visibility: public
|
||
Signature: pry(target=?)
|
||
|
||
Start a Pry REPL.
|
||
This method differs from Pry.start in that it does not
|
||
support an options hash. Also, when no parameter is provided, the Pry
|
||
session will start on the implied receiver rather than on
|
||
top-level (as in the case of Pry.start).
|
||
It has two forms of invocation. In the first form no parameter
|
||
should be provided and it will start a pry session on the
|
||
receiver. In the second form it should be invoked without an
|
||
explicit receiver and one parameter; this will start a Pry
|
||
session on the parameter.
|
||
param [Object, Binding] target The receiver of the Pry session.
|
||
example First form
|
||
"dummy".pry
|
||
example Second form
|
||
pry "dummy"
|
||
example Start a Pry session on current self (whatever that is)
|
||
pry</code></pre></div></div>
|
||
|
||
<p>You can also run these commands for code that was written in C. This requires
|
||
you to install the gem <code>pry-doc</code> (<code>gem install pry-doc</code>). Do note that this
|
||
only works for core C code, currently Pry does not support this for third party
|
||
extensions.</p>
|
||
|
||
<p>Another very cool feature is that Pry can be used as a debugging tool for your
|
||
code without having to manually jump into a session. By loading Pry, which can
|
||
be done by writing <code>require "pry"</code> or by using the option <code>-r pry</code> when
|
||
invoking Ruby you gain access to everything Pry has to offer. The most useful
|
||
tool is <code>binding.pry</code>. This method starts a Pry session and pauses the
|
||
script.</p>
|
||
|
||
<p>Lets say you have the following script and want to see the values of the
|
||
variables:</p>
|
||
|
||
<div class="CodeRay"><div class="code"><pre><code class="language-ruby">language = <span class="string"><span class="delimiter">'</span><span class="content">Ruby</span><span class="delimiter">'</span></span>
|
||
number = <span class="integer">10</span>
|
||
|
||
<span class="comment"># Do something awesome with the above variables.</span></code></pre></div></div>
|
||
|
||
<p>The typical approach would be to insert a puts statement above the comment
|
||
followed by an exit statement. Pry in a way can do a similar thing, it just
|
||
makes it a lot more awesome. If you modify the script as following you can
|
||
truly debug your code like a boss:</p>
|
||
|
||
<div class="CodeRay"><div class="code"><pre><code class="language-ruby">language = <span class="string"><span class="delimiter">'</span><span class="content">Ruby</span><span class="delimiter">'</span></span>
|
||
number = <span class="integer">10</span>
|
||
|
||
binding.pry
|
||
|
||
<span class="comment"># Do something awesome with the above variables.</span></code></pre></div></div>
|
||
|
||
<p>If you now run the script by calling <code>ruby -r pry file.rb</code> you get a fancy
|
||
Pry session:</p>
|
||
|
||
<div class="CodeRay"><div class="code"><pre><code class="language-text">[yorickpeterse@Wifi-Ninja in ~]$ ruby -r pry file.rb
|
||
|
||
From: file.rb @ line 4 in Object#N/A:
|
||
|
||
1: language = 'Ruby'
|
||
2: number = 10
|
||
3:
|
||
=> 4: binding.pry
|
||
5:
|
||
6: # Do something awesome with the above variables.
|
||
[1] pry(main)></code></pre></div></div>
|
||
|
||
<p>A nice thing about starting Pry this way is that it starts in the context of
|
||
the call to <code>binding.pry</code> meaning you get access to data such as the local
|
||
variables. These can be displayed by calling <code>ls</code> or by simply typing their
|
||
name.</p>
|
||
|
||
<div class="CodeRay"><div class="code"><pre><code class="language-text">[yorickpeterse@Wifi-Ninja in ~]$ ruby -r pry file.rb
|
||
|
||
From: file.rb @ line 4 in Object#N/A:
|
||
|
||
1: language = 'Ruby'
|
||
2: number = 10
|
||
3:
|
||
=> 4: binding.pry
|
||
5:
|
||
6: # Do something awesome with the above variables.
|
||
[1] pry(main)> ls
|
||
self methods: include private public to_s
|
||
locals: _ _dir_ _ex_ _file_ _in_ _out_ _pry_ language number
|
||
[2] pry(main)> number
|
||
=> 10
|
||
[3] pry(main)></code></pre></div></div>
|
||
|
||
<p>Moving out of the “breakpoint” (or moving to the next one if you have multiple
|
||
ones defined) can be done by hitting ^D (Ctrl+D usually).</p>
|
||
|
||
<p>Besides the features mentioned in this article Pry has several more. For
|
||
example, long output is piped to Less. This can be quite useful if you’re
|
||
trying to display a big hash using <code>pp</code>. The full list of features can be
|
||
found on the <a href="http://pry.github.com/">Pry website</a> as well as by invoking the <code>help</code>
|
||
command inside a Pry session. If you’re in need of help or have any suggestions
|
||
you can join the IRC channel #pry on the Freenode network (irc.freenode.net).
|
||
The source code of Pry is hosted on <a href="http://github.com/pry/pry">Github</a>.</p>
|
||
|
||
|
||
</section>
|
||
</div>
|
||
</body>
|
||
</html>
|