<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Gray Soft / Tags / Hidden Features</title>
  <id>tag:graysoftinc.com,2014-03-20:/tags/Hidden%20Features</id>
  <updated>2015-05-23T05:18:20Z</updated>
  <link rel="self" href="http://graysoftinc.com/tags/Hidden%20Features/feed.xml"/>
  <link rel="alternate" href="http://graysoftinc.com/tags/Hidden%20Features"/>
  <link rel="first" href="http://graysoftinc.com/tags/Hidden%20Features/feed.xml?page=1"/>
  <link rel="last" href="http://graysoftinc.com/tags/Hidden%20Features/feed.xml?page=2"/>
  <link rel="next" href="http://graysoftinc.com/tags/Hidden%20Features/feed.xml?page=2"/>
  <author>
    <name>James Edward Gray II</name>
  </author>
  <entry>
    <title>Rich Methods</title>
    <link rel="alternate" href="http://graysoftinc.com/ruby-voodoo/rich-methods"/>
    <id>tag:graysoftinc.com,2015-05-23:/posts/140</id>
    <updated>2015-05-23T05:18:20Z</updated>
    <summary>A quick look into the half hidden extras of some common Ruby methods.</summary>
    <content type="html">&lt;p&gt;Some APIs provide collections of dirt simple methods that just do one little thing.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Let's look at some examples of what I am talking about.&lt;/p&gt;

&lt;h4&gt;Get a &lt;em&gt;Line&lt;/em&gt; at a Time&lt;/h4&gt;

&lt;p&gt;I suspect most Rubyists have used &lt;code&gt;gets()&lt;/code&gt; to read lines of input from some kind of &lt;code&gt;IO&lt;/code&gt;.  Here's the basic usage:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"stringio"&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;StringIO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;END_STR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="sh"&gt;&amp;lt;xml&amp;gt;&lt;/span&gt;
&lt;span class="sh"&gt;  &amp;lt;tags&amp;gt;Content&amp;lt;/tags&amp;gt;&lt;/span&gt;
&lt;span class="sh"&gt;&amp;lt;/xml&amp;gt;&lt;/span&gt;
&lt;span class="no"&gt;END_STR&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;#&amp;lt;StringIO:0x007fd5a264fa08&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gets&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;xml&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gets&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"  &amp;lt;tags&amp;gt;Content&amp;lt;/tags&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I didn't want to mess with external files for these trivial examples, so I just loaded &lt;code&gt;StringIO&lt;/code&gt; from the standard library.  It allows us to wrap a simple &lt;code&gt;String&lt;/code&gt; (defined in this example using &lt;a href="http://graysoftinc.com/ruby-voodoo/working-with-multiline-strings"&gt;the &lt;em&gt;heredoc&lt;/em&gt; syntax&lt;/a&gt;) in the &lt;code&gt;IO&lt;/code&gt; interface.  In other words, I'm calling &lt;code&gt;gets()&lt;/code&gt; here for a &lt;code&gt;String&lt;/code&gt; just as I could with a &lt;code&gt;File&lt;/code&gt; or &lt;code&gt;$stdin&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As the last two calls show, &lt;code&gt;gets()&lt;/code&gt; reads until it finds a &lt;code&gt;"\n"&lt;/code&gt; and then returns the content read.  Actually, that's what it does by default, but you can tell &lt;code&gt;gets()&lt;/code&gt; what character to read to, if you prefer:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rewind&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;xml&amp;gt;"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;  &amp;lt;tags&amp;gt;"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Content&amp;lt;/tags&amp;gt;"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;As you can see above, one tiny change to the &lt;code&gt;gets()&lt;/code&gt; call, specifying the character to read to as the tag ending &lt;code&gt;"&amp;gt;"&lt;/code&gt;, can make this happen.&lt;/p&gt;

&lt;p&gt;"But wait, there's more!"&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;StringIO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"One&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;Two&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;Three"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;#&amp;lt;StringIO:0x007fd5a260efa8&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"One&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Two&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The empty &lt;code&gt;String&lt;/code&gt; (&lt;code&gt;""&lt;/code&gt;) is a magic value for the character to read to, since it makes no sense as that value.  This turns on &lt;em&gt;paragraph mode&lt;/em&gt; 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).&lt;/p&gt;

&lt;p&gt;These aren't even all the features of &lt;code&gt;gets()&lt;/code&gt;.  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 &lt;code&gt;String&lt;/code&gt; objects.&lt;/p&gt;

&lt;p&gt;Let's look at another method.&lt;/p&gt;

&lt;h4&gt;
&lt;code&gt;Hash&lt;/code&gt; Merging&lt;/h4&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;To show what I mean, let's play with good old &lt;code&gt;merge()&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;d&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:a&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:b&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:c&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:d&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Most Rubyists run into examples like this pretty early in their studies.  The code just returns a fresh &lt;code&gt;Hash&lt;/code&gt; containing the keys and values of both the receiver and the &lt;code&gt;Hash&lt;/code&gt; passed as an argument to &lt;code&gt;merge()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;How are ties handled?&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="ss"&gt;:two&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:a&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:b&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;:two&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:c&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;Hash&lt;/code&gt; passed as an argument to &lt;code&gt;merge()&lt;/code&gt; wins.  Again, I doubt this is much of a surprise to anyone.&lt;/p&gt;

&lt;p&gt;However, I don't think everyone knows that you can take control of this merging process.  During a &lt;code&gt;merge()&lt;/code&gt; any conflict will be passed to a block, if provided, and the block can return what to store in the new &lt;code&gt;Hash&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="ss"&gt;:two&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;old&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;new&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;old&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;new&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:a&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:b&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:two&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:c&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;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 &lt;code&gt;merge()&lt;/code&gt; takes a block.&lt;/p&gt;

&lt;p&gt;Can you guess &lt;a href="https://github.com/rails/rails/blob/42e66fac38b54dd53d062fb5d3376218ed2ffdae/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb#L17-L20"&gt;how &lt;code&gt;ActiveSupport&lt;/code&gt; implements &lt;code&gt;reverse_merge!()&lt;/code&gt;&lt;/a&gt; now?&lt;/p&gt;

&lt;h4&gt;Easy Tokenizing&lt;/h4&gt;

&lt;p&gt;Let's do one last method with a rich interface (even though Ruby has many more):&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"1,2,3"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;","&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"3"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is another very common method.  It turns a &lt;code&gt;String&lt;/code&gt; into an &lt;code&gt;Array&lt;/code&gt; by dividing up the contents everywhere the passed separator is encountered.  I used a &lt;code&gt;String&lt;/code&gt; separator above but a &lt;code&gt;Regexp&lt;/code&gt; is also allowed:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"1, 2, 3"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\s*,\s*/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"3"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This makes it easier to handle complex separators.  For example, the &lt;code&gt;Regexp&lt;/code&gt; above permits optional whitespace characters on either side of the comma.&lt;/p&gt;

&lt;p&gt;But a &lt;code&gt;Regexp&lt;/code&gt; can include capture groups.  How are they handled?&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"1, 2, 3"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\s*(,)\s*/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;","&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;","&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"3"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Easy enough:  the captured value(s) are returned with the separated contents.&lt;/p&gt;

&lt;p&gt;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 &lt;code&gt;split()&lt;/code&gt; can make dividing some input into tokens pretty darn easy:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;xml&amp;gt;&amp;lt;tags&amp;gt;Content&amp;lt;/tags&amp;gt;&amp;lt;/xml&amp;gt;"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/(&amp;lt;[^&amp;gt;]+&amp;gt;)/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;xml&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;tags&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Content"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;/tags&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;/xml&amp;gt;"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can use this one feature as a backbone for a moderately complex parser.  &lt;a href="https://github.com/soveran/mote/blob/b43b3879076dade130aac8c34b76cb06caf26e35/lib/mote.rb#L23-L26"&gt;&lt;em&gt;Mote&lt;/em&gt; does&lt;/a&gt; just that.&lt;/p&gt;

&lt;p&gt;I made &lt;a href="https://codalyzed.com/videos/lesscode"&gt;a video explaining how this parsing trick (and more) are accomplished&lt;/a&gt; in detail.  You can use the coupon &lt;code&gt;BLOGREADER&lt;/code&gt; for $3 off if you want to check it out.&lt;/p&gt;</content>
    <author>
      <name>James Edward Gray II</name>
    </author>
  </entry>
  <entry>
    <title>Random Access Terminal</title>
    <link rel="alternate" href="http://graysoftinc.com/terminal-tricks/random-access-terminal"/>
    <id>tag:graysoftinc.com,2015-01-30:/posts/136</id>
    <updated>2017-07-18T21:40:47Z</updated>
    <summary>A look at the special codes your terminal understands, its modes of operation, and how we can use those details to do fancy I/O.</summary>
    <content type="html">&lt;p&gt;I've recently been playing around with fancy terminal output in Ruby.  I've learned quite a bit about this arcane magic.  I've also realized that the documentation is pretty spotty.  I want to see if I can improve that with a few blog posts, so let's dive right in.&lt;/p&gt;

&lt;h4&gt;Output&lt;/h4&gt;

&lt;p&gt;Program output typically happens in a linear order from top to bottom.  For example, this code:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"onez"&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"twos"&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"threes"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;generates this output:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;onez
twos
threes
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But what if you need to change some output?  Could you replace the &lt;code&gt;z&lt;/code&gt; above with an &lt;code&gt;s&lt;/code&gt; if you needed to?  Yes, but it can get a little involved.&lt;/p&gt;

&lt;h5&gt;ANSI Escape Codes&lt;/h5&gt;

