× {{alert.msg}} Never ask again
Get notified about new tutorials RECEIVE NEW TUTORIALS
Thomas Broomfield
Jan 23, 2016
<h1>Ruby's Tap.</h1> <p>As software projects grow, being able to demonstrate your intention to other developers through clear and reasonable code is paramount. In this series I cover short tips to do just that.</p> <p>Today we cover the under appreciated #tap method:</p> <p>Library: <a href="http://ruby-doc.org/core-2.3.0/">Ruby Core</a>. Class: <a href="http://ruby-doc.org/core-2.3.0/Object.html#method-i-tap">Object</a>. Version: ruby &gt; 1.9</p> <p> </p> <h3>What does it do?</h3> <p>Ruby describes <code>#tap</code>’s behavior as “Yields self to the block, and then returns self”. Put simply, it lets you act on an object while ensuring the object is also returned.</p> <p>Example:</p> <pre><code class="language-ruby">1 <span style="color:rgb(147, 161, 161)">car</span> <span style="color:rgb(133, 153, 0)">=</span> <span style="color:rgb(203, 75, 22)">Car</span><span style="color:rgb(133, 153, 0)">.</span><span style="color:rgb(147, 161, 161)">create</span><span style="color:rgb(133, 153, 0)">.</span><span style="color:rgb(147, 161, 161)">tap</span> <span style="color:rgb(133, 153, 0)">do</span> <span style="color:rgb(133, 153, 0)">|</span><span style="color:rgb(147, 161, 161)">c</span><span style="color:rgb(133, 153, 0)">|</span> 2 <span style="color:rgb(147, 161, 161)">c</span><span style="color:rgb(133, 153, 0)">.</span><span style="color:rgb(147, 161, 161)">wheels</span> <span style="color:rgb(133, 153, 0)">=</span> <span style="color:rgb(42, 161, 152)">4</span> 3 <span style="color:rgb(147, 161, 161)">c</span><span style="color:rgb(133, 153, 0)">.</span><span style="color:rgb(147, 161, 161)">move_to_showroom!</span> 4 <span style="color:rgb(133, 153, 0)">end</span> 5 <span style="color:rgb(147, 161, 161)">car</span><span style="color:rgb(133, 153, 0)">.</span><span style="color:rgb(147, 161, 161)">wheels</span> <span style="color:rgb(88, 110, 117)">#=&gt; 4</span></code></pre> <h3>Why use it?</h3> <p>On the surface this looks useless. In almost all cases, you could just as easily do the following:</p> <pre><code class="language-ruby">1 <span style="color:rgb(133, 153, 0)">def</span> <span style="color:rgb(38, 139, 210)">make_car</span> 2 <span style="color:rgb(147, 161, 161)">car</span> <span style="color:rgb(133, 153, 0)">=</span> <span style="color:rgb(203, 75, 22)">Car</span><span style="color:rgb(133, 153, 0)">.</span><span style="color:rgb(147, 161, 161)">create</span> 3 <span style="color:rgb(147, 161, 161)">car</span><span style="color:rgb(133, 153, 0)">.</span><span style="color:rgb(147, 161, 161)">wheels</span> <span style="color:rgb(133, 153, 0)">=</span> <span style="color:rgb(42, 161, 152)">4</span> 4 <span style="color:rgb(147, 161, 161)">car</span><span style="color:rgb(133, 153, 0)">.</span><span style="color:rgb(147, 161, 161)">move_to_showroom!</span> 5 <span style="color:rgb(133, 153, 0)">end</span></code></pre> <p>Why should we ever use <code>#tap</code> then?</p> <blockquote> <p>Tap <strong>should</strong> be used to make the return value of a method explicitly clear.</p> </blockquote> <p>For example, with the above <code>#make_car</code> method, imagine if the <code>#move_to_showroom!</code> method returned an instance of the car. This would mean the <code>#make_car</code> method also returns the newly created car. This is far from explicit in the code, a team member could quite easily add more lines to the <code>#make_car</code> method, changing the return value and breaking various parts of your application that have come to rely on <code>#make_car</code>.</p> <p>This can be avoided, changing the method to <code>#tap</code> as below shouts <strong>This method absolutely needs to return an instance of Car</strong> from the proverbial rooftops.</p> <pre><code class="language-ruby">1 <span style="color:rgb(133, 153, 0)">def</span> <span style="color:rgb(38, 139, 210)">make_car</span> 2 <span style="color:rgb(203, 75, 22)">Car</span><span style="color:rgb(133, 153, 0)">.</span><span style="color:rgb(147, 161, 161)">create</span><span style="color:rgb(133, 153, 0)">.</span><span style="color:rgb(147, 161, 161)">tap</span> <span style="color:rgb(133, 153, 0)">do</span> <span style="color:rgb(133, 153, 0)">|</span><span style="color:rgb(147, 161, 161)">c</span><span style="color:rgb(133, 153, 0)">|</span> 3 <span style="color:rgb(147, 161, 161)">c</span><span style="color:rgb(133, 153, 0)">.</span><span style="color:rgb(147, 161, 161)">wheels</span> <span style="color:rgb(133, 153, 0)">=</span> <span style="color:rgb(42, 161, 152)">4</span> 4 <span style="color:rgb(147, 161, 161)">c</span><span style="color:rgb(133, 153, 0)">.</span><span style="color:rgb(147, 161, 161)">move_to_showroom!</span> 5 <span style="color:rgb(88, 110, 117)"># In future, more lines can be added here without accidentally altering the return value of the method.</span> 6 <span style="color:rgb(133, 153, 0)">end</span> 7 <span style="color:rgb(133, 153, 0)">end</span></code></pre> <p>Protecting your methods from accidental future sabotage can take many forms, but <code>#tap</code>can be a handy tool for your kit.</p>

Get New Tutorials Delivered to Your Inbox

New tutorials will be sent to your Inbox once a week.

comments powered by Disqus