“Cargo Culting in ruby”

July 4, 2008

“Cargo culting”, when used in a computer-programming context, refers
to the practice of using techniques (or even entire blocks of code)
seen elsewhere without wholly understanding how they work. (The term
“cargo cult”, if you are unfamiliar with it, has its own fascinating
etymology, which is covered nicely at wikipedia.)
Cargo culting is a dangerous phenomenon, watering down the state of the
art and encouraging cookie-cutter code shoved blindly into black boxes.

Consider
the following snippet of code, taken from a project that was submitted
to us some time ago. (Alas, I cannot find the original submitter—I
apologize for that!)

1<tt><br /></tt>2<tt><br /></tt>3<tt>
</tt></pre></td>
  <td class="code"><pre><span class="r">def</span> <span class="fu">account_code?</span><tt><br /></tt>  !! <span class="iv">@account_code</span>.nil?<tt><br /></tt><span class="r">end</span><tt>
</tt></pre></td>
</tr></tbody></table>

	<p>To me, this looks cargo-culted, since it
is seems that the programmer did not understand what the ”!!” idiom was
all about. They probably saw it used somewhere and “cargo culted” it,
using it without knowledge, assuming that it was, for some reason,
“necessary”.</p>

	<p>Now, the way ”!!” works is this: take the value behind the ”!!”, negate it, and negate it again. It’s just double-negation: <code>!(!(@account_code.nil?))</code>.
The ultimate effect is to take some value, and convert it into an
honest-to-goodness “true” or “false”. (In my ever-so-humble opinion,
the ”!!” idiom is an abomination: it’s far too clever for its own good.
First of all, you rarely ever need a real boolean value, and for those
times you do, it is better to be explicit in the conversion, by using a
ternary operator or full-blown <code>if</code> statement, for instance.)</p>

	<p>In other words, the double-negation of <code>nil?</code> results in absolutely no difference from the use of <code>nil?</code> by itself, since <code>nil?</code> will return a true/false value. This, in turn, means the effect in the original is actually not what was intended for the <code>account_code?</code>
predicate. It should have returned “true” if the account code existed
(was “non-nil”), not “false”. Thus, the method should have actually
been written thus:</p>

<table class="CodeRay"><tbody><tr>
  <td title="click to toggle" class="line_numbers"><pre>1<tt><br /></tt>2<tt><br /></tt>3<tt>
</tt></pre></td>
  <td class="code"><pre><span class="r">def</span> <span class="fu">account_code?</span><tt><br /></tt>  ! <span class="iv">@account_code</span>.nil?<tt><br /></tt><span class="r">end</span><tt>
</tt></pre></td>
</tr></tbody></table>

	<p>In this case, cargo-culting resulted in
the code being buggy. This is not an uncommon outcome of using
techniques or code without understanding their purpose. If you ever
find yourself copying something into your own code, with a justfying
“I-don’t-know-what-it-does, but-it-appears-to-work”, <em>stop immediately</em>. Do some research. Figure it out. Learn what it means.</p>

	<p>Further, note that unless you actually <em>need</em> a true boolean value from that, you can shorten the implementation of the <code>account_code?</code> predicate even further:</p>

<table class="CodeRay"><tbody><tr>
  <td title="click to toggle" class="line_numbers"><pre>1<tt><br /></tt>2<tt><br /></tt>3<tt>
</tt></pre></td>
  <td class="code"><pre><span class="r">def</span> <span class="fu">account_code?</span><tt><br /></tt>  <span class="iv">@account_code</span><tt><br /></tt><span class="r">end</span><tt>
</tt>

This works because Ruby treats nil and false as false, and everything else as true.

If there is one thing that Koz and I want you, our readers, to come away from this site with, it is an understanding of why
you should do things one way and not another. Ultimately, it makes the
difference between being a mediocre programmer, and becoming a great
programmer.

Entry Filed under: Cargo Culting in ruby, rails, ruby on rails. Tags: , , .

Leave a Comment

Required

Required, hidden

Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Trackback this post  |  Subscribe to the comments via RSS Feed


Recent Posts

Archives

Category Cloud

Active Record active scaffold ajax calendar date select capistrano deployment edge rails formula 1 2008 For those who dont want to update the prototype.js Framesets vs iFrames fun html javascript mysql plugin rails regexp ror Ruby ruby on rails ruy on rails SQL string functions Text Area they can checkout 1.8.3 of the calender date select titleize titleize vs capitalize tutorial Uncategorized validations

Tags

Links

Meta

Pages

Calendar

July 2008
M T W T F S S
« Jun   Aug »
 123456
78910111213
14151617181920
21222324252627
28293031