&lt;p&gt;In many cases, we just push some characters to &lt;code&gt;$stdout&lt;/code&gt; (the stream &lt;code&gt;Kernel#puts&lt;/code&gt; is writing to above) and your terminal program happily shows them to the user.  However, your terminal is watching these characters for &lt;a href="http://en.wikipedia.org/wiki/ANSI_escape_code"&gt;special sequences&lt;/a&gt; that it understands.  Some of those sequences of characters can cause your terminal to take actions other than just writing some output to the screen.&lt;/p&gt;

&lt;p&gt;For example, there are sequences that move the cursor (the point where output is written) to different locations.  Using those special codes, we could change the &lt;code&gt;z&lt;/code&gt; in our example:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="no"&gt;CSI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\e&lt;/span&gt;&lt;span class="s2"&gt;["&lt;/span&gt;

&lt;span class="vg"&gt;$stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"onez"&lt;/span&gt;
&lt;span class="vg"&gt;$stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"twos"&lt;/span&gt;
&lt;span class="vg"&gt;$stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"threes"&lt;/span&gt;

&lt;span class="vg"&gt;$stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;CSI&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;3A"&lt;/span&gt;  &lt;span class="c1"&gt;# move up three lines&lt;/span&gt;
&lt;span class="vg"&gt;$stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;CSI&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;3C"&lt;/span&gt;  &lt;span class="c1"&gt;# move right three characters&lt;/span&gt;

&lt;span class="vg"&gt;$stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="s2"&gt;"s"&lt;/span&gt;         &lt;span class="c1"&gt;# overwrite the 'z'&lt;/span&gt;

&lt;span class="vg"&gt;$stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;CSI&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;3B"&lt;/span&gt;  &lt;span class="c1"&gt;# move down three lines (after our output)&lt;/span&gt;
&lt;span class="vg"&gt;$stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;CSI&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;4D"&lt;/span&gt;  &lt;span class="c1"&gt;# move back four characters (to the start of the line)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you run that code, it will initially produce the output from the previous example.  It will then move the cursor to the &lt;code&gt;z&lt;/code&gt;, overwrite it with an &lt;code&gt;s&lt;/code&gt;, and return the cursor to where it was.  This likely happens too fast for you to see the change, but you can insert &lt;code&gt;sleep()&lt;/code&gt; calls if you want to watch it work.&lt;/p&gt;

&lt;p&gt;All of the escapes used in this example are commands used to move the cursor around by a specific number of lines or characters in an indicated direction.  Note that I switched to using the &lt;code&gt;write()&lt;/code&gt; method when I started using escapes.  &lt;code&gt;puts()&lt;/code&gt; would have printed my escape followed by a newline (moving me away from where I wanted to be).&lt;/p&gt;

&lt;p&gt;I used relative positioning commands above, meaning that I moved from where I knew the cursor was to where I wanted it be.  I couldn't move to some absolute coordinates, because I don't know what else is on your screen when the program is run.  You probably have at least a command prompt above the output and I have no idea how big that is.  Now, if I clear the screen before I generate output, I could go on to treat it like a known grid of coordinates:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="no"&gt;CSI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\e&lt;/span&gt;&lt;span class="s2"&gt;["&lt;/span&gt;

&lt;span class="vg"&gt;$stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;CSI&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;2J"&lt;/span&gt;    &lt;span class="c1"&gt;# clear screen&lt;/span&gt;
&lt;span class="vg"&gt;$stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;CSI&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;1;1H"&lt;/span&gt;  &lt;span class="c1"&gt;# move to top left corner&lt;/span&gt;

&lt;span class="vg"&gt;$stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"onez"&lt;/span&gt;
&lt;span class="vg"&gt;$stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"twos"&lt;/span&gt;
&lt;span class="vg"&gt;$stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"threes"&lt;/span&gt;

&lt;span class="vg"&gt;$stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;CSI&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;s"&lt;/span&gt;     &lt;span class="c1"&gt;# save cursor position&lt;/span&gt;

&lt;span class="vg"&gt;$stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;CSI&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;1;4H"&lt;/span&gt;  &lt;span class="c1"&gt;# move to line 1, character 4&lt;/span&gt;
&lt;span class="vg"&gt;$stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="s2"&gt;"s"&lt;/span&gt;           &lt;span class="c1"&gt;# overwrite the 'z'&lt;/span&gt;

&lt;span class="vg"&gt;$stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;CSI&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;u"&lt;/span&gt;     &lt;span class="c1"&gt;# restore cursor position&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is the same trick, but using absolute positioning and some other fancy codes to &lt;em&gt;save&lt;/em&gt; and &lt;em&gt;restore&lt;/em&gt; the cursor's position.  The movement escape used here, &lt;code&gt;CSIy;xH&lt;/code&gt;, allows us to jump directly to any position on the screen.  The top left corner is &lt;code&gt;1;1&lt;/code&gt; with &lt;code&gt;y&lt;/code&gt; counting lines down and &lt;code&gt;x&lt;/code&gt; counting characters to the right.&lt;/p&gt;

&lt;p&gt;Clearing the screen can be a little tricky.  First, you can clear part or all of it.  I chose all here with the &lt;code&gt;2&lt;/code&gt; in &lt;code&gt;CSI2J&lt;/code&gt;.  You also need to remember though that clearing the screen doesn't usually change the position of the cursor.  That's why I sent it back to the top left corner after the clear.&lt;/p&gt;

&lt;p&gt;This code was pretty eye opening to me.  It helped me to realize that a terminal doesn't have to be treated as a sequence of lines.  It can alternately be treated like a drawing canvas with coordinates used to represent each spot that a character can be placed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WARNING&lt;/strong&gt;:  terminals vary in exactly which codes they support.  Most of the examples I'm showing will probably work on most UNIX-like terminals.  I've tested them on my own UNIX box, but even there I found minor differences.  For example, the code above works as expected in my normal terminal, but the terminal emulation mode I often use in Emacs doesn't seem to honor the save and restore cursor codes.  It can be quite a bit of work to properly support the various kinds of terminals you can encounter.&lt;/p&gt;

&lt;h6&gt;Colors&lt;/h6&gt;

&lt;p&gt;It probably goes without saying that there are codes to change the color of your output and do other fancy graphic tricks.  These can get slightly complex because they require a little math to indicate choice of foreground or background colors.  They can also involve multiple codes at once when you want to select the &lt;em&gt;bright&lt;/em&gt; version of a color.  Here's a pretty trivial example:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="no"&gt;CSI&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\e&lt;/span&gt;&lt;span class="s2"&gt;["&lt;/span&gt;
&lt;span class="no"&gt;COLORS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="ss"&gt;black&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;red&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;green&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;yellow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;magenta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;cyan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;white&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="mi"&gt;7&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;foreground&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;colored&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;color_name_to_escape_code&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;foreground&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;colored&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;color_name_to_escape_code&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;background&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;background&lt;/span&gt;
  &lt;span class="n"&gt;colored&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;
  &lt;span class="n"&gt;colored&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;CSI&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;0m"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;color_name_to_escape_code&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;short_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\Abright_/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;color&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;COLORS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;short_name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_sym&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;escape&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;CSI&lt;/span&gt;&lt;span class="si"&gt;}#{&lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="n"&gt;escape&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;";1"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;short_name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;
  &lt;span class="n"&gt;escape&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"m"&lt;/span&gt;
  &lt;span class="n"&gt;escape&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"C"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:red&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"O"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:bright_red&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"L"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:bright_yellow&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"O"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:bright_green&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"R"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:bright_blue&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"S"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:blue&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:bright_magenta&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;char&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="vg"&gt;$stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;char&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:white&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="vg"&gt;$stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you run that, you should see not-quite-a-rainbow of colored letters on white, regardless of the default color settings in your terminal.&lt;/p&gt;

&lt;p&gt;It's pretty important to remember to issue a reset code (&lt;code&gt;CSI0m&lt;/code&gt;) after playing with graphic settings like this.  If your program exits without doing so, the terminal could be left in some pretty garish states.  You can see that my &lt;code&gt;color()&lt;/code&gt; method sets some colors, writes the desired content, then immediately resets.  This process minimizes the chances of me bleeding over graphics changes into other output.&lt;/p&gt;

&lt;p&gt;Visit that link I gave earlier on &lt;a href="http://en.wikipedia.org/wiki/ANSI_escape_code"&gt;ANSI escape codes&lt;/a&gt; for specifics about any of the sequences I've used here, a good description of what the &lt;code&gt;CSI&lt;/code&gt; is, and more.&lt;/p&gt;

&lt;h5&gt;The Status Line Trick&lt;/h5&gt;

&lt;p&gt;While ANSI codes allow you to do pretty much any output trick you can dream up with enough effort, there's another trick that just so easy it's worth knowing for the times when it can save you some work.&lt;/p&gt;

&lt;p&gt;We usually end lines of output with a newline character (&lt;code&gt;\n&lt;/code&gt;).  &lt;code&gt;Kernel#puts&lt;/code&gt; does this for us automatically.  The exact effect of that character depends on the mode your terminal is currently in.  We'll cover that more below, but there's another way to end lines.  You could use the carriage return (&lt;code&gt;\r&lt;/code&gt;) character.  (In truth, using both characters is also an option.  Again, I'll go into that below.)&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;\r&lt;/code&gt; does move the cursor back to the beginning of the line, but it does not advance to the next line.  This gives you a simple way to overwrite the content you previously placed on the last line only.  That can come in handy for updating a status line or progress bar.&lt;/p&gt;

&lt;p&gt;Here's a contrived example that just shows progress while it pretends to do some work:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="n"&gt;chunks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="vg"&gt;$stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Time left:"&lt;/span&gt;
&lt;span class="kp"&gt;loop&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="vg"&gt;$stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="s2"&gt;"|&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="s1"&gt;'#'&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="si"&gt;}#{&lt;/span&gt;&lt;span class="s1"&gt;' '&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;|&lt;/span&gt;&lt;span class="se"&gt;\r&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;chunks&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
    &lt;span class="vg"&gt;$stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;next_chunk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="n"&gt;next_chunk&lt;/span&gt;
  &lt;span class="n"&gt;chunks&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;next_chunk&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Sample output from partway through a run looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Time left:
|#####     |
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You may need to run it to appreciate the result, but the last line just keeps updating with the bar of &lt;code&gt;#&lt;/code&gt;'s, growing each time.  Notice that there is a final &lt;code&gt;puts()&lt;/code&gt; when we exit the &lt;code&gt;loop()&lt;/code&gt;, so the new command prompt won't erase the progress bar.  You may or may not wish to do that in your own programs.&lt;/p&gt;

&lt;h4&gt;Input&lt;/h4&gt;

&lt;p&gt;I'll be honest and admit that I covered output first because it's easier.  Buckle up and we'll see if can survive the jump into input.&lt;/p&gt;

&lt;p&gt;I've mentioned before that &lt;a href="http://graysoftinc.com/my-projects/i-just-want-one-character"&gt;programmers often ask how to read a single character from the keyboard&lt;/a&gt; and it can get tricky.  This time I'm going to try to explain what's really going on without hiding behind a library that simplifies the process.  I'll also show you some fancy new ways to accomplish the task.&lt;/p&gt;

&lt;h5&gt;Terminal Modes&lt;/h5&gt;

&lt;p&gt;Your terminal can operate in &lt;a href="http://en.wikipedia.org/wiki/POSIX_terminal_interface#History"&gt;a variety of modes&lt;/a&gt;.  The default &lt;em&gt;cooked mode&lt;/em&gt; has several effects.  One of those effects is that input is buffered until you press the return key.  This buffering allows you to edit content you are entering—using arrow keys, backspace/delete keys, etc.—without all programs needing to handle all of those special cases.  That's a great feature, right up to the point where you just want to read one character.&lt;/p&gt;

&lt;p&gt;Watch what happens when I try:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="kp"&gt;loop&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vg"&gt;$stdin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getc&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"You typed:  &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;char&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inspect&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;?q&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here's some output from a run of that program:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;a
You typed:  "a"
You typed:  "\n"
q
You typed:  "q"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What you need to catch here is that I pushed an &lt;code&gt;a&lt;/code&gt;, but my program wouldn't acknowledge it, until I pressed return too.  Then it read both characters.  The &lt;code&gt;q&lt;/code&gt; was treated the same way, the program just ended before showing the second newline.&lt;/p&gt;

&lt;p&gt;If we really want to do this right, we've got to get out of cooked mode (or at least disable its line buffering feature).  In older Ruby code, you had three choices for doing this:  shell out to &lt;code&gt;stty&lt;/code&gt; (tricky to get right), make very arcane C-style calls to &lt;code&gt;ioctl()&lt;/code&gt; (a nightmare), or use a gem that hid the details from you (your best bet, by far).  Now you understand &lt;a href="http://graysoftinc.com/my-projects/i-just-want-one-character"&gt;my old advice&lt;/a&gt; to just use &lt;code&gt;HighLine&lt;/code&gt;.  But I have good news!  Ruby is older and wiser now.&lt;/p&gt;

&lt;h6&gt;A New Standard Library&lt;/h6&gt;

&lt;p&gt;The easiest approach to reading just one character is to switch into &lt;em&gt;raw mode&lt;/em&gt; (or a similar mode) and try again.  However, this change will affect your program's output as well due to other features of cooked mode.  Given that, your best bet is to jump into raw mode, grab a character, and return to cooked mode immediately.&lt;/p&gt;

&lt;p&gt;Ruby now ships with a standard library that will do exactly that:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"io/console"&lt;/span&gt;

&lt;span class="kp"&gt;loop&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vg"&gt;$stdin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getch&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"You typed:  &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;char&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inspect&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;?q&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Behold the magic:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;You typed:  "a"
You typed:  "q"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There are no newlines this time because the computer is now responding the instant I press a key.  Victory.  Sort of.&lt;/p&gt;

&lt;p&gt;Even this tiny dip of our toes into raw mode has changed other things.  You don't see what I typed &lt;em&gt;echoed&lt;/em&gt; before the program provides its own output as it was before.  This is another feature of cooked mode and you'll need to do your own echoing when reading like this, if you need it.&lt;/p&gt;

&lt;p&gt;Here's another change that happens when I push control-C:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;You typed:  "\u0003"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see, it no longer interrupts my process.  In fact, all of the control sequences have lost their magic powers (control-D to close &lt;code&gt;$stdin&lt;/code&gt; and control-Z to suspend the program, for example).  You will now need to handle these keystrokes yourself if you want them to have some effect.  (Please do support control-C at the very least!)&lt;/p&gt;

&lt;p&gt;Terminals have another mode that helps with this control keystroke issue, called &lt;em&gt;cbreak mode&lt;/em&gt;.  It gives you a near raw mode experience, but with these low-level keystrokes still handled.  It makes me very sad to report that &lt;code&gt;io/console&lt;/code&gt; doesn't yet support this handy mode.&lt;/p&gt;

&lt;p&gt;Still, &lt;code&gt;io/console&lt;/code&gt; is great to have.  You can read about what it can do in &lt;a href="http://www.ruby-doc.org/stdlib-2.2.0/libdoc/io/console/rdoc/IO.html"&gt;the API documentation&lt;/a&gt; and &lt;a href="https://github.com/nobu/io-console"&gt;its README&lt;/a&gt;.  Here's one more simple example of how easy &lt;code&gt;io/console&lt;/code&gt; can make things, like finding the screen size:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"io/console"&lt;/span&gt;

&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cols&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vg"&gt;$stdout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;winsize&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Columns:  &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;cols&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, Rows:  &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h6&gt;Full Raw Mode&lt;/h6&gt;

&lt;p&gt;Dipping into raw mode to grab characters is great when it works for your needs, but the code I've showed so far has a drawback.  &lt;code&gt;io/console&lt;/code&gt;'s &lt;code&gt;getch()&lt;/code&gt; is a blocking method.  It will wait for input.  This is a problem if you need to manage your own event loop, take user input when it's available, but continue making things happen when it's not.&lt;/p&gt;

&lt;p&gt;If there's a way to solve this problem with just &lt;code&gt;io/console&lt;/code&gt;, I haven't been able to derive the proper incantation.  However, we can pull it off by pulling one more standard library into the mix.&lt;/p&gt;

&lt;p&gt;To show how this works, imagine that we want to prompt a user with what to do if they don't take any action for a few seconds.  Here's some code:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"io/console"&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"io/wait"&lt;/span&gt;

&lt;span class="vg"&gt;$stdin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;last_read&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;
  &lt;span class="n"&gt;prompted&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
  &lt;span class="kp"&gt;loop&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ready?&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sysread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;char&lt;/span&gt;
      &lt;span class="n"&gt;last_read&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;
      &lt;span class="n"&gt;prompted&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"You typed:  &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;char&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inspect&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;?q&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;prompted&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;last_read&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
        &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Please type a character."&lt;/span&gt;
        &lt;span class="n"&gt;prompted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This time I used &lt;code&gt;io/console&lt;/code&gt; to put the whole program into raw mode.  Cooked mode is restored when the block passed to &lt;code&gt;raw()&lt;/code&gt; exits.&lt;/p&gt;

&lt;p&gt;The other library I used is &lt;code&gt;io/wait&lt;/code&gt;.  It adds a &lt;code&gt;ready?()&lt;/code&gt; method to &lt;code&gt;$stdin&lt;/code&gt; that will return &lt;code&gt;true&lt;/code&gt; when there's content waiting to be read.  I pull that content out a byte at a time using the low-level &lt;code&gt;sysread()&lt;/code&gt; to avoid any buffering.&lt;/p&gt;

&lt;p&gt;This kind of works, but we've picked up a new issue:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Please type a character.
                        You typed:  "a"
                                       You typed:  "q"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;See how my output is now staggered?&lt;/p&gt;

&lt;p&gt;Yet another feature of cooked mode is that newlines in your program's output are translated to a carriage return newline sequence (&lt;code&gt;\r\n&lt;/code&gt;).  Rubyists are used to &lt;code&gt;puts()&lt;/code&gt;ing out some content, with a newline added, and seeing the cursor move to the beginning of the next line.  But a newline doesn't really do that by itself.&lt;/p&gt;

&lt;p&gt;The newline character means move down a line.  As we saw earlier, a carriage return sends you to the beginning of the current line.  So it's really the combined effect of both that we're used to being normal.&lt;/p&gt;

&lt;p&gt;My output above has only the newline effect, because we're in raw mode and the translation to a two character sequence isn't active.  That explains the problem and gives us a way around it.  In raw mode, you'll need to manually end lines with &lt;code&gt;\r\n&lt;/code&gt; when you want to move to the beginning of the next line.&lt;/p&gt;

&lt;p&gt;Here's a fixed version of the code above:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"io/console"&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"io/wait"&lt;/span&gt;

&lt;span class="vg"&gt;$stdin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;last_read&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;
  &lt;span class="n"&gt;prompted&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
  &lt;span class="kp"&gt;loop&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ready?&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sysread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;char&lt;/span&gt;
      &lt;span class="n"&gt;last_read&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;
      &lt;span class="n"&gt;prompted&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"You typed:  &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;char&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inspect&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;  &lt;span class="c1"&gt;# added \r\n&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;?q&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;prompted&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;last_read&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
        &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Please type a character.&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;   &lt;span class="c1"&gt;# added \r\n&lt;/span&gt;
        &lt;span class="n"&gt;prompted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The comments show the two minor changes to the code.&lt;/p&gt;

&lt;p&gt;And now the output looks more typical:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Please type a character.
You typed:  "a"
You typed:  "q"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We've handled a lot of cases, but there are still issues with a raw approach like this.  I'll show you one more.  Watch what happens when I press an arrow key while running our latest program:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;You typed:  "\e"
You typed:  "["
You typed:  "A"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ugh.  That's all one keystroke, but we pulled it out as separate bytes.  This means we wouldn't be able to have conditionals in our program check for this keypress.&lt;/p&gt;

&lt;p&gt;Can we fix it?  Sure.  We can add some more code to detect these escape sequences and combine them into a single &lt;code&gt;String&lt;/code&gt;.  Here's what that might look like:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"io/console"&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"io/wait"&lt;/span&gt;

&lt;span class="no"&gt;CSI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\e&lt;/span&gt;&lt;span class="s2"&gt;["&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_char_or_sequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ready?&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sysread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="no"&gt;CSI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_with?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                        &lt;span class="o"&gt;||&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_with?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;CSI&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                      &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
              &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;codepoints&lt;/span&gt;&lt;span class="o"&gt;[-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;between?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;126&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
          &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;next_char&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_char_or_sequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;next_char&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="vg"&gt;$stdin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;last_read&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;
  &lt;span class="n"&gt;prompted&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
  &lt;span class="kp"&gt;loop&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_char_or_sequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;char&lt;/span&gt;
      &lt;span class="n"&gt;last_read&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;
      &lt;span class="n"&gt;prompted&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"You typed:  &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;char&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inspect&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sc"&gt;?q&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;prompted&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;last_read&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
        &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Please type a character.&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;prompted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;All of the new code here is in the &lt;code&gt;get_char_or_sequence()&lt;/code&gt; method.  The &lt;code&gt;while&lt;/code&gt; loop in there checks to see if a read character looks like the start of a &lt;code&gt;CSI&lt;/code&gt; sequence and keeps reading, assuming there's more input, until we've seen the full &lt;code&gt;CSI&lt;/code&gt;.  Then, if what we've read starts with a &lt;code&gt;CSI&lt;/code&gt; and there's still more input, we keep reading until we see a termination character for the sequence.&lt;/p&gt;

&lt;p&gt;The end result?  We can now treat arrow keys as a single unit (as long as our terminal returns them as ANSI escape sequences with a leading &lt;code&gt;CSI&lt;/code&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;You typed:  "\e[A"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That's progress.  There's definitely more we could handle though, like non-&lt;code&gt;CSI&lt;/code&gt; escape sequences and larger Unicode characters.  This rabbit hole goes pretty deep.  You'll need to decide how many such cases you need to handle for your programs needs.&lt;/p&gt;

&lt;p&gt;If you have to deal with many of the various topics covered by this post, you may want to consider using a gem that can handle some of them for you.  They can really smooth over some of these edge cases.  The details of that are another blog post, but my hope is that this article starts to at least get you familiar with what's involved in fancy terminal I/O.&lt;/p&gt;</content>
    <author>
      <name>James Edward Gray II</name>
    </author>
  </entry>
  <entry>
    <title>The Three Tick Sort</title>
    <link rel="alternate" href="http://graysoftinc.com/ruby-voodoo/the-three-tick-sort"/>
    <id>tag:graysoftinc.com,2014-10-24:/posts/133</id>
    <updated>2014-11-11T19:21:30Z</updated>
    <summary>You 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.</summary>
    <content type="html">&lt;p&gt;Yesterday I showed a newer programmer some code like &lt;code&gt;scores.sort_by(&amp;amp;:reverse)&lt;/code&gt;.  This provoked a comment about how they where going to look up &lt;code&gt;sort_by()&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;Allow me to enumerate those tricks for you, but first let's flesh out an example.  Consider this code:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="n"&gt;scores&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="ss"&gt;fifteen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;five_card_run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;five_card_flush&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;four_card_run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;four_card_flush&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;his_nobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;        &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;pair&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;            &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;three_card_run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sort_by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:reverse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Score &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; for &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;."&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; Score 1 for his_nobs.&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; Score 2 for fifteen.&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; Score 2 for pair.&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; Score 3 for three_card_run.&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; Score 4 for four_card_flush.&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; Score 4 for four_card_run.&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; Score 5 for five_card_flush.&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; Score 5 for five_card_run.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In this case, the magic method call (&lt;code&gt;scores.sort_by(&amp;amp;:reverse)&lt;/code&gt;) 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.&lt;/p&gt;

&lt;p&gt;Let's take it a piece at a time.&lt;/p&gt;

&lt;p&gt;First you need to know that &lt;code&gt;Hash#each&lt;/code&gt; iterates over &lt;em&gt;pairs&lt;/em&gt;.  (All other iterators, like &lt;code&gt;sort_by()&lt;/code&gt;, use &lt;code&gt;each()&lt;/code&gt; under the hood, remember.)  A pair is a two element &lt;code&gt;Array&lt;/code&gt; containing key then value.  If your block takes one argument, you'll get this pair &lt;code&gt;Array&lt;/code&gt;.  If it takes more, Ruby will extract the values out of the &lt;code&gt;Array&lt;/code&gt; due to its "multiple assignment" rules.  In other words, you can do this:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;or this:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;pair&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This means I could have used &lt;code&gt;sort_by { |key, value| [value, key] }&lt;/code&gt;, but I used the &lt;code&gt;Array&lt;/code&gt; interface instead:  &lt;code&gt;sort_by { |pair| pair.reverse }&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That leads us to the second part of this magic trick:  you can &lt;code&gt;sort_by()&lt;/code&gt; an &lt;code&gt;Array&lt;/code&gt;?  Yes, you can.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sort_by()&lt;/code&gt; works with any object that defines the spaceship operator (&lt;code&gt;&amp;lt;=&amp;gt;&lt;/code&gt;), which &lt;code&gt;Array&lt;/code&gt; does:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you probably work out from the code above, &lt;code&gt;Array&lt;/code&gt; objects compare themselves based on their contents.  Later elements are used to break ties from earlier comparisons:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;By calling &lt;code&gt;reverse()&lt;/code&gt; on the pairs in the sorting &lt;code&gt;Array&lt;/code&gt;, I put the score into the primary sorting role and used the hand name as a tie breaker.&lt;/p&gt;

&lt;p&gt;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!&lt;/p&gt;

&lt;p&gt;When you have a block of the form &lt;code&gt;method { |object| object.thing_i_care_about }&lt;/code&gt; you can rewrite it as &lt;code&gt;method(&amp;amp;:thing_i_care_about)&lt;/code&gt;.  Again we need to break this trick down into pieces to understand it.&lt;/p&gt;

&lt;p&gt;First, &lt;code&gt;:thing_i_care_about&lt;/code&gt; is a &lt;code&gt;Symbol&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:thing_i_care_about&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:thing_i_care_about&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:thing_i_care_about&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Symbol&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Next, Ruby will try to convert the final argument to a method into a &lt;code&gt;Proc&lt;/code&gt; object, if it's proceeded by a &lt;code&gt;&amp;amp;&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;m&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:m&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="no"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="ss"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;wrong&lt;/span&gt; &lt;span class="n"&gt;argument&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="no"&gt;Object&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="no"&gt;Proc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;irb&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;
    &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="sr"&gt;/Users/&lt;/span&gt;&lt;span class="n"&gt;jeg2&lt;/span&gt;&lt;span class="o"&gt;/.&lt;/span&gt;&lt;span class="n"&gt;rubies&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ruby&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="ss"&gt;irb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="ss"&gt;:in&lt;/span&gt; &lt;span class="sb"&gt;`&amp;lt;main&amp;gt;'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then you have to know that any object can choose to play ball as a &lt;code&gt;Proc&lt;/code&gt; by defining a &lt;code&gt;to_proc()&lt;/code&gt; method:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;#&amp;lt;Object:0x007fc5841fb278&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;o&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_proc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;proc&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Howdy."&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:to_proc&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;#&amp;lt;Proc:0x007fc5841e6d28@(irb):8&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, you can probably guess that &lt;code&gt;Symbol&lt;/code&gt; defines &lt;code&gt;to_proc&lt;/code&gt;.  Watch what it does:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;symbol_to_proc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:to_s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_proc&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;#&amp;lt;Proc:0x007fc5841e2750&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;symbol_to_proc&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"42"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;symbol_to_proc&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"#&amp;lt;Object:0x007fc5841c1a50&amp;gt;"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;See how it just calls the method named after the &lt;code&gt;Symbol&lt;/code&gt;?  (It's essentially using &lt;code&gt;send()&lt;/code&gt; under the hood.)&lt;/p&gt;

&lt;p&gt;Combine all of those bits together and you can do some pretty fancy sorting with very little code.&lt;/p&gt;</content>
    <author>
      <name>James Edward Gray II</name>
    </author>
  </entry>
  <entry>
    <title>Delaying Decisions</title>
    <link rel="alternate" href="http://graysoftinc.com/rubies-in-the-rough/delaying-decisions"/>
    <id>tag:graysoftinc.com,2012-05-11:/posts/114</id>
    <updated>2014-04-29T03:29:32Z</updated>
    <summary>In this article I talk about the value of delaying programming decisions and look at some ways you can implement code to do that.</summary>
    <content type="html">&lt;p&gt;I love playing with Ruby's &lt;code&gt;Hash&lt;/code&gt;.  I think it has a neat API and experimenting with it can actually help you understand how to write good Ruby.  Let's dig into this idea to see what I mean.&lt;/p&gt;

&lt;h4&gt;The nil Problem&lt;/h4&gt;

&lt;p&gt;In &lt;a href="https://www.destroyallsoftware.com/screencasts/catalog/exceptions-and-control-flow"&gt;Destroy All Software #9&lt;/a&gt; Gary chooses to show an example in Python because, unlike Ruby's &lt;code&gt;Hash&lt;/code&gt;, it will raise an error for a non-existent key.  Ruby just returns &lt;code&gt;nil&lt;/code&gt;, he explains.&lt;/p&gt;

&lt;p&gt;What Gary said isn't really true, but I'm guessing he just didn't know that at the time.  He was in the process of switching to Ruby from Python and I'm guessing he just didn't have a deep enough understanding of Ruby's &lt;code&gt;Hash&lt;/code&gt; yet.  I bet he does know how it works now.&lt;/p&gt;

&lt;p&gt;But assume he was right.  What's he saying and why does it matter?  Consider some code like this:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SearchesController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show&lt;/span&gt;
    &lt;span class="n"&gt;terms&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:terms&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="no"&gt;SomeModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;terms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is what Gary doesn't like, and rightfully so.  Because I indexed into &lt;code&gt;params&lt;/code&gt; here with the &lt;code&gt;[]()&lt;/code&gt; method, I will indeed get a &lt;code&gt;nil&lt;/code&gt; if the &lt;code&gt;:terms&lt;/code&gt; key wasn't in &lt;code&gt;params&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The problem with &lt;code&gt;nil&lt;/code&gt; is that it's a ticking time bomb just waiting to go off.  It has a very limited interface by design, so calling methods on it may raise errors.  It's probably not the interface your code is expecting.  For example, in the code above I likely intended to get a &lt;code&gt;String&lt;/code&gt; in &lt;code&gt;terms&lt;/code&gt;, but if I got &lt;code&gt;nil&lt;/code&gt; instead and I later try to call &lt;code&gt;String&lt;/code&gt; methods on it, it's going to blow up.&lt;/p&gt;

&lt;p&gt;This gets worse because &lt;code&gt;nil&lt;/code&gt; values tend to bounce around in the code a bit.  This means the error may finally manifest far from the line where I actually assigned &lt;code&gt;terms&lt;/code&gt;, which is the real problem that needs fixing.  For example, let's say the model code I handed off to looks something like this:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SomeModel&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;terms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;terms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\S+/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is where the error would show up.  The call to &lt;code&gt;scan()&lt;/code&gt; would toss a &lt;code&gt;NoMethodError&lt;/code&gt; since &lt;code&gt;nil&lt;/code&gt; doesn't have &lt;code&gt;scan()&lt;/code&gt;.  The stack trace would lead us here, but, as I said before, this isn't what needs fixing.&lt;/p&gt;

&lt;p&gt;Now, we &lt;em&gt;could&lt;/em&gt; fix it here.  One way to do that would be to insert a conversion before the &lt;code&gt;scan()&lt;/code&gt; call:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;terms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\S+/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That's probably not a good idea though.  We've now said that calling &lt;code&gt;SomeModel.search(nil)&lt;/code&gt; is OK and that doesn't really make much sense.&lt;/p&gt;

&lt;p&gt;A slightly better fix would be to add a guard before the call to &lt;code&gt;scan()&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;fail&lt;/span&gt; &lt;span class="no"&gt;ArgumentError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"You must pass search terms"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;terms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt;
&lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;terms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\S+/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This would get us a better error message that actually tells us what went wrong.  But the stack trace still wouldn't be ideal.  It's going to bring us here first even though the real issue is in the controller.&lt;/p&gt;

&lt;h5&gt;My Favorite Method to the Rescue&lt;/h5&gt;

&lt;p&gt;This whole problem started because I allowed the &lt;code&gt;Hash&lt;/code&gt; to give me a &lt;code&gt;nil&lt;/code&gt;.  I didn't want a &lt;code&gt;nil&lt;/code&gt;, so I shouldn't have said it was OK.&lt;/p&gt;

&lt;p&gt;That brings us to &lt;code&gt;fetch()&lt;/code&gt;.  Watch this:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:missing&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:missing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="ss"&gt;KeyError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ss"&gt;found&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="ss"&gt;:missing&lt;/span&gt;
&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="ss"&gt;:in&lt;/span&gt; &lt;span class="sb"&gt;`fetch'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can think of &lt;code&gt;[]()&lt;/code&gt; as saying give me some key, if it exists.  You get a &lt;code&gt;nil&lt;/code&gt; if it doesn't.  Now &lt;code&gt;fetch()&lt;/code&gt;, on the other hand, is more like saying I need this key, no substitutions allowed.  This forces &lt;code&gt;fetch()&lt;/code&gt; to raise a &lt;code&gt;KeyError&lt;/code&gt; when the key is missing, since &lt;code&gt;nil&lt;/code&gt; isn't allowed.&lt;/p&gt;

&lt;p&gt;The best fix to the problem I started with would be to replace the initial assignment in the controller with this:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="n"&gt;terms&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:terms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You may also want to add some code to handle the &lt;code&gt;KeyError&lt;/code&gt;, but the important thing is that the problem now triggers from the proper place.  This is the most helpful error we could work with in this scenario.&lt;/p&gt;

&lt;h4&gt;I Don't Know What You Need&lt;/h4&gt;

&lt;p&gt;Let's take a step back for a moment to the overall &lt;code&gt;Hash&lt;/code&gt;.  What exactly is a &lt;code&gt;Hash&lt;/code&gt; in your code?  The only right answer is that I have no idea.&lt;/p&gt;

&lt;p&gt;You might be creating a typical key-to-value mapping:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;first&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"James"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;last&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Gray"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:first&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"James"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:last&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"Gray"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:last&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Gray"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Alternately, you could be tracking some counts:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;counts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;counts&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:one&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="n"&gt;counts&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:three&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;counts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;values_at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:zero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:one&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:three&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Or you could be keeping some named buckets for data:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;buckets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;buckets&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:one&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;buckets&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:three&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;buckets&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:one&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:three&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Perhaps it's even a deeply nested structure that you wish to track:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tree&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;default_proc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:deeply&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="ss"&gt;:nested&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="ss"&gt;:structure&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:deeply&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="ss"&gt;:nested&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="ss"&gt;:branch&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tree&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:deeply&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:nested&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:structure&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:branch&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}}}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;These are all very different, but valid, uses of a &lt;code&gt;Hash&lt;/code&gt; in Ruby to model various data structures and there are other options too.  Ruby can't know what you intend to do.  But it was wisely designed so that it doesn't have to know.&lt;/p&gt;

&lt;p&gt;Note the progression above that makes this possible.  You can create a normal &lt;code&gt;Hash&lt;/code&gt;.  You can pass a default object, like an initialization value for counters.  Or you can go all the way to defining the default behavior with custom code inside of a block as I did in the last two examples.&lt;/p&gt;

&lt;p&gt;Ruby delays the decision of default behavior so that it can leave that decision to you.  You know what you need better than Ruby does.&lt;/p&gt;

&lt;p&gt;And it doesn't stop there.&lt;/p&gt;

&lt;h5&gt;Back to My Favorite&lt;/h5&gt;

&lt;p&gt;Being able to set some default behavior at &lt;code&gt;Hash&lt;/code&gt; construction time is great, but what if I don't know everything I need to know even then?  What if I need to delay the decision even more, until key lookup time?  What if what I actually need is different at different times?  The answer is that &lt;code&gt;fetch()&lt;/code&gt; can handle those cases too.&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:missing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:missing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"giimnss"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can see that &lt;code&gt;fetch()&lt;/code&gt; also supports default return values for a missing keys and it will even allow you to provide custom code to handle the situation however you need to.&lt;/p&gt;

&lt;p&gt;If you only get one thing out of this article, make it &lt;code&gt;Hash#fetch()&lt;/code&gt;.  It's a powerhouse tool that enables you to do all kinds of fancy tricks.  (It's worth noting that &lt;code&gt;Hash#delete()&lt;/code&gt; is similarly flexible.  &lt;a href="http://ruby-doc.org/core-1.9.3/Hash.html#method-i-delete"&gt;Look it up&lt;/a&gt;.)  But that's not really why I'm showing you these methods.&lt;/p&gt;

&lt;h4&gt;The Pattern is the Thing&lt;/h4&gt;

&lt;p&gt;The real reason to play with these methods is that they represent a great tactic for Ruby programming in general.  It's important to remember that you won't know exactly what the users of your code will need.  Delay making that decision whenever you can.&lt;/p&gt;

&lt;p&gt;In fact, delay it as long as you can, ideally just pushing the decision off on the user when they finally need to make it.  They will know what they need better than you do.  Let them raise an error, do a conversion, or whatever else makes sense for them.&lt;/p&gt;

&lt;p&gt;In a lot of ways, this discussion is about Ruby's blocks.  That's the great tool Ruby gives us to allow us to delay these decisions.  Consider even a simple method like this:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;do_some_io_operations_for_me&lt;/span&gt;
  &lt;span class="c1"&gt;# ... IO code here...&lt;/span&gt;
&lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;IOError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Errno&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;EACCES&lt;/span&gt; &lt;span class="c1"&gt;#, ...&lt;/span&gt;
  &lt;span class="nb"&gt;block_given?&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;raise&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is a pretty perfect setup, in my opinion.  This code tries to push through some &lt;code&gt;IO&lt;/code&gt; operations.  Those could fail for any number of reasons, so the code intelligently traps the errors that apply.  If a users gives a block, they can control what happens on error without even needing to know which errors the &lt;code&gt;IO&lt;/code&gt; code could trigger.  However, the decision of exactly what to do is left to the caller.&lt;/p&gt;

&lt;p&gt;Of course, the biggest limitation on this strategy is that we only get one block in Ruby.  Once you delay one decision with it, you won't have it for other purposes.  Try not to let that stop you though!  Ruby doesn't.&lt;/p&gt;

&lt;p&gt;Consider the &lt;code&gt;find()&lt;/code&gt; iterator.  With &lt;code&gt;find()&lt;/code&gt; the block is already tied up for the test, but Ruby wants to let you decide what happens when nothing is found.  Returning &lt;code&gt;nil&lt;/code&gt; is not enough for those cases, because &lt;code&gt;nil&lt;/code&gt; could legitimately be what the block found.  Because of that, &lt;code&gt;find()&lt;/code&gt; cheats to expose kind of a second block:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;fail&lt;/span&gt; &lt;span class="no"&gt;ArgumentError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Not found"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="ss"&gt;ArgumentError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Not&lt;/span&gt; &lt;span class="n"&gt;found&lt;/span&gt;
&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="ss"&gt;:in&lt;/span&gt; &lt;span class="sb"&gt;`block in &amp;lt;main&amp;gt;'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I think these kind of tricks come out a little cleaner with the new "stabby &lt;code&gt;lambda()&lt;/code&gt;" (&lt;code&gt;-&amp;gt;&lt;/code&gt;) syntax that I used above.&lt;/p&gt;

&lt;h4&gt;Further Investigation&lt;/h4&gt;

&lt;p&gt;Fully getting the hang of when and where to use blocks in Ruby seems to take almost as long to get a feel for as the rest of the language does.  Here are some sources that might shave a little time off of the journey though:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I wrote &lt;a href="/ruby-tutorials/code-as-a-data-type"&gt;an article&lt;/a&gt; on blocks a long time ago.  I think it has aged fairly well and still provides some insight into why blocks exist and what they really are.&lt;/li&gt;
&lt;li&gt;Rake is a great example of the delayed decisions I am advocating in this article in many ways.  When you think about it, Rakes is really just an executable dependency graph of delayed decisions.  For a more concrete example though, check out Rake's &lt;a href="http://martinfowler.com/articles/rake.html#FileTasks"&gt;FileTask&lt;/a&gt;.  It's a delayed decision about how to build a file from one or more dependencies any time the content is no longer fresh.&lt;/li&gt;
&lt;li&gt;The 2.10.0 release of RSpec brings with it &lt;a href="https://github.com/rspec/rspec-expectations#yielding"&gt;some matchers for yielded control to a block&lt;/a&gt;.  This can make testing all of those block methods I'm asking you to write a little easier.&lt;/li&gt;
&lt;/ul&gt;</content>
    <author>
      <name>James Edward Gray II</name>
    </author>
  </entry>
  <entry>
    <title>The Secret Shell Helper</title>
    <link rel="alternate" href="http://graysoftinc.com/the-standard-library/the-secret-shell-helper"/>
    <id>tag:graysoftinc.com,2008-10-13:/posts/64</id>
    <updated>2014-04-11T22:02:14Z</updated>
    <summary>Some coverage of an undocumented standard library.</summary>
    <content type="html">&lt;p&gt;Someone pops onto the Ruby Talk mailing list fairly regularly asking how to break up content like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;one "two" "a longer three"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;They expect to end with a three element &lt;code&gt;Array&lt;/code&gt;, where the third item will contain spaces.  They generally expect the quotes will have been removed as well.&lt;/p&gt;

&lt;p&gt;If your needs are very, very simple you may be able to handle this with a regular expression:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'one "two" "a longer three"'&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/"([^"]*)"|(\S+)/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flatten&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compact&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; ["one", "two", "a longer three"]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That just searches for either a set of quotes with some non-quote characters between them or a run of non-whitespace characters.  Those are the two possibilities for the fields.  Note that the two separate capture here mean &lt;code&gt;scan()&lt;/code&gt; will returns contents in the form:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;[[&lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"one"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"two"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"a longer three"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That's why I added a &lt;code&gt;flatten()&lt;/code&gt; and &lt;code&gt;compact()&lt;/code&gt; to get down to the actual matches.&lt;/p&gt;

&lt;p&gt;The regular expression approach can get pretty complex though if any kind of escaping for quotes is involved.  When that happens, you may need to step up to a parser.&lt;/p&gt;

&lt;p&gt;One choice for that would be to abuse a CSV parser to get it to divide up the data for you.  Here's how you would do that with &lt;code&gt;FasterCSV&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"rubygems"&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"faster_csv"&lt;/span&gt;

&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'one "two" "a longer three"'&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:col_sep&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; ["one", "two", "a longer three"]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you see, replacing the column separator (traditionally a comma) with a simple space gets &lt;code&gt;FasterCSV&lt;/code&gt; to break down this data correctly.&lt;/p&gt;

&lt;p&gt;This parser will handle escaping, though it's CSV style escaping.  That means that quotes will need to be doubled:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"rubygems"&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"faster_csv"&lt;/span&gt;

&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'simple "embedded ""quote"" characters"'&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:col_sep&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; ["simple", "embedded \"quote\" characters"]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I doubt that fits the data well too often.  I suspect that an escaped quote is more often &lt;code&gt;\"&lt;/code&gt; than &lt;code&gt;""&lt;/code&gt;.  Why is that?  Well, data of this type isn't typically CSV data.  Which leads us to the natural question, what kind of data are we really working with here?&lt;/p&gt;

&lt;p&gt;I'm guessing it's shell data more often that not.  Most shells handle quoting like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ruby -e 'p ARGV' one "two" "a longer three"
["one", "two", "a longer three"]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If that's really the case, we're going to need a shell oriented parser.  It's sadly not well known, I assume because it's strangely absent from &lt;a href="http://ruby-doc.org/"&gt;http://ruby-doc.org/&lt;/a&gt;, but Ruby ships with such a parser.  The standard &lt;code&gt;Shellwords&lt;/code&gt; library will break these down for you:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"shellwords"&lt;/span&gt;

&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"one 'two' 'a longer three'"&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;Shellwords&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shellwords&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; ["one", "two", "a longer three"]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If your data really is shell content, you'll be glad to know that &lt;code&gt;Shellwords&lt;/code&gt; will handle all the special cases:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"shellwords"&lt;/span&gt;

&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;shell&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;Shellwords&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shellwords&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shell&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="sx"&gt;%Q{"escaped \\"quote\\" characters"}&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="sx"&gt;%Q{escaped\\ spaces}&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="sx"&gt;%Q{'back to'" back quoting"}&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; ["escaped \"quote\" characters"]&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; ["escaped spaces"]&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; ["back to back quoting"]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;Shellwords&lt;/code&gt; has some new features in Ruby 1.9 as well:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;shellsplit()&lt;/code&gt; is added as an alias for &lt;code&gt;shellwords()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shellescape()&lt;/code&gt; was added to escape a &lt;code&gt;String&lt;/code&gt; for use in Bash&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shelljoin()&lt;/code&gt; was added to escape and join an &lt;code&gt;Array&lt;/code&gt; of arguments&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shellsplit()&lt;/code&gt; and &lt;code&gt;shellescape()&lt;/code&gt; are added to &lt;code&gt;String&lt;/code&gt; and &lt;code&gt;shelljoin()&lt;/code&gt; is added to &lt;code&gt;Array&lt;/code&gt; for easier access&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Hopefully this helps you find the right parser for your data.&lt;/p&gt;</content>
    <author>
      <name>James Edward Gray II</name>
    </author>
  </entry>
  <entry>
    <title>All About Struct</title>
    <link rel="alternate" href="http://graysoftinc.com/ruby-voodoo/all-about-struct"/>
    <id>tag:graysoftinc.com,2008-10-10:/posts/63</id>
    <updated>2014-04-11T19:49:24Z</updated>
    <summary>Ruby even has shortcuts for building data classes for you.</summary>
    <content type="html">&lt;p&gt;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 &lt;code&gt;Array&lt;/code&gt; or &lt;code&gt;Hash&lt;/code&gt;, 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.&lt;/p&gt;

&lt;p&gt;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 &lt;code&gt;Struct&lt;/code&gt;.  Allow me to show you what I mean.&lt;/p&gt;

&lt;p&gt;Imagine I need a basic class to represent a &lt;code&gt;Contact&lt;/code&gt;.  Ruby gives us so many shortcuts that the class could be very small even without &lt;code&gt;Struct&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Contact&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@first&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt;
    &lt;span class="vi"&gt;@last&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;
    &lt;span class="vi"&gt;@email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="kp"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:first&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:last&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You could shorten that up more with some multiple assignment if you like, but that's the basics.  Now using &lt;code&gt;Struct&lt;/code&gt; is even easier:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="no"&gt;Contact&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:first&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:last&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;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 &lt;code&gt;Struct&lt;/code&gt; is more lenient:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;Contact&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="sx"&gt;%w[James Gray james@grayproductions.net]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; #&amp;lt;struct Contact first="James",&lt;/span&gt;
&lt;span class="c1"&gt;#                     last="Gray",&lt;/span&gt;
&lt;span class="c1"&gt;#                     email="james@grayproductions.net"&amp;gt;&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;Contact&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="sx"&gt;%w[James Gray]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; #&amp;lt;struct Contact first="James", last="Gray", email=nil&amp;gt;&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;Contact&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"James"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; #&amp;lt;struct Contact first="James", last=nil, email=nil&amp;gt;&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;Contact&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; #&amp;lt;struct Contact first=nil, last=nil, email=nil&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you can see, all arguments to the constructor &lt;code&gt;Struct&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;Now lets look once more at how I built that &lt;code&gt;Struct&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="no"&gt;ClassName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;Struct::new()&lt;/code&gt; builds and returns &lt;code&gt;Class&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;You can forgo the assignment to a constant if you pass the first argument as a constant name in &lt;code&gt;String&lt;/code&gt; form:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Contact"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:first&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:last&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This would not define a top-level &lt;code&gt;Contact&lt;/code&gt;, but instead a &lt;code&gt;Struct::Contact&lt;/code&gt;.  Given that, your name must be unique among all &lt;code&gt;Struct&lt;/code&gt;s defined when using this approach.&lt;/p&gt;

&lt;p&gt;Getting back to our fledgling &lt;code&gt;Contact&lt;/code&gt;, it's important to note that it does have all the getter and setter methods for the attributes:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Contact&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; #&amp;lt;struct Contact first=nil, last=nil, email=nil&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"James"&lt;/span&gt;
&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;last&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Gray"&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; #&amp;lt;struct Contact first="James", last="Gray", email=nil&amp;gt;&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;last&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; "Gray"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Again, &lt;code&gt;Struct&lt;/code&gt; always defines both getter and setter for all attributes.  That may or may not work for you.&lt;/p&gt;

&lt;p&gt;You can also set values using a &lt;code&gt;Hash&lt;/code&gt; like syntax:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"james@grayproductions.net"&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"email"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; "james@grayproductions.net"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;String&lt;/code&gt; and &lt;code&gt;Symbol&lt;/code&gt; keys are interchangeable.&lt;/p&gt;

&lt;p&gt;Another awesome feature is that &lt;code&gt;Struct&lt;/code&gt; gives you other ways to go through this data.  Here are three of my personal favorites:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;members&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; ["first", "last", "email"]&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; ["James", "Gray", "james@grayproductions.net"]&lt;/span&gt;
&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each_pair&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; first: James&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; last: Gray&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; email: james@grayproductions.net&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Contact&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:first&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:last&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is a neat example because it shows how flexible Ruby is.  The parent &lt;code&gt;Class&lt;/code&gt; for a &lt;code&gt;Class&lt;/code&gt; definition doesn't have to be just a constant name.  It can actually be any code that results in a &lt;code&gt;Class&lt;/code&gt; object.  Then we can just inherit from it and add to it as we like.&lt;/p&gt;

&lt;p&gt;However, projects like Rails have shown the error of this approach.  Because Rails is often dynamically reloading code, &lt;code&gt;Class&lt;/code&gt; definitions will be rerun.  That means the &lt;code&gt;Struct&lt;/code&gt; call will happen again, resulting in a fresh parent &lt;code&gt;Class&lt;/code&gt; object (which happens to have the exact same behavior).  Ruby will see the new parent for an existing definition and choke with an error:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;superclass mismatch for class Contact (TypeError)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The good news is that this isn't much of an issue because &lt;code&gt;Struct&lt;/code&gt; plans for it.  It's prepared to accept a block during definition and the contents of that block will be evaluate within your new &lt;code&gt;Class&lt;/code&gt;.  Thus it's trivial to add methods:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="no"&gt;Contact&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:first&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:last&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_hash&lt;/span&gt;
    &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="o"&gt;[*&lt;/span&gt;&lt;span class="n"&gt;members&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flatten&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# ...&lt;/span&gt;

&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_hash&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; {"last"=&amp;gt;"Gray",&lt;/span&gt;
&lt;span class="c1"&gt;#     "first"=&amp;gt;"James",&lt;/span&gt;
&lt;span class="c1"&gt;#     "email"=&amp;gt;"james@grayproductions.net"}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There is a gotcha when defining methods this way though.  &lt;code&gt;Struct&lt;/code&gt; 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:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="no"&gt;Contact&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:first&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:last&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;full&lt;/span&gt;
    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# ...&lt;/span&gt;

&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;full&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; "James Gray"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If &lt;code&gt;Struct&lt;/code&gt; isn't dynamic enough for you, you may want to examine the standard &lt;code&gt;OpenStruct&lt;/code&gt; library.  It's essentially a &lt;code&gt;Hash&lt;/code&gt; with a method interface, allowing you to change attributes as needed.  You can also initialize it with a &lt;code&gt;Hash&lt;/code&gt;, if needed:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"ostruct"&lt;/span&gt;

&lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;OpenStruct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:first&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"James"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:last&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Gray"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;last&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; "Gray"&lt;/span&gt;

&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;suffix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"II"&lt;/span&gt;  &lt;span class="c1"&gt;# add an attribute&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;suffix&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; "II"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Sadly, &lt;code&gt;OpenStruct&lt;/code&gt; is missing most of the niceties of &lt;code&gt;Struct&lt;/code&gt;.  Because of that, I don't feel it buys you much over a &lt;code&gt;Hash&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Keep &lt;code&gt;Struct&lt;/code&gt; 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.&lt;/p&gt;</content>
    <author>
      <name>James Edward Gray II</name>
    </author>
  </entry>
  <entry>
    <title>I'm Addicted to the Word Array</title>
    <link rel="alternate" href="http://graysoftinc.com/ruby-voodoo/im-addicted-to-the-word-array"/>
    <id>tag:graysoftinc.com,2008-10-03:/posts/58</id>
    <updated>2014-04-11T18:53:50Z</updated>
    <summary>Let me show you what may very well be my favorite little piece of Ruby syntax.</summary>
    <content type="html">&lt;p&gt;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 &lt;code&gt;Array&lt;/code&gt;."  I really am.&lt;/p&gt;

&lt;p&gt;I suspect most of you know this, but the word &lt;code&gt;Array&lt;/code&gt; is a shortcut that can lessen the quote-comma-quote syndrome of simple a simple &lt;code&gt;Array&lt;/code&gt; like:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"wordy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Array"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can create the same &lt;code&gt;Array&lt;/code&gt; with the word &lt;code&gt;Array&lt;/code&gt; syntax:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="sx"&gt;%w[a wordy Array]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That's essentially just a &lt;code&gt;String&lt;/code&gt; that will automatically be &lt;code&gt;split()&lt;/code&gt; on whitespace to build an &lt;code&gt;Array&lt;/code&gt;.  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:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"pp"&lt;/span&gt;
&lt;span class="n"&gt;pp&lt;/span&gt; &lt;span class="sx"&gt;%w[ one   two   three&lt;/span&gt;
&lt;span class="sx"&gt;       four  five  six&lt;/span&gt;
&lt;span class="sx"&gt;       seven eight nine&lt;/span&gt;
&lt;span class="sx"&gt;             zero        ]&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; ["one",&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt;  "two",&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt;  "three",&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt;  "four",&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt;  "five",&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt;  "six",&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt;  "seven",&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt;  "eight",&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt;  "nine",&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt;  "zero"]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that you can chose the punctuation characters used at either ends of the &lt;code&gt;Array&lt;/code&gt;, some of which are paired while others just repeat:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="sx"&gt;%w(a wordy Array)&lt;/span&gt;
&lt;span class="sx"&gt;%w{a wordy Array}&lt;/span&gt;
&lt;span class="sx"&gt;%w&amp;lt;a wordy Array&amp;gt;&lt;/span&gt;

&lt;span class="sx"&gt;%w!a wordy Array!&lt;/span&gt;
&lt;span class="sx"&gt;%w%a wordy Array%&lt;/span&gt;
&lt;span class="sx"&gt;%w#a wordy Array#&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I tend to just stick with &lt;code&gt;%w[ … ]&lt;/code&gt; though because I like how it parallels the &lt;code&gt;[ … ]&lt;/code&gt; for a normal &lt;code&gt;Array&lt;/code&gt;.  It's pretty smart too and will allow nested brackets, as long as they are paired properly:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="sx"&gt;%w[ [[]] abc[1] [start end] ]&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; ["[[]]", "abc[1]", "[start", "end]"]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="no"&gt;STATUSES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;%w[Pending Requested Booked Declined Submitted]&lt;/span&gt;
&lt;span class="n"&gt;validates_inclusion_of&lt;/span&gt; &lt;span class="ss"&gt;:status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:in&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;STATUSES&lt;/span&gt;

&lt;span class="n"&gt;before_filter&lt;/span&gt; &lt;span class="ss"&gt;:find_user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:only&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="sx"&gt;%w[show edit update destroy]&lt;/span&gt;

&lt;span class="vg"&gt;$LOAD_PATH&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;__FILE__&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="sx"&gt;%w[.. lib]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="no"&gt;Card&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:face&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:suit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;cards&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="sx"&gt;%w[heart spade club diamond]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;suit&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="sx"&gt;%w[A 2 3 4 5 6 7 8 9 T J Q K]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;face&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;cards&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Card&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;face&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;suit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Everyone of those examples was pulled out of real code I've written.  I'm a serious 12 stepper on this issue.&lt;/p&gt;

&lt;p&gt;That's the basics.  However, like most delights in Rubyland, the word &lt;code&gt;Array&lt;/code&gt; hides some lesser known surprises.  First, did you know that you can embed entries with spaces in them?&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="no"&gt;SORT_OPTIONS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;%w[ Default&lt;/span&gt;
&lt;span class="sx"&gt;                   Name&lt;/span&gt;
&lt;span class="sx"&gt;                   Price&lt;/span&gt;
&lt;span class="sx"&gt;                   Average\ Rating ]&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;SORT_OPTIONS&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; ["Default", "Name", "Price", "Average Rating"]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;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 &lt;code&gt;Array&lt;/code&gt;.  This is great for the occasional multiword entry though.&lt;/p&gt;

&lt;p&gt;It doesn't stop there either.  Remember when I said the word &lt;code&gt;Array&lt;/code&gt; is essentially a &lt;code&gt;String&lt;/code&gt;?  Well, you can even mix in some interpolation, if you switch to the capital &lt;code&gt;W&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="no"&gt;MODE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;const_defined?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:Test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="ss"&gt;:test&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="ss"&gt;:data&lt;/span&gt;
&lt;span class="no"&gt;PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;__FILE__&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="sx"&gt;%W[.. .. &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;MODE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sx"&gt; db.sqlite]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is code from a trivial SQLite wrapper I made.  It determines what &lt;code&gt;MODE&lt;/code&gt; to run in with a simple test that will pass after &lt;code&gt;Test::Unit&lt;/code&gt; has been loaded.  It then builds a &lt;code&gt;PATH&lt;/code&gt; to the database using the selected &lt;code&gt;MODE&lt;/code&gt;.  It's interpolation in the word &lt;code&gt;Array&lt;/code&gt; that makes that easy to do.&lt;/p&gt;

&lt;p&gt;It's probably worth mentioning that interpolated values are not subject to internal splitting:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"three four"&lt;/span&gt;
&lt;span class="n"&gt;ary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;%W[one two &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sx"&gt;]&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;ary&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; ["one", "two", "three four"]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The capital &lt;code&gt;W&lt;/code&gt; version supports some other &lt;code&gt;String&lt;/code&gt; escapes as well, though I confess that I've never made use of this:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="sx"&gt;%W[&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="sx"&gt; &lt;/span&gt;&lt;span class="se"&gt;\x20&lt;/span&gt;&lt;span class="sx"&gt; &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sx"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; ["\t", " ", "\n"]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Well, that's all the word &lt;code&gt;Array&lt;/code&gt; 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 &lt;code&gt;Array&lt;/code&gt; Anonymous User meetings.&lt;/p&gt;</content>
    <author>
      <name>James Edward Gray II</name>
    </author>
  </entry>
  <entry>
    <title>Working With Multiline Strings</title>
    <link rel="alternate" href="http://graysoftinc.com/ruby-voodoo/working-with-multiline-strings"/>
    <id>tag:graysoftinc.com,2008-10-02:/posts/56</id>
    <updated>2014-04-11T18:54:39Z</updated>
    <summary>Ruby borrows and expands upon some interesting syntax from shell scripting languages.</summary>
    <content type="html">&lt;p&gt;I imagine most Rubyists are aware that Ruby has "heredocs," but do you really know all they can do?  Let's find out.&lt;/p&gt;

&lt;p&gt;A "here document" is a literal syntax for a multiline &lt;code&gt;String&lt;/code&gt;.  In the most basic form, they look like this:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;END_HEREDOC&lt;/span&gt;
&lt;span class="sh"&gt;This is a&lt;/span&gt;
&lt;span class="sh"&gt;  multiline,&lt;/span&gt;
&lt;span class="sh"&gt;as is String!&lt;/span&gt;
&lt;span class="no"&gt;END_HEREDOC&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; "This is a\n  multiline,\nas is String!\n"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;&amp;lt;&amp;lt;NAME&lt;/code&gt; syntax introduces the heredoc, but it actually begins at the start of the following line.  It continues until &lt;code&gt;NAME&lt;/code&gt; 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 &lt;code&gt;String&lt;/code&gt; and dropped in where the original &lt;code&gt;&amp;lt;&amp;lt;NAME&lt;/code&gt; designator appeared.&lt;/p&gt;

&lt;p&gt;There are some important details in that description, namely that the &lt;code&gt;String&lt;/code&gt; 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):&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;END_SQL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\s+/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;
&lt;span class="sh"&gt;SELECT * FROM     users&lt;/span&gt;
&lt;span class="sh"&gt;         ORDER BY users.id DESC&lt;/span&gt;
&lt;span class="no"&gt;END_SQL&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; "SELECT * FROM users ORDER BY users.id DESC"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The spacing in the above example was to make it easier for a human to understand, but I use &lt;code&gt;gsub()&lt;/code&gt; and &lt;code&gt;strip()&lt;/code&gt; to normalize the actual String.  You can do that since the heredoc doesn't begin until the next line.&lt;/p&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;send_messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;send_messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;END_MESSAGE_ONE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;END_MESSAGE_TWO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="sh"&gt;This is message one.&lt;/span&gt;

&lt;span class="sh"&gt;...&lt;/span&gt;
&lt;span class="no"&gt;END_MESSAGE_ONE&lt;/span&gt;
&lt;span class="sh"&gt;Another message.&lt;/span&gt;

&lt;span class="sh"&gt;....&lt;/span&gt;
&lt;span class="no"&gt;END_MESSAGE_TWO&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; "This is message one.:\n\n...\n"&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; "Another message.\n\n...\n"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Another interesting thing to know about heredocs is that they are double-quoted &lt;code&gt;String&lt;/code&gt;s by default.  You can use any escapes allowed there as well as interpolation:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;DOUBLE_QUOTED&lt;/span&gt;
&lt;span class="sh"&gt;Tricks:&lt;/span&gt;
&lt;span class="sh"&gt;\tindented&lt;/span&gt;
&lt;span class="sh"&gt;\t#{100 + 23}&lt;/span&gt;
&lt;span class="no"&gt;DOUBLE_QUOTED&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; "Tricks:\n\tindented\n\t123\n"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However, if you would prefer single-quoted behavior, you can just surround the heredoc name with single quotes:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;SINGLE_QUOTED&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="sh"&gt;Tricks:&lt;/span&gt;
&lt;span class="sh"&gt;\tindented&lt;/span&gt;
&lt;span class="sh"&gt;\t#{100 + 23}&lt;/span&gt;
&lt;span class="no"&gt;SINGLE_QUOTED&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; "Tricks:\n\\tindented\n\\t\#{100 + 23}\n"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There's one more trick with regard to heredoc syntax.  If you begin with &lt;code&gt;&amp;lt;&amp;lt;-NAME&lt;/code&gt;, 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:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;HateMacro&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate_hate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;module_eval&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="no"&gt;END_RUBY&lt;/span&gt;
&lt;span class="sh"&gt;      def self.hate_#{target}&lt;/span&gt;
&lt;span class="sh"&gt;        puts "#{target.to_s.capitalize} sucks!"&lt;/span&gt;
&lt;span class="sh"&gt;      end&lt;/span&gt;
&lt;span class="no"&gt;    END_RUBY&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;HateMacro&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;generate_hate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:emacs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Just for Jim Weirich!&lt;/span&gt;
&lt;span class="no"&gt;HateMacro&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hate_emacs&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&amp;gt; Emacs sucks!&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That &lt;code&gt;String&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;A final point of interest that may be of value to TextMate users:  TextMate will properly syntax highlight the contents of &lt;code&gt;&amp;lt;&amp;lt;-SQL&lt;/code&gt;, &lt;code&gt;&amp;lt;&amp;lt;-HTML&lt;/code&gt;, and &lt;code&gt;&amp;lt;&amp;lt;-CODE_FOR_EVAL&lt;/code&gt; (as Ruby) heredocs.  You do need to use the indented form though even if you don't indent the content.&lt;/p&gt;

&lt;p&gt;Hopefully all of this gives you some new ideas for ways you might handle multiline &lt;code&gt;String&lt;/code&gt;s with Ruby.  You don't need heredocs everywhere, but they can clean things up with the right usage.&lt;/p&gt;</content>
    <author>
      <name>James Edward Gray II</name>
    </author>
  </entry>
  <entry>
    <title>I Just Want One Character!</title>
    <link rel="alternate" href="http://graysoftinc.com/my-projects/i-just-want-one-character"/>
    <id>tag:graysoftinc.com,2006-10-01:/posts/22</id>
    <updated>2014-04-03T22:46:33Z</updated>
    <summary>Here's a simple trick that comes in handy surprisingly often.  If you want "any key" to really work for things other than return, you will like this one.</summary>
    <content type="html">&lt;p&gt;Every so often a person asks the question on Ruby Talk, "How can I get just one character from the keyboard (without needing the user to hit return)?"  Everyone is always quick to post solutions, but sadly there are some issues with almost every one of them.&lt;/p&gt;

&lt;p&gt;The general consensus is that this is a tough problem to solve correctly.  I say that's the exact reason to let &lt;a href="https://github.com/JEG2/highline"&gt;HighLine&lt;/a&gt; handle this for you:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby -w&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"highline/system_extensions"&lt;/span&gt;
&lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;HighLine&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SystemExtensions&lt;/span&gt;

&lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"Enter one character:  "&lt;/span&gt;
&lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_character&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;char&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chr&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That doesn't look too tough, does it?&lt;/p&gt;

&lt;p&gt;What's terrific about this solution is that under-the-hood &lt;code&gt;HighLine&lt;/code&gt; will check your platform and libraries and then try to use the solution that makes the most sense for your environment.  The code is really pretty robust too, because people a lot smarter than me have been sending in patches for over a year, slowly eliminating all of those tricky edge cases.&lt;/p&gt;

&lt;p&gt;As you can see, I've split this functionality of &lt;code&gt;HighLine&lt;/code&gt; into a separate module so you don't even need to load the full &lt;code&gt;HighLine&lt;/code&gt; system.  This was done just because this is such a real and common problem.  This section of &lt;code&gt;HighLine&lt;/code&gt; is &lt;a href="https://github.com/JEG2/highline/blob/master/lib/highline/system_extensions.rb"&gt;one pure Ruby file&lt;/a&gt;, so feel free to vendor it if the external dependency is an issue.&lt;/p&gt;

&lt;p&gt;Trust me, reading individual characters from the keyboard doesn't have to be that tough.  You just need the right tool for the job.&lt;/p&gt;</content>
    <author>
      <name>James Edward Gray II</name>
    </author>
  </entry>
  <entry>
    <title>PStore Meets YAML</title>
    <link rel="alternate" href="http://graysoftinc.com/the-standard-library/pstore-meets-yaml"/>
    <id>tag:graysoftinc.com,2006-07-30:/posts/20</id>
    <updated>2014-04-03T20:00:39Z</updated>
    <summary>For more standard library fun, let me show you how to get two of my favorite data storage tools to play nice with each other.</summary>
    <content type="html">&lt;p&gt;I love the &lt;code&gt;PStore&lt;/code&gt; standard library.  It's a very graceful interface to get some fairly robust serialized mini-database handling in just a few lines.  With it you get:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Transactions with commit and rollbacks (automatic on exception).&lt;/li&gt;
&lt;li&gt; File locking, shared and exclusive.&lt;/li&gt;
&lt;li&gt; Multiprocessing safety.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;code&gt;PStore&lt;/code&gt; does even more, including some file mode checking and MD5 hashing to avoid unneeded writes, but the above are the major selling points for me.&lt;/p&gt;

&lt;p&gt;Now, if I had to level any one complaint at &lt;code&gt;PStore&lt;/code&gt;, it would be that because it uses &lt;code&gt;Marshal&lt;/code&gt; under the hood it doesn't create files you can easily browse or tweak by hand.  (&lt;code&gt;Marshal&lt;/code&gt; is a feature, don't get me wrong.  It's fast, which is very helpful.)  Sometimes though I want &lt;code&gt;PStore&lt;/code&gt; protection with the &lt;code&gt;YAML&lt;/code&gt; file format.&lt;/p&gt;

&lt;p&gt;I'm embarrassed to admit that I use to use a hack for this:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"pstore"&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"yaml"&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PStore&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="no"&gt;Marshal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;YAML&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That just redefines the &lt;code&gt;Marshal&lt;/code&gt; constant in a scope that should only alter &lt;code&gt;PStore&lt;/code&gt;.  The library only uses &lt;code&gt;dump()&lt;/code&gt; and &lt;code&gt;load()&lt;/code&gt; and those methods work the same with &lt;code&gt;Marshal&lt;/code&gt; and &lt;code&gt;YAML&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ready for the punch-line?&lt;/p&gt;

&lt;p&gt;I learned today that my fragile hack has been in vain, no matter how clever it may be.  &lt;code&gt;YAML&lt;/code&gt; ships with a file that will load and modify &lt;code&gt;PStore&lt;/code&gt; for you.  Usage is as simple as:&lt;/p&gt;

&lt;div class="highlight highlight-ruby"&gt;&lt;pre&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"yaml/store"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;From there just replace your &lt;code&gt;PStore.new()&lt;/code&gt; calls with &lt;code&gt;YAML::Store.new()&lt;/code&gt; and you're in business.  &lt;code&gt;YAML::Store&lt;/code&gt; is a subclass of &lt;code&gt;PStore&lt;/code&gt;, so you won't need to change one bit of the API to get &lt;code&gt;PStore&lt;/code&gt; robustness with &lt;code&gt;YAML&lt;/code&gt; output.&lt;/p&gt;</content>
    <author>
      <name>James Edward Gray II</name>
    </author>
  </entry>
</feed>
