<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[reedy.in / words]]></title>
  <link href="http://reedy.in/words/atom.xml" rel="self"/>
  <link href="http://reedy.in/words/"/>
  <updated>2015-01-08T16:13:26+01:00</updated>
  <id>http://reedy.in/words/</id>
  <author>
    <name><![CDATA[Dan Reedy]]></name>
    <email><![CDATA[comments@reedy.in]]></email>
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Deep Fetch]]></title>
    <link href="http://reedy.in/words/archive/2015/01/08/deep-fetch/"/>
    <updated>2015-01-08T09:40:00+01:00</updated>
    <id>http://reedy.in/words/archive/2015/01/08/deep-fetch</id>
    <content type="html"><![CDATA[<p>Sometimes you come across a piece of code of code that feels more verbose than it needs to be.
These code fragments stand out against the rest of the code-base in a Ruby file and can often
lead to frustrations and debug issues due to unneeded complexity.</p>

<p>I was pairing with a colleague and we had one of these experiences. We both looked at the section
of code in question and knew there should be a more &#8220;rubyesque&#8221; way.</p>

<p>The original code looked something like the following:</p>

<figure class='code'><figcaption><span>Original Code</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">node</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>  <span class="s2">&quot;webserver&quot;</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="s2">&quot;users&quot;</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>      <span class="s2">&quot;admin&quot;</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>        <span class="s2">&quot;password&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;some amazing password&quot;</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">if</span> <span class="n">node</span><span class="o">[</span><span class="s1">&#39;webserver&#39;</span><span class="o">].</span><span class="n">member?</span><span class="p">(</span><span class="s1">&#39;users&#39;</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="n">node</span><span class="o">[</span><span class="s1">&#39;webserver&#39;</span><span class="o">][</span><span class="s1">&#39;users&#39;</span><span class="o">].</span><span class="n">member?</span><span class="p">(</span><span class="s1">&#39;admin&#39;</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="n">node</span><span class="o">[</span><span class="s1">&#39;webserver&#39;</span><span class="o">][</span><span class="s1">&#39;users&#39;</span><span class="o">][</span><span class="s1">&#39;admin&#39;</span><span class="o">].</span><span class="n">member?</span><span class="p">(</span><span class="s1">&#39;password&#39;</span><span class="p">)</span>
</span><span class='line'>  <span class="n">defaults</span><span class="o">[</span><span class="s1">&#39;password&#39;</span><span class="o">]</span> <span class="o">=</span> <span class="n">node</span><span class="o">[</span><span class="s1">&#39;webserver&#39;</span><span class="o">][</span><span class="s1">&#39;users&#39;</span><span class="o">][</span><span class="s1">&#39;admin&#39;</span><span class="o">][</span><span class="s1">&#39;password&#39;</span><span class="o">]</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is a pretty common use case, especially as we are consuming JSON resources that have several levels deep. You can search StackOverview and find
<a href="http://stackoverflow.com/questions/7139471/transform-a-ruby-hash-into-a-dotted-path-key-string">any</a> <a href="http://stackoverflow.com/questions/1820451/ruby-style-how-to-check-whether-a-nested-hash-element-exists">number</a> of <a href="http://stackoverflow.com/questions/8301566/find-key-value-pairs-deep-inside-a-hash-containing-an-arbitrary-number-of-nested">solutions</a>.
The solution isn&#8217;t complex and, while you can certainly download any number of gems to provide a solution, it turns out it only take a few lines of ruby to
implement a nested search method.</p>

<p>After writing this post I came across a Gem called <a href="https://github.com/pewniak747/deep_fetch">deep_fetch</a> which provides a slightly different implementation. Rather than rename the methods throughout this post I wanted to give them a nod for a ready-made gem that provides the same basic functionality.</p>

<h2>One Possible Solution</h2>

<p>First, this isn&#8217;t the only way to solve this problem. That is the beauty of Ruby, there are many ways to implement smart solutions to common problems.
Now, lets dive in.</p>

<p>After a brief conversation we decided we wanted our solution to accept any number of keys, returning the value for the last key or <code>false</code>.</p>

<figure class='code'><figcaption><span>Ideal implementation</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">node</span><span class="o">.</span><span class="n">our_custom_search</span><span class="p">(</span><span class="s1">&#39;webserver&#39;</span><span class="p">,</span> <span class="s1">&#39;users&#39;</span><span class="p">,</span> <span class="s1">&#39;admin&#39;</span><span class="p">,</span> <span class="s1">&#39;password&#39;</span><span class="p">)</span>
</span><span class='line'><span class="c1">#=&gt; &quot;some amazing password&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="n">node</span><span class="o">.</span><span class="n">our_custom_search</span><span class="p">(</span><span class="s1">&#39;webserver&#39;</span><span class="p">,</span> <span class="s1">&#39;users&#39;</span><span class="p">,</span> <span class="s1">&#39;jdoe&#39;</span><span class="p">,</span> <span class="s1">&#39;password&#39;</span><span class="p">)</span>
</span><span class='line'><span class="c1">#=&gt; false</span>
</span></code></pre></td></tr></table></div></figure>




<!-- more -->


<p>I like to start by looking at what methods we already have access to. Since we are working with a <a href="http://ruby-doc.org/core-2.2.0/Hash.html">Hash</a> object I went to the Ruby docs and saw that <a href="http://ruby-doc.org/core-2.2.0/Hash.html#method-i-fetch">#fetch</a> looked promising.
The <code>#fetch</code> method allows you to provide a key, either a <code>String</code> or <code>Symbol</code>, and receive it&#8217;s value. The reason <code>#fetch</code> is ideal for our solution is that you can optionally provide a default value in the event that the provided key doesn&#8217;t exist. An exception is raised if you do not provide a default value and the key does not exist.</p>

<figure class='code'><figcaption><span>Fetch Default Value Example</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># Test Hash</span>
</span><span class='line'><span class="n">person</span> <span class="o">=</span> <span class="p">{</span> <span class="nb">name</span><span class="p">:</span> <span class="s1">&#39;Dan Reedy&#39;</span><span class="p">,</span> <span class="n">website</span><span class="p">:</span> <span class="s1">&#39;http://reedy.in&#39;</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Valid Fetch</span>
</span><span class='line'><span class="n">person</span><span class="o">.</span><span class="n">fetch</span><span class="p">(</span><span class="ss">:name</span><span class="p">)</span>
</span><span class='line'><span class="c1">#=&gt; &#39;Dan Reedy&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Invalid Fetch without a default</span>
</span><span class='line'><span class="n">person</span><span class="o">.</span><span class="n">fetch</span><span class="p">(</span><span class="ss">:email</span><span class="p">)</span>
</span><span class='line'><span class="c1">#=&gt; KeyError: key not found: :email</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Invalid Fetch with a default</span>
</span><span class='line'><span class="n">person</span><span class="o">.</span><span class="n">fetch</span><span class="p">(</span><span class="ss">:email</span><span class="p">,</span> <span class="kp">nil</span><span class="p">)</span>
</span><span class='line'><span class="c1">#=&gt; nil</span>
</span></code></pre></td></tr></table></div></figure>


<p>Playing off of the name of this method we decided to name our solution <code>#deep_fetch</code>.</p>

<h2>Let&#8217;s be Good Testers</h2>

<p>With the usage defined it is time for test. Since I want to use standard libraries the <code>MiniTest</code> module will be the testing framework<sup id='fnref:1'><a href='#fn:1' rel='footnote'>1</a></sup>.</p>

<figure class='code'><figcaption><span>hash_deep_fetch_test.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;minitest/autorun&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="n">describe</span> <span class="no">Hash</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">before</span> <span class="k">do</span>
</span><span class='line'>    <span class="vi">@hash</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>      <span class="s1">&#39;webserver&#39;</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>        <span class="s1">&#39;users&#39;</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>          <span class="s1">&#39;admin&#39;</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>            <span class="s1">&#39;password&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;some amazing password&#39;</span>
</span><span class='line'>          <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">describe</span> <span class="s1">&#39;#deep_fetch&#39;</span> <span class="k">do</span>
</span><span class='line'>    <span class="n">it</span> <span class="s1">&#39;returns the correct value for the provided keys&#39;</span> <span class="k">do</span>
</span><span class='line'>      <span class="vi">@hash</span><span class="o">.</span><span class="n">deep_fetch</span><span class="p">(</span><span class="s1">&#39;webserver&#39;</span><span class="p">,</span><span class="s1">&#39;users&#39;</span><span class="p">,</span><span class="s1">&#39;admin&#39;</span><span class="p">,</span><span class="s1">&#39;password&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">must_equal</span> <span class="s1">&#39;some amazing password&#39;</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>    <span class="n">it</span> <span class="s1">&#39;returns false if the provided keys do not exist&#39;</span> <span class="k">do</span>
</span><span class='line'>      <span class="vi">@hash</span><span class="o">.</span><span class="n">deep_fetch</span><span class="p">(</span><span class="s1">&#39;webserver&#39;</span><span class="p">,</span><span class="s1">&#39;users&#39;</span><span class="p">,</span><span class="s1">&#39;jdoe&#39;</span><span class="p">,</span><span class="s1">&#39;password&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">must_equal</span> <span class="kp">false</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Running the test will result in the expected failures.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Run options: --seed 25720
</span><span class='line'>
</span><span class='line'># Running:
</span><span class='line'>
</span><span class='line'>EE
</span><span class='line'>
</span><span class='line'>Finished in 0.001193s, 1676.4459 runs/s, 0.0000 assertions/s.
</span><span class='line'>
</span><span class='line'>  1) Error:
</span><span class='line'>Hash::#deep_fetch#test_0001_returns the correct value for the provided keys:
</span><span class='line'>NoMethodError: undefined method `deep_fetch' for #&lt;Hash:0x007f944c0ee6f0&gt;
</span><span class='line'>    deep_merge.rb:26:in `block (3 levels) in &lt;main&gt;'
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>  2) Error:
</span><span class='line'>Hash::#deep_fetch#test_0002_returns false if the provided keys do not exist:
</span><span class='line'>NoMethodError: undefined method `deep_fetch' for #&lt;Hash:0x007f944c0ed1b0&gt;
</span><span class='line'>    deep_merge.rb:29:in `block (3 levels) in &lt;main&gt;'
</span><span class='line'>
</span><span class='line'>2 runs, 0 assertions, 0 failures, 2 errors, 0 skips</span></code></pre></td></tr></table></div></figure>


<h2>Implementing the #deep_fetch method</h2>

<p>With the knowledge that we are going to take a collection of keys and reduce that down to a single value I chose to use the <code>Enumerable#reduce</code> method for looping. The added benefit with <code>#reduce</code> is the ability to assign the initial value of the <code>memo</code> block variable to <code>self</code>.</p>

<figure class='code'><figcaption><span>hash_deep_fetch.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">Hash</span><span class="o">.</span><span class="n">class_eval</span> <span class="k">do</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">deep_fetch</span><span class="p">(</span><span class="o">*</span><span class="n">keys</span><span class="p">)</span>
</span><span class='line'>    <span class="n">keys</span><span class="o">.</span><span class="n">reduce</span><span class="p">(</span><span class="nb">self</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">memo</span><span class="p">,</span> <span class="n">key</span><span class="o">|</span>
</span><span class='line'>      <span class="n">memo</span><span class="o">.</span><span class="n">fetch</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is enough for the first test to pass.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Run options: --seed 60473
</span><span class='line'>
</span><span class='line'># Running:
</span><span class='line'>
</span><span class='line'>.E
</span><span class='line'>
</span><span class='line'>Finished in 0.001141s, 1752.8484 runs/s, 876.4242 assertions/s.
</span><span class='line'>
</span><span class='line'>  1) Error:
</span><span class='line'>Hash::#deep_fetch#test_0002_returns false if the provided keys do not exist:
</span><span class='line'>KeyError: key not found: "jdoe"
</span><span class='line'>    deep_merge.rb:8:in `fetch'
</span><span class='line'>    deep_merge.rb:8:in `block in deep_fetch'
</span><span class='line'>    deep_merge.rb:7:in `each'
</span><span class='line'>    deep_merge.rb:7:in `reduce'
</span><span class='line'>    deep_merge.rb:7:in `deep_fetch'
</span><span class='line'>    deep_merge.rb:31:in `block (3 levels) in &lt;main&gt;'
</span><span class='line'>
</span><span class='line'>2 runs, 1 assertions, 0 failures, 1 errors, 0 skips</span></code></pre></td></tr></table></div></figure>


<p>The <code>#fetch</code> method raises an exception if a key isn&#8217;t found. In our implementation we decided that we wanted false if the keys do not exist, so the staight forward solution is to capture the <code>KeyError</code> exception and return false.</p>

<figure class='code'><figcaption><span>hash_deep_fetch.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">Hash</span><span class="o">.</span><span class="n">class_eval</span> <span class="k">do</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">deep_fetch</span><span class="p">(</span><span class="o">*</span><span class="n">keys</span><span class="p">)</span>
</span><span class='line'>    <span class="n">keys</span><span class="o">.</span><span class="n">reduce</span><span class="p">(</span><span class="nb">self</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">memo</span><span class="p">,</span> <span class="n">key</span><span class="o">|</span>
</span><span class='line'>      <span class="n">memo</span><span class="o">.</span><span class="n">fetch</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">rescue</span> <span class="no">KeyError</span>
</span><span class='line'>    <span class="kp">false</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>That&#8217;s it! Nine lines of code and we have a method to dive deep into nested hashes and pull out values.</p>

<h2>But wait&#8230;there&#8217;s more!</h2>

<p>There are two ways I think we can improve this method.</p>

<h3>Specify a default value if the key isn&#8217;t found</h3>

<p>First, I think it would be nice to specify the default value, much like the actual <code>#fetch</code> method. Rather than returning <code>false</code> the code will let the <code>KeyError</code> be raised if there isn&#8217;t a default. First update the test.</p>

<figure class='code'><figcaption><span>hash_deep_fetch_test.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># ... the setup code ...</span>
</span><span class='line'><span class="n">describe</span> <span class="s1">&#39;#deep_fetch&#39;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">it</span> <span class="s1">&#39;returns the correct value for the provided keys&#39;</span> <span class="k">do</span>
</span><span class='line'>    <span class="vi">@hash</span><span class="o">.</span><span class="n">deep_fetch</span><span class="p">(</span><span class="s1">&#39;webserver&#39;</span><span class="p">,</span><span class="s1">&#39;users&#39;</span><span class="p">,</span><span class="s1">&#39;admin&#39;</span><span class="p">,</span><span class="s1">&#39;password&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">must_equal</span> <span class="s1">&#39;some amazing password&#39;</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>  <span class="n">it</span> <span class="s1">&#39;raises KeyError exception if the provided keys do not exist&#39;</span> <span class="k">do</span>
</span><span class='line'>    <span class="o">-&gt;</span> <span class="p">{</span> <span class="vi">@hash</span><span class="o">.</span><span class="n">deep_fetch</span><span class="p">(</span><span class="s1">&#39;webserver&#39;</span><span class="p">,</span><span class="s1">&#39;users&#39;</span><span class="p">,</span><span class="s1">&#39;jdoe&#39;</span><span class="p">,</span><span class="s1">&#39;password&#39;</span><span class="p">)</span> <span class="p">}</span><span class="o">.</span><span class="n">must_raise</span> <span class="no">KeyError</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>  <span class="n">it</span> <span class="s1">&#39;returns the provided default value if the key does not exist&#39;</span> <span class="k">do</span>
</span><span class='line'>    <span class="vi">@hash</span><span class="o">.</span><span class="n">deep_fetch</span><span class="p">(</span><span class="s1">&#39;webserver&#39;</span><span class="p">,</span><span class="s1">&#39;users&#39;</span><span class="p">,</span><span class="s1">&#39;jdoe&#39;</span><span class="p">,</span><span class="s1">&#39;password&#39;</span><span class="p">,</span> <span class="n">default</span><span class="p">:</span> <span class="kp">false</span><span class="p">)</span><span class="o">.</span><span class="n">must_equal</span> <span class="kp">false</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'><span class="c1"># ... the rest ...</span>
</span></code></pre></td></tr></table></div></figure>


<p>This results in a new failure.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Run options: --seed 47519
</span><span class='line'>
</span><span class='line'># Running:
</span><span class='line'>
</span><span class='line'>.E.
</span><span class='line'>
</span><span class='line'>Finished in 0.001223s, 2452.9845 runs/s, 1635.3230 assertions/s.
</span><span class='line'>
</span><span class='line'>  1) Error:
</span><span class='line'>Hash::#deep_fetch#test_0003_returns the provided default value if the key does not exist:
</span><span class='line'>KeyError: key not found: "jdoe"
</span><span class='line'>    deep_merge.rb:8:in `fetch'
</span><span class='line'>    deep_merge.rb:8:in `block in deep_fetch'
</span><span class='line'>    deep_merge.rb:7:in `each'
</span><span class='line'>    deep_merge.rb:7:in `reduce'
</span><span class='line'>    deep_merge.rb:7:in `deep_fetch'
</span><span class='line'>    deep_merge.rb:40:in `block (3 levels) in &lt;main&gt;'
</span><span class='line'>
</span><span class='line'>3 runs, 2 assertions, 0 failures, 1 errors, 0 skips</span></code></pre></td></tr></table></div></figure>


<p>Now to make it pass. I&#8217;ll take advantage of Ruby 2&#8217;s keyword arguments for this example.</p>

<figure class='code'><figcaption><span>hash_deep_fetch.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">Hash</span><span class="o">.</span><span class="n">class_eval</span> <span class="k">do</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">deep_fetch</span><span class="p">(</span><span class="o">*</span><span class="n">keys</span><span class="p">,</span> <span class="n">default</span><span class="p">:</span> <span class="kp">false</span><span class="p">)</span>
</span><span class='line'>    <span class="n">keys</span><span class="o">.</span><span class="n">reduce</span><span class="p">(</span><span class="nb">self</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">memo</span><span class="p">,</span> <span class="n">key</span><span class="o">|</span>
</span><span class='line'>      <span class="n">memo</span><span class="o">.</span><span class="n">fetch</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">rescue</span> <span class="no">KeyError</span>
</span><span class='line'>    <span class="n">default</span><span class="o">.</span><span class="n">nil?</span> <span class="p">?</span> <span class="k">raise</span> <span class="p">:</span> <span class="n">default</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Allow #deep_fetch to locate values by a key path</h3>

<p>Developers who spend time with Objective-C&#8217;s dictionaries or the various other implementations of Key-Value stores will be familiar with the idea of a key path. Simply put it is a string of dot separated keys<sup id='fnref:3'><a href='#fn:3' rel='footnote'>3</a></sup>.
Rather than changing the existing method, we will create a new method called <code>#fetch_keypath</code> which will leverage <code>deep_fetch</code> behind the scenes.</p>

<p>As always, test first.</p>

<figure class='code'><figcaption><span>hash_deep_fetch_test.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># ... Setup &amp; other tests ...</span>
</span><span class='line'><span class="n">describe</span> <span class="s1">&#39;#fetch_keypath&#39;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">it</span> <span class="s1">&#39;returns the correct value for the provided keypath&#39;</span> <span class="k">do</span>
</span><span class='line'>    <span class="vi">@hash</span><span class="o">.</span><span class="n">fetch_keypath</span><span class="p">(</span><span class="s1">&#39;webserver.users.admin.password&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">must_equal</span> <span class="s1">&#39;some amazing password&#39;</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'><span class="c1"># ... the rest ...</span>
</span></code></pre></td></tr></table></div></figure>


<p>Then code the solution. The internals of this method will rely on the splat operator again. This time it is used to pass the elements within the array as individual arguments rather than a single argument.</p>

<figure class='code'><figcaption><span>hash_deep_fetch.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">Hash</span><span class="o">.</span><span class="n">class_eval</span> <span class="k">do</span>
</span><span class='line'>  <span class="c1"># ... #deep_fetch method</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">fetch_keypath</span><span class="p">(</span><span class="n">keypath</span><span class="p">)</span>
</span><span class='line'>    <span class="n">deep_fetch</span><span class="p">(</span><span class="o">*</span><span class="n">keypath</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;.&#39;</span><span class="p">))</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Adding the optional default value is trivial at this point.</p>

<figure class='code'><figcaption><span>hash_deep_fetch_test.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># ... Setup &amp; other tests ...</span>
</span><span class='line'><span class="n">describe</span> <span class="s1">&#39;#fetch_keypath&#39;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">it</span> <span class="s1">&#39;returns the correct value for the provided keypath&#39;</span> <span class="k">do</span>
</span><span class='line'>    <span class="vi">@hash</span><span class="o">.</span><span class="n">fetch_keypath</span><span class="p">(</span><span class="s1">&#39;webserver.users.admin.password&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">must_equal</span> <span class="s1">&#39;some amazing password&#39;</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>  <span class="n">it</span> <span class="s1">&#39;raises KeyError if the provided keys do not exist&#39;</span> <span class="k">do</span>
</span><span class='line'>    <span class="o">-&gt;</span> <span class="p">{</span> <span class="vi">@hash</span><span class="o">.</span><span class="n">fetch_keypath</span><span class="p">(</span><span class="s1">&#39;webserver.users.jdoe.password&#39;</span><span class="p">)</span> <span class="p">}</span><span class="o">.</span><span class="n">must_raise</span> <span class="no">KeyError</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>  <span class="n">it</span> <span class="s1">&#39;returns the provided default value if the key does not exist&#39;</span> <span class="k">do</span>
</span><span class='line'>    <span class="vi">@hash</span><span class="o">.</span><span class="n">deep_fetch</span><span class="p">(</span><span class="s1">&#39;webserver&#39;</span><span class="p">,</span><span class="s1">&#39;users&#39;</span><span class="p">,</span><span class="s1">&#39;jdoe&#39;</span><span class="p">,</span><span class="s1">&#39;password&#39;</span><span class="p">,</span> <span class="n">default</span><span class="p">:</span> <span class="s1">&#39;Key Missing&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">must_equal</span> <span class="s1">&#39;Key Missing&#39;</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'><span class="c1"># ... the rest ...</span>
</span></code></pre></td></tr></table></div></figure>


<p>And the updated <code>#fetch_keypath</code> method</p>

<figure class='code'><figcaption><span>hash_deep_fetch.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'>  <span class="k">def</span> <span class="nf">fetch_keypath</span><span class="p">(</span><span class="n">keypath</span><span class="p">,</span> <span class="n">default</span><span class="p">:</span> <span class="kp">false</span><span class="p">)</span>
</span><span class='line'>    <span class="n">deep_fetch</span><span class="p">(</span><span class="o">*</span><span class="n">keypath</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;.&#39;</span><span class="p">),</span> <span class="n">default</span><span class="p">:</span> <span class="n">default</span><span class="p">)</span>
</span><span class='line'>  <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>You can grab the tests and code for this blog at <a href="https://gist.github.com/danreedy/da3a6d42367c955ce093">Github</a>. Also, thanks to <a href="https://github.com/elbandito">Travis Longoria</a> for the inspiration.</p>

<div class="footnotes">
    <ol>
        <li class='footnote' id='fn:1'>Old habits die hard though, so I&#8217;ll use the RSpec style for my tests <a href='#fnref:1' rev='footnote'>↩</a></li><li class='footnote' id='fn:2'>The <a href="http://ruby-doc.org/core-2.2.0/Enumerable.html#method-i-inject">#inject</a> and <a href="http://ruby-doc.org/core-2.2.0/Enumerable.html#method-i-reduce">#reduce</a> methods provide the same functionality. I prefer <code>#reduce</code> as I feel it makes more sense, reducing a collection down to a single result. <a href='#fnref:2' rev='footnote'>↩</a></li><li class='footnote' id='fn:3'><a href="https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/KeyValueCoding/Articles/BasicPrinciples.html">Key-Value Coding Programming Guide</a> <a href='#fnref:3' rev='footnote'>↩</a></li>
    </ol>
</div>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Version Control Will Save Your Life]]></title>
    <link href="http://reedy.in/words/archive/2013/04/22/version-control-will-save-your-life/"/>
    <updated>2013-04-22T08:51:00+02:00</updated>
    <id>http://reedy.in/words/archive/2013/04/22/version-control-will-save-your-life</id>
    <content type="html"><![CDATA[<p>A few months back I had the pleasure of presenting to the TechDawgs student organization at <a href="http://siu.edu">SIU Carbondale</a>. I was given free choice of topic and I decided to try to explain why version control is important.</p>

<p>I believe one of the most overlooked &#8220;core&#8221; skills that a student should learn is version control. Many tools (and some operating systems) come with some kind of revision system built-in, but anyone serious about development needs to have a firm grasp on how to manually handle versioning in their projects.</p>

<p>When I hire a new student developer to work with me at <a href="http://housing.siu.edu">my day job</a> the first several weeks are spent on introductory training and we hit on aspects of version control using Git throughout the process. There are lots of great resources to teach and explain Git. My favorites include the <a href="http://www.codeschool.com/courses/try-git">Try Git</a> course at <a href="http://codeschool.com">Code School</a>, the <a href="http://pragprog.com/book/pg_git/pragmatic-guide-to-git">Pragmatic Guide to Git</a>, and the <a href="http://git-scm.com/book">Pro Git</a> book are my top three recommended sources.</p>

<p>If you aren&#8217;t intimately familiar with Git, especially using the command line interface, I would encourage you to take the time to dive in. Get to know the basic commands by heart and remember that it is always acceptable to refer to the documentation if you forget a command or argument. It&#8217;s more important to do it, than to have it memorized.</p>

<p>If you are interested you can take a look at my slides for the presentation to TechDawgs. And remember, Version control will save your life!</p>

<script async class="speakerdeck-embed" data-id="9d0a56105dde01306aec22000a9f2f35" data-ratio="1.2994923857868" src="https://speakerdeck.com/assets/embed.js"></script>




<!--more-->

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Dynamic Validation in a Rails Model]]></title>
    <link href="http://reedy.in/words/archive/2013/04/05/dynamic-validation/"/>
    <updated>2013-04-05T11:10:00+02:00</updated>
    <id>http://reedy.in/words/archive/2013/04/05/dynamic-validation</id>
    <content type="html"><![CDATA[<p>Since 2005 I have maintained a <abbr title="Content Management System">CMS</abbr>
developed on the Rails platform for my <a href="http://www.housing.siu.edu">day job</a>. There are a number of people who maintain the content on that page and one of the most requested features was for the content staff to create &#8220;dynamic&#8221; forms.</p>

<p>Over time our implementation failed for a variety of reasons, mostly due to improvements to Ruby and the Rails framework. The most recent issue hit us with Rails version 3.2.x and completely broke the code. Remedying the issue require rewriting the validation aspects of the code.</p>

<p>Before looking at the fix, I&#8217;ll describe how the dynamic forms work. From the administrative section a new <code>Form</code> can be created. A <code>Form</code> has many <code>FormComponents</code> that define the various questions and accepted answers. A <code>FormResponse</code> then takes the questions and answers provided and saves it as an &#8220;isolated&#8221; snapshot. This allows the form to be updated at-will but does not break the history of responses. For example, a particular option may no longer be available or a question from a form my be removed entirely.</p>

<figure class='code'><figcaption><span>Model Relationship</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">Form</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span><span class='line'>  <span class="n">has_many</span> <span class="ss">:form_components</span><span class="p">,</span> <span class="n">dependent</span><span class="p">:</span> <span class="ss">:destroy</span>
</span><span class='line'>  <span class="n">has_many</span> <span class="ss">:form_responses</span><span class="p">,</span> <span class="n">dependent</span><span class="p">:</span> <span class="ss">:nullify</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">FormComponent</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span><span class='line'>  <span class="n">belongs_to</span> <span class="ss">:form</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">FormResponse</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span><span class='line'>  <span class="n">belongs_to</span> <span class="ss">:form</span><span class="p">,</span> <span class="kp">include</span><span class="p">:</span> <span class="ss">:form_components</span>
</span><span class='line'>  <span class="n">has_many</span> <span class="ss">:form_components</span><span class="p">,</span> <span class="n">through</span><span class="p">:</span> <span class="ss">:form</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>A <code>FormComponent</code> can be any of the standard form elements, including selects, check boxes, and radio buttons. Accepted answers are stored in a comma separated list and the form is rendered using Rails standard form helpers. Additionally, a form component can be determined to be required, accepted, or match a specific regular expression.</p>

<!-- more -->


<p>The following code snippet shows creating a <code>FormComponent</code> called <code>full_name</code> that is a required field within the form.</p>

<figure class='code'><figcaption><span>Example FormComponent</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="vi">@form</span> <span class="o">=</span> <span class="no">Form</span><span class="o">.</span><span class="n">first</span>
</span><span class='line'><span class="vi">@form_component</span> <span class="o">=</span> <span class="vi">@form</span><span class="o">.</span><span class="n">form_components</span><span class="o">.</span><span class="n">build</span><span class="p">(</span><span class="n">kind</span><span class="p">:</span> <span class="s1">&#39;text_field&#39;</span><span class="p">,</span>
</span><span class='line'>             <span class="n">required</span><span class="p">:</span> <span class="kp">true</span><span class="p">,</span> <span class="n">question</span><span class="p">:</span> <span class="s1">&#39;full_name&#39;</span><span class="p">,</span> <span class="n">label</span><span class="p">:</span> <span class="s1">&#39;Your Full Name&#39;</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>There are three hurdles to jump for this to work.</p>

<ol>
<li>We don&#8217;t know what the questions are going to be for a given form in advance.</li>
<li>The answers need to presented to the visitor in a form that will be saved in a <code>FormResponse</code>.</li>
<li><code>FormResponse</code> needs to run the validations defined in <code>FormComponent</code></li>
</ol>


<p>The code to display the form fields is relatively straight-forward. Here are the relevant pieces.</p>

<figure class='code'><figcaption><span>Public Form Controller</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">def</span> <span class="nf">new</span>
</span><span class='line'>  <span class="c1"># @form is defined either by a param or UUID, etc...</span>
</span><span class='line'>  <span class="vi">@form_response</span> <span class="o">=</span> <span class="no">FormResponse</span><span class="o">.</span><span class="n">single_response_for</span><span class="p">(</span><span class="vi">@form</span><span class="p">)</span> <span class="c1"># I&#39;ll discuss this soon</span>
</span><span class='line'>  <span class="n">respond_with</span><span class="p">(</span><span class="vi">@form_response</span><span class="p">)</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span>Public Form View</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="o">=</span> <span class="n">form_for</span> <span class="vi">@form_response</span> <span class="k">do</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span>
</span><span class='line'>  <span class="o">%</span><span class="n">fieldset</span>
</span><span class='line'>    <span class="o">%</span><span class="n">legend</span> <span class="no">Form</span> <span class="no">Fields</span>
</span><span class='line'>    <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">hidden_field</span> <span class="ss">:form_id</span><span class="p">,</span> <span class="vi">@form_response</span><span class="o">.</span><span class="n">form</span><span class="o">.</span><span class="n">id</span>
</span><span class='line'>    <span class="o">-</span> <span class="vi">@form_response</span><span class="o">.</span><span class="n">form_components</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">component</span><span class="o">|</span>
</span><span class='line'>      <span class="o">=</span> <span class="n">render</span> <span class="n">partial</span><span class="p">:</span> <span class="n">component</span><span class="o">.</span><span class="n">kind</span> <span class="n">locals</span><span class="p">:</span> <span class="p">{</span> <span class="n">f</span><span class="p">:</span> <span class="n">f</span><span class="p">,</span> <span class="n">component</span><span class="p">:</span> <span class="n">component</span> <span class="p">}</span>
</span><span class='line'>  <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">submit</span>
</span></code></pre></td></tr></table></div></figure>


<p>To keep things <abbr title="Don't Repeat Yourself">DRY</abbr> I&#8217;ve created a  view partial for each kind of form component. Using the example <code>FormComponent</code> from earlier, this form would use the <code>_text_field.html.haml</code> partial which looks like this.</p>

<figure class='code'><figcaption><span>Component Partial for Text Fields</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">label</span> <span class="n">component</span><span class="o">.</span><span class="n">question</span><span class="p">,</span> <span class="n">component</span><span class="o">.</span><span class="n">label</span>
</span><span class='line'><span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">text_field</span> <span class="n">component</span><span class="o">.</span><span class="n">question</span>
</span></code></pre></td></tr></table></div></figure>


<p>The other partials are not much more complicated and I am looking forward to the Rails 4 <a href="http://edgeapi.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_check_boxes">#collection_check_boxes</a> method, which I think can clean them up even more. That is all that&#8217;s required to display the form for submission. Clicking submit will send the following parameters to <code>FormResponse#create</code>.</p>

<figure class='code'><figcaption><span>Submitted Parameters</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="p">{</span><span class="n">form_response</span><span class="p">:</span> <span class="p">{</span> <span class="n">form_id</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="n">full_name</span><span class="p">:</span> <span class="s1">&#39;Dan Reedy&#39;</span> <span class="p">}</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span>FormResponse#create</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">def</span> <span class="nf">create</span>
</span><span class='line'>  <span class="vi">@form</span> <span class="o">=</span> <span class="no">Form</span><span class="o">.</span><span class="n">includes</span><span class="p">(</span><span class="ss">:form_components</span><span class="p">)</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:form_response</span><span class="o">][</span><span class="ss">:form_id</span><span class="o">]</span><span class="p">)</span>
</span><span class='line'>  <span class="vi">@form_response</span> <span class="o">=</span> <span class="no">FormResponse</span><span class="o">.</span><span class="n">single_response_for</span><span class="p">(</span><span class="vi">@form</span><span class="p">)</span>
</span><span class='line'>  <span class="n">respond_with</span><span class="p">(</span><span class="vi">@form_response</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="nb">format</span><span class="o">|</span>
</span><span class='line'>    <span class="k">if</span> <span class="vi">@form_response</span><span class="o">.</span><span class="n">save</span>
</span><span class='line'>      <span class="c1"># Send an email, redirect, or do other stuff</span>
</span><span class='line'>    <span class="k">else</span>
</span><span class='line'>      <span class="c1"># Display the form again with error messages</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>The <code>FormResponse#create</code> action uses the same <code>#single_response_for</code><sup id='fnref:1'><a href='#fn:1' rel='footnote'>1</a></sup> method that we used in <code>new</code>. To understand what is happening we have to look at the <code>FormResponse</code> class.</p>

<figure class='code'><figcaption><span>FormResponse.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">FormResponse</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span><span class='line'>  <span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">dup</span><span class="p">(</span><span class="o">&amp;</span><span class="n">block</span><span class="p">)</span>
</span><span class='line'>    <span class="k">super</span><span class="o">.</span><span class="n">tap</span> <span class="k">do</span> <span class="o">|</span><span class="nb">dup</span><span class="o">|</span>
</span><span class='line'>      <span class="k">def</span> <span class="nc">dup</span><span class="o">.</span><span class="nf">name</span><span class="p">()</span> <span class="no">FormResponse</span><span class="o">.</span><span class="n">name</span> <span class="k">end</span>
</span><span class='line'>      <span class="nb">dup</span><span class="o">.</span><span class="n">class_eval</span><span class="p">(</span><span class="o">&amp;</span><span class="n">block</span><span class="p">)</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">single_response_for</span><span class="p">(</span><span class="n">form</span><span class="p">)</span>
</span><span class='line'>    <span class="n">block</span> <span class="o">=</span> <span class="no">Proc</span><span class="o">.</span><span class="n">new</span> <span class="k">do</span>
</span><span class='line'>      <span class="n">form</span><span class="o">.</span><span class="n">form_components</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">component</span><span class="o">|</span>
</span><span class='line'>        <span class="nb">method</span> <span class="o">=</span> <span class="n">component</span><span class="o">.</span><span class="n">question</span><span class="o">.</span><span class="n">to_sym</span>
</span><span class='line'>        <span class="kp">attr_accessor</span> <span class="nb">method</span>
</span><span class='line'>        <span class="n">validates_presence_of</span> <span class="nb">method</span> <span class="k">if</span> <span class="n">component</span><span class="o">.</span><span class="n">required?</span>
</span><span class='line'>        <span class="n">validates_acceptance_of</span> <span class="nb">method</span> <span class="k">if</span> <span class="n">component</span><span class="o">.</span><span class="n">acceptance?</span>
</span><span class='line'>        <span class="k">if</span> <span class="n">component</span><span class="o">.</span><span class="n">format</span><span class="o">.</span><span class="n">present?</span>
</span><span class='line'>          <span class="n">validates_format_of</span> <span class="nb">method</span><span class="p">,</span> <span class="n">with</span><span class="p">:</span> <span class="no">Regexp</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">component</span><span class="o">.</span><span class="n">format</span><span class="p">)</span>
</span><span class='line'>        <span class="k">end</span>
</span><span class='line'>      <span class="k">end</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>    <span class="nb">dup</span><span class="p">(</span><span class="o">&amp;</span><span class="n">block</span><span class="p">)</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">form_id</span><span class="p">:</span> <span class="n">form</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>It looks like a lot is happening in <code>#single_response_for</code> but it isn&#8217;t doing anything overly complex. It starts by creating a <code>Proc</code> that will be sent to <code>dup</code> at the end. The <code>Proc</code> is where all the unique methods and validations for <em>this</em> instance of <code>FormResponse</code> will be defined.</p>

<p>Inside the <code>Proc</code> each <code>FormComponent</code> for that <code>Form</code> is used in <code>attr_accessor</code> and, depending on the options, any of the standard Rails validations.</p>

<p>Once the <code>Proc</code> is defined it is passed to the <code>dup</code> method, which we override to pass our custom block into the shallow copy of <code>FormResponse</code>. The result is a unique instance of <code>FormResponse</code> with attributes and validations defined by <code>FormComponent</code>.</p>

<figure class='code'><figcaption><span>FormResponse.rb</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># Instantiate with #new</span>
</span><span class='line'><span class="o">&gt;</span> <span class="vi">@form_response</span> <span class="o">=</span> <span class="no">FormResponse</span><span class="o">.</span><span class="n">new</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="c1">#&lt;FormResponse id: nil, form_id: nil, answers: nil&gt;</span>
</span><span class='line'><span class="o">&gt;</span> <span class="vi">@form_response</span><span class="o">.</span><span class="n">valid?</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="kp">true</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Instantiate with #single_response_for</span>
</span><span class='line'><span class="o">&gt;</span> <span class="vi">@form_response</span> <span class="o">=</span> <span class="no">FormResponse</span><span class="o">.</span><span class="n">single_response_for</span><span class="p">(</span><span class="no">Form</span><span class="o">.</span><span class="n">first</span><span class="p">)</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="c1">#&lt;#&lt;Class:0x007f939a770210&gt; id: nil, form_id: 1, answers: nil&gt;</span>
</span><span class='line'><span class="o">&gt;</span> <span class="vi">@form_response</span><span class="o">.</span><span class="n">valid?</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="kp">false</span>
</span><span class='line'><span class="o">&gt;</span> <span class="vi">@form_response</span><span class="o">.</span><span class="n">errors?</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="c1">#&lt;ActiveModel::Errors:0x007f939a610b40 @base=#&lt;#&lt;Class:0x007f939a770210&gt; ..., @messages={:full_name=&gt;[&quot;can&#39;t be blank&quot;]}&gt; </span>
</span></code></pre></td></tr></table></div></figure>


<p>Solving this problem highlights many of the things I love about the Ruby language. If you&#8217;ve solved this issue another way, think this was terrible, or otherwise have a comment, please share!</p>

<div class="footnotes">
    <ol>
        <li class='footnote' id='fn:1'>Thanks go to <a href="https://github.com/ahoward">ahoward</a> on <a href="https://github.com/rails/rails/issues/5449">Rails issue #5449</a> for a cleaner implementation than what I was originally doing. <a href='#fnref:1' rev='footnote'>↩</a></li>
    </ol>
</div>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A Blast from the Past]]></title>
    <link href="http://reedy.in/words/archive/2013/01/31/a-blast-from-the-past/"/>
    <updated>2013-01-31T11:45:00+01:00</updated>
    <id>http://reedy.in/words/archive/2013/01/31/a-blast-from-the-past</id>
    <content type="html"><![CDATA[<p>Every 4-5 months I receive an email from someone who has come across an old forum post called <a href="http://railsforum.com/viewtopic.php?id=265">HOWTO: Beginning Relationships</a> that I wrote in 2006.</p>

<p>It&#8217;s fun to go back and look at that early code. It was aimed at being an absolute beginners guide to starting a Ruby on Rails project. The images are no longer available and I would be hard-pressed to find them in my digital archives, but the content is intact.</p>

<p>Most of the time the questions are the result of differences between Rails 3 and what I am guessing to be Rails 1.x. When I wrote that tutorial the <code>through:</code> option had just been added! However, What always surprises me is there seems to be a decent number of people who are not grasping the most basic concepts, despite the availability of great books<sup id='fnref:1'><a href='#fn:1' rel='footnote'>1</a></sup></p>

<p>I&#8217;ve been considering re-writing this tutorial to reflect the changes in Rails 3.2.x but tend to stop when I look at the landscape of great beginner resources, the least of which are the well written Ruby on Rails Guides<sup id='fnref:2'><a href='#fn:2' rel='footnote'>2</a></sup>. It seems, though, that maybe some dead simple beginning tutorials might be helpful for people looking for the concepts rather than the full techniques. This is what Code School<sup id='fnref:3'><a href='#fn:3' rel='footnote'>3</a></sup> is great at, but for quick reference it is difficult to hunt through their slides and not everyone will pay for access.</p>

<p>I am regularly training brand new developers, typically students with little to no previous experience in any web development. I plan take with some of our initial conversations related to setup, design, and implementation and turn them into short tutorials. I think I&#8217;ll start with a refresh of that 6 and a half year old(!) tutorial on basic relationships.</p>

<div class="footnotes">
    <ol>
        <li class='footnote' id='fn:1'>I highly recommend <a href="http://pragprog.com">The Pragmatic Publishers</a> are your first stop for books <a href='#fnref:1' rev='footnote'>↩</a></li><li class='footnote' id='fn:2'><a href="http://guides.rubyonrails.org">http://guides.rubyonrails.org</a> <a href='#fnref:2' rev='footnote'>↩</a></li><li class='footnote' id='fn:3'><a href="http://codeschool.com">http://codeschool.com</a> <a href='#fnref:3' rev='footnote'>↩</a></li>
    </ol>
</div>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Thoughts on Format]]></title>
    <link href="http://reedy.in/words/archive/2013/01/30/thoughts-on-format/"/>
    <updated>2013-01-30T09:36:00+01:00</updated>
    <id>http://reedy.in/words/archive/2013/01/30/thoughts-on-format</id>
    <content type="html"><![CDATA[<p>While writing for this blog, besides finding it extremely difficult to string words together into coherent sentences, I have often wondered about the best format. I hope what I write is worth reading from beginning to end, but will often reference outside material within the body of the post.</p>

<p>I&#8217;ve settled on a format I like and used it in the previous post. If I am commenting on a specific article or site I will reference it and provide a link within the first paragraph. Beyond that any links to other resources will occur as footnotes for the post. if you wish to jump to the footnote you certainly may, but by providing all external links in one spot I hope you will read through the whole post before flipping away to another page.</p>

<p>This post is primarily to remind myself of this decision for future writing. Also, to my future self who is reading this, don&#8217;t over-think it, just write.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Reminds me of a Quote]]></title>
    <link href="http://reedy.in/words/archive/2013/01/18/reminds-me-of-a-quote/"/>
    <updated>2013-01-18T08:17:00+01:00</updated>
    <id>http://reedy.in/words/archive/2013/01/18/reminds-me-of-a-quote</id>
    <content type="html"><![CDATA[<p>I&#8217;ve been watching The West Wing on Netflix lately and often one of the principal actors will rattle off the perfect quote for the situation. While working at the University I&#8217;ve met a few people who are able to quote the greats in their field, though rarely verbatim and often the result is to simply show they know the quote rather than a mastery of the situation. I don&#8217;t see that a lot within the web development profession.</p>

<p>Perhaps it is because my chosen field is relatively young, we do not have the luxury of 200+ years of speeches to pull from as is the case in The West Wing, or perhaps its because the greatest developers are often hidden behind their code. There are certainly a few cases that disprove my point. Many in the Ruby community look to _why<sup id='fnref:1'><a href='#fn:1' rel='footnote'>1</a></sup> and all the work he did in advocating Ruby, quoting from his Poignant Guide<sup id='fnref:2'><a href='#fn:2' rel='footnote'>2</a></sup>. The recent suicide of Aaron Swartz has pulled people to his writing<sup id='fnref:3'><a href='#fn:3' rel='footnote'>3</a></sup> and I&#8217;ve seen many quote his work. I think we&#8217;ll see even more of this as the Save Publishing<sup id='fnref:4'><a href='#fn:4' rel='footnote'>4</a></sup> bookmarklet continues to gain users. However, most developers won&#8217;t spend time reading lengthy writing by other programmers. However, with social coding sites we are seeing a different trend emerge.</p>

<p>Just like the great speech writers of history who spend hours reading historical speeches, reciting inauguration addresses, and listening to world leaders, we developers spend our time looking through shared repositories on sites like Github, Bit Bucket, and Google Code. We line ourselves up with programmers who code like we want to code and practice making our code look like theirs. There are strong personalities in our profession and attached is an equally strong sense of style in development. The result is not verbatim quotes, but instead an alignment of coding style. All of our coding practices originated from someone&#8217;s idea, from how we name variables to whether we use presenter classes to any other number of development choices. What is important is that we do not stifle our own voice while learning from these greats.</p>

<p>I don&#8217;t spend as much time as I would like reading speeches and writings of histories greats, although I am interested in such things. I do, however, spend a lot of time reading the code of developers more talented than myself and I learn from them. We may not have hundreds of years to look back over, but we have a vast amount of knowledge we can look at now. Taking the time to dig in deeper, showing interest in the body of work we pull from, displays a passion for the process and a desire for greater understanding. This is important.</p>

<div class="footnotes">
    <ol>
        <li class='footnote' id='fn:1'><a href="http://en.wikipedia.org/wiki/Why_the_lucky_stiff">Wikipedia: Why the lucky stiff</a> <a href='#fnref:1' rev='footnote'>↩</a></li><li class='footnote' id='fn:2'><a href="http://mislav.uniqpath.com/poignant-guide/">why&#8217;s Poignant Guide to Ruby</a> <a href='#fnref:2' rev='footnote'>↩</a></li><li class='footnote' id='fn:3'><a href="http://www.aaronsw.com/">Aaron Swartz&#8217;s website</a> <a href='#fnref:3' rev='footnote'>↩</a></li><li class='footnote' id='fn:4'><a href="http://www.savepublishing.com/">Save Publishing</a> <a href='#fnref:4' rev='footnote'>↩</a></li>
    </ol>
</div>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The Recipe]]></title>
    <link href="http://reedy.in/words/archive/2012/10/29/the-recipe/"/>
    <updated>2012-10-29T14:52:00+01:00</updated>
    <id>http://reedy.in/words/archive/2012/10/29/the-recipe</id>
    <content type="html"><![CDATA[<p>I think my wife is pretty amazing. She is a busy woman. We have four young children that we homeschool. She has been working hard to heal her body from food allergies by following the GAPS diet. She cares for our house, our chickens, and our garden. She is a doula and is regularly consulted by friends with infants and toddlers for advice. Through all that, she lifts me up and makes me into a better man than I would be otherwise.</p>

<p>Both she and I like to cook. One result of the GAPS diet is that all the things I have become good at cooking are no longer legal options for our evening meals. Gone are the nights of whole-wheat pizza crusts or pancakes for supper. It&#8217;s taken some adjusting, and I will admit that I&#8217;ve been less than enthusiastic about the situation, but through this process my wife has demonstrated this passion to improve again and again. When faced with the question &#8220;What&#8217;s for dinner?&#8221; I am dumbfounded, suggesting &#8220;Eggs? Chicken?&#8221; whereas she is regularly searching for new and exciting ways to make our meals enjoyable. Often building upon a basic recipe using the knowledge she&#8217;s gained through this process. Eventually, she ditches the recipe and relies completely upon her expertise.</p>

<p>Recipes are interesting things. They act like safety nets for us when we&#8217;re just beginning. It&#8217;s wise to leverage them when we are getting started. This is as true in software development as it is in cooking. Some of the best beginning programming books available are called <em>cookbooks</em> or include the word <em>recipe</em> in the title. This books take common scenarios and provide a basic solution. Often times this is enough to satisfy the requirement and the programmer can then move onto another feature.</p>

<p>There&#8217;s a problem with recipes though. If you never deviate from the recipe then you aren&#8217;t really improving. You may get better at completing that recipe, but what if you never learn how to substitute ingredients, adjust the yield, or navigate an unexpected problem? Recipes are vital when you are starting, but they can hold you back.</p>

<p>This is what my wife is great at. She can take one or more recipes and improvise to create something better. As programmers we should do the same. Be aware of the recipes, the best practices, but do not limit yourself to them. Aspire to improve the recipes while understanding <em>why</em> they became the best practice.</p>

<p>What we do as developers isn&#8217;t always complicated. A large portion of what we do is converting database queries to HTML. It isn&#8217;t always glamorous or exciting, but we cannot give into the <em>good enough</em> mentality, that&#8217;s when we lose the passion to be great at what we do. Simple shouldn&#8217;t result in lazy. In Jiro Dreams of Sushi we see this at an extreme level. Sushi, only sushi, is prepared day in and day out at a level beyond what anyone else is doing. This doesn&#8217;t prevent the chef, Jiro, from evaluating every plate to understand what could improve.</p>

<p>Our challenge is to not settle back and use the same recipe over and over, never striving to improve. If you do use a recipe, make sure to tailor it to your own style and demands. A well established recipe aims for the widest adoption, which isn&#8217;t necessarily what you are doing in your development.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Refactoring: A Basic Introduction]]></title>
    <link href="http://reedy.in/words/archive/2012/10/09/refactoring-a-basic-introduction/"/>
    <updated>2012-10-09T09:47:00+02:00</updated>
    <id>http://reedy.in/words/archive/2012/10/09/refactoring-a-basic-introduction</id>
    <content type="html"><![CDATA[<p>I work for a University, though not as a professor. I do have the privilege to work with students in a variety of capacities, including web application development. There are several departments on campus that offer web development courses but they tend to focus on basic tasks performed with PHP rather than a greater understanding of the industry and the options within. Over the years I have been able to introduce many students to using Ruby and Rails as well as the underlying concepts perpetuated by agile development.</p>

<p>One of the key concepts is the idea of refactoring. Core to test driven development and essential to keeping your code DRY<sup id='fnref:1'><a href='#fn:1' rel='footnote'>1</a></sup>, this concept is often not even discussed in the introductory development courses or, if it is taught, is overlooked by the students. Simply defined, refactoring is the process of rewriting code to make it easier to maintain while not altering the behavior of the application. When done well you eliminate complexities while making the code easier to work with. As I look at the attributes of a great craftsmen I see two that can be attributed with refactoring; <em>aspire to improve</em> and <em>maintain cleanliness</em>.</p>

<p>The first weeks of employment of a new developer on my staff consists of going through online courses<sup id='fnref:2'><a href='#fn:2' rel='footnote'>2</a></sup> and reading well-written books.<sup id='fnref:3'><a href='#fn:3' rel='footnote'>3</a></sup> Then, we spend some time pair-programming where we share one workstation with one of us driving and the other navigating.<sup id='fnref:4'><a href='#fn:4' rel='footnote'>4</a></sup> Through this process the new developer often gets their first taste of refactoring code. I have repeated this cycle many times as I train new developers and, the most recent time, I had the idea to document our refactoring for future reference.</p>

<!-- more -->


<h2>Refactoring In Practice</h2>

<p>The following is a summary of conversation and actions performed by myself and one of the student developers.</p>

<p>Our active user story<sup id='fnref:5'><a href='#fn:5' rel='footnote'>5</a></sup> was to provide date ranges for an application period, interview sign up period, and interview session period for an employment application feature of the website. The current implementation was displaying the beginning and ending dates on individual lines. You can also see that the <code>interviews_begin_on</code> and <code>interviews_end_on</code> attributes are optional.</p>

<figure class='code'><figcaption><span>Initial implementation of ra_app_terms/show.html.haml (View)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># list_display is a helper for creating DL elements</span>
</span><span class='line'><span class="c1"># def list_display(label, content)</span>
</span><span class='line'><span class="c1">#   capture_haml do</span>
</span><span class='line'><span class="c1">#     haml_tag :dt, label</span>
</span><span class='line'><span class="c1">#     haml_tag :dd do</span>
</span><span class='line'><span class="c1">#       haml_concat content</span>
</span><span class='line'><span class="c1">#     end</span>
</span><span class='line'><span class="c1">#    end</span>
</span><span class='line'><span class="c1">#  end</span>
</span><span class='line'><span class="o">%</span><span class="n">dl</span>
</span><span class='line'>  <span class="o">=</span> <span class="n">list_display</span> <span class="s1">&#39;Apps Accepted Beginning&#39;</span><span class="p">,</span> <span class="vi">@ra_app_term</span><span class="o">.</span><span class="n">available_at</span><span class="o">.</span><span class="n">to_s</span><span class="p">(</span><span class="ss">:typical</span><span class="p">)</span>
</span><span class='line'>  <span class="o">=</span> <span class="n">list_display</span> <span class="s1">&#39;Apps No Longer Accepted&#39;</span><span class="p">,</span> <span class="vi">@ra_app_term</span><span class="o">.</span><span class="n">unavailable_at</span><span class="o">.</span><span class="n">to_s</span><span class="p">(</span><span class="ss">:typical</span><span class="p">)</span>
</span><span class='line'>  <span class="o">=</span> <span class="n">list_display</span> <span class="s1">&#39;Interviews Begin&#39;</span><span class="p">,</span> <span class="vi">@ra_app_term</span><span class="o">.</span><span class="n">interviews_begin_on</span><span class="o">.</span><span class="n">to_s</span><span class="p">(</span><span class="ss">:long</span><span class="p">)</span> <span class="k">if</span> <span class="vi">@ra_app_term</span><span class="o">.</span><span class="n">interviews_begin_on</span><span class="o">.</span><span class="n">present?</span>
</span><span class='line'>  <span class="o">=</span> <span class="n">list_display</span> <span class="s1">&#39;Interviews End&#39;</span><span class="p">,</span> <span class="vi">@ra_app_term</span><span class="o">.</span><span class="n">interviews_end_on</span><span class="o">.</span><span class="n">to_s</span><span class="p">(</span><span class="ss">:long</span><span class="p">)</span> <span class="k">if</span> <span class="vi">@ra_app_term</span><span class="o">.</span><span class="n">interviews_end_on</span><span class="o">.</span><span class="n">present?</span>
</span></code></pre></td></tr></table></div></figure>


<p>Our customer<sup id='fnref:6'><a href='#fn:6' rel='footnote'>6</a></sup> requested we simplify this display, using a format similar to &#8220;10/01/12 - 10/09/12&#8221;. The first step is to write a our failing test<sup id='fnref:7'><a href='#fn:7' rel='footnote'>7</a></sup> with the syntax we plan to use in our view. We also focus only on one piece at a time, so we start with <code>available_at</code> and <code>unavailable_at</code>. We plan to create a method called <code>application_period</code>, so we add the following test.</p>

<figure class='code'><figcaption><span>ra_app_term_spec.rb (RSpec)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">context</span> <span class="s2">&quot;displaying date periods&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">subject</span> <span class="p">{</span> <span class="n">ra_app_terms</span><span class="p">(</span><span class="ss">:spring_2013</span><span class="p">)</span> <span class="p">}</span>
</span><span class='line'>  <span class="n">describe</span> <span class="s2">&quot;#application_period&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="n">its</span><span class="p">(</span><span class="ss">:application_period</span><span class="p">)</span> <span class="p">{</span> <span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;09/01/12 - 10/14/12&quot;</span> <span class="p">}</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Predictably, this test fails since we&#8217;ve not created the <code>application_period</code> method. So, we switch to the model and add the method.</p>

<figure class='code'><figcaption><span>ra_app_term.rb (Model)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">def</span> <span class="nf">application_period</span>
</span><span class='line'>  <span class="s2">&quot;</span><span class="si">#{</span><span class="nb">self</span><span class="o">.</span><span class="n">available_at</span><span class="o">.</span><span class="n">to_s</span><span class="p">(</span><span class="ss">:us_date</span><span class="p">)</span><span class="si">}</span><span class="s2"> - </span><span class="si">#{</span><span class="nb">self</span><span class="o">.</span><span class="n">unavailable_at</span><span class="o">.</span><span class="n">to_s</span><span class="p">(</span><span class="ss">:us_date</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Our test now passes so we move to the next set of attributes related to interview sign ups. Switching back to our spec file we add another test.</p>

<figure class='code'><figcaption><span>ra_app_term_spec.rb (RSpec)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">describe</span> <span class="s2">&quot;#interview_sign_up_period&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">its</span><span class="p">(</span><span class="ss">:interview_sign_up_period</span><span class="p">)</span> <span class="p">{</span> <span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;10/17/12 - 10/23/12&quot;</span> <span class="p">}</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Skipping forward to making this test pass we add the <code>interview_sign_up_period</code> method to the model.</p>

<figure class='code'><figcaption><span>ra_app_term.rb (Model)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">def</span> <span class="nf">interview_sign_up_period</span>
</span><span class='line'>  <span class="s2">&quot;</span><span class="si">#{</span><span class="nb">self</span><span class="o">.</span><span class="n">interview_sign_up_at</span><span class="o">.</span><span class="n">to_s</span><span class="p">(</span><span class="ss">:us_date</span><span class="p">)</span><span class="si">}</span><span class="s2"> - </span><span class="si">#{</span><span class="nb">self</span><span class="o">.</span><span class="n">interview_sign_up_until</span><span class="o">.</span><span class="n">to_s</span><span class="p">(</span><span class="ss">:us_date</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>The test passes and the astute student points out that we could refactor these methods, simplifying the long term maintenance of our code. At this point he becomes the driver and updates the model.</p>

<figure class='code'><figcaption><span>ra_app_term.rb (Model)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">def</span> <span class="nf">application_period</span>
</span><span class='line'>  <span class="n">display_date_period</span><span class="p">(</span><span class="nb">self</span><span class="o">.</span><span class="n">available_at</span><span class="p">,</span> <span class="nb">self</span><span class="o">.</span><span class="n">unavailable_at</span><span class="p">)</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="k">def</span> <span class="nf">interview_sign_up_period</span>
</span><span class='line'>  <span class="n">display_date_period</span><span class="p">(</span><span class="nb">self</span><span class="o">.</span><span class="n">interview_sign_up_at</span><span class="p">,</span> <span class="nb">self</span><span class="o">.</span><span class="n">interview_sign_up_until</span><span class="p">)</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="kp">private</span>
</span><span class='line'><span class="k">def</span> <span class="nf">display_date_period</span><span class="p">(</span><span class="n">first_date</span><span class="p">,</span> <span class="n">last_date</span><span class="p">)</span>
</span><span class='line'>  <span class="s2">&quot;</span><span class="si">#{</span><span class="n">first_date</span><span class="o">.</span><span class="n">to_s</span><span class="p">(</span><span class="ss">:us_date</span><span class="p">)</span><span class="si">}</span><span class="s2"> - </span><span class="si">#{</span><span class="n">last_date</span><span class="o">.</span><span class="n">to_s</span><span class="p">(</span><span class="ss">:us_date</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>We run our test which returns two passing examples. That&#8217;s refactoring in a nutshell. What happened next made this little change extremely important. The phone rang and it was our customer. He expresses that they&#8217;d like to add a notice to any applicant letting them know when the interview sign up period is using the format of &#8220;October 14 until October 23.&#8221; Our refactor meant we could focus our efforts on the new <code>display_date_period</code> method and not the individual date range methods.</p>

<p>I switched to the spec and add the following test and then hand the keyboard over to the student.</p>

<figure class='code'><figcaption><span>ra_app_term_spec.rb (RSpec)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">describe</span> <span class="s2">&quot;#interview_sign_up_period&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">its</span><span class="p">(</span><span class="ss">:interview_sign_up_period</span><span class="p">)</span> <span class="p">{</span> <span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;10/17/12 - 10/23/12&quot;</span> <span class="p">}</span>
</span><span class='line'>  <span class="n">it</span> <span class="s2">&quot;allows optional date_format&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="n">subject</span><span class="o">.</span><span class="n">interview_sign_up_period</span><span class="p">(</span><span class="n">date_format</span><span class="p">:</span> <span class="ss">:month_day</span><span class="p">)</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;October 17 - October 23&quot;</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>My student developer drives the following change to our model to handle the now optional date format.</p>

<figure class='code'><figcaption><span>ra_app_term.rb (Model)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">def</span> <span class="nf">application_period</span><span class="p">(</span><span class="n">options</span><span class="o">=</span><span class="p">{})</span>
</span><span class='line'>  <span class="n">display_date_period</span><span class="p">(</span><span class="nb">self</span><span class="o">.</span><span class="n">available_at</span><span class="p">,</span> <span class="nb">self</span><span class="o">.</span><span class="n">unavailable_at</span><span class="p">,</span> <span class="n">options</span><span class="p">)</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="k">def</span> <span class="nf">interview_sign_up_period</span><span class="p">(</span><span class="n">options</span><span class="o">=</span><span class="p">{})</span>
</span><span class='line'>  <span class="n">display_date_period</span><span class="p">(</span><span class="nb">self</span><span class="o">.</span><span class="n">interview_sign_up_at</span><span class="p">,</span> <span class="nb">self</span><span class="o">.</span><span class="n">interview_sign_up_until</span><span class="p">,</span> <span class="n">options</span><span class="p">)</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="kp">private</span>
</span><span class='line'><span class="k">def</span> <span class="nf">display_date_period</span><span class="p">(</span><span class="n">first_date</span><span class="p">,</span><span class="n">last_date</span><span class="p">,</span><span class="n">options</span><span class="p">)</span>
</span><span class='line'>  <span class="s2">&quot;</span><span class="si">#{</span><span class="n">first_date</span><span class="o">.</span><span class="n">to_s</span><span class="p">(</span><span class="n">options</span><span class="o">[</span><span class="ss">:date_format</span><span class="o">]</span><span class="p">)</span><span class="si">}</span><span class="s2"> - </span><span class="si">#{</span><span class="n">last_date</span><span class="o">.</span><span class="n">to_s</span><span class="p">(</span><span class="n">options</span><span class="o">[</span><span class="ss">:date_format</span><span class="o">]</span><span class="p">)</span><span class="s2">&quot;</span>
</span><span class='line'><span class="s2">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>The model changes just made are a prime example as to why we write tests. After I kept quiet and let the tests run my student was surprised to see our previously successful tests were failing, while the new test passed. I pointed out to him that the output from the <code>display_date_period</code> method is expecting <code>options[:date_format]</code> to contain a value.</p>

<p>At this point I take the liberty to point out a couple of other Rubyisms we could use to better equip ourselves for future development. I explain the splat operator<sup id='fnref:8'><a href='#fn:8' rel='footnote'>8</a></sup>, <code>extract_options!</code>,  and <code>join</code>. These will each help us handle the latest request from the customer.</p>

<p>I take over as driver and update <code>display_date_period</code> method to handle an options hash.</p>

<figure class='code'><figcaption><span>ra_app_term.rb (Model)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="kp">private</span>
</span><span class='line'><span class="k">def</span> <span class="nf">display_date_period</span><span class="p">(</span><span class="o">*</span><span class="n">dates</span><span class="p">)</span>
</span><span class='line'>  <span class="n">options</span> <span class="o">=</span> <span class="n">dates</span><span class="o">.</span><span class="n">extract_options!</span>
</span><span class='line'>  <span class="n">options</span><span class="o">[</span><span class="ss">:date_format</span><span class="o">]</span> <span class="o">||=</span> <span class="ss">:us_date</span>
</span><span class='line'>  <span class="n">options</span><span class="o">[</span><span class="ss">:separator</span><span class="o">]</span> <span class="o">||=</span> <span class="s1">&#39; - &#39;</span>
</span><span class='line'>  <span class="n">dates</span><span class="o">.</span><span class="n">collect</span> <span class="p">{</span> <span class="o">|</span><span class="n">date</span><span class="o">|</span> <span class="n">date</span><span class="o">.</span><span class="n">to_s</span><span class="p">(</span><span class="n">options</span><span class="o">[</span><span class="ss">:date_format</span><span class="o">]</span><span class="p">)</span> <span class="p">}</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">options</span><span class="o">[</span><span class="ss">:separator</span><span class="o">]</span><span class="p">)</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>We re-run the test suite and we have three passing tests. My student drives again and writes the next test to handle passing optional joining text.</p>

<figure class='code'><figcaption><span>ra_app_term_spec.rb (RSpec)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">describe</span> <span class="s2">&quot;#interview_sign_up_period&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">its</span><span class="p">(</span><span class="ss">:interview_sign_up_period</span><span class="p">)</span> <span class="p">{</span> <span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;10/17/12 - 10/23/12&quot;</span> <span class="p">}</span>
</span><span class='line'>  <span class="n">it</span> <span class="s2">&quot;allows optional date_format&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="n">subject</span><span class="o">.</span><span class="n">interview_sign_up_period</span><span class="p">(</span><span class="n">date_format</span><span class="p">:</span> <span class="ss">:month_day</span><span class="p">)</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;October 17 - October 23&quot;</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>  <span class="n">it</span> <span class="s2">&quot;allows optional separator&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="n">subject</span><span class="o">.</span><span class="n">interview_sign_up_period</span><span class="p">(</span><span class="n">separator</span><span class="p">:</span> <span class="s1">&#39; until &#39;</span><span class="p">)</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;10/17/12 until 10/23/12&quot;</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>The previous update to <code>display_date_period</code> set the method up to handle an optional separator being defined, so our new tests run without any issue. My student, interested in seeing whether my code would actually handle multiple options adds one additional test.</p>

<figure class='code'><figcaption><span>ra_app_term_spec.rb (RSpec)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">describe</span> <span class="s2">&quot;#interview_sign_up_period&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">its</span><span class="p">(</span><span class="ss">:interview_sign_up_period</span><span class="p">)</span> <span class="p">{</span> <span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;10/17/12 - 10/23/12&quot;</span> <span class="p">}</span>
</span><span class='line'>  <span class="n">it</span> <span class="s2">&quot;allows optional date_format&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="n">subject</span><span class="o">.</span><span class="n">interview_sign_up_period</span><span class="p">(</span><span class="n">date_format</span><span class="p">:</span> <span class="ss">:month_day</span><span class="p">)</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;October 17 - October 23&quot;</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>  <span class="n">it</span> <span class="s2">&quot;allows optional separator&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="n">subject</span><span class="o">.</span><span class="n">interview_sign_up_period</span><span class="p">(</span><span class="n">separator</span><span class="p">:</span> <span class="s1">&#39; until &#39;</span><span class="p">)</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;10/17/12 until 10/23/12&quot;</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>  <span class="n">it</span> <span class="s2">&quot;allows multiple options&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="n">subject</span><span class="o">.</span><span class="n">interview_sign_up_period</span><span class="p">(</span><span class="n">date_format</span><span class="p">:</span> <span class="ss">:month_day</span><span class="p">,</span> <span class="n">separator</span><span class="p">:</span> <span class="s1">&#39; until &#39;</span><span class="p">)</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;October 17 until October 23&quot;</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>The test results all come back green, 5 passing tests. I mention that we haven&#8217;t written the test to handle the interview session period. Our initial story requested this feature for application period, interview sign up period, and interview session period. Before I finish talking the student has already written the next test.</p>

<figure class='code'><figcaption><span>ra_app_term_spec.rb (RSpec)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">describe</span> <span class="s2">&quot;#interview_period&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">its</span><span class="p">(</span><span class="ss">:interview_period</span><span class="p">)</span> <span class="p">{</span> <span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;10/25/12&quot;</span> <span class="p">}</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>We both notice a problem. According to the original design it is optional to have an end date for the interview period. Our test fixture had a value for <code>interviews_begin_on</code> but had a null value for <code>interviews_end_on</code>. We know the first time running the test will fail because we haven&#8217;t defined <code>interview_period</code>, so we switch to the model to add that method. We also decide to handle null values within <code>display_date_period</code>, so that this model looks similar to the other specific date period methods.</p>

<figure class='code'><figcaption><span>ra_app_term.rb (Model)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">def</span> <span class="nf">interview_period</span><span class="p">(</span><span class="n">options</span><span class="o">=</span><span class="p">{})</span>
</span><span class='line'>  <span class="n">display_date_period</span><span class="p">(</span><span class="nb">self</span><span class="o">.</span><span class="n">interviews_begin_on</span><span class="p">,</span> <span class="nb">self</span><span class="o">.</span><span class="n">interviews_end_on</span><span class="p">,</span> <span class="n">options</span><span class="p">)</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now we have to determine the best way to handle the possible null date attribute. I suggest we run our test to see what errors we get. The error is <code>wrong number of arguments(1 for 0) in #to_s</code>. I point out that if you call <code>to_s</code> on a null value the result is an empty string. However, unlike the <code>to_s</code> method of a <code>Date</code> or <code>Time</code> object, you cannot provide an argument.</p>

<p>To correct this we can explicitly test that the provided value is a <code>Date</code> or <code>Time</code> object or we can use an inline <code>rescue</code> to handle the exception. I take over driving and use the inline <code>rescue</code> to demonstrate another Rubyism.</p>

<figure class='code'><figcaption><span>ra_app_term.rb (Model)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="kp">private</span>
</span><span class='line'><span class="k">def</span> <span class="nf">display_date_period</span><span class="p">(</span><span class="o">*</span><span class="n">dates</span><span class="p">)</span>
</span><span class='line'>  <span class="n">options</span> <span class="o">=</span> <span class="n">dates</span><span class="o">.</span><span class="n">extract_options!</span>
</span><span class='line'>  <span class="n">options</span><span class="o">[</span><span class="ss">:date_format</span><span class="o">]</span> <span class="o">||=</span> <span class="ss">:us_date</span>
</span><span class='line'>  <span class="n">options</span><span class="o">[</span><span class="ss">:separator</span><span class="o">]</span> <span class="o">||=</span> <span class="s1">&#39; - &#39;</span>
</span><span class='line'>  <span class="n">dates</span><span class="o">.</span><span class="n">collect</span> <span class="p">{</span> <span class="o">|</span><span class="n">date</span><span class="o">|</span> <span class="n">date</span><span class="o">.</span><span class="n">to_s</span><span class="p">(</span><span class="n">options</span><span class="o">[</span><span class="ss">:date_format</span><span class="o">]</span><span class="p">)</span> <span class="k">rescue</span> <span class="kp">nil</span> <span class="p">}</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">options</span><span class="o">[</span><span class="ss">:separator</span><span class="o">]</span><span class="p">)</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>We run the test suite and our test it fails on our expectation and not because of an exception. The returned result was <code>"10/25/12 - "</code> which means our null value is being accounted for in the <code>join</code> method. We open <a href="http://ruby-doc.org">Ruby-doc.org</a> and look into <code>Array</code> methods to strip out a null element and find two that would work: <code>reject</code> and <code>delete_if</code>. Because we do not need the behavior to be destructive we go with <code>reject</code> and use the proc shortcut<sup id='fnref:9'><a href='#fn:9' rel='footnote'>9</a></sup> with the <code>blank?</code> method to check for null values.</p>

<figure class='code'><figcaption><span>ra_app_term.rb (Model)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="kp">private</span>
</span><span class='line'><span class="k">def</span> <span class="nf">display_date_period</span><span class="p">(</span><span class="o">*</span><span class="n">dates</span><span class="p">)</span>
</span><span class='line'>  <span class="n">options</span> <span class="o">=</span> <span class="n">dates</span><span class="o">.</span><span class="n">extract_options!</span>
</span><span class='line'>  <span class="n">options</span><span class="o">[</span><span class="ss">:date_format</span><span class="o">]</span> <span class="o">||=</span> <span class="ss">:us_date</span>
</span><span class='line'>  <span class="n">options</span><span class="o">[</span><span class="ss">:separator</span><span class="o">]</span> <span class="o">||=</span> <span class="s1">&#39; - &#39;</span>
</span><span class='line'>  <span class="n">dates</span><span class="o">.</span><span class="n">reject</span><span class="p">(</span><span class="o">&amp;</span><span class="ss">:blank?</span><span class="p">)</span><span class="o">.</span><span class="n">collect</span> <span class="p">{</span> <span class="o">|</span><span class="n">date</span><span class="o">|</span> <span class="n">date</span><span class="o">.</span><span class="n">to_s</span><span class="p">(</span><span class="n">options</span><span class="o">[</span><span class="ss">:date_format</span><span class="o">]</span><span class="p">)</span> <span class="k">rescue</span> <span class="kp">nil</span> <span class="p">}</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">options</span><span class="o">[</span><span class="ss">:separator</span><span class="o">]</span><span class="p">)</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>All the tests are now passing. The student, ready to continue with adding edge cases asks &#8220;What happens if they pass more than two dates?&#8221; and reaches for the keyboard to start driving our next test. I quickly put the proverbial brakes on. We could spend the rest of the day working to accept every possible combination of arguments, but as it stands now we have refactored redundant code and have met the customer&#8217;s request. We instead switch gears and update the view to use the new methods.</p>

<figure class='code'><figcaption><span>Final show.html.haml (View)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="o">%</span><span class="n">dl</span>
</span><span class='line'>  <span class="o">=</span> <span class="n">list_display</span> <span class="s1">&#39;Application Period&#39;</span><span class="p">,</span> <span class="vi">@ra_app_term</span><span class="o">.</span><span class="n">application_period</span>
</span><span class='line'>  <span class="o">=</span> <span class="n">list_display</span> <span class="s1">&#39;Interview Sign-up Period&#39;</span><span class="p">,</span> <span class="vi">@ra_app_term</span><span class="o">.</span><span class="n">interview_sign_up_period</span>
</span><span class='line'>  <span class="o">=</span> <span class="n">list_display</span> <span class="s1">&#39;Interview Period&#39;</span><span class="p">,</span> <span class="vi">@ra_app_term</span><span class="o">.</span><span class="n">interview_period</span>
</span></code></pre></td></tr></table></div></figure>


<p>We pull open the page in our browser and everything works as expected. The final step is to add the notice to applicants that they can sign up for an interview.</p>

<p>The previous example was relatively simple, but it is a scenario I see many times while teaching new developers. We refactored early in the process and because we did when the code was still simple, adding more complexity was relatively simple. Ultimately, this could have been handled by a presenter class to keep presentation out of the model and that is exactly what we did in a future update.</p>

<h3>The Model</h3>

<figure class='code'><figcaption><span>ra_app_term.rb (Model)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">RaAppTerm</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span><span class='line'>  <span class="c1"># ... additional code</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">application_period</span><span class="p">(</span><span class="n">options</span><span class="o">=</span><span class="p">{})</span>
</span><span class='line'>    <span class="n">date_period_display</span> <span class="nb">self</span><span class="o">.</span><span class="n">available_at</span><span class="p">,</span> <span class="nb">self</span><span class="o">.</span><span class="n">unavailable_at</span><span class="p">,</span> <span class="n">options</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">interview_sign_up_period</span><span class="p">(</span><span class="n">options</span><span class="o">=</span><span class="p">{})</span>
</span><span class='line'>    <span class="n">date_period_display</span> <span class="nb">self</span><span class="o">.</span><span class="n">interview_sign_up_at</span><span class="p">,</span> <span class="nb">self</span><span class="o">.</span><span class="n">interview_sign_up_until</span><span class="p">,</span> <span class="n">options</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">interview_period</span><span class="p">(</span><span class="n">options</span><span class="o">=</span><span class="p">{})</span>
</span><span class='line'>    <span class="n">date_period_display</span> <span class="nb">self</span><span class="o">.</span><span class="n">interviews_begin_on</span><span class="p">,</span> <span class="nb">self</span><span class="o">.</span><span class="n">interviews_end_on</span><span class="p">,</span> <span class="n">options</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="kp">private</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">date_period_display</span><span class="p">(</span><span class="o">*</span><span class="n">dates</span><span class="p">)</span>
</span><span class='line'>    <span class="n">options</span> <span class="o">=</span> <span class="n">dates</span><span class="o">.</span><span class="n">extract_options!</span>
</span><span class='line'>    <span class="n">options</span><span class="o">[</span><span class="ss">:separator</span><span class="o">]</span> <span class="o">||=</span> <span class="s1">&#39; - &#39;</span>
</span><span class='line'>    <span class="n">options</span><span class="o">[</span><span class="ss">:date_format</span><span class="o">]</span> <span class="o">||=</span> <span class="ss">:us_date</span>
</span><span class='line'>    <span class="n">dates</span><span class="o">.</span><span class="n">reject</span><span class="p">(</span><span class="o">&amp;</span><span class="ss">:blank?</span><span class="p">)</span><span class="o">.</span><span class="n">collect</span> <span class="p">{</span> <span class="o">|</span><span class="n">date</span><span class="o">|</span> <span class="n">date</span><span class="o">.</span><span class="n">to_s</span><span class="p">(</span><span class="n">options</span><span class="o">[</span><span class="ss">:date_format</span><span class="o">]</span><span class="p">)</span> <span class="k">rescue</span> <span class="kp">nil</span> <span class="p">}</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">options</span><span class="o">[</span><span class="ss">:separator</span><span class="o">]</span><span class="p">)</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># ... additional code</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<h3>The Spec</h3>

<figure class='code'><figcaption><span>ra_app_term.rb (RSpec)</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;spec_helper&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="n">describe</span> <span class="no">RaAppTerm</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">fixtures</span> <span class="ss">:ra_app_terms</span>
</span><span class='line'>  <span class="c1"># ... additional code</span>
</span><span class='line'>  <span class="n">context</span> <span class="s2">&quot;displaying date periods&quot;</span> <span class="k">do</span>
</span><span class='line'>    <span class="n">subject</span> <span class="p">{</span> <span class="n">ra_app_terms</span><span class="p">(</span><span class="ss">:spring_2013</span><span class="p">)</span> <span class="p">}</span>
</span><span class='line'>    <span class="n">describe</span> <span class="s2">&quot;#application_period&quot;</span> <span class="k">do</span>
</span><span class='line'>      <span class="n">its</span><span class="p">(</span><span class="ss">:application_period</span><span class="p">)</span> <span class="p">{</span> <span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;09/01/12 - 10/14/12&quot;</span> <span class="p">}</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>    <span class="n">describe</span> <span class="s2">&quot;#interview_sign_up_period&quot;</span> <span class="k">do</span>
</span><span class='line'>      <span class="n">its</span><span class="p">(</span><span class="ss">:interview_sign_up_period</span><span class="p">)</span> <span class="p">{</span> <span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;10/17/12 - 10/23/12&quot;</span> <span class="p">}</span>
</span><span class='line'>      <span class="n">it</span> <span class="s2">&quot;allows optional date_format&quot;</span> <span class="k">do</span>
</span><span class='line'>        <span class="n">subject</span><span class="o">.</span><span class="n">interview_sign_up_period</span><span class="p">(</span><span class="n">date_format</span><span class="p">:</span> <span class="ss">:month_day</span><span class="p">)</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;October 17 - October 23&quot;</span>
</span><span class='line'>      <span class="k">end</span>
</span><span class='line'>      <span class="n">it</span> <span class="s2">&quot;allows optional separator&quot;</span> <span class="k">do</span>
</span><span class='line'>        <span class="n">subject</span><span class="o">.</span><span class="n">interview_sign_up_period</span><span class="p">(</span><span class="n">separator</span><span class="p">:</span> <span class="s1">&#39; until &#39;</span><span class="p">)</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;10/17/12 until 10/23/12&quot;</span>
</span><span class='line'>      <span class="k">end</span>
</span><span class='line'>      <span class="n">it</span> <span class="s2">&quot;allows multiple options&quot;</span> <span class="k">do</span>
</span><span class='line'>        <span class="n">subject</span><span class="o">.</span><span class="n">interview_sign_up_period</span><span class="p">(</span><span class="n">date_format</span><span class="p">:</span> <span class="ss">:month_day</span><span class="p">,</span> <span class="n">separator</span><span class="p">:</span> <span class="s1">&#39; until &#39;</span><span class="p">)</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;October 17 until October 23&quot;</span>
</span><span class='line'>      <span class="k">end</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>    <span class="n">describe</span> <span class="s2">&quot;#interview_period&quot;</span> <span class="k">do</span>
</span><span class='line'>      <span class="n">its</span><span class="p">(</span><span class="ss">:interview_period</span><span class="p">)</span> <span class="p">{</span> <span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;10/25/12&quot;</span> <span class="p">}</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>  <span class="c1"># ... additional code</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>




<div class="footnotes">
    <ol>
        <li class='footnote' id='fn:1'>Don&#8217;t Repeat Yourself <a href='#fnref:1' rev='footnote'>↩</a></li><li class='footnote' id='fn:2'><a href="http://www.codeschool.com">Codeschool</a> is my curriculum of choice <a href='#fnref:2' rev='footnote'>↩</a></li><li class='footnote' id='fn:3'><a href="http://pragprog.com">The Pragmatic Bookshelf</a> provides a fantastic selection of topics <a href='#fnref:3' rev='footnote'>↩</a></li><li class='footnote' id='fn:4'>An excellent overview of pair programming is available from The Art of Agile Development&#8217;s <a href="http://www.jamesshore.com/Agile-Book/pair_programming.html"> Pair Programming chapter</a> <a href='#fnref:4' rev='footnote'>↩</a></li><li class='footnote' id='fn:5'>Once again take a look at The Art of Agile Development, this time at the <a href="http://www.jamesshore.com/Agile-Book/stories.html">Stories chapter</a>. <a href='#fnref:5' rev='footnote'>↩</a></li><li class='footnote' id='fn:6'>We develop web applications for different units within our department, which we refer to as customers <a href='#fnref:6' rev='footnote'>↩</a></li><li class='footnote' id='fn:7'>We practice Test Driven Development (TDD) after all <a href='#fnref:7' rev='footnote'>↩</a></li><li class='footnote' id='fn:8'>The splat operator is used to handle an unknown number of arguments. The collection is assigned to an array <a href='#fnref:8' rev='footnote'>↩</a></li><li class='footnote' id='fn:9'>A great way to save code when doing simple tasks. See <a href="http://asciicasts.com/episodes/6-shortcut-blocks-with-symbol-to-proc">Shortcut Blocks with Symbol to_proc</a> for more information <a href='#fnref:9' rev='footnote'>↩</a></li>
    </ol>
</div>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Babel by Mumford and Sons]]></title>
    <link href="http://reedy.in/words/archive/2012/09/25/babel-by-mumford-and-sons/"/>
    <updated>2012-09-25T15:25:00+02:00</updated>
    <id>http://reedy.in/words/archive/2012/09/25/babel-by-mumford-and-sons</id>
    <content type="html"><![CDATA[<p>I&#8217;m just going to leave this here, <a href="http://doesmumfordsoundlikematthews.herokuapp.com">Does Marcus Mumford sound like Dave Matthews?</a>.</p>

<p>With that out of the way, let&#8217;s get to the sophomore album, released today, by Mumford and Sons. Babel is fantastic. True to the original sound they established on <em>Sigh No More</em>. Each track has fresh instrumentation and the vocals are simple and point to issues that resonate in each of us.</p>

<p>I appreciate the confidence Marcus Mumford has in approaching subject matter such as faith, life, and death. In several instances the vocals stand with minimal accompaniment and express themselves powerfully. On more than one occasion I replayed pieces of a track to really listen to what was being said.</p>

<p>I, poorly, play the banjo and am I huge fan of Winston&#8217;s command of the instrument. Do yourself a favor and listen attentively to how precise and technical his playing is, you won&#8217;t be disappointed.</p>

<p>If you have a Spotify account, give the album a listen. Then go buy it. These guys are the real deal and I hope they continue to be supported to make great music.</p>

<iframe src="https://embed.spotify.com/?uri=spotify:album:4NzfIyezKTNvMxceOAk5LO" width="300" height="380" frameborder="0" allowtransparency="true"></iframe>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Why So Serious?]]></title>
    <link href="http://reedy.in/words/archive/2012/09/19/why-so-serious/"/>
    <updated>2012-09-19T17:01:00+02:00</updated>
    <id>http://reedy.in/words/archive/2012/09/19/why-so-serious</id>
    <content type="html"><![CDATA[<p>I take myself too seriously. At least I think I take myself too seriously. I can often confuse this with perfectionism, of which I also am guilty. I tend only to do the things I know I can be successful at. For that reason, I tend to focus on a specific task, project, or goal and ignore outside influences. This trait tends to make people think I&#8217;m pretty serious. Really, I just don&#8217;t like to fail.</p>

<!-- more -->


<p>There&#8217;s this movie, Jiro Dreams of Sushi, which has me thinking about how I conduct myself as a professional. Jiro is a sushi chef. <em>Only</em> sushi. His restaurant does not serve drinks or appetizers, <em>only sushi</em>. He is serious about Sushi. He wasn&#8217;t a good father, he wasn&#8217;t a good husband, he wasn&#8217;t good at a lot of things, but he was serious about making sushi. Not to say he was bad at all those things, though the documentary certainly illustrates some of his failures, they just were not his primary goal.</p>

<p>Developers like conferences. I&#8217;m not entirely sure why. Perhaps we like to reassure ourselves that we aren&#8217;t crazy. Maybe we just like to have an excuse to travel. Whatever the reason, we descend on a city with reckless abandon. I was in Chicago recently for <a href="http://www.windycityrails.org" title="Windy City Rails">WindyCityRails 2012</a>, a two-day conference for Rails developers. At the end of the two days I wondered if it was worth attending.</p>

<p>Since 2005<sup id='fnref:1'><a href='#fn:1' rel='footnote'>1</a></sup> I have spent nearly all of my time developing using the <a href="http://www.ruby-lang.org/en/" title="Ruby Programming Language">Ruby</a> language and the <a href="http://rubyonrails.org" title="Ruby on Rails">Rails</a> framework. In that time it has become a darling language of agile developers and startups. A problem started to emerge though. Through several successes and even more eccentric personalities, Ruby developers started being called <em>Rock Stars</em> and <em>Ninjas</em><sup id='fnref:2'><a href='#fn:2' rel='footnote'>2</a></sup>.</p>

<p>At one point in my life I wanted to be a rock star<sup id='fnref:3'><a href='#fn:3' rel='footnote'>3</a></sup>. I had long hair<sup id='fnref:4'><a href='#fn:4' rel='footnote'>4</a></sup>. I liked ninjas. I watched dubbed kung fu movies and wore black T-shirts. I&#8217;m down with rock stars and ninjas. The thing is, I&#8217;ve grown up. I&#8217;ve, theoretically, matured. I don&#8217;t want to be a rock star anymore. Ninja are still mesmerizing, but primarily because I have a young son.</p>

<p>At WindyCityRails the background on one presenters computer was himself giving his webcam the finger<sup id='fnref:5'><a href='#fn:5' rel='footnote'>5</a></sup>. Another attempted to give a live demonstration without much success but with much cursing under his breath. A third was successful in his live demo, but what he showed was how to pour a beer<sup id='fnref:6'><a href='#fn:6' rel='footnote'>6</a></sup>.</p>

<p>I mention these three presenters not to ridicule or say they were wrong. It&#8217;s not easy to present, I know, I&#8217;ve been a presenter at conferences on several occasions. The reason I mention them is to illustrate that I left the conference feeling as though our industry doesn&#8217;t take itself seriously. That isn&#8217;t quite right though. I <em>do</em> think my industry takes itself seriously. So what was it about these presentations?</p>

<p>I&#8217;m an average photographer. I&#8217;m an average writer. I want to a <em>great</em> developer. I want to be perfect, though I know that is impossible. I take my aspirations seriously. I read through repositories on <a href="http://github.com" title="Github">Github</a>. I follow developers on twitter. I watch screencasts, I read blogs, and review<sup id='fnref:7'><a href='#fn:7' rel='footnote'>7</a></sup> books. I do these things in the interest of becoming a better developer.</p>

<p>Those presenters weren&#8217;t bad. They didn&#8217;t do anything wrong. The problem was within me. I went to WindyCityRails wanting to walk away with knowledge that would make me a better developer. That is not what I received. Instead, I made some new professional connections, shared some war stories with new developers, and laughed at humorous improv comedy. My expectations were wrong to begin with but I was serious about my goal. The marquee names did not deliver toward my goal and I left feeling let down. That was the fault of my expectations. The interactions with others made the conference a success and worth attending and that should have been enough.</p>

<p>So, what should I do? For starters, I created this blog. I established the entry page for <a href="http://reedy.in" title="This page, don't click">reedy.in</a> while at that conference. I starting thinking about topics. I mulled over the tone, I questioned my abilities to write, and then I simply got started.</p>

<p>Next, I&#8217;ve resolved to be serious about what I do, but for the right reasons and at the right time. I am fortunate to have opportunities to teach students<sup id='fnref:8'><a href='#fn:8' rel='footnote'>8</a></sup> about Ruby on Rails, often times with zero prior knowledge of the language or framework, and I hope to plant in them the desire to become craftsman, not just programmers. University is a chance to make mistakes and learn. I want them to take the opportunity seriously. It is also a chance to have fun and experiment, so I plan to give them a place to make the mistakes that we have all had to learn from as developers. <em>Being serious for the right reasons, at the right time.</em></p>

<p>When I present, I plan to take the opportunity seriously and focus on the message, not on me. If the presentation doesn&#8217;t inform, educate, and inspire then it isn&#8217;t worth doing. I would like to present at more conferences, specifically industry conferences. So far I have presented at several small, local conferences and events related to higher education. I have a difficult time deciding on what topic I&#8217;d like to present and I think this blog might help me identify that. I am not that interesting of a person but I like interesting things. Those interesting things should be in the foreground.</p>

<p>At WindyCityRails, I would have done well to ask myself &#8220;Why So Serious?&#8221;<sup id='fnref:9'><a href='#fn:9' rel='footnote'>9</a></sup> The answer might have surprised me and I now, after having written this blog, I will set my expectations with a better set of criteria. Crafting not only the code I write, but myself as a person.</p>

<div class="footnotes">
    <ol>
        <li class='footnote' id='fn:1'>I had paternity leave thanks to my first child being born. In addition to staring at him, I began learning Ruby on Rails. <a href='#fnref:1' rev='footnote'>↩</a></li><li class='footnote' id='fn:2'><a href="http://ontwik.com/ruby/how-to-become-a-famous-rails-developer-ruby-rockstar-or-code-ninja/" title="How to become a famous Rails Developer, Ruby Rockstar or Code Ninja">How to become a famous Rails Developer, Ruby Rockstar or Code Ninja</a> by Chris Wanstrath is a great satirical piece about this <a href='#fnref:2' rev='footnote'>↩</a></li><li class='footnote' id='fn:3'>More accurately, I wanted to ska punk star. It was the 90s and I played trumpet, cut me a break on that one. <a href='#fnref:3' rev='footnote'>↩</a></li><li class='footnote' id='fn:4'><a href="https://s3.amazonaws.com/random-so/ptb.jpg" rel="lightbox" title="Dan Reedy, circa 1999">Proof</a> <a href='#fnref:4' rev='footnote'>↩</a></li><li class='footnote' id='fn:5'><a href="http://en.wikipedia.org/wiki/Finger_(gesture)">A not so kind gesture</a>, also called the bird or flipping us off <a href='#fnref:5' rev='footnote'>↩</a></li><li class='footnote' id='fn:6'><a href="http://www.instructables.com/id/How-To-Pour-Beer---Bottle-and-Draught-aka-Draft-o/">If you&#8217;re curious</a> <a href='#fnref:6' rev='footnote'>↩</a></li><li class='footnote' id='fn:7'>I had the honor of being a technical reviewer of <a href="http://pragprog.com/book/warv/the-rails-view">The Rails View</a> by John Athayde and Bruce Williams, published 2012 by The Pragmatic Bookshelf <a href='#fnref:7' rev='footnote'>↩</a></li><li class='footnote' id='fn:8'>I work at a <a href="http://siu.edu">university</a> and hire student staff as developers <a href='#fnref:8' rev='footnote'>↩</a></li><li class='footnote' id='fn:9'>Most of you will get this reference, so I won&#8217;t link specifically to the Dark Knight marketing campaign or the related meme. <a href='#fnref:9' rev='footnote'>↩</a></li>
    </ol>
</div>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[When Inspiration Strikes]]></title>
    <link href="http://reedy.in/words/archive/2012/09/18/when-inspiration-strikes/"/>
    <updated>2012-09-18T13:53:00+02:00</updated>
    <id>http://reedy.in/words/archive/2012/09/18/when-inspiration-strikes</id>
    <content type="html"><![CDATA[<p>Inspiration is a funny thing. It isn&#8217;t always for the best, sometimes causing us to make mistakes. Without it, though, we would never take risks. We would never succeed. We wouldn&#8217;t put a dent in the universe<sup id='fnref:1'><a href='#fn:1' rel='footnote'>1</a></sup>. The source of our inspiration can play a part in our success or failure as well. We are inspired by the things around us. As others are saying, &#8220;our creativity comes from without, not within&#8221;<sup id='fnref:2'><a href='#fn:2' rel='footnote'>2</a></sup>.</p>

<!-- more -->


<p>In 1996 I would ride my bike to place called The Education Technology Center, a public computer lab. I was fourteen. It wasn&#8217;t very far from my house and on July 5 I was waiting at the door when it opened for the day. The day before they were closed for Independence Day and I&#8217;m sure I had a fine holiday with friends and family, but I was anxious to get back to lab.</p>

<p>You see, when I was born I wasn&#8217;t the only &#8220;new&#8221; thing in our house. Around the time I was born my Dad bought an <a href="http://en.wikipedia.org/wiki/Atari_8-bit_family" title="Atari 8-bit Family">Atari 400</a>. Sure, it took me a few years to gain the ability to use it, but growing up with that beige box hooked up to an old cathode ray tube TV meant that I never knew life without a computer; I never knew life without this sound<sup id='fnref:3'><a href='#fn:3' rel='footnote'>3</a></sup>.</p>

<p><audio controls><source src='https://s3.amazonaws.com/random-so/boot-std.mp3'></audio></p>

<p>As I rode my bike to the Education Technology Center I thought about all the things I would do online that day. It was a different web then. There was no Google, Yahoo! was a startup, there was no dot-com bubble. It was young, it was like me. I checked into the lab and the attendant, himself only a few years older than me, told me about this new service where <em>anyone</em> could get a <em>free</em> email address. Until this point I functioned online without such a thing. But here I was, one day after this free service, Hotmail<sup id='fnref:4'><a href='#fn:4' rel='footnote'>4</a></sup>, began offering an email account to anyone and I was faced with a decision&#8230;What address do I choose?</p>

<p>One year prior a film came out that, for better or worse, shaped my online persona. <a href="http://www.imdb.com/title/tt0113243/" title="Hackers (1995)">Hackers</a>, a movie with questionable ties to any sort of reality, took this beige box that I had grown up with and gave it life beyond 8-bit games. Sure, we&#8217;d used our Atari and connected to bulletin board systems using a 300-baud modem, but what this movie showed was something <em>beyond</em> that. It provided inspiration.</p>

<p>I chose poorly&#8230;I chose o2kuwl.</p>

<p>I&#8217;m not proud about it. I could have had my pick of nearly any account name. Instead, in an attempt to be unique but still pay homage to the movie that so influenced me, I made a terrible choice. But I was inspired to make that choice and for many years that was my identify. Email, IRC, chatrooms, forums, and anywhere else. I was o2kuwl. I made a choice because I was inspired and I lived with it&#8230;for awhile anyway.</p>

<p>Another movie has inspired me lately. This one doesn&#8217;t have over the top visuals or unrealistic depictions of hacking the gibson<sup id='fnref:5'><a href='#fn:5' rel='footnote'>5</a></sup>. Instead, it&#8217;s about one man&#8217;s quest for perfection. In <a href="http://www.magpictures.com/jirodreamsofsushi/" title="Jiro Dreams of Sushi - Official Movie Site">Jiro Dreams of Sushi</a>, Jiro attempts to make perfect sushi, knowing full well that such perfection is impossible. He is a 職人<sup id='fnref:6'><a href='#fn:6' rel='footnote'>6</a></sup>, and strives to make those around him one as well, no matter the cost. This devotion to his craft has made me question my commitment to my own profession. I spend much of my day working with simple tools to make a product that is uniquely crafted to a specific need, much like Jiro. The result of my work is not beautifully plated sushi, but instead &#8220;hand-crafted&#8221; web applications. Clean code.</p>

<p>Jiro, aside from providing another reason to desire a trip to Japan, has inspired me to look at what I do with a critical eye. He has also inspired me to write this and what I hope will become regular entries on this site. There is much to learn from master craftsman from professionals other than our own and I am not the first to recognize the links between developers and chefs<sup id='fnref:7'><a href='#fn:7' rel='footnote'>7</a></sup>. Whether this is simply for me or if you, the reader, gain something from this is ultimately irrelevant. What matters is inspiration has struck and it&#8217;s time to act.</p>

<p>In Jiro Dreams of Sushi, Masuhiro Yamamoto provides five attributes of a great chef. I believe they can be extended beyond that just chefs and I will use them as the basis for future entries. They are</p>

<ol>
<li>Take your work seriously</li>
<li>Aspire to improve</li>
<li>Maintain cleanliness</li>
<li>Be a better leader than a collaborator</li>
<li>Be passionate about your work.</li>
</ol>


<p>Certainly something to think about&#8230;</p>

<div class="footnotes">
    <ol>
        <li class='footnote' id='fn:1'>As Steve Jobs would have said <a href='#fnref:1' rev='footnote'>↩</a></li><li class='footnote' id='fn:2'><a href="http://www.ted.com/talks/kirby_ferguson_embrace_the_remix.html">Kirby Fergson&#8217;s <em>Embrace the Remix TED talk</em></a> <a href='#fnref:2' rev='footnote'>↩</a></li><li class='footnote' id='fn:3'>Thanks to <a href="http://www.atariage.com/forums/topic/190073-looking-for-mp3-of-atari-booting-sound-anyone-have/">Atari Age Forums</a> for this audio file. <a href='#fnref:3' rev='footnote'>↩</a></li><li class='footnote' id='fn:4'>The pre-Microsoft <a href="http://en.wikipedia.org/wiki/Hotmail">Hotmail</a> was groundbreaking <a href='#fnref:4' rev='footnote'>↩</a></li><li class='footnote' id='fn:5'><a href="http://www.youtube.com/watch?v=x3XzPhdBx9g">Hacking the Gibson</a>, a clip from Hackers <a href='#fnref:5' rev='footnote'>↩</a></li><li class='footnote' id='fn:6'>Shokunin, a craftsman or artisan <a href='#fnref:6' rev='footnote'>↩</a></li><li class='footnote' id='fn:7'><a href="http://codelikeachef.com">Code like a Chef</a> by Greg Baugues <a href='#fnref:7' rev='footnote'>↩</a></li>
    </ol>
</div>

]]></content>
  </entry>
  
</feed>
