tag:www.rhnh.net,2008:/hirb
Hirb - Xavier Shay's Blog
2009-12-29T00:24:28Z
Enki
Xavier Shay
notreal@rhnh.net
tag:www.rhnh.net,2008:Post/811
2009-12-29T00:27:00Z
2009-12-29T00:24:28Z
Ruby debugging with puts, tap and Hirb
<p>I use <code>puts</code> heaps when debugging. Combined with <code>tap</code>, it’s pretty handy. You can jump right in the middle of a method chain without having to move things around into variables.</p><table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">x = long.chain.of.methods.tap {|x| puts x }.to.do.something.with<tt>
</tt></pre></td>
</tr></table>
<p>I thought hey why don’t I merge the two? And for bonus points, add in Hirb’s table display to format my models nicely. These are fairly personal customizations, and aren’t specific to a project, so I put them in my own <code>~/.railsrc</code> file rather than each project.</p><table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt>5<tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt><strong>10</strong><tt>
</tt>11<tt>
</tt>12<tt>
</tt>13<tt>
</tt>14<tt>
</tt>15<tt>
</tt>16<tt>
</tt>17<tt>
</tt>18<tt>
</tt>19<tt>
</tt><strong>20</strong><tt>
</tt>21<tt>
</tt>22<tt>
</tt>23<tt>
</tt>24<tt>
</tt>25<tt>
</tt>26<tt>
</tt>27<tt>
</tt>28<tt>
</tt>29<tt>
</tt><strong>30</strong><tt>
</tt>31<tt>
</tt>32<tt>
</tt>33<tt>
</tt>34<tt>
</tt>35<tt>
</tt>36<tt>
</tt>37<tt>
</tt>38<tt>
</tt>39<tt>
</tt><strong>40</strong><tt>
</tt>41<tt>
</tt>42<tt>
</tt>43<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><span class="c"># config/initializers/developer_specific_customizations.rb</span><tt>
</tt><span class="r">if</span> <span class="s"><span class="dl">%w(</span><span class="k">development test</span><span class="dl">)</span></span>.include?(<span class="co">Rails</span>.env)<tt>
</tt> railsrc = <span class="s"><span class="dl">"</span><span class="il"><span class="idl">#{</span><span class="co">ENV</span>[<span class="s"><span class="dl">'</span><span class="k">HOME</span><span class="dl">'</span></span>]<span class="idl">}</span></span><span class="k">/.railsrc</span><span class="dl">"</span></span><tt>
</tt> load(railsrc) <span class="r">if</span> <span class="co">File</span>.exist?(railsrc)<tt>
</tt><span class="r">end</span><tt>
</tt><tt>
</tt><span class="c"># ~/.railsrc</span><tt>
</tt>require <span class="s"><span class="dl">'</span><span class="k">hirb</span><span class="dl">'</span></span><tt>
</tt><tt>
</tt><span class="co">Hirb</span>.enable <span class="sy">:pager</span> => <span class="pc">false</span><tt>
</tt><tt>
</tt><span class="r">class</span> <span class="cl">Object</span><tt>
</tt> <span class="r">def</span> <span class="fu">tapp</span>(prefix = <span class="pc">nil</span>, &block)<tt>
</tt> block ||= lambda {|x| x }<tt>
</tt><tt>
</tt> tap <span class="r">do</span> |x|<tt>
</tt> value = block[x]<tt>
</tt> value = <span class="co">Hirb</span>::<span class="co">View</span>.formatter.format_output(value) || value.inspect<tt>
</tt><tt>
</tt> <span class="r">if</span> prefix<tt>
</tt> print prefix<tt>
</tt> <span class="r">if</span> value.lines.count > <span class="i">1</span><tt>
</tt> print <span class="s"><span class="dl">"</span><span class="k">:</span><span class="ch">\n</span><span class="dl">"</span></span><tt>
</tt> <span class="r">else</span><tt>
</tt> print <span class="s"><span class="dl">"</span><span class="k">: </span><span class="dl">"</span></span><tt>
</tt> <span class="r">end</span><tt>
</tt> <span class="r">end</span><tt>
</tt> puts value<tt>
</tt> <span class="r">end</span><tt>
</tt> <span class="r">end</span><tt>
</tt><span class="r">end</span><tt>
</tt><tt>
</tt><span class="c"># Usage (in your spec files, perhaps?)</span><tt>
</tt><span class="s"><span class="dl">"</span><span class="k">hello</span><span class="dl">"</span></span>.tapp <span class="c"># => hello</span><tt>
</tt><span class="s"><span class="dl">"</span><span class="k">hello</span><span class="dl">"</span></span>.tapp(<span class="s"><span class="dl">'</span><span class="k">a</span><span class="dl">'</span></span>) <span class="c"># => a - "hello</span><tt>
</tt><span class="s"><span class="dl">"</span><span class="k">hello</span><span class="dl">"</span></span>.tapp(&<span class="sy">:length</span>) <span class="c"># => 5</span><tt>
</tt><span class="co">MyModel</span>.first.tapp <span class="c"># =></span><tt>
</tt><span class="c"># +----+-------------------------+</span><tt>
</tt><span class="c"># | id | created_at |</span><tt>
</tt><span class="c"># +----+-------------------------+</span><tt>
</tt><span class="c"># | 7 | 2009-12-29 00:15:56 UTC |</span><tt>
</tt><span class="c"># +----+-------------------------+</span><tt>
</tt><span class="c"># 1 row in set</span><tt>
</tt></pre></td>
</tr></table>