Gray Soft / Ruby Voodootag:graysoftinc.com,2014-03-20:/categories/172015-05-23T05:18:20ZJames Edward Gray IIRich Methodstag:graysoftinc.com,2015-05-23:/posts/1402015-05-23T05:18:20ZA quick look into the half hidden extras of some common Ruby methods.<p>Some APIs provide collections of dirt simple methods that just do one little thing.</p>
<p>This approach in less common in Ruby though, especially in the core and standard library of the language itself. Ruby often gives us rich methods with lots of switches we can toggle and half hidden behaviors.</p>
<p>Let's look at some examples of what I am talking about.</p>
<h4>Get a <em>Line</em> at a Time</h4>
<p>I suspect most Rubyists have used <code>gets()</code> to read lines of input from some kind of <code>IO</code>. Here's the basic usage:</p>
<div class="highlight highlight-ruby"><pre><span class="o">>></span> <span class="nb">require</span> <span class="s2">"stringio"</span>
<span class="o">=></span> <span class="kp">true</span>
<span class="o">>></span> <span class="n">f</span> <span class="o">=</span> <span class="no">StringIO</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="o"><<</span><span class="no">END_STR</span><span class="p">)</span>
<span class="sh"><xml></span>
<span class="sh"> <tags>Content</tags></span>
<span class="sh"></xml></span>
<span class="no">END_STR</span>
<span class="o">=></span> <span class="c1">#<StringIO:0x007fd5a264fa08></span>
<span class="o">>></span> <span class="n">f</span><span class="o">.</span><span class="n">gets</span>
<span class="o">=></span> <span class="s2">"<xml></span><span class="se">\n</span><span class="s2">"</span>
<span class="o">>></span> <span class="n">f</span><span class="o">.</span><span class="n">gets</span>
<span class="o">=></span> <span class="s2">" <tags>Content</tags></span><span class="se">\n</span><span class="s2">"</span>
</pre></div>
<p>I didn't want to mess with external files for these trivial examples, so I just loaded <code>StringIO</code> from the standard library. It allows us to wrap a simple <code>String</code> (defined in this example using <a href="http://graysoftinc.com/ruby-voodoo/working-with-multiline-strings">the <em>heredoc</em> syntax</a>) in the <code>IO</code> interface. In other words, I'm calling <code>gets()</code> here for a <code>String</code> just as I could with a <code>File</code> or <code>$stdin</code>.</p>
<p>As the last two calls show, <code>gets()</code> reads until it finds a <code>"\n"</code> and then returns the content read. Actually, that's what it does by default, but you can tell <code>gets()</code> what character to read to, if you prefer:</p>
<div class="highlight highlight-ruby"><pre><span class="o">>></span> <span class="n">f</span><span class="o">.</span><span class="n">rewind</span>
<span class="o">=></span> <span class="mi">0</span>
<span class="o">>></span> <span class="n">f</span><span class="o">.</span><span class="n">gets</span><span class="p">(</span><span class="s2">">"</span><span class="p">)</span>
<span class="o">=></span> <span class="s2">"<xml>"</span>
<span class="o">>></span> <span class="n">f</span><span class="o">.</span><span class="n">gets</span><span class="p">(</span><span class="s2">">"</span><span class="p">)</span>
<span class="o">=></span> <span class="s2">"</span><span class="se">\n</span><span class="s2"> <tags>"</span>
<span class="o">>></span> <span class="n">f</span><span class="o">.</span><span class="n">gets</span><span class="p">(</span><span class="s2">">"</span><span class="p">)</span>
<span class="o">=></span> <span class="s2">"Content</tags>"</span>
</pre></div>
<p>When you're working with XML documents, newlines don't really mean much. You don't actually care where they are. What you do care about are tags. Reading from tag to tag is like reading one of those great books that skip the boring bits to give you interesting scene after interesting scene.</p>
<p>As you can see above, one tiny change to the <code>gets()</code> call, specifying the character to read to as the tag ending <code>">"</code>, can make this happen.</p>
<p>"But wait, there's more!"</p>
<div class="highlight highlight-ruby"><pre><span class="o">>></span> <span class="n">f</span> <span class="o">=</span> <span class="no">StringIO</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">"One</span><span class="se">\n\n</span><span class="s2">Two</span><span class="se">\n\n</span><span class="s2">Three"</span><span class="p">)</span>
<span class="o">=></span> <span class="c1">#<StringIO:0x007fd5a260efa8></span>
<span class="o">>></span> <span class="n">f</span><span class="o">.</span><span class="n">gets</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
<span class="o">=></span> <span class="s2">"One</span><span class="se">\n\n</span><span class="s2">"</span>
<span class="o">>></span> <span class="n">f</span><span class="o">.</span><span class="n">gets</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
<span class="o">=></span> <span class="s2">"Two</span><span class="se">\n\n</span><span class="s2">"</span>
</pre></div>
<p>The empty <code>String</code> (<code>""</code>) is a magic value for the character to read to, since it makes no sense as that value. This turns on <em>paragraph mode</em> and in that mode Ruby will read one paragraph at a time. For this purpose a paragraphs are defined as being separated by two consecutive newlines (or a blank line in word processor terms).</p>
<p>These aren't even all the features of <code>gets()</code>. It can do more. For example, you can provide an upper limit of bytes to read, to prevent wonky input from forcing your program to allocate the tons of memory to hold large Ruby <code>String</code> objects.</p>
<p>Let's look at another method.</p>
<h4>
<code>Hash</code> Merging</h4>
<p>Many Ruby methods sneak their rich functionality in through the use of blocks. Deferring some decision to the caller by allowing them to provide custom code for handling it makes some methods crazy flexible.</p>
<p>To show what I mean, let's play with good old <code>merge()</code>:</p>
<div class="highlight highlight-ruby"><pre><span class="o">>></span> <span class="p">{</span><span class="ss">a</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="ss">b</span><span class="p">:</span> <span class="mi">2</span><span class="p">}</span><span class="o">.</span><span class="n">merge</span><span class="p">(</span><span class="ss">c</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="ss">d</span><span class="p">:</span> <span class="mi">4</span><span class="p">)</span>
<span class="o">=></span> <span class="p">{</span><span class="ss">:a</span><span class="o">=></span><span class="mi">1</span><span class="p">,</span> <span class="ss">:b</span><span class="o">=></span><span class="mi">2</span><span class="p">,</span> <span class="ss">:c</span><span class="o">=></span><span class="mi">3</span><span class="p">,</span> <span class="ss">:d</span><span class="o">=></span><span class="mi">4</span><span class="p">}</span>
</pre></div>
<p>Most Rubyists run into examples like this pretty early in their studies. The code just returns a fresh <code>Hash</code> containing the keys and values of both the receiver and the <code>Hash</code> passed as an argument to <code>merge()</code>.</p>
<p>How are ties handled?</p>
<div class="highlight highlight-ruby"><pre><span class="o">>></span> <span class="p">{</span><span class="ss">a</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="ss">b</span><span class="p">:</span> <span class="mi">2</span><span class="p">}</span><span class="o">.</span><span class="n">merge</span><span class="p">(</span><span class="ss">b</span><span class="p">:</span> <span class="ss">:two</span><span class="p">,</span> <span class="ss">c</span><span class="p">:</span> <span class="mi">3</span><span class="p">)</span>
<span class="o">=></span> <span class="p">{</span><span class="ss">:a</span><span class="o">=></span><span class="mi">1</span><span class="p">,</span> <span class="ss">:b</span><span class="o">=></span><span class="ss">:two</span><span class="p">,</span> <span class="ss">:c</span><span class="o">=></span><span class="mi">3</span><span class="p">}</span>
</pre></div>
<p>The <code>Hash</code> passed as an argument to <code>merge()</code> wins. Again, I doubt this is much of a surprise to anyone.</p>
<p>However, I don't think everyone knows that you can take control of this merging process. During a <code>merge()</code> any conflict will be passed to a block, if provided, and the block can return what to store in the new <code>Hash</code>:</p>
<div class="highlight highlight-ruby"><pre><span class="o">>></span> <span class="p">{</span><span class="ss">a</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="ss">b</span><span class="p">:</span> <span class="mi">2</span><span class="p">}</span><span class="o">.</span><span class="n">merge</span><span class="p">(</span><span class="ss">b</span><span class="p">:</span> <span class="ss">:two</span><span class="p">,</span> <span class="ss">c</span><span class="p">:</span> <span class="mi">3</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">_</span><span class="p">,</span> <span class="n">old</span><span class="p">,</span> <span class="kp">new</span><span class="o">|</span> <span class="nb">Array</span><span class="p">(</span><span class="n">old</span><span class="p">)</span> <span class="o">+</span> <span class="nb">Array</span><span class="p">(</span><span class="kp">new</span><span class="p">)</span> <span class="p">}</span>
<span class="o">=></span> <span class="p">{</span><span class="ss">:a</span><span class="o">=></span><span class="mi">1</span><span class="p">,</span> <span class="ss">:b</span><span class="o">=>[</span><span class="mi">2</span><span class="p">,</span> <span class="ss">:two</span><span class="o">]</span><span class="p">,</span> <span class="ss">:c</span><span class="o">=></span><span class="mi">3</span><span class="p">}</span>
</pre></div>
<p>You can throw away either item, log the conflict, combine them as I have done here, or do whatever else you can think of, all because <code>merge()</code> takes a block.</p>
<p>Can you guess <a href="https://github.com/rails/rails/blob/42e66fac38b54dd53d062fb5d3376218ed2ffdae/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb#L17-L20">how <code>ActiveSupport</code> implements <code>reverse_merge!()</code></a> now?</p>
<h4>Easy Tokenizing</h4>
<p>Let's do one last method with a rich interface (even though Ruby has many more):</p>
<div class="highlight highlight-ruby"><pre><span class="o">>></span> <span class="s2">"1,2,3"</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">","</span><span class="p">)</span>
<span class="o">=></span> <span class="o">[</span><span class="s2">"1"</span><span class="p">,</span> <span class="s2">"2"</span><span class="p">,</span> <span class="s2">"3"</span><span class="o">]</span>
</pre></div>
<p>This is another very common method. It turns a <code>String</code> into an <code>Array</code> by dividing up the contents everywhere the passed separator is encountered. I used a <code>String</code> separator above but a <code>Regexp</code> is also allowed:</p>
<div class="highlight highlight-ruby"><pre><span class="o">>></span> <span class="s2">"1, 2, 3"</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="sr">/\s*,\s*/</span><span class="p">)</span>
<span class="o">=></span> <span class="o">[</span><span class="s2">"1"</span><span class="p">,</span> <span class="s2">"2"</span><span class="p">,</span> <span class="s2">"3"</span><span class="o">]</span>
</pre></div>
<p>This makes it easier to handle complex separators. For example, the <code>Regexp</code> above permits optional whitespace characters on either side of the comma.</p>
<p>But a <code>Regexp</code> can include capture groups. How are they handled?</p>
<div class="highlight highlight-ruby"><pre><span class="o">>></span> <span class="s2">"1, 2, 3"</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="sr">/\s*(,)\s*/</span><span class="p">)</span>
<span class="o">=></span> <span class="o">[</span><span class="s2">"1"</span><span class="p">,</span> <span class="s2">","</span><span class="p">,</span> <span class="s2">"2"</span><span class="p">,</span> <span class="s2">","</span><span class="p">,</span> <span class="s2">"3"</span><span class="o">]</span>
</pre></div>
<p>Easy enough: the captured value(s) are returned with the separated contents.</p>
<p>The real question this raises for me is, "What the heck is this feature good for?" Well, one thing I have found over the years is that this usage of <code>split()</code> can make dividing some input into tokens pretty darn easy:</p>
<div class="highlight highlight-ruby"><pre><span class="o">>></span> <span class="s2">"<xml><tags>Content</tags></xml>"</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="sr">/(<[^>]+>)/</span><span class="p">)</span>
<span class="o">=></span> <span class="o">[</span><span class="s2">""</span><span class="p">,</span> <span class="s2">"<xml>"</span><span class="p">,</span> <span class="s2">""</span><span class="p">,</span> <span class="s2">"<tags>"</span><span class="p">,</span> <span class="s2">"Content"</span><span class="p">,</span> <span class="s2">"</tags>"</span><span class="p">,</span> <span class="s2">""</span><span class="p">,</span> <span class="s2">"</xml>"</span><span class="o">]</span>
</pre></div>
<p>You can use this one feature as a backbone for a moderately complex parser. <a href="https://github.com/soveran/mote/blob/b43b3879076dade130aac8c34b76cb06caf26e35/lib/mote.rb#L23-L26"><em>Mote</em> does</a> just that.</p>
<p>I made <a href="https://codalyzed.com/videos/lesscode">a video explaining how this parsing trick (and more) are accomplished</a> in detail. You can use the coupon <code>BLOGREADER</code> for $3 off if you want to check it out.</p>James Edward Gray IIThe Three Tick Sorttag:graysoftinc.com,2014-10-24:/posts/1332014-11-11T19:21:30ZYou can do some pretty fancy sorting in Ruby if you know what a Hash iterates over, how an Array compares to another Array, and how to manufacture blocks using a Symbol.<p>Yesterday I showed a newer programmer some code like <code>scores.sort_by(&:reverse)</code>. This provoked a comment about how they where going to look up <code>sort_by()</code> later to figure out what magic is involved here. It made me sad to realize how many cool tricks they weren't going to see in that bit of documentation.</p>
<p>Allow me to enumerate those tricks for you, but first let's flesh out an example. Consider this code:</p>
<div class="highlight highlight-ruby"><pre><span class="n">scores</span> <span class="o">=</span> <span class="p">{</span>
<span class="ss">fifteen</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
<span class="n">five_card_run</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span>
<span class="n">five_card_flush</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span>
<span class="n">four_card_run</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span>
<span class="n">four_card_flush</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span>
<span class="n">his_nobs</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
<span class="ss">pair</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
<span class="n">three_card_run</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span>
<span class="p">}</span>
<span class="n">scores</span><span class="o">.</span><span class="n">sort_by</span><span class="p">(</span><span class="o">&</span><span class="ss">:reverse</span><span class="p">)</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="nb">name</span><span class="p">,</span> <span class="n">score</span><span class="o">|</span>
<span class="nb">puts</span> <span class="s2">"Score </span><span class="si">#{</span><span class="n">score</span><span class="si">}</span><span class="s2"> for </span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="s2">."</span>
<span class="k">end</span>
<span class="c1"># >> Score 1 for his_nobs.</span>
<span class="c1"># >> Score 2 for fifteen.</span>
<span class="c1"># >> Score 2 for pair.</span>
<span class="c1"># >> Score 3 for three_card_run.</span>
<span class="c1"># >> Score 4 for four_card_flush.</span>
<span class="c1"># >> Score 4 for four_card_run.</span>
<span class="c1"># >> Score 5 for five_card_flush.</span>
<span class="c1"># >> Score 5 for five_card_run.</span>
</pre></div>
<p>In this case, the magic method call (<code>scores.sort_by(&:reverse)</code>) has reordered a list of Cribbage hands first by point value and then alphabetically ("ASCIIabetically" in truth). How this happens is a pretty interesting journey though.</p>
<p>Let's take it a piece at a time.</p>
<p>First you need to know that <code>Hash#each</code> iterates over <em>pairs</em>. (All other iterators, like <code>sort_by()</code>, use <code>each()</code> under the hood, remember.) A pair is a two element <code>Array</code> containing key then value. If your block takes one argument, you'll get this pair <code>Array</code>. If it takes more, Ruby will extract the values out of the <code>Array</code> due to its "multiple assignment" rules. In other words, you can do this:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">hash</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="o">|</span>
<span class="c1"># ...</span>
<span class="k">end</span>
</pre></div>
<p>or this:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">hash</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">pair</span><span class="o">|</span>
<span class="c1"># ...</span>
<span class="k">end</span>
</pre></div>
<p>This means I could have used <code>sort_by { |key, value| [value, key] }</code>, but I used the <code>Array</code> interface instead: <code>sort_by { |pair| pair.reverse }</code>.</p>
<p>That leads us to the second part of this magic trick: you can <code>sort_by()</code> an <code>Array</code>? Yes, you can.</p>
<p><code>sort_by()</code> works with any object that defines the spaceship operator (<code><=></code>), which <code>Array</code> does:</p>
<div class="highlight highlight-ruby"><pre><span class="o">>></span> <span class="o">[</span><span class="mi">0</span><span class="o">]</span> <span class="o"><=></span> <span class="o">[</span><span class="mi">0</span><span class="o">]</span>
<span class="o">=></span> <span class="mi">0</span>
<span class="o">>></span> <span class="o">[</span><span class="mi">1</span><span class="o">]</span> <span class="o"><=></span> <span class="o">[</span><span class="mi">2</span><span class="o">]</span>
<span class="o">=></span> <span class="o">-</span><span class="mi">1</span>
<span class="o">>></span> <span class="o">[</span><span class="mi">2</span><span class="o">]</span> <span class="o"><=></span> <span class="o">[</span><span class="mi">1</span><span class="o">]</span>
<span class="o">=></span> <span class="mi">1</span>
</pre></div>
<p>As you probably work out from the code above, <code>Array</code> objects compare themselves based on their contents. Later elements are used to break ties from earlier comparisons:</p>
<div class="highlight highlight-ruby"><pre><span class="o">>></span> <span class="o">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="o">]</span> <span class="o"><=></span> <span class="o">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="o">]</span>
<span class="o">=></span> <span class="o">-</span><span class="mi">1</span>
<span class="o">>></span> <span class="o">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="o">]</span> <span class="o"><=></span> <span class="o">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="o">]</span>
<span class="o">=></span> <span class="mi">1</span>
</pre></div>
<p>By calling <code>reverse()</code> on the pairs in the sorting <code>Array</code>, I put the score into the primary sorting role and used the hand name as a tie breaker.</p>
<p>That pretty much explains what the block I passed to the iterator did, so there's just one problem left: I didn't actually use a block!</p>
<p>When you have a block of the form <code>method { |object| object.thing_i_care_about }</code> you can rewrite it as <code>method(&:thing_i_care_about)</code>. Again we need to break this trick down into pieces to understand it.</p>
<p>First, <code>:thing_i_care_about</code> is a <code>Symbol</code>:</p>
<div class="highlight highlight-ruby"><pre><span class="o">>></span> <span class="ss">:thing_i_care_about</span>
<span class="o">=></span> <span class="ss">:thing_i_care_about</span>
<span class="o">>></span> <span class="ss">:thing_i_care_about</span><span class="o">.</span><span class="n">class</span>
<span class="o">=></span> <span class="no">Symbol</span>
</pre></div>
<p>Next, Ruby will try to convert the final argument to a method into a <code>Proc</code> object, if it's proceeded by a <code>&</code>:</p>
<div class="highlight highlight-ruby"><pre><span class="o">>></span> <span class="k">def</span> <span class="nf">m</span><span class="p">(</span><span class="o">&</span><span class="n">block</span><span class="p">)</span> <span class="n">block</span> <span class="k">end</span>
<span class="o">=></span> <span class="ss">:m</span>
<span class="o">>></span> <span class="n">m</span><span class="p">(</span><span class="o">&</span><span class="no">Object</span><span class="o">.</span><span class="n">new</span><span class="p">)</span>
<span class="ss">TypeError</span><span class="p">:</span> <span class="n">wrong</span> <span class="n">argument</span> <span class="n">type</span> <span class="no">Object</span> <span class="p">(</span><span class="n">expected</span> <span class="no">Proc</span><span class="p">)</span>
<span class="n">from</span> <span class="p">(</span><span class="n">irb</span><span class="p">):</span><span class="mi">4</span>
<span class="n">from</span> <span class="sr">/Users/</span><span class="n">jeg2</span><span class="o">/.</span><span class="n">rubies</span><span class="o">/</span><span class="n">ruby</span><span class="o">-</span><span class="mi">2</span><span class="o">.</span><span class="mi">1</span><span class="o">.</span><span class="mi">3</span><span class="o">/</span><span class="n">bin</span><span class="o">/</span><span class="ss">irb</span><span class="p">:</span><span class="mi">11</span><span class="ss">:in</span> <span class="sb">`<main>'</span>
</pre></div>
<p>Then you have to know that any object can choose to play ball as a <code>Proc</code> by defining a <code>to_proc()</code> method:</p>
<div class="highlight highlight-ruby"><pre><span class="o">>></span> <span class="n">o</span> <span class="o">=</span> <span class="no">Object</span><span class="o">.</span><span class="n">new</span>
<span class="o">=></span> <span class="c1">#<Object:0x007fc5841fb278></span>
<span class="o">>></span> <span class="k">def</span> <span class="nc">o</span><span class="o">.</span><span class="nf">to_proc</span><span class="p">;</span> <span class="nb">proc</span> <span class="p">{</span> <span class="nb">puts</span> <span class="s2">"Howdy."</span> <span class="p">}</span> <span class="k">end</span>
<span class="o">=></span> <span class="ss">:to_proc</span>
<span class="o">>></span> <span class="n">m</span><span class="p">(</span><span class="o">&</span><span class="n">o</span><span class="p">)</span>
<span class="o">=></span> <span class="c1">#<Proc:0x007fc5841e6d28@(irb):8></span>
</pre></div>
<p>Now, you can probably guess that <code>Symbol</code> defines <code>to_proc</code>. Watch what it does:</p>
<div class="highlight highlight-ruby"><pre><span class="o">>></span> <span class="n">symbol_to_proc</span> <span class="o">=</span> <span class="ss">:to_s</span><span class="o">.</span><span class="n">to_proc</span>
<span class="o">=></span> <span class="c1">#<Proc:0x007fc5841e2750></span>
<span class="o">>></span> <span class="n">symbol_to_proc</span><span class="o">[</span><span class="mi">42</span><span class="o">]</span>
<span class="o">=></span> <span class="s2">"42"</span>
<span class="o">>></span> <span class="n">symbol_to_proc</span><span class="o">[</span><span class="no">Object</span><span class="o">.</span><span class="n">new</span><span class="o">]</span>
<span class="o">=></span> <span class="s2">"#<Object:0x007fc5841c1a50>"</span>
</pre></div>
<p>See how it just calls the method named after the <code>Symbol</code>? (It's essentially using <code>send()</code> under the hood.)</p>
<p>Combine all of those bits together and you can do some pretty fancy sorting with very little code.</p>James Edward Gray IIAll About Structtag:graysoftinc.com,2008-10-10:/posts/632014-04-11T19:49:24ZRuby even has shortcuts for building data classes for you.<p>I build small little data classes all the time and there's a reason for that: Ruby makes it trivial to do so. That's a big win because we all know that what is a trivial data class today will be tomorrow's super object, right? If I start out using a simple <code>Array</code> or <code>Hash</code>, I'll probably end up redoing most of the logic at both ends eventually. Or I can start with the trivial class and grow it naturally.</p>
<p>The key to all this though is that I don't write those classes myself! That's what Ruby is for. More specifically, you need to learn to love <code>Struct</code>. Allow me to show you what I mean.</p>
<p>Imagine I need a basic class to represent a <code>Contact</code>. Ruby gives us so many shortcuts that the class could be very small even without <code>Struct</code>:</p>
<div class="highlight highlight-ruby"><pre><span class="k">class</span> <span class="nc">Contact</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">first</span><span class="p">,</span> <span class="n">last</span><span class="p">,</span> <span class="n">email</span><span class="p">)</span>
<span class="vi">@first</span> <span class="o">=</span> <span class="n">first</span>
<span class="vi">@last</span> <span class="o">=</span> <span class="n">last</span>
<span class="vi">@email</span> <span class="o">=</span> <span class="n">email</span>
<span class="k">end</span>
<span class="kp">attr_accessor</span> <span class="ss">:first</span><span class="p">,</span> <span class="ss">:last</span><span class="p">,</span> <span class="ss">:email</span>
<span class="k">end</span>
</pre></div>
<p>You could shorten that up more with some multiple assignment if you like, but that's the basics. Now using <code>Struct</code> is even easier:</p>
<div class="highlight highlight-ruby"><pre><span class="no">Contact</span> <span class="o">=</span> <span class="no">Struct</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">:first</span><span class="p">,</span> <span class="ss">:last</span><span class="p">,</span> <span class="ss">:email</span><span class="p">)</span>
</pre></div>
<p>To be fair, that's not 100% the same as the previous code. My original class required that three arguments get passed to the constructor whereas <code>Struct</code> is more lenient:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">p</span> <span class="no">Contact</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="o">*</span><span class="sx">%w[James Gray james@grayproductions.net]</span><span class="p">)</span>
<span class="c1"># >> #<struct Contact first="James",</span>
<span class="c1"># last="Gray",</span>
<span class="c1"># email="james@grayproductions.net"></span>
<span class="nb">p</span> <span class="no">Contact</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="o">*</span><span class="sx">%w[James Gray]</span><span class="p">)</span>
<span class="c1"># >> #<struct Contact first="James", last="Gray", email=nil></span>
<span class="nb">p</span> <span class="no">Contact</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">"James"</span><span class="p">)</span>
<span class="c1"># >> #<struct Contact first="James", last=nil, email=nil></span>
<span class="nb">p</span> <span class="no">Contact</span><span class="o">.</span><span class="n">new</span>
<span class="c1"># >> #<struct Contact first=nil, last=nil, email=nil></span>
</pre></div>
<p>As you can see, all arguments to the constructor <code>Struct</code> builds for you are optional. It will just fill in the passed values, from left to right. This may or may not be an advantage for your needs.</p>
<p>Now lets look once more at how I built that <code>Struct</code>:</p>
<div class="highlight highlight-ruby"><pre><span class="no">ClassName</span> <span class="o">=</span> <span class="no">Struct</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="p">)</span>
</pre></div>
<p><code>Struct::new()</code> builds and returns <code>Class</code> objects. If you then assign that to a constant, you can pretty much treat it like any other class you build. Ruby usually just handles the constant assignment for you.</p>
<p>You can forgo the assignment to a constant if you pass the first argument as a constant name in <code>String</code> form:</p>
<div class="highlight highlight-ruby"><pre><span class="no">Struct</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">"Contact"</span><span class="p">,</span> <span class="ss">:first</span><span class="p">,</span> <span class="ss">:last</span><span class="p">,</span> <span class="ss">:email</span><span class="p">)</span>
</pre></div>
<p>This would not define a top-level <code>Contact</code>, but instead a <code>Struct::Contact</code>. Given that, your name must be unique among all <code>Struct</code>s defined when using this approach.</p>
<p>Getting back to our fledgling <code>Contact</code>, it's important to note that it does have all the getter and setter methods for the attributes:</p>
<div class="highlight highlight-ruby"><pre><span class="n">c</span> <span class="o">=</span> <span class="no">Contact</span><span class="o">.</span><span class="n">new</span>
<span class="nb">p</span> <span class="n">c</span>
<span class="c1"># >> #<struct Contact first=nil, last=nil, email=nil></span>
<span class="n">c</span><span class="o">.</span><span class="n">first</span> <span class="o">=</span> <span class="s2">"James"</span>
<span class="n">c</span><span class="o">.</span><span class="n">last</span> <span class="o">=</span> <span class="s2">"Gray"</span>
<span class="nb">p</span> <span class="n">c</span>
<span class="c1"># >> #<struct Contact first="James", last="Gray", email=nil></span>
<span class="nb">p</span> <span class="n">c</span><span class="o">.</span><span class="n">last</span>
<span class="c1"># >> "Gray"</span>
</pre></div>
<p>Again, <code>Struct</code> always defines both getter and setter for all attributes. That may or may not work for you.</p>
<p>You can also set values using a <code>Hash</code> like syntax:</p>
<div class="highlight highlight-ruby"><pre><span class="n">c</span><span class="o">[</span><span class="ss">:email</span><span class="o">]</span> <span class="o">=</span> <span class="s2">"james@grayproductions.net"</span>
<span class="nb">p</span> <span class="n">c</span><span class="o">[</span><span class="s2">"email"</span><span class="o">]</span>
<span class="c1"># >> "james@grayproductions.net"</span>
</pre></div>
<p><code>String</code> and <code>Symbol</code> keys are interchangeable.</p>
<p>Another awesome feature is that <code>Struct</code> gives you other ways to go through this data. Here are three of my personal favorites:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">p</span> <span class="n">c</span><span class="o">.</span><span class="n">members</span>
<span class="c1"># >> ["first", "last", "email"]</span>
<span class="nb">p</span> <span class="n">c</span><span class="o">.</span><span class="n">values</span>
<span class="c1"># >> ["James", "Gray", "james@grayproductions.net"]</span>
<span class="n">c</span><span class="o">.</span><span class="n">each_pair</span> <span class="k">do</span> <span class="o">|</span><span class="nb">name</span><span class="p">,</span> <span class="n">value</span><span class="o">|</span>
<span class="nb">puts</span> <span class="s2">"</span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="s2">: </span><span class="si">#{</span><span class="n">value</span><span class="si">}</span><span class="s2">"</span>
<span class="k">end</span>
<span class="c1"># >> first: James</span>
<span class="c1"># >> last: Gray</span>
<span class="c1"># >> email: james@grayproductions.net</span>
</pre></div>
<p>We get a lot of functionality for free. That's obvious. But eventually you are always going to want to add your own. In times past, the following was a common idiom for that:</p>
<div class="highlight highlight-ruby"><pre><span class="k">class</span> <span class="nc">Contact</span> <span class="o"><</span> <span class="no">Struct</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">:first</span><span class="p">,</span> <span class="ss">:last</span><span class="p">,</span> <span class="ss">:email</span><span class="p">)</span>
<span class="c1"># ...</span>
<span class="k">end</span>
</pre></div>
<p>This is a neat example because it shows how flexible Ruby is. The parent <code>Class</code> for a <code>Class</code> definition doesn't have to be just a constant name. It can actually be any code that results in a <code>Class</code> object. Then we can just inherit from it and add to it as we like.</p>
<p>However, projects like Rails have shown the error of this approach. Because Rails is often dynamically reloading code, <code>Class</code> definitions will be rerun. That means the <code>Struct</code> call will happen again, resulting in a fresh parent <code>Class</code> object (which happens to have the exact same behavior). Ruby will see the new parent for an existing definition and choke with an error:</p>
<pre><code>superclass mismatch for class Contact (TypeError)
</code></pre>
<p>The good news is that this isn't much of an issue because <code>Struct</code> plans for it. It's prepared to accept a block during definition and the contents of that block will be evaluate within your new <code>Class</code>. Thus it's trivial to add methods:</p>
<div class="highlight highlight-ruby"><pre><span class="no">Contact</span> <span class="o">=</span> <span class="no">Struct</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">:first</span><span class="p">,</span> <span class="ss">:last</span><span class="p">,</span> <span class="ss">:email</span><span class="p">)</span> <span class="k">do</span>
<span class="k">def</span> <span class="nf">to_hash</span>
<span class="no">Hash</span><span class="o">[*</span><span class="n">members</span><span class="o">.</span><span class="n">zip</span><span class="p">(</span><span class="n">values</span><span class="p">)</span><span class="o">.</span><span class="n">flatten</span><span class="o">]</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="c1"># ...</span>
<span class="nb">p</span> <span class="n">c</span><span class="o">.</span><span class="n">to_hash</span>
<span class="c1"># >> {"last"=>"Gray",</span>
<span class="c1"># "first"=>"James",</span>
<span class="c1"># "email"=>"james@grayproductions.net"}</span>
</pre></div>
<p>There is a gotcha when defining methods this way though. <code>Struct</code> cheats on the internal implementation and doesn't actually place values in real instance variables. Thus, you will need to stick to accessing your data through the method interface:</p>
<div class="highlight highlight-ruby"><pre><span class="no">Contact</span> <span class="o">=</span> <span class="no">Struct</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">:first</span><span class="p">,</span> <span class="ss">:last</span><span class="p">,</span> <span class="ss">:email</span><span class="p">)</span> <span class="k">do</span>
<span class="k">def</span> <span class="nf">full</span>
<span class="s2">"</span><span class="si">#{</span><span class="n">first</span><span class="si">}</span><span class="s2"> </span><span class="si">#{</span><span class="n">last</span><span class="si">}</span><span class="s2">"</span><span class="o">.</span><span class="n">strip</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="c1"># ...</span>
<span class="nb">p</span> <span class="n">c</span><span class="o">.</span><span class="n">full</span>
<span class="c1"># >> "James Gray"</span>
</pre></div>
<p>If <code>Struct</code> isn't dynamic enough for you, you may want to examine the standard <code>OpenStruct</code> library. It's essentially a <code>Hash</code> with a method interface, allowing you to change attributes as needed. You can also initialize it with a <code>Hash</code>, if needed:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">require</span> <span class="s2">"ostruct"</span>
<span class="nb">name</span> <span class="o">=</span> <span class="no">OpenStruct</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">:first</span> <span class="o">=></span> <span class="s2">"James"</span><span class="p">,</span> <span class="ss">:last</span> <span class="o">=></span> <span class="s2">"Gray"</span><span class="p">)</span>
<span class="nb">p</span> <span class="nb">name</span><span class="o">.</span><span class="n">last</span>
<span class="c1"># >> "Gray"</span>
<span class="nb">name</span><span class="o">.</span><span class="n">suffix</span> <span class="o">=</span> <span class="s2">"II"</span> <span class="c1"># add an attribute</span>
<span class="nb">p</span> <span class="nb">name</span><span class="o">.</span><span class="n">suffix</span>
<span class="c1"># >> "II"</span>
</pre></div>
<p>Sadly, <code>OpenStruct</code> is missing most of the niceties of <code>Struct</code>. Because of that, I don't feel it buys you much over a <code>Hash</code>.</p>
<p>Keep <code>Struct</code> in mind next time you need a simple data object. It's hardly any effort to setup, it comes fully loaded with options, and it can grow as your needs do.</p>James Edward Gray IIDual Interface Modulestag:graysoftinc.com,2008-10-09:/posts/622014-04-11T19:28:44ZTwo different ways to use modules with one simple trick.<p>I'm guessing we've all seen Ruby's <code>Math</code> <code>Module</code>. I'm sure you know that you can call methods in it as "module (or class) methods:"</p>
<div class="highlight highlight-ruby"><pre><span class="no">Math</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span> <span class="c1"># => 2.0</span>
</pre></div>
<p>That's just one way to use the <code>Math</code> <code>Module</code> though. Another is to treat it as a mixin and call the same methods as instance methods:</p>
<div class="highlight highlight-ruby"><pre><span class="k">module</span> <span class="nn">MyMathyThing</span>
<span class="kp">extend</span> <span class="no">Math</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">my_sqrt</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
<span class="n">sqrt</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">MyMathyThing</span><span class="o">.</span><span class="n">my_sqrt</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span> <span class="c1"># => 2.0</span>
</pre></div>
<p>Ruby ships with a few <code>Module</code>s that work like this, including the mighty <code>Kernel</code>.</p>
<p>How is this dual interface accomplished? With the seldom seen <code>module_function()</code> method. You use this much like you would <code>private()</code>, to affect all following method definitions:</p>
<div class="highlight highlight-ruby"><pre><span class="k">module</span> <span class="nn">Greeter</span>
<span class="kp">module_function</span>
<span class="k">def</span> <span class="nf">hello</span>
<span class="s2">"Hello!"</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">module</span> <span class="nn">MyGreeter</span>
<span class="kp">extend</span> <span class="no">Greeter</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">my_hello</span>
<span class="n">hello</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">Greeter</span><span class="o">.</span><span class="n">hello</span> <span class="c1"># => "Hello!"</span>
<span class="no">MyGreeter</span><span class="o">.</span><span class="n">my_hello</span> <span class="c1"># => "Hello!"</span>
</pre></div>
<p>As you can see, it magically gives us the dual interface for the methods beneath it. You can also affect specific methods by name, just as you could with <code>private()</code>. This is equivalent to my definition above:</p>
<div class="highlight highlight-ruby"><pre><span class="k">module</span> <span class="nn">Greeter</span>
<span class="k">def</span> <span class="nf">hello</span>
<span class="s2">"Hello!"</span>
<span class="k">end</span>
<span class="kp">module_function</span> <span class="ss">:hello</span>
<span class="k">end</span>
</pre></div>
<p>What this helper actually does is to make a copy of the method and move it up to the module interface level. Once the copy is made, they can be affected separately:</p>
<div class="highlight highlight-ruby"><pre><span class="k">module</span> <span class="nn">Copies</span>
<span class="k">def</span> <span class="nf">copy</span>
<span class="s2">"Copied!"</span>
<span class="k">end</span>
<span class="kp">module_function</span> <span class="ss">:copy</span>
<span class="n">alias_method</span> <span class="ss">:copier</span><span class="p">,</span> <span class="ss">:copy</span>
<span class="kp">public</span> <span class="ss">:copier</span>
<span class="k">undef</span> <span class="ss">:copy</span>
<span class="k">end</span>
<span class="no">Copies</span><span class="o">.</span><span class="n">copy</span> <span class="c1"># => "Copied!"</span>
<span class="n">c</span> <span class="o">=</span> <span class="no">Object</span><span class="o">.</span><span class="n">new</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="no">Copies</span><span class="p">)</span>
<span class="n">c</span><span class="o">.</span><span class="n">copier</span> <span class="c1"># => "Copied!"</span>
<span class="n">c</span><span class="o">.</span><span class="n">copy</span>
<span class="c1"># ~> -:16: undefined method `copy' for #<Object:0x26e6c> (NoMethodError)</span>
</pre></div>
<p>This process also marks the instance method version <code>private()</code>, which is why I needed the call to <code>public()</code> in the last example. This means that methods you mixin to another object do not add to its external interface:</p>
<div class="highlight highlight-ruby"><pre><span class="k">module</span> <span class="nn">Selfish</span>
<span class="kp">module_function</span>
<span class="k">def</span> <span class="nf">mine</span>
<span class="s2">"mine"</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">module</span> <span class="nn">Sharing</span>
<span class="kp">extend</span> <span class="no">Selfish</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">yours_and_mine</span>
<span class="s2">"yours and </span><span class="si">#{</span><span class="n">mine</span><span class="si">}</span><span class="s2">"</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">Sharing</span><span class="o">.</span><span class="n">yours_and_mine</span> <span class="c1"># => "yours and mine"</span>
<span class="no">Sharing</span><span class="o">.</span><span class="n">mine</span>
<span class="c1"># ~> -:18: private method `mine' called for Sharing:Module (NoMethodError)</span>
</pre></div>
<p>As we've seen there are some advantages to this interface, but there are some drawbacks too. For example, I first tried to write the <code>MyGreeter</code> example as:</p>
<div class="highlight highlight-ruby"><pre><span class="k">module</span> <span class="nn">MyGreeter</span>
<span class="kp">include</span> <span class="no">Greeter</span>
<span class="kp">module_function</span>
<span class="k">def</span> <span class="nf">my_hello</span>
<span class="n">hello</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">MyGreeter</span><span class="o">.</span><span class="n">my_hello</span> <span class="c1"># => </span>
<span class="c1"># ~> -:15:in `my_hello': undefined local variable or method</span>
<span class="c1"># ~> `hello' for MyGreeter:Module (NameError)</span>
<span class="c1"># ~> from -:20</span>
</pre></div>
<p>That didn't work because the <code>Greeter</code> functionality was not copied up with my method. You can fix that by using a different trick to duplicate the functionality:</p>
<div class="highlight highlight-ruby"><pre><span class="k">module</span> <span class="nn">MyGreeter</span>
<span class="kp">include</span> <span class="no">Greeter</span>
<span class="kp">extend</span> <span class="nb">self</span> <span class="c1"># mixin functionality to our own Module interface</span>
<span class="k">def</span> <span class="nf">my_hello</span>
<span class="n">hello</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">MyGreeter</span><span class="o">.</span><span class="n">my_hello</span> <span class="c1"># => "Hello!"</span>
</pre></div>
<p>This provides a similar dual interface, but there are important differences. First, we've changed the <code>ancestors()</code> of <code>MyGreeter</code>, not copied methods:</p>
<div class="highlight highlight-ruby"><pre><span class="no">MyGreeter</span><span class="o">.</span><span class="n">ancestors</span> <span class="c1"># => [MyGreeter, Greeter]</span>
</pre></div>
<p>There's just one method and changing it affects everywhere it is used.</p>
<p>We also didn't magically make the mixin interface <code>private()</code> and it will bleed through:</p>
<div class="highlight highlight-ruby"><pre><span class="k">module</span> <span class="nn">MyNestedGreeter</span>
<span class="kp">extend</span> <span class="no">MyGreeter</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">my_nested_hello</span>
<span class="n">my_hello</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">MyNestedGreeter</span><span class="o">.</span><span class="n">my_nested_hello</span> <span class="c1"># => "Hello!"</span>
<span class="no">MyNestedGreeter</span><span class="o">.</span><span class="n">my_hello</span> <span class="c1"># => "Hello!"</span>
</pre></div>
<p>It's all tradeoffs of course, but knowing our options allows us to make informed choices about what is best for our needs.</p>James Edward Gray IIReadable Booleanstag:graysoftinc.com,2008-10-08:/posts/612014-04-11T19:19:30ZHere's a quick tip for how to make your methods calls even more readable than the method writer intended.<p>There's a great little trick you can do to improve the readability of your code. A common problem is dealing with methods that have a boolean flag arguments. Here's an example I ran into just today in a Rails application:</p>
<div class="highlight highlight-ruby"><pre><span class="k">def</span> <span class="nf">rating_stars</span><span class="p">(</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="n">,</span> <span class="n">clickable</span> <span class="o">=</span> <span class="kp">false</span><span class="p">)</span>
<span class="c1"># ...</span>
<span class="k">end</span>
</pre></div>
<p>The problem with this is that you typically see calls like this scattered around the application:</p>
<div class="highlight highlight-erb"><pre><span class="cp"><%=</span> <span class="n">rating_stars</span><span class="p">(</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="n">,</span> <span class="kp">true</span><span class="p">)</span> <span class="cp">%></span><span class="x"></span>
</pre></div>
<p>Would you know what <code>true</code> did there if I hadn't shown you the name of the variable first? I didn't. I had to go hunting for that method definition.</p>
<p>Ironically the opposite problem, a magical dangling <code>false</code>, is much more rare in my experience. That's typically the default for these kind of arguments and it just makes more sense and reads better to leave it out.</p>
<p>Anyway, the point is that we can typically improve the ease of understanding the common case. Remember that in Ruby <code>false</code> and <code>nil</code> are false while everything else is true. That means that truth is very loosely defined and we can pass a lot of things for our boolean flag value. For example, after looking up the method and understanding what was needed, I chose to call it like this:</p>
<div class="highlight highlight-erb"><pre><span class="cp"><%=</span> <span class="n">rating_stars</span><span class="p">(</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="n">,</span> <span class="ss">:clickable</span><span class="p">)</span> <span class="cp">%></span><span class="x"></span>
</pre></div>
<p>My hope is that might save a future maintainer a trip to the method definition to understand the call.</p>
<p>I've used that trick in quite a few situations now. To give another example, <code>FasterCSV</code>'s documentation encourages user code to pass <code>:headers => :first_row</code> instead of just <code>:headers => true</code>. That has the advantage of being more self-documenting as well as leaving me room for possible expansion to the API.</p>James Edward Gray IIDSL Block Stylestag:graysoftinc.com,2008-10-07:/posts/602014-04-11T19:14:19ZThere are two different ways to handle a DSL using Ruby's blocks but you don't really have to choose.<p>There's an argument that rages in the Ruby camps: to <code>instance_eval()</code> or not to <code>instance_eval()</code>. Most often this argument is triggered by DSL discussions where we tend to want code like:</p>
<div class="highlight highlight-ruby"><pre><span class="n">configurable</span><span class="o">.</span><span class="n">config</span> <span class="k">do</span>
<span class="n">width</span> <span class="mi">100</span>
<span class="n">mode</span> <span class="ss">:wrap</span>
<span class="k">end</span>
</pre></div>
<p>You can accomplish something like this by passing the block to <code>instance_eval()</code> and changing <code>self</code> to an object that defines the <code>width()</code> and <code>mode()</code> methods. Of course changing <code>self</code> is always dangerous. We may have already been inside an object and planning to use methods from that namespace:</p>
<div class="highlight highlight-ruby"><pre><span class="k">class</span> <span class="nc">MyObject</span>
<span class="kp">include</span> <span class="no">Configurable</span> <span class="c1"># to get the config() method shown above</span>
<span class="k">def</span> <span class="nf">initialize</span>
<span class="n">config</span> <span class="k">do</span>
<span class="n">width</span> <span class="n">calculate_width</span> <span class="c1"># a problem: may not work with instance_eval()</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="kp">private</span>
<span class="k">def</span> <span class="nf">calculate_width</span> <span class="c1"># the method we want to use</span>
<span class="c1"># ...</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
<p>In this example, if <code>width()</code> comes from a different configuration object, we're in trouble. The <code>instance_eval()</code> will shift the focus away from our <code>MyObject</code> instance and we will get a <code>NoMethodError</code> when we try to call <code>calculate_width()</code>. This may prevent us from being able to use <code>Configurable</code> in our code.</p>
<p>A common solution is to pass the object with the <code>width()</code> and <code>mode()</code> methods into the block. You can then make calls on that object and keep the same <code>self</code>. This could fix the above problem example:</p>
<div class="highlight highlight-ruby"><pre><span class="n">config</span> <span class="k">do</span> <span class="o">|</span><span class="n">c</span><span class="o">|</span>
<span class="n">c</span><span class="o">.</span><span class="n">width</span> <span class="n">calculate_width</span>
<span class="k">end</span>
</pre></div>
<p>I imagine most of us agree that's not quite as smooth, but it tends to get viewed as a necessary evil. It's just not safe to always use <code>instance_eval()</code>. I think there are some issues with that line of thinking though:</p>
<ul>
<li>Sometimes <code>instance_eval()</code> is OK and we would prefer to have the prettier syntax when it is</li>
<li>Library authors are making this blanket decision for all the use cases</li>
<li>We have a super dynamic language here so we should be able to have it both ways</li>
</ul><p>It turns out that we can accommodate both schools of thought rather easily. You can ask Ruby to bundle up any block into a <code>Proc</code> object and <code>Proc</code> objects have an <code>arity()</code> method that will tell you how many arguments they expect. We can use that to determine when to switch strategies:</p>
<div class="highlight highlight-ruby"><pre><span class="k">class</span> <span class="nc">DSL</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="o">&</span><span class="n">dsl_code</span><span class="p">)</span> <span class="c1"># creates the Proc</span>
<span class="k">if</span> <span class="n">dsl_code</span><span class="o">.</span><span class="n">arity</span> <span class="o">==</span> <span class="mi">1</span> <span class="c1"># the arity() check</span>
<span class="n">dsl_code</span><span class="o">[</span><span class="nb">self</span><span class="o">]</span> <span class="c1"># argument expected, pass the object</span>
<span class="k">else</span>
<span class="nb">instance_eval</span><span class="p">(</span><span class="o">&</span><span class="n">dsl_code</span><span class="p">)</span> <span class="c1"># no argument, use instance_eval()</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">do_something</span>
<span class="nb">puts</span> <span class="s2">"Doing something..."</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">DSL</span><span class="o">.</span><span class="n">new</span> <span class="p">{</span> <span class="o">|</span><span class="n">d</span><span class="o">|</span> <span class="n">d</span><span class="o">.</span><span class="n">do_something</span> <span class="p">}</span>
<span class="c1"># >> Doing something...</span>
<span class="no">DSL</span><span class="o">.</span><span class="n">new</span> <span class="p">{</span> <span class="n">do_something</span> <span class="p">}</span>
<span class="c1"># >> Doing something... </span>
</pre></div>
<p>Users of this code can now decide how they want it to work based on their needs as the examples show.</p>
<p>With a language like Ruby these limitations just become opportunities for showing off how dynamic our code can be. Don't be so quick to give in to necessary evils.</p>James Edward Gray IIConversion Methodstag:graysoftinc.com,2008-10-06:/posts/592014-04-11T19:05:08ZThere are quite a few things to know about the simple type conversion methods in Ruby.<p>I want to take a step back from all the syntax I've been covering lately and just talk about some simple methods in Ruby's core. Ruby ships with so many great helpers, it's often hard to keep track of what everything can do. Specifically, let's talk about the type conversion methods.</p>
<p>I assume we all make calls to <code>to_s()</code> and <code>to_i()</code> regularly:</p>
<div class="highlight highlight-ruby"><pre><span class="mi">255</span><span class="o">.</span><span class="n">to_s</span> <span class="c1"># => "255"</span>
<span class="s2">"255"</span><span class="o">.</span><span class="n">to_i</span> <span class="c1"># => 255</span>
</pre></div>
<p>There shouldn't be any surprises there. Even these two simple methods can do more though. They make it possible to convert to and from various numeric bases. For example, here are the same conversions into and out of base 16 (hexadecimal):</p>
<div class="highlight highlight-ruby"><pre><span class="mi">255</span><span class="o">.</span><span class="n">to_s</span><span class="p">(</span><span class="mi">16</span><span class="p">)</span> <span class="c1"># => "ff"</span>
<span class="s2">"ff"</span><span class="o">.</span><span class="n">to_i</span><span class="p">(</span><span class="mi">16</span><span class="p">)</span> <span class="c1"># => 255</span>
</pre></div>
<p>Ruby has other ways to do these same conversions. Here are two unusual methods (beginning with capital letters) that are similar:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">String</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span> <span class="c1"># => "255"</span>
<span class="nb">Integer</span><span class="p">(</span><span class="s2">"255"</span><span class="p">)</span> <span class="c1"># => 255</span>
</pre></div>
<p>I'll be honest and tell you that I don't really find <code>String()</code> useful as it just calls <code>to_s()</code> for you, but <code>Integer()</code> is a different story. First of all, <code>to_i()</code> is very lenient about what it converts while <code>Integer()</code> is more strict:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">p</span> <span class="s2">"C#"</span><span class="o">.</span><span class="n">to_i</span>
<span class="c1"># >> 0</span>
<span class="nb">Integer</span><span class="p">(</span><span class="s2">"C#"</span><span class="p">)</span>
<span class="c1"># ~> -:5:in `Integer': invalid value for Integer: "C#" (ArgumentError)</span>
</pre></div>
<p>That can be handy when you want to be sure you you have a number.</p>
<p>Now while <code>Integer()</code> must be passed a number, it understands numbers in all of the native formats Ruby does: decimal, octal, hexadecimal, and binary. In comparison, <code>to_i()</code> just understands decimal integers:</p>
<div class="highlight highlight-ruby"><pre><span class="mi">255</span> <span class="c1"># => 255</span>
<span class="mo">0377</span> <span class="c1"># => 255</span>
<span class="mh">0xFF</span> <span class="c1"># => 255</span>
<span class="m-Bin">0b11111111</span> <span class="c1"># => 255</span>
<span class="nb">Integer</span><span class="p">(</span><span class="s2">"255"</span><span class="p">)</span> <span class="c1"># => 255</span>
<span class="nb">Integer</span><span class="p">(</span><span class="s2">"0377"</span><span class="p">)</span> <span class="c1"># => 255</span>
<span class="nb">Integer</span><span class="p">(</span><span class="s2">"0xFF"</span><span class="p">)</span> <span class="c1"># => 255</span>
<span class="nb">Integer</span><span class="p">(</span><span class="s2">"0b11111111"</span><span class="p">)</span> <span class="c1"># => 255</span>
<span class="s2">"255"</span><span class="o">.</span><span class="n">to_i</span> <span class="c1"># => 255</span>
<span class="s2">"0377"</span><span class="o">.</span><span class="n">to_i</span> <span class="c1"># => 377</span>
<span class="s2">"0xFF"</span><span class="o">.</span><span class="n">to_i</span> <span class="c1"># => 0</span>
<span class="s2">"0b11111111"</span><span class="o">.</span><span class="n">to_i</span> <span class="c1"># => 0</span>
</pre></div>
<p>If you want to be sure you are passing in safe content to either method, you should probably verify the <code>String</code> contents with a regular expression before you make the call.</p>
<p>There is a <code>Float()</code> method as well, but it doesn't give you much over <code>to_f()</code>. The only significant difference is how they handle <code>nil</code>:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">p</span> <span class="kp">nil</span><span class="o">.</span><span class="n">to_f</span>
<span class="c1"># >> 0.0</span>
<span class="nb">Float</span><span class="p">(</span><span class="kp">nil</span><span class="p">)</span>
<span class="c1"># ~> -:10:in `Float': can't convert nil into Float (TypeError)</span>
</pre></div>
<p>Numbers aren't the only thing we can convert in Ruby though. Let's talk about <code>Array()</code>. Ruby use to have a direct <code>to_a()</code> method on all objects, but it has been deprecated in Ruby 1.8:</p>
<div class="highlight highlight-ruby"><pre><span class="err">$</span> <span class="n">ruby</span> <span class="o">-</span><span class="n">ve</span> <span class="s1">'p 5.to_a'</span>
<span class="n">ruby</span> <span class="mi">1</span><span class="o">.</span><span class="mi">8</span><span class="o">.</span><span class="mi">6</span> <span class="p">(</span><span class="mi">2008</span><span class="o">-</span><span class="mi">08</span><span class="o">-</span><span class="mi">11</span> <span class="n">patchlevel</span> <span class="mi">287</span><span class="p">)</span> <span class="o">[</span><span class="n">i686</span><span class="o">-</span><span class="n">darwin9</span><span class="o">.</span><span class="mi">4</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span>
<span class="o">-</span><span class="ss">e</span><span class="p">:</span><span class="mi">1</span><span class="p">:</span> <span class="ss">warning</span><span class="p">:</span> <span class="n">default</span> <span class="sb">`to_a' will be obsolete</span>
<span class="sb">[5]</span>
</pre></div>
<p>And it's finally gone in Ruby 1.9:</p>
<div class="highlight highlight-ruby"><pre><span class="err">$</span> <span class="n">ruby_dev</span> <span class="o">-</span><span class="n">ve</span> <span class="s1">'p 5.to_a'</span>
<span class="n">ruby</span> <span class="mi">1</span><span class="o">.</span><span class="mi">9</span><span class="o">.</span><span class="mi">0</span> <span class="p">(</span><span class="mi">2008</span><span class="o">-</span><span class="mi">09</span><span class="o">-</span><span class="mi">27</span> <span class="n">revision</span> <span class="mi">0</span><span class="p">)</span> <span class="o">[</span><span class="n">i386</span><span class="o">-</span><span class="n">darwin9</span><span class="o">.</span><span class="mi">5</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span>
<span class="o">-</span><span class="ss">e</span><span class="p">:</span><span class="mi">1</span><span class="ss">:in</span> <span class="sb">`<main>': undefined method `</span><span class="nb">to_a</span><span class="err">'</span> <span class="k">for</span> <span class="mi">5</span><span class="ss">:Fixnum</span> <span class="p">(</span><span class="no">NoMethodError</span><span class="p">)</span>
</pre></div>
<p>That leaves us with just <code>Array()</code>, but that's not a bad thing at all since it is very handy. What makes <code>Array()</code> great is the three different behaviors it has on the objects you pass:</p>
<ul>
<li>It has no effect on an <code>Array</code> which is return unchanged</li>
<li>It returns an empty <code>Array</code> when passed <code>nil</code>
</li>
<li>All other objects are returned wrapped in an <code>Array</code>
</li>
</ul><p>Here are examples of each of those:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">Array</span><span class="p">(</span><span class="o">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="o">]</span><span class="p">)</span> <span class="c1"># => [1, 2, 3]</span>
<span class="nb">Array</span><span class="p">(</span><span class="kp">nil</span><span class="p">)</span> <span class="c1"># => []</span>
<span class="nb">Array</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span> <span class="c1"># => [5]</span>
</pre></div>
<p>These simple rules mean that you can count on an <code>Array</code> being returned from <code>Array()</code>, no matter what you pass it. Thus it is safe to call any <code>Array</code> methods on the result, including iterators.</p>
<p>To give a more practical example, let's say you have some parameter your Rails application is prepared to receive. You may receive any number of items in this parameter: zero, one, or many. You can process them with a simple:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">Array</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:choices</span><span class="o">]</span><span class="p">)</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">choice</span><span class="o">|</span>
<span class="c1"># process choice here...</span>
<span class="k">end</span>
</pre></div>
<p>There's one last conversion method that I make regular use of and it is <code>Hash[]</code>. Note the brackets there as they aren't parentheses like the other methods we've been talking about. This one is a class method on <code>Hash</code>.</p>
<p>This method is very simple in function. It takes an even number of arguments and creates a <code>Hash</code>:</p>
<div class="highlight highlight-ruby"><pre><span class="no">Hash</span><span class="o">[</span><span class="s2">"a"</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="s2">"b"</span><span class="p">,</span> <span class="mi">2</span><span class="o">]</span> <span class="c1"># => {"a"=>1, "b"=>2}</span>
</pre></div>
<p>At first glance, that doesn't seem to gain us much over the normal <code>Hash</code> literal syntax of <code>{ … }</code>. However, this is a method call we can use to build a <code>Hash</code> and that means we can apply the normal tricks of method calls to it, like splatting an <code>Array</code> of arguments:</p>
<div class="highlight highlight-ruby"><pre><span class="no">Hash</span><span class="o">[*</span><span class="sx">%w[a 1 b 2]</span><span class="o">]</span> <span class="c1"># => {"a"=>"1", "b"=>"2"}</span>
</pre></div>
<p>That opens up all kinds of possibilities for converting from <code>Array</code> objects to <code>Hash</code> objects or for building iterations that result in a <code>Hash</code>:</p>
<div class="highlight highlight-ruby"><pre><span class="n">h</span> <span class="o">=</span> <span class="no">Hash</span><span class="o">[*</span><span class="sx">%w[a 1 b 2 c 3]</span><span class="o">.</span><span class="n">map</span> <span class="p">{</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="nb">Integer</span><span class="p">(</span><span class="n">f</span><span class="p">)</span> <span class="k">rescue</span> <span class="n">f</span> <span class="p">}</span><span class="o">]</span>
<span class="nb">p</span> <span class="n">h</span>
<span class="c1"># >> {"a"=>1, "b"=>2, "c"=>3}</span>
<span class="nb">p</span> <span class="no">Hash</span><span class="o">[*</span><span class="n">h</span><span class="o">.</span><span class="n">select</span> <span class="p">{</span> <span class="o">|</span><span class="n">_</span><span class="p">,</span> <span class="n">n</span><span class="o">|</span> <span class="p">(</span><span class="n">n</span> <span class="o">%</span> <span class="mi">2</span><span class="p">)</span><span class="o">.</span><span class="n">nonzero?</span> <span class="p">}</span><span class="o">.</span><span class="n">flatten</span><span class="o">]</span>
<span class="c1"># >> {"a"=>1, "c"=>3}</span>
</pre></div>
<p>Notice how we get a <code>Hash</code> out of the last line there when Ruby 1.8 would usually give us an <code>Array</code> of <code>Array</code> objects. Ruby 1.9 modifies most <code>Hash</code> iterators to return a <code>Hash</code> though:</p>
<div class="highlight highlight-ruby"><pre><span class="err">$</span> <span class="n">ruby_dev</span> <span class="o">-</span><span class="n">ve</span> <span class="s1">'p({"a"=>1, "b"=>2, "c"=>3}.select { |_, n| (n % 2).nonzero? })'</span>
<span class="n">ruby</span> <span class="mi">1</span><span class="o">.</span><span class="mi">9</span><span class="o">.</span><span class="mi">0</span> <span class="p">(</span><span class="mi">2008</span><span class="o">-</span><span class="mi">09</span><span class="o">-</span><span class="mi">27</span> <span class="n">revision</span> <span class="mi">0</span><span class="p">)</span> <span class="o">[</span><span class="n">i386</span><span class="o">-</span><span class="n">darwin9</span><span class="o">.</span><span class="mi">5</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span>
<span class="p">{</span><span class="s2">"a"</span><span class="o">=></span><span class="mi">1</span><span class="p">,</span> <span class="s2">"c"</span><span class="o">=></span><span class="mi">3</span><span class="p">}</span>
</pre></div>
<p>Hopefully that gives you some fresh ideas about how you might handle simple conversions in the future.</p>James Edward Gray III'm Addicted to the Word Arraytag:graysoftinc.com,2008-10-03:/posts/582014-04-11T18:53:50ZLet me show you what may very well be my favorite little piece of Ruby syntax.<p>Continuing with my recent trend of showing of fun uses of Ruby syntax, I have a confession to make: I'm addicted to Ruby's "word <code>Array</code>." I really am.</p>
<p>I suspect most of you know this, but the word <code>Array</code> is a shortcut that can lessen the quote-comma-quote syndrome of simple a simple <code>Array</code> like:</p>
<div class="highlight highlight-ruby"><pre><span class="o">[</span><span class="s2">"a"</span><span class="p">,</span> <span class="s2">"wordy"</span><span class="p">,</span> <span class="s2">"Array"</span><span class="o">]</span>
</pre></div>
<p>You can create the same <code>Array</code> with the word <code>Array</code> syntax:</p>
<div class="highlight highlight-ruby"><pre><span class="sx">%w[a wordy Array]</span>
</pre></div>
<p>That's essentially just a <code>String</code> that will automatically be <code>split()</code> on whitespace to build an <code>Array</code>. You can use any amount of space any place you like, so you can layout the data in whatever way makes the most sense for you:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">require</span> <span class="s2">"pp"</span>
<span class="n">pp</span> <span class="sx">%w[ one two three</span>
<span class="sx"> four five six</span>
<span class="sx"> seven eight nine</span>
<span class="sx"> zero ]</span>
<span class="c1"># >> ["one",</span>
<span class="c1"># >> "two",</span>
<span class="c1"># >> "three",</span>
<span class="c1"># >> "four",</span>
<span class="c1"># >> "five",</span>
<span class="c1"># >> "six",</span>
<span class="c1"># >> "seven",</span>
<span class="c1"># >> "eight",</span>
<span class="c1"># >> "nine",</span>
<span class="c1"># >> "zero"]</span>
</pre></div>
<p>Note that you can chose the punctuation characters used at either ends of the <code>Array</code>, some of which are paired while others just repeat:</p>
<div class="highlight highlight-ruby"><pre><span class="sx">%w(a wordy Array)</span>
<span class="sx">%w{a wordy Array}</span>
<span class="sx">%w<a wordy Array></span>
<span class="sx">%w!a wordy Array!</span>
<span class="sx">%w%a wordy Array%</span>
<span class="sx">%w#a wordy Array#</span>
</pre></div>
<p>I tend to just stick with <code>%w[ … ]</code> though because I like how it parallels the <code>[ … ]</code> for a normal <code>Array</code>. It's pretty smart too and will allow nested brackets, as long as they are paired properly:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">p</span> <span class="sx">%w[ [[]] abc[1] [start end] ]</span>
<span class="c1"># >> ["[[]]", "abc[1]", "[start", "end]"]</span>
</pre></div>
<p>With just that much, this feature is crazy useful. Here are examples with Rails validations and filters, platform-safe relative path building, and simple iteration just to give you some ideas:</p>
<div class="highlight highlight-ruby"><pre><span class="no">STATUSES</span> <span class="o">=</span> <span class="sx">%w[Pending Requested Booked Declined Submitted]</span>
<span class="n">validates_inclusion_of</span> <span class="ss">:status</span><span class="p">,</span> <span class="ss">:in</span> <span class="o">=></span> <span class="no">STATUSES</span>
<span class="n">before_filter</span> <span class="ss">:find_user</span><span class="p">,</span> <span class="ss">:only</span> <span class="o">=></span> <span class="sx">%w[show edit update destroy]</span>
<span class="vg">$LOAD_PATH</span> <span class="o"><<</span> <span class="no">File</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="no">File</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="bp">__FILE__</span><span class="p">),</span> <span class="o">*</span><span class="sx">%w[.. lib]</span><span class="p">)</span>
<span class="no">Card</span> <span class="o">=</span> <span class="no">Struct</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">:face</span><span class="p">,</span> <span class="ss">:suit</span><span class="p">)</span>
<span class="n">cards</span> <span class="o">=</span> <span class="o">[</span> <span class="o">]</span>
<span class="sx">%w[heart spade club diamond]</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">suit</span><span class="o">|</span>
<span class="sx">%w[A 2 3 4 5 6 7 8 9 T J Q K]</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">face</span><span class="o">|</span>
<span class="n">cards</span> <span class="o"><<</span> <span class="no">Card</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">face</span><span class="p">,</span> <span class="n">suit</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
<p>Everyone of those examples was pulled out of real code I've written. I'm a serious 12 stepper on this issue.</p>
<p>That's the basics. However, like most delights in Rubyland, the word <code>Array</code> hides some lesser known surprises. First, did you know that you can embed entries with spaces in them?</p>
<div class="highlight highlight-ruby"><pre><span class="no">SORT_OPTIONS</span> <span class="o">=</span> <span class="sx">%w[ Default</span>
<span class="sx"> Name</span>
<span class="sx"> Price</span>
<span class="sx"> Average\ Rating ]</span>
<span class="nb">p</span> <span class="no">SORT_OPTIONS</span>
<span class="c1"># >> ["Default", "Name", "Price", "Average Rating"]</span>
</pre></div>
<p>As you can see, a simple backslash escapes spaces. Now this is a technique you can definitely abuse and if you find yourself escaping every other space, you should probably just break down and build a normal <code>Array</code>. This is great for the occasional multiword entry though.</p>
<p>It doesn't stop there either. Remember when I said the word <code>Array</code> is essentially a <code>String</code>? Well, you can even mix in some interpolation, if you switch to the capital <code>W</code>:</p>
<div class="highlight highlight-ruby"><pre><span class="no">MODE</span> <span class="o">=</span> <span class="no">Object</span><span class="o">.</span><span class="n">const_defined?</span><span class="p">(</span><span class="ss">:Test</span><span class="p">)</span> <span class="p">?</span> <span class="ss">:test</span> <span class="p">:</span> <span class="ss">:data</span>
<span class="no">PATH</span> <span class="o">=</span> <span class="no">File</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="no">File</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="bp">__FILE__</span><span class="p">),</span> <span class="o">*</span><span class="sx">%W[.. .. </span><span class="si">#{</span><span class="no">MODE</span><span class="si">}</span><span class="sx"> db.sqlite]</span><span class="p">)</span>
</pre></div>
<p>This is code from a trivial SQLite wrapper I made. It determines what <code>MODE</code> to run in with a simple test that will pass after <code>Test::Unit</code> has been loaded. It then builds a <code>PATH</code> to the database using the selected <code>MODE</code>. It's interpolation in the word <code>Array</code> that makes that easy to do.</p>
<p>It's probably worth mentioning that interpolated values are not subject to internal splitting:</p>
<div class="highlight highlight-ruby"><pre><span class="n">var</span> <span class="o">=</span> <span class="s2">"three four"</span>
<span class="n">ary</span> <span class="o">=</span> <span class="sx">%W[one two </span><span class="si">#{</span><span class="n">var</span><span class="si">}</span><span class="sx">]</span>
<span class="nb">p</span> <span class="n">ary</span>
<span class="c1"># >> ["one", "two", "three four"]</span>
</pre></div>
<p>The capital <code>W</code> version supports some other <code>String</code> escapes as well, though I confess that I've never made use of this:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">p</span> <span class="sx">%W[</span><span class="se">\t</span><span class="sx"> </span><span class="se">\x20</span><span class="sx"> </span><span class="se">\n</span><span class="sx">]</span>
<span class="c1"># >> ["\t", " ", "\n"]</span>
</pre></div>
<p>Well, that's all the word <code>Array</code> goodness I can pack into a single blog post. Hopefully you are sold and I'll be seeing a lot more of you at the Word <code>Array</code> Anonymous User meetings.</p>James Edward Gray IIInterpolation and Statementstag:graysoftinc.com,2008-10-02:/posts/572014-04-11T16:52:57ZThere are two aspects of Ruby syntax that really have a great synergy when used together. Let me show you what I mean.<p>I still cringe anytime I see code like:</p>
<div class="highlight highlight-ruby"><pre><span class="s2">"1 + 2 = "</span> <span class="o">+</span> <span class="p">(</span><span class="mi">1</span> <span class="o">+</span> <span class="mi">2</span><span class="p">)</span><span class="o">.</span><span class="n">to_s</span> <span class="c1"># => "1 + 2 = 3"</span>
</pre></div>
<p>Some books even advocate the above, which is a real shame for Ruby.</p>
<p>I imagine most of you know that you can rewrite the above to use <code>String</code> interpolation:</p>
<div class="highlight highlight-ruby"><pre><span class="s2">"1 + 2 = </span><span class="si">#{</span><span class="mi">1</span> <span class="o">+</span> <span class="mi">2</span><span class="si">}</span><span class="s2">"</span> <span class="c1"># => "1 + 2 = 3"</span>
</pre></div>
<p>Let's think about that simple code a little bit more than we usually do though. What's really going on here? Obviously <code>#{ … }</code> inserts the result of the embedded code in the <code>String</code>, but it's important to realize that it also calls <code>to_s()</code> on that result to make it fit in the <code>String</code>.</p>
<p>We can really make use of that knowledge if we try. Here's an example:</p>
<div class="highlight highlight-ruby"><pre><span class="no">Name</span> <span class="o">=</span> <span class="no">Struct</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">:first</span><span class="p">,</span> <span class="ss">:last</span><span class="p">)</span> <span class="k">do</span>
<span class="k">def</span> <span class="nf">full</span>
<span class="s2">"</span><span class="si">#{</span><span class="n">first</span><span class="si">}</span><span class="s2"> </span><span class="si">#{</span><span class="n">last</span><span class="si">}</span><span class="s2">"</span><span class="o">.</span><span class="n">strip</span> <span class="c1"># trick 1</span>
<span class="k">end</span>
<span class="n">alias_method</span> <span class="ss">:to_s</span><span class="p">,</span> <span class="ss">:full</span> <span class="c1"># trick 2</span>
<span class="k">end</span>
<span class="no">Name</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">"James"</span><span class="p">)</span><span class="o">.</span><span class="n">full</span> <span class="c1"># => "James"</span>
<span class="no">Name</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">:James</span><span class="p">,</span> <span class="ss">:Gray</span><span class="p">)</span><span class="o">.</span><span class="n">full</span> <span class="c1"># => "James Gray"</span>
<span class="s2">"My name is </span><span class="si">#{</span><span class="no">Name</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s1">'James'</span><span class="p">,</span> <span class="s1">'Gray'</span><span class="p">)</span><span class="si">}</span><span class="s2">."</span> <span class="c1"># => "My name is James Gray."</span>
</pre></div>
<p>I've built a trivial data class for managing names here. In that, I've tried to make use of interpolation to the fullest.</p>
<p>First, I needed to be able to build a reasonable representation of a full name no matter what data I have. My first example shows how this might play out when I only have a first name. That means <code>first()</code> will return <code>"James"</code> and <code>last()</code> will return <code>nil</code>. There are several ways to deal with this, but I chose what I consider to be one of the easiest.</p>
<p>I want something like a <code>String</code> for first and last name. Interpolation pretty much enforces this for me, since it automatically calls <code>to_s()</code> on the interpolated values. It just so happens that <code>nil.to_s</code> is <code>""</code> and following that up with a simple <code>strip()</code> will remove any excess space due to missing names.</p>
<p>You can also see from the second example that I don't have to be strictly using <code>String</code> objects for the names. Anything with a reasonable <code>to_s()</code> will do.</p>
<p>Taking that one step further, the third example shows that even <code>Name</code> itself can benefit from a reasonable <code>to_s()</code>. This allows me to drop the full object right into any old <code>String</code>. You can take this really far by just adding sensible <code>to_s()</code> definitions to all kinds of objects. You could have objects representing data changes dropping themselves right into audit logs, have game move classes automatically serialize themselves for transport over a network protocol, or anything else you can think of.</p>
<p>Hopefully I've made that point now. The implicit <code>to_s()</code> of <code>String</code> interpolation is nice. Now let's look at another aspect of Ruby.</p>
<p>Many languages go to great lengths to distinguish between concepts like a <em>statement</em> and an <em>expression</em>, what each of those does, and where they can appear. Thankfully, Ruby doesn't much care.</p>
<p>What does that mean for us? Well, just about everything evaluates to something. You can kind of think of it as everything having a return value. (It's not really a return value in the case of something like a conditional, but I think that description makes for a good visual of what we are talking about here.) Let me show some examples:</p>
<div class="highlight highlight-ruby"><pre><span class="n">a</span> <span class="o">=</span> <span class="n">b</span> <span class="o">=</span> <span class="mi">2</span>
<span class="n">a</span> <span class="c1"># => 2</span>
<span class="n">b</span> <span class="c1"># => 2</span>
<span class="n">num</span> <span class="o">=</span> <span class="nb">rand</span><span class="p">(</span><span class="mi">20</span><span class="p">)</span> <span class="o">-</span> <span class="mi">10</span>
<span class="n">type</span> <span class="o">=</span> <span class="k">if</span> <span class="n">num</span> <span class="o">>=</span> <span class="mi">0</span> <span class="k">then</span> <span class="ss">:positive</span>
<span class="k">else</span> <span class="ss">:negative</span>
<span class="k">end</span>
<span class="o">[</span><span class="n">num</span><span class="p">,</span> <span class="n">type</span><span class="o">]</span> <span class="c1"># => [-3, :negative]</span>
<span class="n">age</span> <span class="o">=</span> <span class="nb">rand</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span>
<span class="n">group</span> <span class="o">=</span> <span class="k">case</span> <span class="n">age</span>
<span class="k">when</span> <span class="mi">0</span><span class="o">.</span><span class="n">.</span><span class="mi">18</span> <span class="k">then</span> <span class="ss">:child</span>
<span class="k">when</span> <span class="mi">19</span><span class="o">.</span><span class="n">.</span><span class="mi">65</span> <span class="k">then</span> <span class="ss">:adult</span>
<span class="k">when</span> <span class="mi">66</span><span class="o">.</span><span class="n">.</span><span class="mi">100</span> <span class="k">then</span> <span class="ss">:senior</span>
<span class="k">end</span>
<span class="o">[</span><span class="n">age</span><span class="p">,</span> <span class="n">group</span><span class="o">]</span> <span class="c1"># => [44, :adult]</span>
<span class="n">not_run</span> <span class="o">=</span> <span class="k">if</span> <span class="kp">false</span>
<span class="c1"># ...</span>
<span class="k">end</span>
<span class="n">not_run</span> <span class="c1"># => nil</span>
<span class="k">def</span> <span class="nf">do_nothing</span><span class="p">;</span> <span class="k">end</span>
<span class="n">not_run</span> <span class="o">=</span> <span class="n">do_nothing</span>
<span class="n">not_run</span> <span class="c1"># => nil</span>
</pre></div>
<p>Hopefully something in there surprises you. Take special note of the last two which pretty much show that Ruby tends to just go with <code>nil</code> when there's nothing else for a construct to evaluate to. We can use that.</p>
<p>Now, let's throw those two concepts together. Interpolation calls <code>to_s()</code> on the results of any code and we now know that most any code will have a result. That means we can write code like this:</p>
<div class="highlight highlight-ruby"><pre><span class="k">def</span> <span class="nf">pluralize</span><span class="p">(</span><span class="n">count</span><span class="p">,</span> <span class="n">singular</span><span class="p">)</span>
<span class="s2">"</span><span class="si">#{</span><span class="n">count</span><span class="si">}</span><span class="s2"> </span><span class="si">#{</span><span class="n">singular</span><span class="si">}#{</span><span class="s1">'s'</span> <span class="k">unless</span> <span class="n">count</span> <span class="o">==</span> <span class="mi">1</span><span class="si">}</span><span class="s2">"</span>
<span class="k">end</span>
<span class="mi">3</span><span class="o">.</span><span class="n">times</span> <span class="p">{</span> <span class="o">|</span><span class="n">n</span><span class="o">|</span> <span class="nb">puts</span> <span class="n">pluralize</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="s2">"trick"</span><span class="p">)</span> <span class="p">}</span>
<span class="c1"># >> 0 tricks</span>
<span class="c1"># >> 1 trick</span>
<span class="c1"># >> 2 tricks</span>
</pre></div>
<p>Obviously, this is a pretty dumb method compared to the similar functionality in <code>ActiveSupport</code> and other libraries, but check out that last interpolation. I dumped a full <code>unless</code> right in the <code>String</code>. If it triggers, it will evaluate to a simple <code>'s'</code>, which may be an unusual use of a conditional but is exactly what we need here. When it doesn't trigger, we know Ruby will punt with <code>nil</code> and <code>nil.to_s</code> is nothing, so it won't affect our output at all.</p>
<p>Like anything, you can take this technique too far. If you find yourself embedding entire programs in a <code>String</code> it's time to turn in your keyboard. However, if you find yourself slinging <code>to_s()</code> calls like they are going out of style, there's probably some cleanup you could try.</p>James Edward Gray IIWorking With Multiline Stringstag:graysoftinc.com,2008-10-02:/posts/562014-04-11T18:54:39ZRuby borrows and expands upon some interesting syntax from shell scripting languages.<p>I imagine most Rubyists are aware that Ruby has "heredocs," but do you really know all they can do? Let's find out.</p>
<p>A "here document" is a literal syntax for a multiline <code>String</code>. In the most basic form, they look like this:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">p</span> <span class="o"><<</span><span class="no">END_HEREDOC</span>
<span class="sh">This is a</span>
<span class="sh"> multiline,</span>
<span class="sh">as is String!</span>
<span class="no">END_HEREDOC</span>
<span class="c1"># >> "This is a\n multiline,\nas is String!\n"</span>
</pre></div>
<p>The <code><<NAME</code> syntax introduces the heredoc, but it actually begins at the start of the following line. It continues until <code>NAME</code> occurs again, at the beginning of a line. Note the trailing newline in the example above. All of the data between start and finish is packaged up into a <code>String</code> and dropped in where the original <code><<NAME</code> designator appeared.</p>
<p>There are some important details in that description, namely that the <code>String</code> begins on the next line and that it's inserted where the heredoc was started. This means that the rest of the line where the heredoc is started can have normal Ruby code (though your editor may syntax highlight it badly):</p>
<div class="highlight highlight-ruby"><pre><span class="nb">p</span> <span class="o"><<</span><span class="no">END_SQL</span><span class="o">.</span><span class="n">gsub</span><span class="p">(</span><span class="sr">/\s+/</span><span class="p">,</span> <span class="s2">" "</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span>
<span class="sh">SELECT * FROM users</span>
<span class="sh"> ORDER BY users.id DESC</span>
<span class="no">END_SQL</span>
<span class="c1"># >> "SELECT * FROM users ORDER BY users.id DESC"</span>
</pre></div>
<p>The spacing in the above example was to make it easier for a human to understand, but I use <code>gsub()</code> and <code>strip()</code> to normalize the actual String. You can do that since the heredoc doesn't begin until the next line.</p>
<p>Taking it one step further, the content of the rest of the line can include another heredoc. The second one will begin on the line after the first ends. This continues on down for however many you care to make:</p>
<div class="highlight highlight-ruby"><pre><span class="k">def</span> <span class="nf">send_messages</span><span class="p">(</span><span class="o">*</span><span class="n">messages</span><span class="p">)</span>
<span class="n">messages</span><span class="o">.</span><span class="n">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">m</span><span class="o">|</span> <span class="nb">p</span> <span class="n">m</span> <span class="p">}</span>
<span class="k">end</span>
<span class="n">send_messages</span><span class="p">(</span><span class="o"><<</span><span class="no">END_MESSAGE_ONE</span><span class="p">,</span> <span class="o"><<</span><span class="no">END_MESSAGE_TWO</span><span class="p">)</span>
<span class="sh">This is message one.</span>
<span class="sh">...</span>
<span class="no">END_MESSAGE_ONE</span>
<span class="sh">Another message.</span>
<span class="sh">....</span>
<span class="no">END_MESSAGE_TWO</span>
<span class="c1"># >> "This is message one.:\n\n...\n"</span>
<span class="c1"># >> "Another message.\n\n...\n"</span>
</pre></div>
<p>Another interesting thing to know about heredocs is that they are double-quoted <code>String</code>s by default. You can use any escapes allowed there as well as interpolation:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">p</span> <span class="o"><<</span><span class="no">DOUBLE_QUOTED</span>
<span class="sh">Tricks:</span>
<span class="sh">\tindented</span>
<span class="sh">\t#{100 + 23}</span>
<span class="no">DOUBLE_QUOTED</span>
<span class="c1"># >> "Tricks:\n\tindented\n\t123\n"</span>
</pre></div>
<p>However, if you would prefer single-quoted behavior, you can just surround the heredoc name with single quotes:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">p</span> <span class="o"><<</span><span class="sh">'</span><span class="no">SINGLE_QUOTED</span><span class="sh">'</span>
<span class="sh">Tricks:</span>
<span class="sh">\tindented</span>
<span class="sh">\t#{100 + 23}</span>
<span class="no">SINGLE_QUOTED</span>
<span class="c1"># >> "Tricks:\n\\tindented\n\\t\#{100 + 23}\n"</span>
</pre></div>
<p>There's one more trick with regard to heredoc syntax. If you begin with <code><<-NAME</code>, the end marker can be indented on the line it appears on. This is mostly useful when you want to inline some code, for example:</p>
<div class="highlight highlight-ruby"><pre><span class="k">module</span> <span class="nn">HateMacro</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">generate_hate</span><span class="p">(</span><span class="n">target</span><span class="p">)</span>
<span class="nb">module_eval</span> <span class="o"><<-</span><span class="no">END_RUBY</span>
<span class="sh"> def self.hate_#{target}</span>
<span class="sh"> puts "#{target.to_s.capitalize} sucks!"</span>
<span class="sh"> end</span>
<span class="no"> END_RUBY</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">HateMacro</span><span class="o">.</span><span class="n">generate_hate</span><span class="p">(</span><span class="ss">:emacs</span><span class="p">)</span> <span class="c1"># Just for Jim Weirich!</span>
<span class="no">HateMacro</span><span class="o">.</span><span class="n">hate_emacs</span>
<span class="c1"># >> Emacs sucks!</span>
</pre></div>
<p>That <code>String</code> of code will have a bunch of whitespace at the beginning of each line. The space before the end marker is not counted though. This doesn't affect the code of course, but you need to keep it in mind for other content.</p>
<p>A final point of interest that may be of value to TextMate users: TextMate will properly syntax highlight the contents of <code><<-SQL</code>, <code><<-HTML</code>, and <code><<-CODE_FOR_EVAL</code> (as Ruby) heredocs. You do need to use the indented form though even if you don't indent the content.</p>
<p>Hopefully all of this gives you some new ideas for ways you might handle multiline <code>String</code>s with Ruby. You don't need heredocs everywhere, but they can clean things up with the right usage.</p>James Edward Gray II