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>
|