<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Code on MoskitoHero</title><link>/tags/code/</link><description>Recent content in Code on MoskitoHero</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Fri, 12 Jan 2024 00:00:00 +0000</lastBuildDate><atom:link href="/tags/code/index.xml" rel="self" type="application/rss+xml"/><item><title>Ruby Best Practices - Method Arguments</title><link>/post/2024-01-12-ruby-best-practices-method-arguments/</link><pubDate>Fri, 12 Jan 2024 00:00:00 +0000</pubDate><guid>/post/2024-01-12-ruby-best-practices-method-arguments/</guid><description>Simple rules for ordering Ruby method arguments — put optional arguments last, and switch to keyword arguments when you have more than one optional parameter.</description><content:encoded><![CDATA[<div class="paragraph">
<p>To write readable and maintainable code, follow a few simple rules about argument ordering.</p>
</div>
<div class="sect1">
<h2 id="tip-1-optional-arguments-go-last"><a class="anchor" href="#tip-1-optional-arguments-go-last"></a>Tip 1: Optional arguments go last</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When a method takes several arguments, and some of them have default values, make sure to put the optional ones at the end.
Take this method definition:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="ruby"><span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="s2">&#34;val_b&#34;</span><span class="p">,</span> <span class="n">c</span><span class="p">)</span>
  <span class="c1"># some code...</span>
<span class="k">end</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Looks fine at first glance. But in practice, it’s impossible to call this method with values for a and c without also specifying b. You end up writing:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="ruby"><span class="n">foo</span><span class="p">(</span><span class="s2">&#34;val_a&#34;</span><span class="p">,</span> <span class="s2">&#34;val_b&#34;</span><span class="p">,</span> <span class="s2">&#34;val_c&#34;</span><span class="p">)</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>…​which defeats the purpose of setting a default for b if you’re forced to specify it every time. ¯<em>(ツ)</em>/¯</p>
</div>
<div class="sect2">
<h3 id="solution-move-optional-arguments-to-the-end"><a class="anchor" href="#solution-move-optional-arguments-to-the-end"></a>Solution: move optional arguments to the end</h3>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="ruby"><span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="s2">&#34;val_b&#34;</span><span class="p">)</span>
  <span class="c1"># some code...</span>
<span class="k">end</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Now you can call:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="ruby"><span class="n">foo</span><span class="p">(</span><span class="s2">&#34;val_a&#34;</span><span class="p">,</span> <span class="s2">&#34;val_c&#34;</span><span class="p">)</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>No problem 😎.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="tip-2-use-keyword-arguments-aka-kwargs"><a class="anchor" href="#tip-2-use-keyword-arguments-aka-kwargs"></a>Tip 2: Use keyword arguments (aka kwargs)</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Tip 1 only gets you so far. What if you have multiple optional arguments and want to override just the last one? You’d still need to specify all the previous ones.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="ruby"><span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span> <span class="o">=</span> <span class="s2">&#34;val_c&#34;</span><span class="p">,</span> <span class="n">d</span> <span class="o">=</span> <span class="s2">&#34;val_d&#34;</span><span class="p">,</span> <span class="n">e</span> <span class="o">=</span> <span class="s2">&#34;val_e&#34;</span><span class="p">)</span>
  <span class="c1"># some code...</span>
<span class="k">end</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Want to change only e? Too bad — you still have to write:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="ruby"><span class="n">foo</span><span class="p">(</span><span class="s2">&#34;val_a&#34;</span><span class="p">,</span> <span class="s2">&#34;val_b&#34;</span><span class="p">,</span> <span class="s2">&#34;val_c&#34;</span><span class="p">,</span> <span class="s2">&#34;val_d&#34;</span><span class="p">,</span> <span class="s2">&#34;my_val_e&#34;</span><span class="p">)</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Now imagine this in a large codebase:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="ruby"><span class="n">foo</span><span class="p">(</span><span class="n">user</span><span class="p">.</span><span class="nf">id</span><span class="p">,</span> <span class="s2">&#34;DONE&#34;</span><span class="p">,</span> <span class="kp">true</span><span class="p">,</span> <span class="kp">false</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="s2">&#34;always&#34;</span><span class="p">,</span> <span class="kp">true</span><span class="p">,</span> <span class="n">post</span><span class="p">.</span><span class="nf">id</span><span class="p">)</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>And you’re left thinking: <em>&#34;Wait, what’s that <strong>false</strong> again? What does the <strong>1</strong> do? Why <strong>&#39;always&#39;</strong>?&#34;</em>
Not ideal, especially under pressure in a production bug fix.</p>
</div>
<div class="sect2">
<h3 id="solution-switch-to-keyword-arguments-when-you-hit-2-optional-params"><a class="anchor" href="#solution-switch-to-keyword-arguments-when-you-hit-2-optional-params"></a>Solution: switch to keyword arguments when you hit 2+ optional params</h3>
<div class="paragraph">
<p>Benefits:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Argument order doesn’t matter anymore</p>
</li>
<li>
<p>You can ignore defaults entirely</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The method now becomes:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="ruby"><span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="ss">c: </span><span class="s2">&#34;val_c&#34;</span><span class="p">,</span> <span class="ss">d: </span><span class="s2">&#34;val_d&#34;</span><span class="p">,</span> <span class="ss">e: </span><span class="s2">&#34;val_e&#34;</span><span class="p">)</span>
  <span class="c1"># some code...</span>
<span class="k">end</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>To change only e, you write:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="ruby"><span class="n">foo</span><span class="p">(</span><span class="s2">&#34;val_a&#34;</span><span class="p">,</span> <span class="s2">&#34;val_b&#34;</span><span class="p">,</span> <span class="ss">e: </span><span class="s2">&#34;my_val_e&#34;</span><span class="p">)</span></code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="ninja-level-tip-the-clean-coders-take"><a class="anchor" href="#ninja-level-tip-the-clean-coders-take"></a>Ninja-level tip — the clean coder’s take:</h2>
<div class="sectionbody">
<div class="paragraph">
<p><strong>If your method takes more than 1 argument, make everything after the first a keyword argument. Always.</strong></p>
</div>
<div class="sect2">
<h3 id="example"><a class="anchor" href="#example"></a>Example:</h3>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="ruby"><span class="k">def</span> <span class="nf">send_message_to</span><span class="p">(</span><span class="n">recipient</span><span class="p">,</span> <span class="ss">confirm: </span><span class="kp">true</span><span class="p">,</span> <span class="ss">bcc: </span><span class="s2">&#34;joe@bill.com&#34;</span><span class="p">,</span> <span class="ss">cc: </span><span class="s2">&#34;jane@doe.com&#34;</span><span class="p">)</span>
  <span class="c1"># ruby code</span>
<span class="k">end</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Here, the first argument is obvious thanks to the method name: you’re sending a message <em>to</em> someone.
Called without options:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="ruby"><span class="n">send_message_to</span><span class="p">(</span><span class="s2">&#34;sam@sam.com&#34;</span><span class="p">)</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Clear and concise.
Compare a non-keyword version:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="ruby"><span class="n">send_message</span><span class="p">(</span><span class="s2">&#34;recipient@mail.com&#34;</span><span class="p">,</span> <span class="kp">false</span><span class="p">,</span> <span class="s2">&#34;joe@bill.com&#34;</span><span class="p">,</span> <span class="s2">&#34;paul@smith.com&#34;</span><span class="p">)</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>…​with the keyword version:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="ruby"><span class="n">send_message_to</span><span class="p">(</span><span class="s2">&#34;sam@sam.com&#34;</span><span class="p">,</span> <span class="ss">bcc: </span><span class="s2">&#34;paul@smith.com&#34;</span><span class="p">,</span> <span class="ss">confirm: </span><span class="kp">false</span><span class="p">)</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>If you adopt these habits, <a href="&lt;em&gt;GHOST_URL&lt;/em&gt;/writing-code-for-your-future-self">future you</a> will thank you when you revisit the code to debug or tack on yet another parameter.</p>
</div>
</div>
</div>
</div>
]]></content:encoded></item></channel></rss>