<?xml version='1.0' encoding='utf-8' ?>
<rss version='2.0'>
  <channel>
    <title>Matt Sears</title>
    <link>http://example.org</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <generator>Aerial</generator>
    <description></description>
    <pubDate>Sat, 10 Dec 2011 20:38:19 +0000</pubDate>
    <item>
      <title>Minitest Quick Reference</title>
      <link>http://www.mattsears.com/articles/2011/12/10/minitest-quick-reference</link>
      <description>
        <![CDATA[<p><a href="https://github.com/seattlerb/minitest">MiniTest</a>, as the name suggests, is a
        small and fast unit testing framework. Shipped with Ruby 1.9, MiniTest supports
        a complete suite of testing capabilities such as TDD, BDD, mocking, and benchmarking.</p><p>This quick reference aims to demonstrate MiniTest's main concepts and
        provide real world examples to get you acquainted quickly. Let's start with
        MiniTest::Spec.</p><h2>MiniTest::Spec</h2><p>Provides RSpec-like matchers and contexts right out of the box.</p><div class="highlight">
        <pre><span class="nb">require</span> <span class="s1">'minitest/autorun'</span>
        
        <span class="n">describe</span> <span class="no">Hipster</span><span class="p">,</span> <span class="s2">"Demonstration of MiniTest"</span> <span class="k">do</span>
          <span class="n">before</span> <span class="k">do</span>
            <span class="vi">@hipster</span> <span class="o">=</span> <span class="no">Hipster</span><span class="o">.</span><span class="n">new</span>
          <span class="k">end</span>
        
          <span class="n">after</span> <span class="k">do</span>
            <span class="vi">@hipster</span><span class="o">.</span><span class="n">destroy!</span>
          <span class="k">end</span>
        
          <span class="n">subject</span> <span class="k">do</span>
            <span class="nb">Array</span><span class="o">.</span><span class="n">new</span><span class="o">.</span><span class="n">tap</span> <span class="k">do</span> <span class="o">|</span><span class="n">attributes</span><span class="o">|</span>
              <span class="n">attributes</span> <span class="o">&lt;&lt;</span> <span class="s2">"silly hats"</span>
              <span class="n">attributes</span> <span class="o">&lt;&lt;</span> <span class="s2">"skinny jeans"</span>
            <span class="k">end</span>
          <span class="k">end</span>
        
          <span class="n">let</span><span class="p">(</span><span class="ss">:list</span><span class="p">)</span> <span class="p">{</span> <span class="nb">Array</span><span class="o">.</span><span class="n">new</span> <span class="p">}</span>
        
          <span class="n">describe</span> <span class="s2">"when asked about the font"</span> <span class="k">do</span>
            <span class="n">it</span> <span class="s2">"should be helvetica"</span> <span class="k">do</span>
              <span class="vi">@hipster</span><span class="o">.</span><span class="n">preferred_font</span><span class="o">.</span><span class="n">must_equal</span> <span class="s2">"helvetica"</span>
            <span class="k">end</span>
          <span class="k">end</span>
        
          <span class="n">describe</span> <span class="s2">"when asked about mainstream"</span> <span class="k">do</span>
            <span class="n">it</span> <span class="s2">"won't be mainstream"</span> <span class="k">do</span>
              <span class="vi">@hipster</span><span class="o">.</span><span class="n">mainstream?</span><span class="o">.</span><span class="n">wont_equal</span> <span class="kp">true</span>
            <span class="k">end</span>
          <span class="k">end</span>
        <span class="k">end</span>
        </pre>
        </div><h3>Matchers (must | wont)</h3><p>In most cases you can switch between <code>must</code> for positive expectations and <code>wont</code>
        for negative expectations.</p><table>
        <thead><tr>
        <td align="left">Assertion</td>
        <td align="left">Examples</td>
        </tr></thead>
        <tbody>
        <tr>
        <td align="left"><code>must_be</code></td>
        <td align="left"><code>list.size.must_be :==, 0</code></td>
        </tr>
        <tr>
        <td align="left"><code>must_be_close_to</code></td>
        <td align="left"><code>subject.size.must_be_close_to 1,1</code></td>
        </tr>
        <tr>
        <td align="left"><code>must_be_empty</code></td>
        <td align="left"><code>list.must_be_empty</code></td>
        </tr>
        <tr>
        <td align="left"><code>must_be_instance_of</code></td>
        <td align="left"><code>list.must_be_instance_of Array</code></td>
        </tr>
        <tr>
        <td align="left"><code>must_be_kind_of</code></td>
        <td align="left"><code>list.must_be_kind_of Enumerable</code></td>
        </tr>
        <tr>
        <td align="left"><code>must_be_nil</code></td>
        <td align="left"><code>list.first.must_be_nil</code></td>
        </tr>
        <tr>
        <td align="left"><code>must_be_same_as</code></td>
        <td align="left"><code>subject.must_be_same_as subject</code></td>
        </tr>
        <tr>
        <td align="left"><code>must_be_silent</code></td>
        <td align="left"><code>proc { "no stdout or stderr" }.must_be_silent</code></td>
        </tr>
        <tr>
        <td align="left"><code>must_be_within_epsilon</code></td>
        <td align="left"><code>subject.size.must_be_within_epsilon 1,1</code></td>
        </tr>
        <tr>
        <td align="left"><code>must_equal</code></td>
        <td align="left"><code>subject.size.must_equal 2</code></td>
        </tr>
        <tr>
        <td align="left"><code>must_include</code></td>
        <td align="left"><code>subject.must_include "skinny jeans"</code></td>
        </tr>
        <tr>
        <td align="left"><code>must_match</code></td>
        <td align="left"><code>subject.first.must_match /silly/</code></td>
        </tr>
        <tr>
        <td align="left"><code>must_output</code></td>
        <td align="left"><code>proc { print "#{subject.size}!" }.must_output "2!"</code></td>
        </tr>
        <tr>
        <td align="left"><code>must_respond_to</code></td>
        <td align="left"><code>subject.must_respond_to :count</code></td>
        </tr>
        <tr>
        <td align="left"><code>must_raise</code></td>
        <td align="left"><code>proc { subject.foo }.must_raise NoMethodError</code></td>
        </tr>
        <tr>
        <td align="left"><code>must_send</code></td>
        <td align="left"><code>subject.must_send [subject, :values_at, 0]</code></td>
        </tr>
        <tr>
        <td align="left"><code>must_throw</code></td>
        <td align="left"><code>proc { throw :done if subject.any? }.must_throw :done</code></td>
        </tr>
        </tbody>
        </table>
        <h2>MiniTest::Unit::TestCase</h2><p>Provides a rich set of assertions to make your tests clean and readable.</p><div class="highlight">
        <pre><span class="nb">require</span> <span class="s1">'minitest/autorun'</span>
        
        <span class="k">class</span> <span class="nc">TestHipster</span> <span class="o">&lt;</span> <span class="no">MiniTest</span><span class="o">::</span><span class="no">Unit</span><span class="o">::</span><span class="no">TestCase</span>
          <span class="k">def</span> <span class="nf">setup</span>
            <span class="vi">@hipster</span> <span class="o">=</span> <span class="no">Hipster</span><span class="o">.</span><span class="n">new</span>
            <span class="vi">@list</span>    <span class="o">=</span> <span class="nb">Array</span><span class="o">.</span><span class="n">new</span>
            <span class="vi">@subject</span> <span class="o">=</span> <span class="o">[</span><span class="s2">"silly hats"</span><span class="p">,</span> <span class="s2">"skinny jeans"</span><span class="o">]</span>
          <span class="k">end</span>
        
          <span class="k">def</span> <span class="nf">teardown</span>
            <span class="vi">@hipster</span><span class="o">.</span><span class="n">destroy!</span>
          <span class="k">end</span>
        
          <span class="k">def</span> <span class="nf">test_for_helvetica_font</span>
            <span class="n">assert_equal</span> <span class="s2">"helvetica!"</span><span class="p">,</span> <span class="vi">@hipster</span><span class="o">.</span><span class="n">preferred_font</span>
          <span class="k">end</span>
        
          <span class="k">def</span> <span class="nf">test_not_mainstream</span>
            <span class="n">refute</span> <span class="vi">@hipster</span><span class="o">.</span><span class="n">mainstream?</span>
          <span class="k">end</span>
        <span class="k">end</span>
        </pre>
        </div><h3>Assertions (assert | refute)</h3><p>Toggle between <code>assert</code> for positive assertions and <code>refute</code> for negative assertions.</p><table>
        <thead><tr>
        <td align="left">Assertion</td>
        <td align="left">Example</td>
        </tr></thead>
        <tbody>
        <tr>
        <td align="left"><code>assert</code></td>
        <td align="left"><code>assert @subject.any?, "empty subjects"</code></td>
        </tr>
        <tr>
        <td align="left"><code>assert_block</code></td>
        <td align="left"><code>assert_block { @subject.any? }</code></td>
        </tr>
        <tr>
        <td align="left"><code>assert_empty</code></td>
        <td align="left"><code>assert_empty @list</code></td>
        </tr>
        <tr>
        <td align="left"><code>assert_equal</code></td>
        <td align="left"><code>assert_equal 2, @subject.size</code></td>
        </tr>
        <tr>
        <td align="left"><code>assert_in_delta</code></td>
        <td align="left"><code>assert_in_delta @subject.size, 1,1</code></td>
        </tr>
        <tr>
        <td align="left"><code>assert_in_epsilon</code></td>
        <td align="left"><code>assert_in_epsilon @subject.size, 1, 1</code></td>
        </tr>
        <tr>
        <td align="left"><code>assert_include</code></td>
        <td align="left"><code>assert_include "skinny jeans", @subject</code></td>
        </tr>
        <tr>
        <td align="left"><code>assert_instance_of</code></td>
        <td align="left"><code>assert_instance_of Array, @list</code></td>
        </tr>
        <tr>
        <td align="left"><code>assert_kind_of</code></td>
        <td align="left"><code>assert_kind_of Enumerable, @list</code></td>
        </tr>
        <tr>
        <td align="left"><code>assert_match</code></td>
        <td align="left"><code>assert_match @subject.first, /silly/</code></td>
        </tr>
        <tr>
        <td align="left"><code>assert_nil</code></td>
        <td align="left"><code>assert_nil @list.first</code></td>
        </tr>
        <tr>
        <td align="left"><code>assert_operator</code></td>
        <td align="left"><code>assert_operator @list.size, :== , 0</code></td>
        </tr>
        <tr>
        <td align="left"><code>assert_output</code></td>
        <td align="left"><code>assert_output("Size: 2") { print "Size: #{@subject.size}"}</code></td>
        </tr>
        <tr>
        <td align="left"><code>assert_raises</code></td>
        <td align="left"><code>assert_raises(NoMethodError) { @subject.foo }</code></td>
        </tr>
        <tr>
        <td align="left"><code>assert_respond_to</code></td>
        <td align="left"><code>assert_respond_to @subject, :count</code></td>
        </tr>
        <tr>
        <td align="left"><code>assert_same</code></td>
        <td align="left"><code>assert_same @subject, @subject, "It's the same object silly"</code></td>
        </tr>
        <tr>
        <td align="left"><code>assert_send</code></td>
        <td align="left"><code>assert_send [@subject, :values_at, 0]</code></td>
        </tr>
        <tr>
        <td align="left"><code>assert_silent</code></td>
        <td align="left"><code>assert_silent { "no stdout or stderr" }</code></td>
        </tr>
        <tr>
        <td align="left"><code>assert_throws</code></td>
        <td align="left"><code>assert_throws(:error,'is empty') {throw :error if @subject.any?}</code></td>
        </tr>
        </tbody>
        </table>
        <h2>MiniTest::Mock</h2><p>A simple and clean mock system. There two essential methods at our disposal:
        <code>expect</code> and <code>verify</code>.</p><div class="highlight">
        <pre><span class="nb">require</span> <span class="s1">'minitest/autorun'</span>
        
        <span class="k">class</span> <span class="nc">Twipster</span>
          <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">twitter</span><span class="p">)</span>
            <span class="c1"># A Ruby wrapper for the Twitter API</span>
            <span class="vi">@twitter</span> <span class="o">=</span> <span class="n">twitter</span>
          <span class="k">end</span>
        
          <span class="k">def</span> <span class="nf">submit</span><span class="p">(</span><span class="n">tweet</span><span class="p">)</span>
            <span class="vi">@twitter</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="s2">"</span><span class="si">#{</span><span class="n">tweet</span><span class="si">}</span><span class="s2"> #lolhipster"</span><span class="p">)</span>
          <span class="k">end</span>
        <span class="k">end</span>
        
        <span class="n">describe</span> <span class="no">Twipster</span><span class="p">,</span> <span class="s2">"Make every tweet a hipster tweet."</span> <span class="k">do</span>
          <span class="n">before</span> <span class="k">do</span>
            <span class="vi">@twitter</span>  <span class="o">=</span> <span class="no">MiniTest</span><span class="o">::</span><span class="no">Mock</span><span class="o">.</span><span class="n">new</span>
            <span class="vi">@twipster</span> <span class="o">=</span> <span class="no">Twipster</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="vi">@twitter</span><span class="p">)</span>
          <span class="k">end</span>
        
          <span class="n">it</span> <span class="s2">"should append a #lolhipster hashtag and update Twitter with our status"</span> <span class="k">do</span>
            <span class="n">tweet</span> <span class="o">=</span> <span class="s2">"Skyrim? Too mainstream."</span>
            <span class="vi">@twitter</span><span class="o">.</span><span class="n">expect</span> <span class="ss">:update</span><span class="p">,</span> <span class="kp">true</span><span class="p">,</span> <span class="o">[</span><span class="s2">"</span><span class="si">#{</span><span class="n">tweet</span><span class="si">}</span><span class="s2"> #lolhipster"</span><span class="o">]</span>
            <span class="vi">@twipster</span><span class="o">.</span><span class="n">submit</span><span class="p">(</span><span class="n">tweet</span><span class="p">)</span>
            <span class="n">assert</span> <span class="vi">@twitter</span><span class="o">.</span><span class="n">verify</span> <span class="c1"># verifies tweet and hashtag was passed to `@twitter.update`</span>
          <span class="k">end</span>
        <span class="k">end</span>
        </pre>
        </div><h2>Resources</h2><ol>
        <li><a href="https://github.com/seattlerb/minitest">MiniTest on Github</a></li>
        <li><a href="http://docs.seattlerb.org/minitest">MiniTest Rdoc</a></li>
        <li><a href="http://metaskills.net/2011/03/26/using-minitest-spec-with-rails">Using MiniTest::Spec with Rails</a></li>
        <li><a href="http://www.rubyinside.com/a-minitestspec-tutorial-elegant-spec-style-testing-that-comes-with-ruby-5354.html">Ruby Inside: A MiniTest::Spec Tutorial: Elegant Spec-Style Testing That Comes With Ruby</a></li>
        </ol>
        <p>I hope you found this quick guide valuable. Please let me know if you'd like
        to see anything else included and feel free to ask questions or give feedback
        in the comments section.</p>]]>
      </description>
      <pubDate>Sat, 10 Dec 2011 20:38:19 +0000</pubDate>
      <guid isPermaLink='false'>96394f8ab93f70b2e9cbf939b88b446ce9fa7102</guid>
    </item>
    <item>
      <title>Ruby Blocks as Dynamic Callbacks</title>
      <link>http://www.mattsears.com/articles/2011/11/27/ruby-blocks-as-dynamic-callbacks</link>
      <description>
        <![CDATA[<p>Callbacks are a great technique for achieving simplicity and flexibility. Simply put,
        a callback is a block of code passed as an argument to a method. In Ruby, code
        blocks are everywhere and Ruby makes it trivial to pass a block of code to
        methods. For example:</p><div class="highlight">
        <pre><span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">bar</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">block</span><span class="p">)</span>
          <span class="n">callback</span> <span class="o">=</span> <span class="n">block</span>
          <span class="n">callback</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">bar</span><span class="p">)</span>
        <span class="k">end</span>
        
        <span class="n">foo</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span> <span class="p">{</span><span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="n">x</span> <span class="o">*</span> <span class="n">x</span><span class="p">}</span> <span class="c1"># =&gt; 25</span>
        </pre>
        </div><p>But what do we do when a method needs two blocks of code or more? Consider the
        classic case where we want a method to execute a block of code if an action
        succeeds or call different code if an action fails.</p><p>In this article, I will demonstrate how we can pass multiple blocks to a method and
        with some metaprogramming, we can achieve a dynamic callback mechanism with just
        a few lines of code.</p><p>Let's add a method called <code>callback</code> to the Proc class:</p><div class="highlight">
        <pre><span class="k">class</span> <span class="nc">Proc</span>
          <span class="k">def</span> <span class="nf">callback</span><span class="p">(</span><span class="n">callable</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span>
            <span class="nb">self</span> <span class="o">===</span> <span class="no">Class</span><span class="o">.</span><span class="n">new</span> <span class="k">do</span>
              <span class="n">method_name</span> <span class="o">=</span> <span class="n">callable</span><span class="o">.</span><span class="n">to_sym</span>
              <span class="n">define_method</span><span class="p">(</span><span class="n">method_name</span><span class="p">)</span> <span class="p">{</span> <span class="o">|&amp;</span><span class="n">block</span><span class="o">|</span> <span class="n">block</span><span class="o">.</span><span class="n">nil?</span> <span class="p">?</span> <span class="kp">true</span> <span class="p">:</span> <span class="n">block</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span> <span class="p">}</span>
              <span class="n">define_method</span><span class="p">(</span><span class="s2">"</span><span class="si">#{</span><span class="n">method_name</span><span class="si">}</span><span class="s2">?"</span><span class="p">)</span> <span class="p">{</span> <span class="kp">true</span> <span class="p">}</span>
              <span class="k">def</span> <span class="nf">method_missing</span><span class="p">(</span><span class="n">method_name</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">block</span><span class="p">)</span> <span class="kp">false</span><span class="p">;</span> <span class="k">end</span>
            <span class="k">end</span><span class="o">.</span><span class="n">new</span>
          <span class="k">end</span>
        <span class="k">end</span>
        </pre>
        </div><p>That's it! The above <code>Proc#callback</code> method simply yields an anonymous class
        with methods defined to handle our callbacks. This allows for the capability of
        creating and storing dynamic callbacks, which can later be looked up and
        executed as needed.</p><p>Notice anything unusual? We're using the <code>===</code> operand to invoke the
        block. <code>Proc#===</code> is an alias for <code>Proc.call</code>. Anything on the right side of
        <code>===</code> acts as the proc's parameter. Normally, this is to allow a proc object to
        be a target of a <code>when</code> clause in case statements, but we're using it as a super
        simple way of invoking our anonymous class.</p><p>Let&rsquo;s try it with something useful. Let&rsquo;s say we&rsquo;re writing something which
        needs to happen in an all-or-nothing, atomic fashion. Either the whole thing
        works, or none of it does.  A simple case is tweeting:</p><div class="highlight">
        <pre><span class="k">def</span> <span class="nf">tweet</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">block</span><span class="p">)</span>
          <span class="no">Twitter</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
          <span class="n">block</span><span class="o">.</span><span class="n">callback</span> <span class="ss">:success</span>
        <span class="k">rescue</span> <span class="o">=&gt;</span> <span class="n">e</span>
          <span class="n">block</span><span class="o">.</span><span class="n">callback</span> <span class="ss">:failure</span><span class="p">,</span> <span class="n">e</span><span class="o">.</span><span class="n">message</span>
        <span class="k">end</span>
        </pre>
        </div><p>The <code>tweet</code> method accepts a message string and &amp;block parameters. We call
        <code>callback</code> on the block and give it a name. Any name will work :success, :error,
        :fail!, whatever. In addition, we can pass arguments to the blocks (more on that
        later). Now we can provide a status if the tweet was successful or not:</p><div class="highlight">
        <pre><span class="n">tweet</span> <span class="s2">"Ruby methods with multiple blocks. #lolruby"</span> <span class="k">do</span> <span class="o">|</span><span class="n">on</span><span class="o">|</span>
          <span class="n">on</span><span class="o">.</span><span class="n">success</span> <span class="k">do</span>
            <span class="nb">puts</span> <span class="s2">"Tweet successful!"</span>
          <span class="k">end</span>
          <span class="n">on</span><span class="o">.</span><span class="n">failure</span> <span class="k">do</span> <span class="o">|</span><span class="n">status</span><span class="o">|</span>
            <span class="nb">puts</span> <span class="s2">"Error: </span><span class="si">#{</span><span class="n">status</span><span class="si">}</span><span class="s2">"</span>
          <span class="k">end</span>
        <span class="k">end</span>
        </pre>
        </div><p>The advantage here is that we define our own mini DSL. We don't need to worry
        about passing too many or unexpected blocks. We could have easily said
        <code>where.success</code> or <code>on.error</code> or <code>update.fail!</code>. Also note the <code>on.failure</code>
        block includes a <code>status</code> parameter - this contains the exception message
        captured in the <code>tweet</code> method above. So if Twitter was down for whatever
        reason, the <code>on.failure</code> block would be invoked and printed 'Error: Twitter is
        down or being upgraded'.</p><p>Bonus: In addition to wrapping code in blocks, our <code>Proc#callback</code> method
        defines boolean style methods. So we could have call the tweet method like this
        if we wanted to:</p><div class="highlight">
        <pre><span class="n">tweet</span> <span class="s2">"Ruby methods with multiple blocks. #lolruby"</span> <span class="k">do</span> <span class="o">|</span><span class="n">update</span><span class="o">|</span>
          <span class="nb">puts</span> <span class="s2">"Tweet successful!"</span> <span class="k">if</span> <span class="n">update</span><span class="o">.</span><span class="n">success?</span>
          <span class="nb">puts</span> <span class="s2">"Sorry, something went wrong."</span> <span class="k">if</span> <span class="n">update</span><span class="o">.</span><span class="n">failure?</span>
        <span class="k">end</span>
        </pre>
        </div><p>Put the <code>Proc#callback</code> method in a utility library and your code will look neat and tidy.</p><p>As always, I welcome your thoughts and feedback. Let me know what you think of
        the techniques shown here, or share your own favorite code block tricks.</p>]]>
      </description>
      <pubDate>Sun, 27 Nov 2011 11:38:19 +0000</pubDate>
      <guid isPermaLink='false'>5ee46db32aa5a64caf654f0efb0eaf7af042e8a2</guid>
    </item>
    <item>
      <title>Nyan Cat RSpec Formatter</title>
      <link>http://www.mattsears.com/articles/2011/11/16/nyan-cat-rspec-formatter</link>
      <description>
        <![CDATA[<p>I watch a lot of tests run in a given day. So I figured why not make it more
        fun. Inspired by <a href="https://github.com/seattlerb/minitest">minitest</a>'s pride, and um
        cats? I came up with a <a href="http://www.youtube.com/watch?v=QH2-TGUlwu4">Nyan Cat</a>
        inspired RSpec formatter.</p><p>Update: After last week's launch, Nyan Cat received a great response from the
        Ruby world. Over the weekend, I released version 0.0.2.  It includes a few bug
        fixes and some really cool enhancements. Most notably, Nyan Cat now spans
        multiple lines. In addition, it displays running totals of passing, pending,
        and failed specs. Thanks to everyone who contributed! Checkout the new
        screencast below.</p><pre><code>-_-_-_-_-_-_-_,------,
        _-_-_-_-_-_-_-|   /\_/\
        -_-_-_-_-_-_-~|__( ^ .^)
        _-_-_-_-_-_-_-""  ""
        </code></pre><h2>Nyan Cat</h2><p>Much like <a href="https://github.com/kapoq/nyan">Nyan</a>, Nyan Cat simply creates a rainbow
        trail of test results. It counts the number of examples as they execute and
        highlights failed and pending specs. The rainbow changes colors as it runs and
        if all the specs pass, Nyan Cat falls asleep.  If there are any pending or
        failing specs, Nyan cat is concerned and can't sleep.</p><p>Here's a short demo of Nyan Cat in action.</p><p></p>
        <center>
          <iframe src="http://player.vimeo.com/video/32424001?title=0&amp;byline=0&amp;portrait=0" width="640" height="480" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
        </center><p>Installing Nyan Cat is easy. Just install the gem <code>nyan-cat-formatter</code> and simply put the options in your .rspec file:</p><pre><code>--format NyanCatFormatter
        </code></pre><p>Checkout the code on <a href="https://github.com/mattsears/nyan-cat-formatter">Github</a>
        and let me know how you like it.  If you run into any issues, please create an
        issue on Github and I will be sure to get it fixed. Of course you can always
        fork the project and send me a pull request.</p><p>Have fun!</p>]]>
      </description>
      <pubDate>Wed, 16 Nov 2011 20:38:19 +0000</pubDate>
      <guid isPermaLink='false'>9160a22a357a94ef14ad09bd3b2663b6ea05367b</guid>
    </item>
    <item>
      <title>Gaga: A Git-Backed Key/Value Store</title>
      <link>http://www.mattsears.com/articles/2011/10/20/gaga-key-value-store</link>
      <description>
        <![CDATA[<p>Gaga originated from my winning entry in Codebrawl's <a href="http://codebrawl.com/contests/key-value-stores">Key/Value
        Store</a> contest. The challenge
        was to write the best key/value storage backend you can think of. Since Git is
        fast, reliable, and a great tool for storing source code, I was really
        interested in making an easy way to store key/values.</p><p>Built with <a href="https://github.com/mojombo/grit">Grit</a>, Gaga supports SET, GET, KEYS,
        and DELETE operations. And since it's Git, we can easily enhance it to include
        other awesome Git features such as branches, diffs, reverting, etc.</p><h2>Usage</h2><div class="highlight">
        <pre><span class="vi">@gaga</span> <span class="o">=</span> <span class="no">Gaga</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">:repo</span> <span class="o">=&gt;</span> <span class="s1">'/path/to/repo'</span><span class="p">)</span>
        
        <span class="c1"># SET</span>
        <span class="vi">@gaga</span><span class="o">[</span><span class="s1">'lady'</span><span class="o">]</span> <span class="o">=</span> <span class="s2">"gaga"</span>
        
        <span class="c1"># GET</span>
        <span class="vi">@gaga</span><span class="o">[</span><span class="s1">'lady'</span><span class="o">]</span> <span class="c1">#=&gt; "gaga"</span>
        
        <span class="c1"># KEYS</span>
        <span class="vi">@gaga</span><span class="o">.</span><span class="n">keys</span>  <span class="c1">#=&gt; ['lady']</span>
        
        <span class="c1"># DELETE</span>
        <span class="vi">@gaga</span><span class="o">.</span><span class="n">delete</span><span class="p">(</span><span class="s1">'lady'</span><span class="p">)</span> <span class="c1">#=&gt; 'gaga'</span>
        
        <span class="c1"># Remove all items from the store</span>
        <span class="vi">@gaga</span><span class="o">.</span><span class="n">clear</span>
        </pre>
        </div><p>That works pretty well. Now, we can harness the power of Git and enhance our data
        store. For example, we can get a history log for a specific key:</p><div class="highlight">
        <pre><span class="c1"># LOG</span>
        <span class="vi">@gaga</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s1">'lady'</span><span class="p">)</span>
        
        <span class="c1"># Produces:</span>
        <span class="o">[</span>
         <span class="p">{</span><span class="s2">"message"</span><span class="o">=&gt;</span><span class="s2">"all clear"</span><span class="p">,</span><span class="s2">"committer"</span><span class="o">=&gt;</span><span class="p">{</span><span class="s2">"name"</span><span class="o">=&gt;</span><span class="s2">"Matt Sears"</span><span class="p">,</span> <span class="s2">"email"</span><span class="o">=&gt;</span><span class="s2">"matt@mattsears.com"</span><span class="p">},</span> <span class="s2">"committed_date"</span><span class="o">=&gt;</span><span class="s2">"2011-09-05..."</span><span class="p">},</span>
         <span class="p">{</span><span class="s2">"message"</span><span class="o">=&gt;</span><span class="s2">"set 'lady' "</span><span class="p">,</span> <span class="s2">"committer"</span><span class="o">=&gt;</span><span class="p">{</span><span class="s2">"name"</span><span class="o">=&gt;</span><span class="s2">"Matt Sears"</span><span class="p">,</span> <span class="s2">"email"</span><span class="o">=&gt;</span><span class="s2">"matt@mattsears.com"</span><span class="p">},</span> <span class="s2">"committed_date"</span><span class="o">=&gt;</span><span class="s2">"2011-09-05..."</span><span class="p">}</span>
         <span class="p">{</span><span class="s2">"message"</span><span class="o">=&gt;</span><span class="s2">"delete 'lady' "</span><span class="p">,</span> <span class="s2">"committer"</span><span class="o">=&gt;</span><span class="p">{</span><span class="s2">"name"</span><span class="o">=&gt;</span><span class="s2">"Matt Sears"</span><span class="p">,</span> <span class="s2">"email"</span><span class="o">=&gt;</span><span class="s2">"matt@mattsears.com"</span><span class="p">},</span> <span class="s2">"committed_date"</span><span class="o">=&gt;</span><span class="s2">"2011-09-05..."</span><span class="p">}</span>
        <span class="o">]</span>
        </pre>
        </div><p>This is just a start. There's still a lot things we can add.  If you are interested in more detailed information, check out the repo
        on <a href="https://github.com/mattsears/gaga">Github</a>.</p>]]>
      </description>
      <pubDate>Thu, 20 Oct 2011 20:38:19 +0000</pubDate>
      <guid isPermaLink='false'>000c92ed39d10a4f81e1efad0c8fbe30f85cd28a</guid>
    </item>
    <item>
      <title>Print Stamps With Ruby!</title>
      <link>http://www.mattsears.com/articles/2011/5/15/print-stamps-with-ruby</link>
      <description>
        <![CDATA[<p>I've just released <a href="https://github.com/mattsears/stamps">Stamps</a> - A Ruby gem for creating postage labels,
        calculate the shipping cost of packages, standardize domestic
        addresses via USPS CASS certified Address Matching Software, and track
        shipments using the Stamps.com Web Services API.</p><h3>Quick Start</h3><p>First, you will need to register for a (free) developer account at
        <a href="http://developer.stamps.com/developer">Stamps.com</a>. Once you receive
        your test credentials and integration id, just plug them into the
        configuration block:</p><div class="highlight">
        <pre><span class="no">Stamps</span><span class="o">.</span><span class="n">configure</span> <span class="k">do</span> <span class="o">|</span><span class="n">config</span><span class="o">|</span>
          <span class="n">config</span><span class="o">.</span><span class="n">integration_id</span> <span class="o">=</span> <span class="s1">'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXX'</span>
          <span class="n">config</span><span class="o">.</span><span class="n">username</span>       <span class="o">=</span> <span class="s1">'STAMPS USERNAME'</span>
          <span class="n">config</span><span class="o">.</span><span class="n">password</span>       <span class="o">=</span> <span class="s1">'STAMPS PASSWORD'</span>
        <span class="k">end</span>
        </pre>
        </div><p>For a simple test, we can call <code>Stamps.account</code> to retreive
        information about the account.  By default, Stamps will return all
        responses as a Hash.</p><h3>Create a Stamp</h3><p>First, we need to standardize the shipping address that complies with the USPS address
        formatting guidelines:</p><div class="highlight">
        <pre><span class="n">standardized_address</span> <span class="o">=</span> <span class="no">Stamps</span><span class="o">.</span><span class="n">clean_address</span><span class="p">(</span>
          <span class="ss">:address</span> <span class="o">=&gt;</span> <span class="p">{</span>
            <span class="ss">:full_name</span> <span class="o">=&gt;</span> <span class="s1">'The White House'</span><span class="p">,</span>
            <span class="ss">:address1</span>  <span class="o">=&gt;</span> <span class="s1">'1600 Pennsylvania Avenue, NW'</span><span class="p">,</span>
            <span class="ss">:city</span>      <span class="o">=&gt;</span> <span class="s1">'Washington'</span><span class="p">,</span>
            <span class="ss">:state</span>     <span class="o">=&gt;</span> <span class="s1">'DC'</span><span class="p">,</span>
            <span class="ss">:zip_code</span>  <span class="o">=&gt;</span> <span class="s1">'20500'</span>
        <span class="p">})</span>
        </pre>
        </div><p>Now that we have a clean address we can create a new stamp.  The
        <code>Stamps.create!</code> takes the sender and receiver address along with parameters
        on the rate:</p><div class="highlight">
        <pre><span class="n">stamp</span> <span class="o">=</span> <span class="no">Stamps</span><span class="o">.</span><span class="n">create!</span><span class="p">(</span>
            <span class="ss">:rate</span>          <span class="o">=&gt;</span> <span class="p">{</span>
              <span class="ss">:from_zip_code</span> <span class="o">=&gt;</span> <span class="s1">'45440'</span><span class="p">,</span>
              <span class="ss">:to_zip_code</span>   <span class="o">=&gt;</span> <span class="s1">'20500'</span><span class="p">,</span>
              <span class="ss">:weight_oz</span>     <span class="o">=&gt;</span> <span class="s1">'6.5'</span><span class="p">,</span>
              <span class="ss">:ship_date</span>      <span class="o">=&gt;</span> <span class="no">Date</span><span class="o">.</span><span class="n">today</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s1">'%Y-%m-%d'</span><span class="p">),</span>
              <span class="ss">:package_type</span>   <span class="o">=&gt;</span> <span class="s1">'Package'</span><span class="p">,</span>
              <span class="ss">:service_type</span>   <span class="o">=&gt;</span> <span class="s1">'US-FC'</span>  <span class="c1"># Flat-rate</span>
            <span class="p">},</span>
            <span class="ss">:to</span>            <span class="o">=&gt;</span> <span class="n">standardized_address</span><span class="p">,</span>
            <span class="ss">:from</span> <span class="o">=&gt;</span> <span class="p">{</span>
              <span class="ss">:full_name</span>   <span class="o">=&gt;</span> <span class="s1">'Littlelines'</span><span class="p">,</span>
              <span class="ss">:address1</span>    <span class="o">=&gt;</span> <span class="s1">'50 Chestnut Street'</span><span class="p">,</span>
              <span class="ss">:address2</span>    <span class="o">=&gt;</span> <span class="s1">'Suite 234'</span><span class="p">,</span>
              <span class="ss">:city</span>        <span class="o">=&gt;</span> <span class="s1">'Beavervcreek'</span><span class="p">,</span>
              <span class="ss">:state</span>       <span class="o">=&gt;</span> <span class="s1">'OH'</span><span class="p">,</span>
              <span class="ss">:zip_code</span>    <span class="o">=&gt;</span> <span class="s1">'45440'</span>
            <span class="p">}</span>
        <span class="p">)</span>
        </pre>
        </div><h3>Hooray!</h3><p>That's it! Stamps will return a url of the stamp.  Print it and ship it!</p><div class="highlight">
        <pre><span class="n">stamp</span><span class="o">[</span><span class="ss">:url</span><span class="o">]</span>
        </pre>
        </div><p>If you are interested in more detailed information, check out the repo
        on <a href="https://github.com/mattsears/stamps">Github</a>.</p>]]>
      </description>
      <pubDate>Sun, 15 May 2011 20:38:19 +0000</pubDate>
      <guid isPermaLink='false'>10f5818726b6b5930284e2c4d95e1511bdd648ca</guid>
    </item>
    <item>
      <title>Easy Multiple Account Management for Heroku</title>
      <link>http://www.mattsears.com/articles/2011/1/11/easy-multiple-account-management-for-heroku</link>
      <description>
        <![CDATA[<p>Recently, I migrated all of my personal and <a href="http://littlelines.com">business</a> sites
        to <a href="http://heroku.com">Heroku</a>. Heroku, as you may know, is a fantastic
        service for hosting ruby applications. Oh, and it's free!</p><p>Like a lot of folks, I keep work and personal items such
        as email, bank accounts, github, etc in separate accounts.
        Heroku doesn't really place nice with multiple accounts.</p><p>So how to do we effectively manage multiple Heroku accounts?</p><h3>Prerequitites</h3><p>The following assumes you are on the Mac OS or *nix system, own
        multiple Heroku accounts, and have installed the Heroku gem. I should
        also be point out that you will need to create separate ssh
        public keys for each account.</p><h3>Custom Ruby Script</h3><p>One option is we can use a script such as Keith Gaddis
        <a href="http://collectiveidea.com/blog/archives/2010/08/06/heroku-ing-with-multiple-personalities">describes</a>
        over at the Collective Idea blog. With his <a href="https://gist.github.com/511789">switcher</a> script, we can
        switch between two accounts like this:</p><pre><code>ruby switcher.rb personal
        ruby switcher.rb work
        </code></pre><p>This essentially swaps the credentials file (used by the Heroku gem
        for authentication) for the account you want to
        use. This works well enough, however this can be tedious especially if
        you switch between work and personal projects frequently.</p><h3>Enter Heroku Accounts Plugin</h3><p>David Dollar of Heroku recently released an official Heroku
        plugin called <a href="https://github.com/ddollar/heroku-accounts">heroku-accounts</a>. With
        this plugin, we can switch Heroku accounts automatically.</p><p>To get started, we first install the plugin:</p><pre><code>heroku plugins:install git://github.com/ddollar/heroku-accounts.git
        </code></pre><p>The installation process will download the plugin from github and save
        it to the <code>~/.heroku/plugins</code> directory. Now, we can
        setup each of our Heroku accounts with <code>add</code> command:</p><pre><code>heroku accounts:add work
        </code></pre><p>and for our personal account, we can run:</p><pre><code>heroku accounts:add personal
        </code></pre><p>The <code>add</code> command will ask you for your Heroku email address and
        password for each account. The plugin will maintain
        your account credentials in the <code>~/.heroku/accounts</code> folder in your
        home directory. (Passwords are not saved in plain text)</p><p>To assign a project to a specific Heroku account, we run the following
        command in the project root:</p><pre><code>heroku accounts:set personal # or work
        </code></pre><p>This will assign a Heroku account to the project by adding an 'account' variable
        to the project's git config file.</p><h3>Celebrate</h3><p>Hooray! Now we can switch Heroku accounts automatically. Awesome.</p>]]>
      </description>
      <pubDate>Tue, 11 Jan 2011 20:38:19 +0000</pubDate>
      <guid isPermaLink='false'>1ca192f39e0b2f46b5839b3f600393d53cc2af73</guid>
    </item>
    <item>
      <title>5 Ruby Gems for Concise Code</title>
      <link>http://www.mattsears.com/articles/2009/10/31/5-ruby-gems-for-concise-code</link>
      <description>
        <![CDATA[<p>At <a href="http://littlelines.com">Littlelines</a>, we have to write a lot of code under strict time constraints. We work in small teams which means that writing clean and concise code is a necessity. When a Ruby library comes along that makes code easier to grasp in a hurry, test, and maintain - we use it. Here are some gems we have in our toolbox:</p><h2><a href="http://github.com/justinfrench/formtastic">Formtastic</a></h2><p>If you're developing wep apps, more than likely it will include html forms.  Forms can be a time-drain, not to mention very boring to build. Formtastic provides a more concise way of generating form views and includes inline error messages and is semantically rich.</p><h2><a href="http://github.com/giraffesoft/resource_controller">Resource  Controller</a></h2><p>Resource Controller hides away the RESTful controller boiler plate code and make your controllers skinny. Skinny controllers help you to consolidate your business logic into one place, thus saves time on maintenance and testing.</p><h2><a href="http://github.com/binarylogic/searchlogic">Search Logic</a></h2><p>Finding data can get messy. Sometimes we run into situations where we are concatenating strings to build SQL statements and this can lead to bugs. Searchlogic works by creating a number of named scopes that can be called on any ActiveRecord model. The best part, you can dynamically call scopes on associated classes and Searchlogic will take care of creating the necessary joins for you.</p><h2><a href="http://github.com/toastyapps/alchemist">Alchemist</a></h2><p>Occasionally, we work on projects dealing with conversions.  Alchemist is a Ruby library that does conversions for you and thus making your code more readable and easier to maintain. For example:</p><p>Instead of:</p><pre><code>miles = 8 * 1609.344 # converting meters to miles
        </code></pre><p>We can write:</p><pre><code>8.meters.to.miles
        </code></pre><p>Alchemist includes a staggering array of conversions including distance, mass, volume, and more.</p><h2><a href="http://andand.rubyforge.org/">andand</a></h2><p>andand is a handy gem that allows allows natural method chaining for methods that can return nil. This saves a lot of boilerplate code and improves readability. For example:</p><p>Instead of:</p><pre><code>@body = (article = Article.find_by_title('test')) &amp;&amp; article.body
        </code></pre><p>We can write this:</p><pre><code>@body = Article.find_by_title('test').andand.body
        </code></pre><p>This will call find on the Article class and sends 'body' if the result is not nil. In addition, our methods are guarded from NoMethodErrors is the result is nil.</p>]]>
      </description>
      <pubDate>Sat, 31 Oct 2009 20:38:19 +0000</pubDate>
      <guid isPermaLink='false'>796da7232a47882a32b2a180c28c6e08107930f1</guid>
    </item>
    <item>
      <title>20 Clojure Links To Get You Up To Speed</title>
      <link>http://www.mattsears.com/articles/2009/6/6/20-clojure-links-to-get-you-up-to-speed</link>
      <description>
        <![CDATA[<p>Writing multi-threaded code is hard. If you've ever done concurrent programming, you'll <em>probably</em> agree. Clojure offers a compelling alternative to traditional object-oriented approaches to programming and has garnered much attention from the Ruby community because of it's elegant design that lets you get right to the essence of a problem.</p><h2>What is Clojure?</h2><p>Simply put, Clojure is a functional programming language for the Java Virtual Machine with several powerful features for building concurrent applications. In addition, Clojure is fast, robust, and a powerful general-purpose programming language. A dialect of Lisp, Clojure embraces traditional code-as-data philosophy and a powerful macro system, plus some syntactic sugar tailored to Java.</p><p>Now that <a href="http://clojure.blogspot.com/2009/05/clojure-10.html">version 1.0</a> is out and Stuart Halloway's new book <a href="http://www.pragprog.com/titles/shcloj/programming-clojure">Programming Clojure</a> just dropped, I've rounded up some of the best articles and tutorials on Clojure to you get you up to speed quickly.</p><h2>Tutorials and Links</h2><ul>
        <li><p><a href="http://java.ociweb.com/mark/clojure/article.html">A Clojure Tutorial</a> by R. Mark Volkmann</p></li>
        <li><p><a href="http://www.pragprog.com/titles/shcloj/programming-clojure">Programming Clojure book</a> by Stuart Halloway</p></li>
        <li><p><a href="http://blog.thinkrelevance.com/2008/09/16/pcl-clojure">Practical Common Lisp to Clojure</a> by Stuart Halloway</p></li>
        <li><p><a href="http://writingcoding.blogspot.com/2008/06/clojure-series-table-of-contents.html">Clojure Series: Table of Contents</a> by Eric Rochester</p></li>
        <li><p><a href="http://en.wikibooks.org/wiki/Learning_Clojure">Learning Clojure</a> via Wikibooks</p></li>
        <li><p><a href="http://en.wikibooks.org/wiki/Clojure_Programming/Examples/API_Examples">Clojure Programming/Examples/API Examples</a> via Wikibooks</p></li>
        <li><p><a href="http://en.wikibooks.org/wiki/Clojure_Programming/Tutorials_and_Tips">Clojure Programming/Tutorials and Tips</a> via Wikibooks</p></li>
        </ul>
        <h2>Screencasts, Videos, and Presentations</h2><ul>
        <li><p><a href="http://peepcode.com/products/functional-programming-with-clojure">Functional Programming with Clojure</a> by Phil Hagelberg (PeepCode)</p></li>
        <li><p><a href="http://clojure.blip.tv">Clojure Series on Blip.tv</a> by Rich Hickey</p></li>
        <li><p><a href="http://www.youtube.com/view_play_list?p=AC43CFB134E85266">Intro to Clojure</a> by Brian Will (YouTube)</p></li>
        <li><p><a href="http://vimeo.com/2419596">Emacs with Clojure, Slime and Swank</a> by Seth Buntin (Vimeo)</p></li>
        </ul>
        <h2>Tools and Setup</h2><ul>
        <li><p><a href="http://yusupov.com/blog/2009/basic-clojure-setup-part-1/">Basic Clojure Setup</a> by Telman Yusupov</p></li>
        <li><p><a href="http://mark.reid.name/sap/setting-up-clojure.html">Setting Up Clojure for Mac OS X Leopard</a> by Mark Reid</p></li>
        <li><p><a href="http://technomancy.us/126">Getting Emacs setup to write Clojure code</a> by Phil Hagelberg</p></li>
        <li><p><a href="http://github.com/nullstyle/clojure-tmbundle/tree/master">Textmate Bundle for Clojure code</a> by Scott Fleckenstein</p></li>
        <li><p><a href="http://www.vim.org/scripts/script.php?script_id=2501">VimClojure, a Vim plugin for Clojure</a></p></li>
        </ul>
        <h2>Documentation</h2><ul>
        <li><p><a href="http://clojure.org">Official Clojure site</a></p></li>
        <li><p><a href="http://clojure.org/api">Official Clojure API</a></p></li>
        <li><p><a href="http://clj-doc.s3.amazonaws.com/tmp/doc-1116/index.html">Clojure Docs</a></p></li>
        <li><p><a href="http://java.ociweb.com/mark/clojure/ClojureCodingGuidelines.html">Clojure Coding Guidelines</a> by Mark Volkmann</p></li>
        </ul>]]>
      </description>
      <pubDate>Sat, 06 Jun 2009 00:00:00 +0000</pubDate>
      <guid isPermaLink='false'>7010d367853e988bd32aaf70f8b8c41511823e32</guid>
    </item>
    <item>
      <title>Git blogging with Aerial</title>
      <link>http://www.mattsears.com/articles/2009/4/4/git-blogging-with-aerial</link>
      <description>
        <![CDATA[<p>Over the last few years, I have grown tired of maintaining, migrating, and upgrading blog software, so I've decided to roll my own with Ruby code. In doing so, I wanted to keep things as simple as possible with a basic set of features: articles, pages, comments, rss, etc. What I didn't want is a SQL database or an administration tool. I wanted to write articles in my text editor of choice (Emacs), in <a href="http://daringfireball.net/projects/markdown/">Markdown</a> format, and versioned with <a href="http://git-scm.com/">Git</a>. So I've ported this site from Mephisto to my own custom creation. I call it Aerial.</p><p>Much inspiration for Aerial has come from <a href="http://github.com/karmi/marley">Marley</a>, a minimal flat-file blog engine written in Sinatra. Like Marley, Aerial is built with <a href="http://www.sinatrarb.com/">Sinatra</a> and uses plain text files. Unlike Marley, Aerial doesn't use a SQL database and uses <a href="http://github.com/mojombo/grit">Grit</a> to retrieve article and comment files from a Git repository.</p><h2>So how does it work?</h2><p>Articles and comments are stored as plain text files in a local Git directory. Aerial parses each file and converts them the Article and Comment objects with their own set of attributes such as title, body, tags, and author. For example, this article looks something like this:</p><pre><code>Title      : Git blogging with Aerial
        Tags       : projects, ruby, git, sinatra
        Published  : 03/28/2009
        Author     : Matt Sears
        
        Over the last few years...
        </code></pre><p>Since Aerial reads the articles from the Git repository, the contents of article won't display in the browser unless the changes are committed to Git. Same goes for comments.</p><h2>Working with remote repositories</h2><p>Aerial uses local and remote Git repositories to sync data between the production web server and your local environment. For example, when comments are submitted on the production web server, they are checked for Spam via <a href="http://akismet.com/">Akismet</a> and saved to the same directory as the article. Then, the new comment file is added to the production web server's repository and pushed to the remote repository (Github in my case). To pull in user comments to our local environment, simply use the pull command:</p><pre><code>git pull
        </code></pre><p>Now we have all the comments that users have submitted.</p><h2>Getting Started</h2><p>For Aerial to work, you'll need Git installed and the following RubyGems:</p><pre><code>sudo gem install sinatra grit rdiscount haml
        </code></pre><p>Grab the <a href="http://github.com/mattsears/aerial">source code</a> from Github.</p><p>A small configuration file in config/config.yml is used to store information about your blog. You can add your info now or leave it as is and it will still work. To setup and run Aerial, we need to run the boostrap Rake task:</p><pre><code>rake bootstrap
        </code></pre><p>This will install the necessary directories (specified in the config.yml file), javascript files, and insert a sample article to get you started. If every goes smoothly, Aerial should be up and running at:</p><pre><code>http://localhost:4567
        </code></pre><p>Keeping in spirit with minimalism, all the pages use <a href="http://haml.hamptoncatlin.com">Haml</a> for the templating engine. Of course, you may change this to the templating engine of your choice.</p><h2>Creating new articles</h2><p>Create a new folder in the app/articles directory.  You can name this folder anything you want, but it may be helpful to number them so they display in the order you want them to. For example, the folder for this articles looks like this:</p><pre><code>app/articles/011-introducing-aerial
        </code></pre><p>Next, create a text file with the extension '.article' and save it to the new folder.  The '.article' file extension let's Aerial know that this file should be converted to an Article object.  The name of the article will be the article's permalink. Remember, the article will not display on the site until it's committed to the git repository. When the article is completed, we can push it to the remote repository with the push command:</p><pre><code>git push
        </code></pre><p>Now, we're ready to deploy it.</p><h2>Deployment</h2><p>Deployment tasks are handled with <a href="http://rubyhitsquad.com/Vlad_the_Deployer.html">Vlad the Deployer</a>. A simple deployment script is located at config/deploy.rb. It assumes your running Apache and Phusions Passenger, but you can edit this file with your own settings. Future enhancements may include auto-syncing with post-receive hooks so that 'git push' will make Aerial update itself, but for now we can deploy with a simple rake task:</p><pre><code>rake deploy
        </code></pre><p>This is by no means a comprehensive introduction. If you have any questions or run into any problems, please drop me a line.</p>]]>
      </description>
      <pubDate>Sat, 04 Apr 2009 00:00:00 +0000</pubDate>
      <guid isPermaLink='false'>dad405a4784c3736148aede183ad3bf0a3f74131</guid>
    </item>
    <item>
      <title>Two+ Years Working with Rails</title>
      <link>http://www.mattsears.com/articles/2008/12/10/two-years-working-with-rails</link>
      <description>
        <![CDATA[<p>Update: I thought I should give a little background on how I got started with Rails - when I was attending the SDWest conference in March 2006.  I was at the Jolt Awards, and saw @d2h receive the award for the best web development tool for Rails 1.0.  I downloaded Rails that night in the hotel room and was hooked.</p><p>This week marks the two year anniversary when I delivered my first professional Rails app.  Today, I decided to take a look back at the  code of that first project and see what's improved over the past two years.  The result - not bad, but there were a couple areas that stood out. Here are a few:</p><ol>
        <li>The controllers in that first project were out of control. Not sure why, maybe coming from the J2EE world, my first instinct was to cram everything into the controller. It was apparent that the concept of REST wasn't completely baked into my brain yet. Not to mention the concept of fat models, skinny controllers.</li>
        <li>Second, the views and Javascripts were a bit unorganized.  I noticed excessive conditional logic and messy Javascript code in a few of the pages.  If I was to re-write the app today, most of it could be cleanup with rendering partials with collections and using Low Pro to clean up the Javascript.</li>
        <li>Finally, the sheer lack of plugins for that first project was surprising. It's true that the amount and quality of plugins have grown in two years, but I believe the lack of awareness was the main cause.</li>
        </ol>
        <p>So this made me think of what I would say if I were to advise newcomers writing their first Rails app.  I would have to say first, if you find yourself writing code in the controller, then ask yourself "Can I put this logic in the model?". And also be sure to familiarize yourself with the available plugins with sites such as <a href="http://agilewebdevelopment.com">Agile Web Development</a> and <a href="http://github.com">Github</a>. They can save you a ton of work.</p>]]>
      </description>
      <pubDate>Wed, 10 Dec 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink='false'>fd7d3d4a33f5b38653b81b26da93b3ec7d6b9074</guid>
    </item>
    <item>
      <title>RubyConf 2008 Wrap Up</title>
      <link>http://www.mattsears.com/articles/2008/11/23/rubyconf-2008-wrap-up</link>
      <description>
        <![CDATA[<p>This month I headed down to Orlando, Florida for RubyConf 2008. It kicked off with a delightful (and touching) keynote by Matz. He walked through his own programming history with languages including the language he got started with BASIC (the same language I started with). Matz talked about the growing community and a statistic from Gartner that says there are over a million Ruby developers and will grow to 4 million by 2012, which is amazing. He finished up by saying that Ruby is all about love, and included a slide that said "I love you all".  Below are couple highlights from each day.</p><blockquote>
        <p><img src="http://farm4.static.flickr.com/3007/3012059619_54ca460d75.jpg" alt="Alt text" title="The Keynote Audience">
        
        Photo credit: <a href="http://www.flickr.com/photos/danbenjamin/3012059619/in/set-72157608762375251/">Dan BenJamin</a></p>
        </blockquote><h2>Day 1:</h2><p>Gregg Pollack's talk on Scaling Ruby (without Rails) was really good.  He touched on green and native threads, EventMachine, message queues, and profiling code with ruby-prof.  My favorite part of the presentation was the performance tips and tricks of optimizing Ruby code.  His talk is up at EnvyCast and I definitely recommend it.</p><p>Jamis Buck - "Recovering from the Enterprise" was probably my favorite presentation at the conference.  The main theme of his talk was that working in the enterprise solves problems differently than those solutions in Ruby.  Jamis worked in Java (like me) before Ruby and he told a story of how he written a library for dependency injection for Ruby but realized that he was trying to use Java solutions in a Ruby world that didn't need it. He said Java is like Legos and Ruby is like Play-doh and delivered the best quote of the conference "Just in time, not just in case"</p><blockquote>
        <p><img src="http://farm4.static.flickr.com/3022/3012058753_cedb320f27.jpg?v=0" alt="Alt text" title="Glenn Vanderburg and Dave Thomas">
        
        Photo credit: <a href="http://www.flickr.com/photos/danbenjamin/3012058753/in/set-72157608762375251/">Dan BenJamin</a></p>
        </blockquote><h2>Day 2:</h2><p>Effective and Creative Code by Eric Ivancich was awesome.  He discussed how our minds work while programming - the differences between fascination and direct attention, the mental fatique and long periods of direct attention can have on you.  Fascinating stuff.</p><p>Yehuda Katz taught us how to write code that doesn't suck with Interface Oriented Design.  But first, he announced that Merb 1.0 was released just minutes before his presentation.  Then he went on to say that unit tests are not regression tests and that writing regression tests should make sure that the API we are exposing to the world doesn't break while work is being done under the covers.</p><blockquote>
        <p><img src="http://farm4.static.flickr.com/3201/3012061855_402f2b1cd6.jpg" alt="Alt text" title="The Hall Between Sessions">
        
        Photo credit: <a href="http://www.flickr.com/photos/danbenjamin/3012061855/in/set-72157608762375251/">Dan BenJamin</a></p>
        </blockquote><h2>Day 3:</h2><p>I saw Neal Ford's talk on Advanced DSLs in Ruby - one of my favorite topics.  This presentation was really good because Neal was very specific on how to build DSLs in Ruby and not just the basics.  He covered various techniques on writing DSLs and provided a nice summary of his talk on his <a href="http://www.nealford.com/downloads/conferences/canonical/Neal_Ford-Advanced_DSLs_in_Ruby-slides.pdf">website</a>.</p><p>I sat down next to Dave Thomas to listen to Gregory Brown's talk about Prawn, a pure Ruby PDF generation library. Prawn is cool, but how Prawn was born was the most interesting part of the talk. A community funded project called The Ruby Mendicant Project allowed Gregory to quit his job and work on Prawn full time - A Ruby community employee.</p><p>Overall it was an amazing conference.  It was great to see and talk to people that I only get to see online.  Looking forward to next year.</p>]]>
      </description>
      <pubDate>Sun, 23 Nov 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink='false'>2ec9c3f9ef417e1cc7a574ce96893913a609ca94</guid>
    </item>
    <item>
      <title>Quick git add, commit, push, and deploy</title>
      <link>http://www.mattsears.com/articles/2008/11/8/quick-git-add-commit-push-and-deploy</link>
      <description>
        <![CDATA[<p>Last week, I was preparing a presentation and found myself doing a lot of quick fixes and deployments to prepare a web application for a demonstration.  I thought instead of running the following four commands each time:</p><pre><code>git add .
        git commit -a -m 'A description of the change'
        git push
        cap production deploy
        </code></pre><p>It would be nice if I could do all of the above with just one command.  So I created this shell script:</p><pre><code>push() {
        
          # Defaults
          MINLEN=25
          DIRTY=false
          DEPLOY="production deploy"
          REMOTE_REPO = "origin master"
        
          # Check if we have any untracked files
          if git status | grep -q "modified:"
          then
             DIRTY=true
          fi
        
          # Make sure there is a message with the commit
          if [ -z "$1" ] &amp;&amp; (test $DIRTY == true)
          then
            echo "You must specify a message with your commit"
            return
          elif [ ${#1} -lt $MINLEN ] &amp;&amp; (test $DIRTY == true)
          then
            echo "Your message must have at least $MINLEN letters."
          return
          fi
        
          # Commit all the changes by default
          if (test $DIRTY == true)
          then
             echo "Adding new files to Git repository"
             git add .
        
             echo "Commiting to local Git repository"
             git commit -a -m "$1"
        
             # Push changes if a remote repository exists
             if git remote | grep -q "origin"
             then
                echo "Pushing changes to remote repository"
                git push $REMOTE_REPO
             fi
          fi
        
          # Deploy changes via Capistrano
          if ls | grep -q Capfile
          then
             cap $DEPLOY
          fi
        }
        </code></pre><p>The 'push' function will first check to make sure you supplied a description if any recent changes were made.  Second, it will commit all the code and push it to the remote repository (if one exists).</p><p>If none of the code was modified or added, it will skip the Git commands and simply run the Capistrano deploy command and not require a description for the changes.</p><p>To use this script, copy and paste the above function to the end of your ~/.bash_profile file. To run it, simply run the 'push' command.</p><pre><code>push "The description for the committed changes."
        </code></pre><p>That's it!  All the code is added, commited, pushed, and deployed.</p>]]>
      </description>
      <pubDate>Sat, 08 Nov 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink='false'>7edc8f22c2b58a9694d7ccde430da87e65270d06</guid>
    </item>
    <item>
      <title>erubycon 2008</title>
      <link>http://www.mattsears.com/articles/2008/8/24/erubycon-2008</link>
      <description>
        <![CDATA[<p>Last week I made a short drive to Columbus for the erubycon conference presented by the <a href="http://theedgecase.com">EdgeCase</a> crew.  The three day conference, hosted by Microsoft, was an event to demonstrate Ruby's role in the enterprise.  Having worked in the Enterprise for six years, I was very excited to learn more about how Ruby can change the Enterprise.</p><blockquote>
        <p><img src="http://farm4.static.flickr.com/3165/2782317715_0541ef31ee.jpg" alt="Alt text" title="erubycon">
        
        Photo credit: <a href="http://www.flickr.com/photos/edgecase/2782317715/in/set-72157606864457793/">EdgeCase, LLC</a></p>
        </blockquote><p>What is legacy code and how do we avoid it?  Stuart Halloway addresses these questions with his talk <a href="http://blog.thinkrelevance.com/2008/4/1/ending-legacy-code-in-our-lifetime">Ending Legacy Code In Our Lifetime</a>.  This was my favorite talk on the first day because the Enterprise is "full of it" and much my time was spent trying to avoid it. It's nice to see somebody calling attention to it.</p><blockquote>
        <p><img src="http://farm4.static.flickr.com/3250/2782305159_8bb28e367d.jpg" alt="Alt Stuart Halloway">
        
        Photo credit: <a href="http://www.flickr.com/photos/edgecase/2782305159/">EdgeCase, LLC</a></p>
        </blockquote><p>Very interesting talk on JRuby by it's creator Charles Nutter on the second day.  I went back to the hotel room that evening and setup JRuby on my laptop.  I wrote a quick rails app and with <a href="http://caldersphere.rubyforge.org/warbler/">Warbler</a>, had a working war file ready to be deployed to Java application server.  Very impressive.</p><blockquote>
        <p><img src="http://farm4.static.flickr.com/3092/2783141904_a67d981d4e.jpg" alt="Alt Charles Nutter">
        
        Photo credit: <a href="http://www.flickr.com/photos/edgecase/2783141904">EdgeCase, LLC</a></p>
        </blockquote><p>Perhaps my favorite session at the conference was Jim Weirich's talk on concurrent software development. Something I don't think is talked about enough and is certainly important in the Enterprise.  I've written multi-threaded apps in Java and it can be very difficult especially avoiding deadlocks.  Is Ruby the answer? According to Jim, not really. Perhaps a Erlang or Clojure offers a better solution.</p><blockquote>
        <p><img src="http://farm4.static.flickr.com/3203/2783371134_637089301c.jpg" alt="Alt Jim Weirich">
        
        Photo credit: <a href="http://www.flickr.com/photos/edgecase/2783371134/">EdgeCase, LLC</a></p>
        </blockquote><p>And Finally, Chris Wanstrath, co-creator of GitHub talks about Git, GitHub, and a little about side projects.  Oh, and did I mention I really love GitHub?  It's really changing how we develop software.</p><blockquote>
        <p><img src="http://farm4.static.flickr.com/3029/2782508887_bc3260b878.jpg" alt="Chris Wanstrath">
        
        Photo credit: <a href="http://www.flickr.com/photos/edgecase/2782508887">EdgeCase, LLC</a></p>
        </blockquote><ul>
        <li>All the photos above are provided by EdgeCase, LLC and more are available on their <a href="http://www.flickr.com/photos/edgecase/">Flickr</a> page.</li>
        </ul>]]>
      </description>
      <pubDate>Sun, 24 Aug 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink='false'>21a27951c89a908fb4f682312d881ca9c1e08b68</guid>
    </item>
    <item>
      <title>Now running Phusion Passenger</title>
      <link>http://www.mattsears.com/articles/2008/7/25/now-running-phusion-passenger</link>
      <description>
        <![CDATA[<p>Just finished making some major changes to this site.  First thing you might noticed are the changes to the design. In effort to simplify things a bit, I modified a <a href="http://www.quotedprintable.com/pages/scribbish">Scribbish</a> theme to my own liking.  Is it too geeky? The awesome portrait you see at the top right was created by <a href="http://papertelevision.com" title="Paper Television">Josh</a>.  Nailed it.</p><p>Here is a rundown of the changes made:</p><ol>
        <li>Upgraded to Ubuntu 8.04 Hardy Heron</li>
        <li>Installed Apache and Phusion Passenger (mod_rails)</li>
        <li>Change and tweaked Mephisto theme</li>
        </ol>
        <p>I'm still in the process of moving my old blog posts over. More big news coming soon.</p>]]>
      </description>
      <pubDate>Fri, 25 Jul 2008 13:00:13 +0000</pubDate>
      <guid isPermaLink='false'>5712819b49b1d48ecefab8a4480c77d5183d1d90</guid>
    </item>
    <item>
      <title>Littlelines featured at Freshbooks</title>
      <link>http://www.mattsears.com/articles/2008/7/13/littlelines-featured-at-freshbooks</link>
      <description><![CDATA[<p>Josh and I were interviewed by Freshbooks for their "FreshFaces" blog.  Freshbooks is a great tool for keeping track of invoices, so we were pretty excited to talk to them.</p><p>The article can be seen  <a href="http://www.freshbooks.com/blog/2008/04/16/fresh-faces-matt-josh-sears">here</a>.</p>]]></description>
      <pubDate>Sun, 13 Jul 2008 23:07:01 +0000</pubDate>
      <guid isPermaLink='false'>f8e80249a060ad0af4027d1f46394dc961da726b</guid>
    </item>
    <item>
      <title>LinkedIn shares it's communication architecture</title>
      <link>http://www.mattsears.com/articles/2008/7/13/linkedin-shares-it-s-communication-architecture</link>
      <description><![CDATA[<p>I was just reading LinkedIn's presentation on it's architecture and it was like walking down memory lane. I worked with almost the same architecture at <a href="http://www.lexisnexis.com">LexisNexis</a>. We also used Java, Solaris, Tomcat (Websphere mostly), Oracle, JMS and the cached was implemented with C++. Ah, the good ol' days.</p>]]></description>
      <pubDate>Sun, 13 Jul 2008 22:52:33 +0000</pubDate>
      <guid isPermaLink='false'>b3b2fa75b1b3acf560c2663c1ad23d66dab51fc0</guid>
    </item>
    <item>
      <title>SD West</title>
      <link>http://www.mattsears.com/articles/2008/7/13/sd-west</link>
      <description>
        <![CDATA[<p>Really late on this, but here are some snapshots of the Software Development conference in Santa Clara, California. I had a really good time, except I was sick for a couple days. I concentrated mostly on design patterns, generics, C++, Java, and vomiting. :-)</p><blockquote>
        <p><img src="http://farm4.static.flickr.com/3227/2665584462_f8139d5182.jpg?v=0" alt="Alt text" title="Thai Restaurant in Sunnyvale, CA"></p>
        </blockquote><p>I had the opportunity to attend a few good sessions with pros like Bjarne Stroustrup, Herb Sutter, Martin Fowler, Eric Evans, Stephen Dewhurst, Ken Pugh, Allen, Hollub, and Bruce Schneier to name a few. There really is no substitute from learning hands-on from experts like these. I left each session feeling like I just learned an entire year's worth of knowledge. And of course, there were other things to do at the conference besides classes - Jolt awards, the expo, and Joel Spolsky was back to screen his documentary called Aardvarked.</p><blockquote>
        <p><img src="http://farm4.static.flickr.com/3226/2664760057_182fbfc6ff.jpg?v=0" alt="Alt text" title="SDWEST 2006"></p>
        </blockquote><p>This year, I made it point to get out of the hotel, convention center, and bar to explore Silicon Valley. I drove around town with no real plans except to search for better food. The hotel food is awful, which is ironic since it costs 3 times more. Twenty six dollars for a chicken sangwich, fries, and drink - get real. There are a lot more locally owned restaurants in Silicon Valley that are a lot cheaper. There are especially a lot of Thai restaurants, which is good, because I love Thai food. I think I had that like three times.</p><blockquote>
        <p><img src="http://farm4.static.flickr.com/3173/2665582108_d70ae3b895.jpg?v=0" alt="Alt text" title="Rainy day in Silicon Valley"></p>
        </blockquote><p>There are quite a few good restaurants in Sunnyvale too, but you have to know where to look.</p><p>Not going to make it back there this year. This is year is crazy busy and going to get busier and crazier, and any other 'ziers I can't think of right now.</p>]]>
      </description>
      <pubDate>Sun, 13 Jul 2008 20:50:17 +0000</pubDate>
      <guid isPermaLink='false'>671a25ed202ede4553d58e1cf72301aa0a886c43</guid>
    </item>
    <item>
      <title>Finally, MattSears.com</title>
      <link>http://www.mattsears.com/articles/2008/7/13/finally-mattsears-com</link>
      <description><![CDATA[<p>After a decade of waiting, I finally nabbed the mattsears.com domain name. I almost forgot about it until Godaddy sent me an email last week that said it was Pending deletion. Though, I have to admit that I'm not really excite about it as I thought I would be. I guess it's because I've been using matthewsears.com for a couple years now and excepted using my full name instead, but it's cool that I have both now.</p>]]></description>
      <pubDate>Sun, 13 Jul 2008 20:38:19 +0000</pubDate>
      <guid isPermaLink='false'>08c2049da3f440bccf68dac63b8008aad1622066</guid>
    </item>
    <item>
      <title>Relay outbound SMTP email to Gmail</title>
      <link>http://www.mattsears.com/articles/2008/1/8/relay-outbound-smtp-email-to-gmail</link>
      <description>
        <![CDATA[<p>Sending emails with Rails via Gmail is a snap with Marc Chung's excellent plugin <a href="http://code.openrain.com/rails/action_mailer_tls">action_mailer_tls</a>. However, sometimes our production environment isn't using Gmail as a mail server and/or we just need an easy way to send email from our development environment for testing or demonstrating purposes.</p><p>Instead of installing the action_mailer_tls plugin and configuring each of our Rails apps, we can do a one-time setup of our local Postfix client to relay all SMTP outbound emails to our Gmail account. If your running a Mac OS Leopard or Linux, Postfix should already be installed. With a little configuration, we should be up and running in a couple minutes.</p><p>First create /etc/postfix/relay_password file with the server name, email account name and password as shown below. This configuration works with Gmail accounts as well as with Google Apps email accounts. I'm personally using my company's Google Apps with a special email account setup for outbound emails only.</p><pre><code>smtp.gmail.com    example@yourdomain.com:yourpassword
        </code></pre><p>Then tell Postfix about our google accounts information so it knows how and where to relay the email to. This can be done with the postmap command:</p><pre><code>$ postmap /etc/postfix/relay_password
        </code></pre><p>Since Gmail requires a TLS (Transport Layer Security) connection for certificate-based authentication, we'll need to download a free root certificate from Verisign <a href="https://www.verisign.com/support/roots.html" rel="external"></a><a href="https://www.verisign.com/support/roots.html">https://www.verisign.com/support/roots.html</a> to authenticate our remote SMTP client.</p><pre><code>$ mkdir /etc/postfix/certs
        $ cd /etc/postfix/certs
        $ sudo cp roots.zip /etc/postfix/certs
        $ sudo unzip -j roots.zip
        $ sudo openssl x509 -inform der -in ThawtePremiumServerCA.cer -out  ThawtePremiumServerCA.pem
        $ sudo c_rehash /etc/postfix/certs
        </code></pre><p>Now we are ready to configure Postfix. Postfix needs to know what host to relay the email to, the username and password to authenticate the Gmail account, and the path to our certificates for the encrypted session.  Add these lines to the bottom of /etc/postfix/main.cf</p><pre><code>relayhost = smtp.gmail.com:587
        # auth
        smtp_sasl_auth_enable = yes
        smtp_sasl_password_maps = hash:/etc/postfix/relay_password
        smtp_sasl_security_options = noanonymous
        
        # tls
        smtp_tls_security_level = may
        smtp_tls_CApath = /etc/postfix/certs
        smtp_tls_session_cache_database = btree:/etc/postfix/smtp_scache
        smtp_tls_session_cache_timeout = 3600s
        smtp_tls_loglevel = 1
        tls_random_source = dev:/dev/urandom
        </code></pre><p>Restart (or start) Postfix to pick up our new changes.</p><pre><code>$ sudo postfix stop
        $ sudo postfix start
        </code></pre><p>That's it! Now we don't have to do any special installation or configuration to send email via Gmail for our Rails apps. We just need to set the delivery method to :smtp and we're ready to go.</p>]]>
      </description>
      <pubDate>Tue, 08 Jan 2008 00:00:00 +0000</pubDate>
      <guid isPermaLink='false'>b4ab8848688491c937266cb9a628e20552c79127</guid>
    </item>
  </channel>
</rss>

