<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:posterous="http://posterous.com/help/rss/1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
  <channel>
    <title>Ben Scofield</title>
    <link>http://benscofield.com</link>
    <description>Me. On a blog.</description>
    <generator>posterous.com</generator>
    <link xmlns="http://www.w3.org/2005/Atom" href="http://posterous.com/api/sup_update#d595ea6b8" type="application/json" rel="http://api.friendfeed.com/2008/03#sup" />
    
    
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/BenScofield" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="benscofield" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://posterous.superfeedr.com/" /><item>
      <pubDate>Mon, 29 Aug 2011 12:36:00 -0700</pubDate>
      <title>On Interface Segregation</title>
      <link>http://benscofield.com/on-interface-segregation</link>
      <guid>http://benscofield.com/on-interface-segregation</guid>
      <description>
        <![CDATA[<p>
	<p class="p1">As promised, here's the first installment of my&nbsp;<a href="http://benscofield.com/on-fractal-design"><span class="s1">Fractal Design series</span></a>. I'd like to kick things off with what might seem to be an odd choice for Rubyists: the&nbsp;<a href="http://en.wikipedia.org/wiki/Interface_segregation_principle"><span class="s1">interface segregation principle</span></a>.</p>
<p class="p2"><strong>A Brief Introduction to the ISP</strong></p>
<p class="p1">Interface Segregation is one of the SOLID design principles, and states:</p>
<p class="p2"><em>Clients should not be forced to depend upon interfaces that they do not use.</em> (<a href="http://www.objectmentor.com/resources/articles/isp.pdf"><span class="s1">source</span></a>)</p>
<p class="p2">The idea is that when a class implements an interface, it should only get methods that it needs. When followed, you get higher cohesion and less coupling in your code.</p>
<p class="p2">In Ruby, we don't have explicit interface constructs -- but we do have plenty of violations of this principle.</p>
<p class="p1"><strong>Utility Modules</strong></p>
<p class="p1">At RailsConf a few months ago, DHH justified the asset pipeline by referring to the <span class="s2">javascripts</span> and <span class="s2">stylesheets</span> folders in Rails as junk drawers, full of bric-a-brac and this-and-that. Modules make a much better target for that description, though.</p>
<p class="p1">I've seen (and/or written) any number of medium- or larger-sized Ruby applications where there's a utility module, filled with all sorts of methods used here or there in the application. Such modules are created with the best of intentions -- people just want to stay DRY, after all, so they extract methods that appear in multiple classes or views, but they end up dropping those into an ever-expanding, unfocused module that then has to be included all over the place even when only a fraction of it is used in any particular context.</p>
<p class="p3"><span class="s3"><span class="s4"><div class="data type-ruby">
    
      <table class="lines" cellspacing="0" cellpadding="0">
        <tr>
          <td>
            <pre class="line_numbers"><span rel="#L1" id="L1">1</span>
<span rel="#L2" id="L2">2</span>
<span rel="#L3" id="L3">3</span>
<span rel="#L4" id="L4">4</span>
<span rel="#L5" id="L5">5</span>
<span rel="#L6" id="L6">6</span>
<span rel="#L7" id="L7">7</span>
<span rel="#L8" id="L8">8</span>
<span rel="#L9" id="L9">9</span>
<span rel="#L10" id="L10">10</span>
<span rel="#L11" id="L11">11</span>
<span rel="#L12" id="L12">12</span>
<span rel="#L13" id="L13">13</span>
<span rel="#L14" id="L14">14</span>
<span rel="#L15" id="L15">15</span>
</pre>
          </td>
          <td width="100%">
            
              
                <div class="highlight"><pre /><div class="line" id="LC1"><span class="k">module</span> <span class="nn">Toolbox</span></div><div class="line" id="LC2">&nbsp;&nbsp;<span class="kp">module_function</span></div><div class="line" id="LC3"><br /></div><div class="line" id="LC4">&nbsp;&nbsp;<span class="k">def</span> <span class="nf">log</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">priority</span> <span class="o">=</span> <span class="ss">:warn</span><span class="p">)</span></div><div class="line" id="LC5">&nbsp;&nbsp;&nbsp;&nbsp;<span class="no">Logger</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="ss">:priority</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span></div><div class="line" id="LC6">&nbsp;&nbsp;<span class="k">end</span></div><div class="line" id="LC7">&nbsp;&nbsp;</div><div class="line" id="LC8">&nbsp;&nbsp;<span class="k">def</span> <span class="nf">format_cc</span><span class="p">(</span><span class="n">number</span><span class="p">)</span></div><div class="line" id="LC9">&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">number</span><span class="o">.</span><span class="n">scan</span><span class="p">(</span><span class="sr">/\d{4}/</span><span class="p">)</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">&#39;-&#39;</span><span class="p">)</span></div><div class="line" id="LC10">&nbsp;&nbsp;<span class="k">end</span></div><div class="line" id="LC11">&nbsp;&nbsp;</div><div class="line" id="LC12">&nbsp;&nbsp;<span class="k">def</span> <span class="nf">select_random_element</span><span class="p">(</span><span class="n">array</span><span class="p">)</span></div><div class="line" id="LC13">&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">array</span><span class="o">[</span><span class="nb">rand</span><span class="p">(</span><span class="n">array</span><span class="o">.</span><span class="n">length</span><span class="p">)</span><span class="o">]</span></div><div class="line" id="LC14">&nbsp;&nbsp;<span class="k">end</span></div><div class="line" id="LC15"><span class="k">end</span></div></pre></div>
              
            
          </td>
        </tr>
      </table>
    
  </div></span></span></p>
<p class="p1">Sure, many classes that include Toolbox might use the log method -- but how many of them need to format credit card numbers, or select a random element from an array? Here's a better approach:</p>
<p class="p3"><span class="s3"><span class="s4"><div class="data type-ruby">
    
      <table class="lines" cellspacing="0" cellpadding="0">
        <tr>
          <td>
            <pre class="line_numbers"><span rel="#L1" id="L1">1</span>
<span rel="#L2" id="L2">2</span>
<span rel="#L3" id="L3">3</span>
<span rel="#L4" id="L4">4</span>
<span rel="#L5" id="L5">5</span>
<span rel="#L6" id="L6">6</span>
<span rel="#L7" id="L7">7</span>
<span rel="#L8" id="L8">8</span>
<span rel="#L9" id="L9">9</span>
<span rel="#L10" id="L10">10</span>
<span rel="#L11" id="L11">11</span>
<span rel="#L12" id="L12">12</span>
<span rel="#L13" id="L13">13</span>
<span rel="#L14" id="L14">14</span>
<span rel="#L15" id="L15">15</span>
<span rel="#L16" id="L16">16</span>
<span rel="#L17" id="L17">17</span>
<span rel="#L18" id="L18">18</span>
<span rel="#L19" id="L19">19</span>
<span rel="#L20" id="L20">20</span>
<span rel="#L21" id="L21">21</span>
<span rel="#L22" id="L22">22</span>
<span rel="#L23" id="L23">23</span>
<span rel="#L24" id="L24">24</span>
<span rel="#L25" id="L25">25</span>
<span rel="#L26" id="L26">26</span>
<span rel="#L27" id="L27">27</span>
</pre>
          </td>
          <td width="100%">
            
              
                <div class="highlight"><pre /><div class="line" id="LC1"><span class="k">module</span> <span class="nn">Toolbox</span></div><div class="line" id="LC2">&nbsp;&nbsp;<span class="k">module</span> <span class="nn">Logger</span></div><div class="line" id="LC3">&nbsp;&nbsp;&nbsp;&nbsp;<span class="kp">module_function</span></div><div class="line" id="LC4"><br /></div><div class="line" id="LC5">&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">def</span> <span class="nf">log</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">priority</span> <span class="o">=</span> <span class="ss">:warn</span><span class="p">)</span></div><div class="line" id="LC6">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="no">Logger</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="ss">:priority</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span></div><div class="line" id="LC7">&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class="line" id="LC8">&nbsp;&nbsp;<span class="k">end</span></div><div class="line" id="LC9">&nbsp;&nbsp;</div><div class="line" id="LC10">&nbsp;&nbsp;<span class="k">module</span> <span class="nn">CreditCard</span></div><div class="line" id="LC11">&nbsp;&nbsp;&nbsp;&nbsp;<span class="kp">module_function</span></div><div class="line" id="LC12"><br /></div><div class="line" id="LC13">&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">def</span> <span class="nf">format_cc</span><span class="p">(</span><span class="n">number</span><span class="p">)</span></div><div class="line" id="LC14">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">number</span><span class="o">.</span><span class="n">scan</span><span class="p">(</span><span class="sr">/\d{4}/</span><span class="p">)</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">&#39;-&#39;</span><span class="p">)</span></div><div class="line" id="LC15">&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class="line" id="LC16">&nbsp;&nbsp;<span class="k">end</span></div><div class="line" id="LC17">&nbsp;&nbsp;</div><div class="line" id="LC18">&nbsp;&nbsp;<span class="k">module</span> <span class="nn">CoreExt</span></div><div class="line" id="LC19">&nbsp;&nbsp;&nbsp;&nbsp;<span class="kp">module_function</span></div><div class="line" id="LC20"><br /></div><div class="line" id="LC21">&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">module</span> <span class="nn">Array</span></div><div class="line" id="LC22">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">def</span> <span class="nf">select_random_element</span><span class="p">(</span><span class="n">array</span><span class="p">)</span></div><div class="line" id="LC23">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">array</span><span class="o">[</span><span class="nb">rand</span><span class="p">(</span><span class="n">array</span><span class="o">.</span><span class="n">length</span><span class="p">)</span><span class="o">]</span></div><div class="line" id="LC24">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class="line" id="LC25">&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class="line" id="LC26">&nbsp;&nbsp;<span class="k">end</span></div><div class="line" id="LC27"><span class="k">end</span></div></pre></div>
              
            
          </td>
        </tr>
      </table>
    
  </div></span></span></p>
<p class="p1">Granted, there's more code now, but this ISP-following refactoring allows us to include just the pieces of Toolbox that we need where we need them. The result is a cleaner, more comprehensible, and more testable system.</p>
<p class="p1"><strong>ActiveSupport</strong></p>
<p class="p1">For a very long while, the biggest ISP offender in Ruby was ActiveSupport. It was the utility module pattern writ large -- including it anywhere brought in a huge amount of code, the vast majority of which was completely irrelevant to the reason you included it somewhere.</p>
<p class="p1">In Rails 3, ActiveSupport was refactored and modularized so that you could include just the pieces you need as you needed them:</p>
<p class="p3"><span class="s3"><span class="s4"><div class="data type-ruby">
    
      <table class="lines" cellspacing="0" cellpadding="0">
        <tr>
          <td>
            <pre class="line_numbers"><span rel="#L1" id="L1">1</span>
<span rel="#L2" id="L2">2</span>
<span rel="#L3" id="L3">3</span>
</pre>
          </td>
          <td width="100%">
            
              
                <div class="highlight"><pre /><div class="line" id="LC1"><span class="nb">require</span> <span class="s1">&#39;active_support/time&#39;</span></div><div class="line" id="LC2"><span class="nb">require</span> <span class="s1">&#39;active_support/ordered_hash&#39;</span></div><div class="line" id="LC3"><span class="nb">require</span> <span class="s1">&#39;active_support/core_ext/array&#39;</span></div></pre></div>
              
            
          </td>
        </tr>
      </table>
    
  </div></span></span></p>
<p class="p1">And millions of gems, non-Rails applications, and more breathed a sigh of relief.</p>
<p class="p1"><strong>Rails Helpers</strong></p>
<p class="p1">Sticking with Rails, there's one violation of ISP still present in the current releases by default: automatic controller-based helper generation:</p>
<p class="p3"><span class="s3"><span class="s4"><div class="data type-shell">
    
      <table class="lines" cellspacing="0" cellpadding="0">
        <tr>
          <td>
            <pre class="line_numbers"><span rel="#L1" id="L1">1</span>
<span rel="#L2" id="L2">2</span>
<span rel="#L3" id="L3">3</span>
<span rel="#L4" id="L4">4</span>
<span rel="#L5" id="L5">5</span>
<span rel="#L6" id="L6">6</span>
<span rel="#L7" id="L7">7</span>
<span rel="#L8" id="L8">8</span>
<span rel="#L9" id="L9">9</span>
<span rel="#L10" id="L10">10</span>
<span rel="#L11" id="L11">11</span>
<span rel="#L12" id="L12">12</span>
<span rel="#L13" id="L13">13</span>
<span rel="#L14" id="L14">14</span>
<span rel="#L15" id="L15">15</span>
<span rel="#L16" id="L16">16</span>
<span rel="#L17" id="L17">17</span>
<span rel="#L18" id="L18">18</span>
</pre>
          </td>
          <td width="100%">
            
              
                <div class="highlight"><pre /><div class="line" id="LC1"><span class="nv">$ </span>rails g controller Mysteries index show</div><div class="line" id="LC2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;create  app/controllers/mysteries_controller.rb</div><div class="line" id="LC3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;route  get <span class="s2">&quot;mysteries/show&quot;</span></div><div class="line" id="LC4">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;route  get <span class="s2">&quot;mysteries/index&quot;</span></div><div class="line" id="LC5">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;invoke  erb</div><div class="line" id="LC6">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;create    app/views/mysteries</div><div class="line" id="LC7">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;create    app/views/mysteries/index.html.erb</div><div class="line" id="LC8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;create    app/views/mysteries/show.html.erb</div><div class="line" id="LC9">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;invoke  test_unit</div><div class="line" id="LC10">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;create    <span class="nb">test</span>/functional/mysteries_controller_test.rb</div><div class="line" id="LC11">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;invoke  helper</div><div class="line" id="LC12">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;create    app/helpers/mysteries_helper.rb</div><div class="line" id="LC13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;invoke    test_unit</div><div class="line" id="LC14">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;create      <span class="nb">test</span>/unit/helpers/mysteries_helper_test.rb</div><div class="line" id="LC15">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;invoke  assets</div><div class="line" id="LC16">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;create    app/assets/javascripts/mysteries.js.coffee</div><div class="line" id="LC17">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;invoke    scss</div><div class="line" id="LC18">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;create      app/assets/stylesheets/mysteries.css.scss</div></pre></div>
              
            
          </td>
        </tr>
      </table>
    
  </div></span></span></p>
<p class="p1">I can count on one hand the number of controllers I've seen that use the same helper methods across even a majority of their actions, much less all of them. It's a clear violation -- controller-scoped helpers are automatically included in all of that controller's views, regardless of whether they are needed or not.</p>
<p class="p1">Luckily, this is easy to fix. In your <span class="s2">config/application.rb</span>, add a <span class="s2">config.generators</span> block:</p>
<p class="p3"><span class="s3"><span class="s4"><div class="data type-ruby">
    
      <table class="lines" cellspacing="0" cellpadding="0">
        <tr>
          <td>
            <pre class="line_numbers"><span rel="#L1" id="L1">1</span>
<span rel="#L2" id="L2">2</span>
<span rel="#L3" id="L3">3</span>
<span rel="#L4" id="L4">4</span>
<span rel="#L5" id="L5">5</span>
<span rel="#L6" id="L6">6</span>
<span rel="#L7" id="L7">7</span>
<span rel="#L8" id="L8">8</span>
<span rel="#L9" id="L9">9</span>
<span rel="#L10" id="L10">10</span>
<span rel="#L11" id="L11">11</span>
<span rel="#L12" id="L12">12</span>
<span rel="#L13" id="L13">13</span>
<span rel="#L14" id="L14">14</span>
<span rel="#L15" id="L15">15</span>
<span rel="#L16" id="L16">16</span>
<span rel="#L17" id="L17">17</span>
<span rel="#L18" id="L18">18</span>
</pre>
          </td>
          <td width="100%">
            
              
                <div class="highlight"><pre /><div class="line" id="LC1"><span class="nb">require</span> <span class="no">File</span><span class="o">.</span><span class="n">expand_path</span><span class="p">(</span><span class="s1">&#39;../boot&#39;</span><span class="p">,</span> <span class="bp">__FILE__</span><span class="p">)</span></div><div class="line" id="LC2"><br /></div><div class="line" id="LC3"><span class="nb">require</span> <span class="s1">&#39;rails/all&#39;</span></div><div class="line" id="LC4"><br /></div><div class="line" id="LC5"><span class="c1"># If you have a Gemfile, require the gems listed there, including any gems</span></div><div class="line" id="LC6"><span class="c1"># you&#39;ve limited to :test, :development, or :production.</span></div><div class="line" id="LC7"><span class="no">Bundler</span><span class="o">.</span><span class="n">require</span><span class="p">(</span><span class="ss">:default</span><span class="p">,</span> <span class="no">Rails</span><span class="o">.</span><span class="n">env</span><span class="p">)</span> <span class="k">if</span> <span class="n">defined?</span><span class="p">(</span><span class="no">Bundler</span><span class="p">)</span></div><div class="line" id="LC8"><br /></div><div class="line" id="LC9"><span class="k">module</span> <span class="nn">MysteryIncorporated</span></div><div class="line" id="LC10">&nbsp;&nbsp;<span class="k">class</span> <span class="nc">Application</span> <span class="o">&lt;</span> <span class="no">Rails</span><span class="o">::</span><span class="no">Application</span></div><div class="line" id="LC11">&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1"># ...</span></div><div class="line" id="LC12"><br /></div><div class="line" id="LC13">&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">config</span><span class="o">.</span><span class="n">generators</span> <span class="k">do</span> <span class="o">|</span><span class="n">g</span><span class="o">|</span></div><div class="line" id="LC14">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">g</span><span class="o">.</span><span class="n">helper</span> <span class="kp">false</span></div><div class="line" id="LC15">&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class="line" id="LC16">&nbsp;&nbsp;<span class="k">end</span></div><div class="line" id="LC17"><span class="k">end</span></div><div class="line" id="LC18"><br /></div></pre></div>
              
            
          </td>
        </tr>
      </table>
    
  </div></span></span></p>
<p class="p1">And voila, the offending helpers are no longer created:</p>
<p class="p3"><span class="s3"><span class="s4"><div class="data type-shell">
    
      <table class="lines" cellspacing="0" cellpadding="0">
        <tr>
          <td>
            <pre class="line_numbers"><span rel="#L1" id="L1">1</span>
<span rel="#L2" id="L2">2</span>
<span rel="#L3" id="L3">3</span>
<span rel="#L4" id="L4">4</span>
<span rel="#L5" id="L5">5</span>
<span rel="#L6" id="L6">6</span>
<span rel="#L7" id="L7">7</span>
<span rel="#L8" id="L8">8</span>
<span rel="#L9" id="L9">9</span>
<span rel="#L10" id="L10">10</span>
<span rel="#L11" id="L11">11</span>
<span rel="#L12" id="L12">12</span>
<span rel="#L13" id="L13">13</span>
<span rel="#L14" id="L14">14</span>
</pre>
          </td>
          <td width="100%">
            
              
                <div class="highlight"><pre /><div class="line" id="LC1"><span class="nv">$ </span>rails g controller Mysteries index show</div><div class="line" id="LC2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;create  app/controllers/mysteries_controller.rb</div><div class="line" id="LC3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;route  get <span class="s2">&quot;mysteries/show&quot;</span></div><div class="line" id="LC4">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;route  get <span class="s2">&quot;mysteries/index&quot;</span></div><div class="line" id="LC5">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;invoke  erb</div><div class="line" id="LC6">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;create    app/views/mysteries</div><div class="line" id="LC7">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;create    app/views/mysteries/index.html.erb</div><div class="line" id="LC8">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;create    app/views/mysteries/show.html.erb</div><div class="line" id="LC9">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;invoke  test_unit</div><div class="line" id="LC10">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;create    <span class="nb">test</span>/functional/mysteries_controller_test.rb</div><div class="line" id="LC11">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;invoke  assets</div><div class="line" id="LC12">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;create    app/assets/javascripts/mysteries.js.coffee</div><div class="line" id="LC13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;invoke    scss</div><div class="line" id="LC14">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;create      app/assets/stylesheets/mysteries.css.scss</div></pre></div>
              
            
          </td>
        </tr>
      </table>
    
  </div></span></span></p>
<p class="p1">Of course, many of you have probably been ignoring the auto-generated helpers for years, creating smaller, more focused, more ISP-compliant ones the whole time. To you, I say: Good show!</p>
<p class="p1"><strong>JavaScript and CSS</strong></p>
<p class="p1">In my introductory post, I promised that we'd be looking at these principles at various levels of code. In the above examples, we've mainly stuck to the class and library levels (or to reasonable facsimiles thereof) of complexity -- but there's another spectrum on which we can look at code. In addition to the server-side examples we've already seen, we can get significant violations of the ISP on the client-side, with JavaScript and CSS.</p>
<p class="p1">Go to your app and take a look at the JavaScript and CSS you're serving up on each page. Chances are, there's a ton of stuff in there that isn't relevant to any given page -- even if you're using the new Rails asset pipeline, <span class="s2">asset_packager</span>, or something similar, it takes a tremendous and constant effort to make sure you're only sending what you need down the pipe at any given time. I've seen thousands of lines of JavaScript &nbsp;and CSS come down on pages that don't use any of it, and I'm sure you have, too.</p>
<p class="p1">Following the ISP is inherently harder when you get code from a third-party. As much work as has been done to keep JavaScript libraries like jQuery slim, there's still always going to be code in there that you don't need.&nbsp;<a href="http://jqueryui.com/"><span class="s1">jQuery UI</span></a>&nbsp;does a nice job of providing a custom script generator, allowing you to choose only the effects that you want -- but that probably isn't a universal solution.&nbsp;</p>
<p class="p1">With any design principle, there's a tradeoff. With the ISP, it's between convenience and precision. It may be absolutely more correct to have a unique, customized JavaScript and CSS load for each page on your site, but the organizational work to reach that goal -- and the cognitive overhead of figuring out which features are shared between multiple pages and unique to individual ones, so that you can find the right file to edit -- could easily become overwhelming.</p>
<p class="p1"><strong>Libraries and Applications</strong></p>
<p class="p1">When you move from classes and modules to the larger scales of libraries and applications, the ISP doesn't seem to map that closely to the code -- we move from discussing implementing interfaces to providing and consuming them. Nevertheless, I think there's still some good to come out of thinking this way.&nbsp;</p>
<p class="p1">And ISP-friendly gem, for instance, should provide a single chunk of related functionality, without a ton of extraneous stuff thrown in (hey, old ActiveSupport -- there you are again!). An ISP-friendly system of applications would pass around APIs where each application did something relatively specific... but at a certain point this approach transitions from being an example of interface segregation to&nbsp;illustrating the&nbsp;<a href="http://en.wikipedia.org/wiki/Single_responsibility_principle"><span class="s1">Single Responsibility Principle</span></a>&nbsp;(which we'll be getting to soon enough).</p>
	
</p>

<p><a href="http://benscofield.com/on-interface-segregation">Permalink</a> 

	| <a href="http://benscofield.com/on-interface-segregation#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/21967/marmalade.png</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/KESzKKtucV</posterous:profileUrl>
        <posterous:firstName>Ben</posterous:firstName>
        <posterous:lastName>Scofield</posterous:lastName>
        <posterous:nickName>Ben</posterous:nickName>
        <posterous:displayName>Ben Scofield</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Sun, 28 Aug 2011 18:28:00 -0700</pubDate>
      <title>On Fractal Design</title>
      <link>http://benscofield.com/on-fractal-design</link>
      <guid>http://benscofield.com/on-fractal-design</guid>
      <description>
        <![CDATA[<p>
	<p class="p1">I'm on my way back home after a great&nbsp;<a href="http://rubyhoedown.com/"><span class="s1">Ruby Hoedown</span></a>&nbsp;in Nashville, where I gave a talk called "Fractal Design." This is the second(ish) time I've given this talk, having previewed it in a very conversational format at the Charlotte Ruby Users' Group a month or so ago -- but I'm starting to think it's better suited for a blog post (or series of, at least), so: this.</p>
<p class="p1">The idea behind the talk is that, just as fractals are the immensely complex, impressive, and emergent results of the repeated application of a simple set of rules at different levels of magnification, so to might we produce complex and impressive software by repeatedly applying a simple set of principles and practices at different levels of code.</p>
<p class="p1"><span style="font-size: medium;"><strong>The Sierpinski Triangle</strong></span></p>
<p class="p1">So most people have probably seen the&nbsp;<span class="s2"><a href="http://en.wikipedia.org/wiki/Sierpinski_triangle">Sierpinski Triangle</a></span>&nbsp;at some point. Heck, I bet more of them have been idly doodled in middle school math notebooks than were ever generated by practicing mathematicians.</p>
<p class="p1">The basic idea is that you start with an equilateral triangle.&nbsp;</p>
<p><div class='p_embed p_image_embed'>
<img alt="T1" height="225" src="http://posterous.com/getfile/files.posterous.com/temp-2011-08-28/tIwqAnvzqAfnveloIijiHekGugwpFFjdyFiAFBBJJyvHpfmlmxgHHvgDoFEB/t1.png.scaled500.png" width="260" />
</div>
</p>
<p class="p1">You then remove the triangle formed by connecting the midpoints of each side, leaving you with three new triangles:</p>
<p class="p1"><div class='p_embed p_image_embed'>
<img alt="T2" height="225" src="http://posterous.com/getfile/files.posterous.com/temp-2011-08-28/BlgvHpugoDJiyIqHCrrEIEmIAEvGCnuaqymfGlxBglnztBvFyaDiplwpFlmf/t2.png.scaled500.png" width="260" />
</div>
</p>
<p class="p1">Next, you do the same thing to each of these three triangles -- remove smaller triangles from the center of each:</p>
<p><div class='p_embed p_image_embed'>
<img alt="T3" height="225" src="http://posterous.com/getfile/files.posterous.com/temp-2011-08-28/cApexlngvlCGpEBjxDAldaGbsfCqHHDAshjbIhFJqhFBfbbtFaindskekqlE/t3.png.scaled500.png" width="260" />
</div>
</p>
<p class="p1">And on and on, as many times as you like.</p>
<p class="p1"><div class='p_embed p_image_embed'>
<img alt="T4" height="225" src="http://posterous.com/getfile/files.posterous.com/temp-2011-08-28/BrukhHopJozrjExeDhijaHtkkmijvDGomrcqcmhHgueqICwfdxbypoqIyIwo/t4.png.scaled500.png" width="260" />
</div>
</p>
<p class="p1">What you end up with is impossibly intricate, and can be manipulated in surprising ways. When conceived of in three dimensions, you end up with a structure that has an infinite surface area and no volume at all! (a pyramidal&nbsp;<a href="http://en.wikipedia.org/wiki/Menger_sponge"><span class="s1">Menger sponge</span></a>)</p>
<p class="p1"><span style="font-size: medium;"><strong>Software</strong></span></p>
<p class="p1">OK, so software isn't exactly <span style="font-size: small;">analogous</span> to pure geometric space. Nevertheless, we do have distinct levels of magnification:</p>
<p class="p1">methods &rarr; classes &rarr; libraries &rarr; applications &rarr; ecosystems</p>
<p class="p1">We also have a large array of software design principles and practices, each of which is usually couched in the language of one of these levels (or at most, two adjacent levels). The <a href="http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)">SOLID principles</a>, <a href="http://en.wikipedia.org/wiki/Extreme_programming_practices">XP's practices</a>, the <a href="http://en.wikipedia.org/wiki/Law_of_Demeter">law of Demeter</a>, <a href="http://en.wikipedia.org/wiki/Design_pattern_(computer_science)">design patterns</a> -- what would happen if we tried applying them across our entire body of software, instead of just when designing a library's API, a user interface, or a single method?</p>
<p class="p1">So that's the question. In future posts I'll tackle this question with specific principles, and hopefully we'll find something interesting.</p>
<p>&nbsp;</p>
	
</p>

<p><a href="http://benscofield.com/on-fractal-design">Permalink</a> 

	| <a href="http://benscofield.com/on-fractal-design#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/21967/marmalade.png</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/KESzKKtucV</posterous:profileUrl>
        <posterous:firstName>Ben</posterous:firstName>
        <posterous:lastName>Scofield</posterous:lastName>
        <posterous:nickName>Ben</posterous:nickName>
        <posterous:displayName>Ben Scofield</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Wed, 08 Jun 2011 03:49:00 -0700</pubDate>
      <title>On This Blog</title>
      <link>http://benscofield.com/on-this-blog</link>
      <guid>http://benscofield.com/on-this-blog</guid>
      <description>
        <![CDATA[<p>
	<p>Oh! I should mention -- this is the fourth, fifth, or twenty-third incarnation of my blog, all told. It's running on Posterous, which provides an import feature that I used to bring over all of my old posts. Unfortunately, the import isn't perfect, meaning that a lot of old posts have lost some or most of their formatting, and in many cases links don't work. Sorry! I'm hopeful that future value will make up for past pain, but you all will be the judge of that....</p>
	
</p>

<p><a href="http://benscofield.com/on-this-blog">Permalink</a> 

	| <a href="http://benscofield.com/on-this-blog#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/21967/marmalade.png</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/KESzKKtucV</posterous:profileUrl>
        <posterous:firstName>Ben</posterous:firstName>
        <posterous:lastName>Scofield</posterous:lastName>
        <posterous:nickName>Ben</posterous:nickName>
        <posterous:displayName>Ben Scofield</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Tue, 07 Jun 2011 19:41:56 -0700</pubDate>
      <title>On Starting</title>
      <link>http://benscofield.com/on-starting</link>
      <guid>http://benscofield.com/on-starting</guid>
      <description>
        <![CDATA[<p>
	<p>Back in May, I gave a talk at <a href="http://igniterailsconf.com">Ignite RailsConf</a>&nbsp;on being <em>awesome</em>. The presentation revolved around three (well, two and a half) rules, of which the first was:</p>
<p class="p1"><strong>Start stuff</strong></p>
<p class="p1">The justification for this rule is simple: if you don't start things, you'll never succeed. To go cliched, you'll never reach any destination unless you take a first step. Beyond that, though, the more things you start, the more chances you have to be awesome. No one in history ever became great by only doing one thing.</p>
<p class="p1">To prove my point, here is a sweet and not-at-all made-up chart showing the relationship between the number of things someone starts and how awesome they are (all other things being equal, of course)</p>
<p><div class='p_embed p_image_embed'>
<a href="http://posterous.com/getfile/files.posterous.com/temp-2011-06-07/rxrakuDwlCwDevwAajiwcjlBymhHBDbCwJbwGsBvzDryAzkqqhfvCIpayCgr/chart-starting.png.scaled1000.png"><img alt="Chart-starting" height="199" src="http://posterous.com/getfile/files.posterous.com/temp-2011-06-07/rxrakuDwlCwDevwAajiwcjlBymhHBDbCwJbwGsBvzDryAzkqqhfvCIpayCgr/chart-starting.png.scaled500.png" width="500" /></a>
</div>
</p>
<p>OK, it's easy enough to say that you should start lots of stuff, but it's a lot harder to actually do it. As I see it, there are two main problems around following the rule.</p>
<p><strong>What to start</strong></p>
<p>First, you have to figure out <em>what</em> things to start. There's an entire cottage industry around people who think they don't have enough ideas, and I don't have much to add to that -- I'll just tell you what seems to work for me. The more reliably I track my ideas, the more (and better) ideas I seem to have. The medium doesn't seem to matter very much; I've had bursts of creativity with pen and paper, voice recorders, and tools like <a href="http://evernote.com/">Evernote</a> alike. I will say, however, that some choices make reviewing things much easier than others, and now I primarily use Evernote for tracking ideas.</p>
<p><strong>Overcoming intertia</strong></p>
<p>The other major challenge around starting things is inertia. We're all busy, and it takes a real effort to start new projects regularly. For me, the best way to deal with that is to start smaller and smaller projects. When I'm reviewing ideas for something new to work on, things that are too big (writing the Great American Novel, building a new piece of hardware to do some task around the house, etc.) are massively intimidating; the fear that I'll never be able to finish them makes it that much harder to start them. Small projects, on the other hand, make it much easier to convince myself that I'll be able to bang them out -- and that's a huge step.</p>
<p><strong>Next up</strong></p>
<p>There's a lot more to say on starting, of course, but I don't want to ignore the other rule-and-a-half, so I'll be talking about finishing and quitting next.</p>
	
</p>

<p><a href="http://benscofield.com/on-starting">Permalink</a> 

	| <a href="http://benscofield.com/on-starting#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/21967/marmalade.png</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/KESzKKtucV</posterous:profileUrl>
        <posterous:firstName>Ben</posterous:firstName>
        <posterous:lastName>Scofield</posterous:lastName>
        <posterous:nickName>Ben</posterous:nickName>
        <posterous:displayName>Ben Scofield</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Fri, 03 Jun 2011 11:48:00 -0700</pubDate>
      <title>On Haml</title>
      <link>http://benscofield.com/on-haml</link>
      <guid>http://benscofield.com/on-haml</guid>
      <description>
        <![CDATA[<p>
	<p>I've been very happy to see that, for the most part, the evangelism around <a href="http://haml-lang.com/">Haml</a> has died down over the past year or so -- it felt like you couldn't go anywhere in 2010 without getting slapped in the face with significant whitespace. It still crops up every once in a while, though, so I thought I'd add my ever-welcome $0.02 and explain why I don't use it.</p>
<ol>
<li>HTML isn't broken. Sure, it takes more keystrokes, but there are no faults in HTML that are fixed by Haml (unlike <a href="http://sass-lang.com/">Sass</a>, which actually does fix problems in CSS -- and can I just cheer the separation of Sass into <a href="http://rubygems.org/gems/sass">its own gem</a>?).</li>
<li>Significant horizontal whitespace becomes a gigantic problem when you have more than one screen of content. Even relatively simple web pages can run to multiple pages of markup, invalidating the "indentation as visible structure" argument.</li>
<li>Haml implicitly promotes a <code>&lt;div&gt;</code>-heavy markup structure -- it's just too easy to go <code>&lt;div&gt;</code>-crazy with Haml, instead of the slimmer, more semantic markup style that I prefer.</li>
</ol>
<p>Of course, your mileage may vary. Do what you want, but please stop accosting those of us who choose something else.</p>
<p><strong>Edited: </strong>Haml isn't an acronym, so all of my "HAML"s were incorrect. Sorry!</p>
	
</p>

<p><a href="http://benscofield.com/on-haml">Permalink</a> 

	| <a href="http://benscofield.com/on-haml#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/21967/marmalade.png</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/KESzKKtucV</posterous:profileUrl>
        <posterous:firstName>Ben</posterous:firstName>
        <posterous:lastName>Scofield</posterous:lastName>
        <posterous:nickName>Ben</posterous:nickName>
        <posterous:displayName>Ben Scofield</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Mon, 18 Oct 2010 16:14:00 -0700</pubDate>
      <title>Rumbled</title>
      <link>http://benscofield.com/rumbled</link>
      <guid>http://benscofield.com/rumbled</guid>
      <description>
        <![CDATA[<p>
	<p>As I'm just now coming out of the caffeine- and sleep-deprivation-induced haze that was my weekend, I thought it might be interesting to reflect on what exactly happened.  After forgoing competition last year in favor of judging others as an expert panelist, I decided to compete in the <a href="http://railsrumble.com">Rails Rumble</a> once again this time around. As I expected, I had a metric ton of fun building my app (<a href="http://airportatlas.info">Airport Atlas</a> - see its full glory on the <a href="http://airportatlas.info/RDU/2">RDU Terminal 2 map</a>) all by my lonesome. From 8pm Friday to 8pm Sunday, I pounded code, tweaked pixels in Photoshop, and drank Cherry Coke Zero like there was no tomorrow. My work is far from over, though -- for the next few days, the entries are being evaluated by the new crop of experts, after which some of them will go on to public voting. Wish me luck (and <a href="http://railsrumble.com/teams/team-rocketpants">vote for me</a>, if you get the chance!)  <strong>Some (possibly) interesting stats</strong></p>
<ul>
<li>107 commits</li>
<li>251 lines of application code written</li>
<li>214 lines of testing code written&nbsp;(1:0.9 code/test ratio)</li>
<li>67.2% test coverage (abysmal! It was much higher before Sunday :)</li>
<li>20ish cans of Cherry Coke Zero drunk (don't judge me)</li>
</ul>
<p>I'm really looking forward to continuing to work on Airport Atlas, so feel free to leave comments and suggestions here or on <a href="http://railsrumble.com/teams/team-rocketpants">my team page</a>.</p>
	
</p>

<p><a href="http://benscofield.com/rumbled">Permalink</a> 

	| <a href="http://benscofield.com/rumbled#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/21967/marmalade.png</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/KESzKKtucV</posterous:profileUrl>
        <posterous:firstName>Ben</posterous:firstName>
        <posterous:lastName>Scofield</posterous:lastName>
        <posterous:nickName>Ben</posterous:nickName>
        <posterous:displayName>Ben Scofield</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Wed, 07 Jul 2010 11:20:00 -0700</pubDate>
      <title>Event Updates</title>
      <link>http://benscofield.com/event-updates</link>
      <guid>http://benscofield.com/event-updates</guid>
      <description>
        <![CDATA[<p>
	<p>Yes, yes, I know I've been gone for a while. What can I say? <a href="http://puma.com/running">I've</a> <a href="http://railsconf.com">been</a> <a href="http://reviewingted.posterous.com/">really</a> <a href="http://devnation.us">busy</a>.  That said, I'm rejiggering priorities, and pretty high on the list was getting this site updated -- particularly the <a href="http://benscofield.com/speaking/">Speaking</a> and <a href="http://benscofield.com/events/">Upcoming Events</a> pages. If you're interested in knowing where I've been and where I'll be, take a look! (And expect new content here shortly!)</p>
	
</p>

<p><a href="http://benscofield.com/event-updates">Permalink</a> 

	| <a href="http://benscofield.com/event-updates#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/21967/marmalade.png</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/KESzKKtucV</posterous:profileUrl>
        <posterous:firstName>Ben</posterous:firstName>
        <posterous:lastName>Scofield</posterous:lastName>
        <posterous:nickName>Ben</posterous:nickName>
        <posterous:displayName>Ben Scofield</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Tue, 02 Feb 2010 21:00:00 -0800</pubDate>
      <title>Developer Day Austin wrapup</title>
      <link>http://benscofield.com/developer-day-austin-wrapup</link>
      <guid>http://benscofield.com/developer-day-austin-wrapup</guid>
      <description>
        <![CDATA[<p>
	<p>It's been a few days since we wrapped up&nbsp;<a href="http://developer-day.com/events/2010-austin.html">Developer Day Austin</a>, and I'm only now able to catch my breath &ndash; a few snowmageddon- and planning-related incidents combined to keep me pretty busy over the weekend and this week.  In a lot of ways, Austin reminded me of the very first&nbsp;<a href="http://developer-day.com/events/2009-durham.html">Developer Day</a>, back in March of last year. Some of the lessons in logisitics that we learned at that first event, in particular, were significantly reinforced by our experiences in Austin. Despite a few hiccups, however, the event as a whole went over well. I think we were able to bring together at least a few people who don't often meet up &ndash; front-end developers and Rubyists, with a few Pythonists and others in the mix.  Our lineup of talks was front-end heavy this go-round, and that was interesting; I thought&nbsp;<a href="http://speakerrate.com/talks/2062-javascript-ui-architecture-be-all-that-you-can-be">Kyle Simpson</a> and&nbsp;<a href="http://speakerrate.com/talks/2064-superclassy-inheritance-with-javascript">Alex Sexton</a> did a great job bringing the JavaScript thunder, for instance, and I'm encouraged to bring in more front-end talks at future events (especially because JavaScript is almost a&nbsp;<a href="http://en.wikipedia.org/wiki/Lingua_franca"><em>lingua franca</em></a> for web developers at this point).&nbsp;Unfortunately, I had to leave midway through the day (the aforementioned snowmageddon incident), so I missed&nbsp;<a href="http://speakerrate.com/talks/2065-the-art-of-the-spike">Aaron Bedra</a>,&nbsp;<a href="http://speakerrate.com/talks/2066-why-jmatter-matters">Eitan Suez</a>, and&nbsp;<a href="http://speakerrate.com/talks/2067-mary-poppins-meets-the-matrix">Bruce Tate</a>, each of whom I was excited to see.  And a few words about Austin... first, Austin is clearly&nbsp;<a href="http://gowalla.com/">Gowalla</a> territory. Stepping off the plane, I was struck by how many featured spots there were, and it made bopping from place to place a lot of fun. Second, it was much colder than I expected. If I thought I underdressed for&nbsp;<a href="http://developer-day.com/events/2009-boulder.html">Boulder</a> last year, it was nothing compared to the mismatch of expectations that Austin (and Dallas, on the way back) triggered.  Anyways, I think Austin provided a good start for the 2010 Developer Day season, and I'm really looking forward to the rest of the series &ndash; speaking of which, the next event is February 27th in Durham, NC, so if you're anywhere nearby&nbsp;<a href="http://developer-day.com/events/2010-durham.html">register today</a>!</p>
	
</p>

<p><a href="http://benscofield.com/developer-day-austin-wrapup">Permalink</a> 

	| <a href="http://benscofield.com/developer-day-austin-wrapup#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/21967/marmalade.png</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/KESzKKtucV</posterous:profileUrl>
        <posterous:firstName>Ben</posterous:firstName>
        <posterous:lastName>Scofield</posterous:lastName>
        <posterous:nickName>Ben</posterous:nickName>
        <posterous:displayName>Ben Scofield</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Mon, 25 Jan 2010 11:42:00 -0800</pubDate>
      <title>Job descriptions vs. goals</title>
      <link>http://benscofield.com/job-descriptions-vs-goals</link>
      <guid>http://benscofield.com/job-descriptions-vs-goals</guid>
      <description>
        <![CDATA[<p>
	<p>Raise your hand if you have a job description - a paragraph or eight that describe your role and responsibilities in your current position.Now, raise your hand if you have a specific set of goals for what you are supposed to accomplish today, this week, this month, and this quarter.  I'm betting that there's little, if any, overlap between those two groups.  I used to be in the job description camp, and I was pretty effective. I built stuff, went to meetings, talked to people, got stuff done... I think I did a good job of matching the description. For the last eight months or so, however, I've been in the second camp. In lieu of a formal job description, I have specific, measurable goals to accomplish in any given time period. As a result, I can tell you exactly how I'm doing at any given point, and where I need to focus my efforts to get more done.  For freelancers, of course, this is probably an obvious change &ndash; when you work for (and substantially by) yourself, your job description is "get everything done," which means you have to fall back on goals. For employees, however, changing your mindset from a vague prose passage to a set of concrete goals can be a massive shift. It can dramatically improve your effectiveness at your current job &ndash; or it could show that you should've been doing something different all along.</p>
	
</p>

<p><a href="http://benscofield.com/job-descriptions-vs-goals">Permalink</a> 

	| <a href="http://benscofield.com/job-descriptions-vs-goals#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/21967/marmalade.png</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/KESzKKtucV</posterous:profileUrl>
        <posterous:firstName>Ben</posterous:firstName>
        <posterous:lastName>Scofield</posterous:lastName>
        <posterous:nickName>Ben</posterous:nickName>
        <posterous:displayName>Ben Scofield</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Thu, 21 Jan 2010 10:50:00 -0800</pubDate>
      <title>Letter-writing</title>
      <link>http://benscofield.com/letter-writing</link>
      <guid>http://benscofield.com/letter-writing</guid>
      <description>
        <![CDATA[<p>
	<p>I had a thought the other day... I wonder if the demise of correspondence via letters has resulted in a reduction in significant thought. Here's the idea:  When long-form letter writing was the predominant means of long-distance communication, you had some astounding exchanges (Descartes' correspondence with pretty much everyone, for instance). Many great thinkers first detailed their theories in these long letters, and I wonder if the form itself made that more likely. Think about it - when you're corresponding via letter, longer messages are more efficient (whereas the opposite is true today, with email, IM, and tweets). Longer messages mean more time writing, and more time writing means more time thinking through what you want to say. As a result, then, writing long letters may have helped people think through their ideas more fully before making them public.  If that's the case, then it very well might be the case that today's preponderance of short-form communication makes it much less likely that anyone will release a complex idea fully-formed &ndash; but the greater frequency (and reach) of their interactions with other people may overcome that deficit. Could it be that letter-writing was waterfall, and email, IM, and Twitter are agile?  (And might this post play into that precise analogy, being far from presenting a fully-formed theory itself?)</p>
	
</p>

<p><a href="http://benscofield.com/letter-writing">Permalink</a> 

	| <a href="http://benscofield.com/letter-writing#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/21967/marmalade.png</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/KESzKKtucV</posterous:profileUrl>
        <posterous:firstName>Ben</posterous:firstName>
        <posterous:lastName>Scofield</posterous:lastName>
        <posterous:nickName>Ben</posterous:nickName>
        <posterous:displayName>Ben Scofield</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Fri, 15 Jan 2010 12:22:00 -0800</pubDate>
      <title>CodeMash recap</title>
      <link>http://benscofield.com/codemash-recap</link>
      <guid>http://benscofield.com/codemash-recap</guid>
      <description>
        <![CDATA[<p>
	<p><div class='p_embed p_image_embed'>
<img alt="Media_httpbenscofield_ihbip" height="127" src="http://posterous.com/getfile/files.posterous.com/import-emqz/hoevvJhiyFnjkbCcrmhFyqFFbJezqeEiAIcBjekdrawaCFxHHfrkJopvHdxr/media_httpbenscofield_ihbip.jpg.scaled500.jpg" width="125" />
</div>
 So, after some difficulties getting the planes to fly on time, I finally made it home from&nbsp;<a href="http://codemash.org/">CodeMash</a> late last night. Despite only being there for a short time (and being intensely jealous of everyone who was able to stay for the full event), I had a great time.  I did notice a couple of differences between CodeMash and the Ruby/open source conferences I normally attend, however. First, the gender balance was, while still skewed, was much closer than I'm used to. I remember hearing somewhere that there were more women in enterprise computing (.Net and Java) than in the more fringe technologies, and I guess I've got anecdotal evidence to back that up, now.  Also, the sponsorship atmosphere was&nbsp;<em>very </em>different &ndash; in fact, it felt more like the&nbsp;<a href="http://www.startupcrawl.com/">Startup Crawl</a> than it did the Expo Hall at RailsConf. Sponsor booths had video games, coding problems, and a ton of giveaways (both raffles and freebies), and their staff were a bit more assertive.  My talk (an updated version of the one I gave at RubyConf) went over well, I think &ndash; no ratings on&nbsp;<a href="http://speakerrate.com/talks/1954-nosql-death-to-relational-databases">SpeakerRate</a> yet, but (like all technical conferences) there were substantial problems with the wifi, so I'm hoping that people will rate it once they return home. I did fail in one significant way, however: I didn't consider my audience as carefully as I should have. The needs of an audience of .Net, Java, and related technologists are somewhat different than those of a room full of Rubyists. I got a question on&nbsp;<a href="http://neo4j.org/">Neo4j</a>'s licensing, for instance, that hasn't come up in any of the half-dozen or more times I've talked about it previously.  I don't think that this problem affected the presentation itself, but it's certainly something I should have done for the question period.</p>
<div style="text-align: left;"><a href="http://www.slideshare.net/bscofield/nosql-codemash-2010" title="NoSQL @ CodeMash 2010" style="font: 14px Helvetica,Arial,Sans-serif; display: block; margin: 12px 0 3px 0; text-decoration: underline;">NoSQL @ CodeMash 2010</a> 
<object height="355" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425">
<param name="allowFullScreen" value="true" />
<param name="allowScriptAccess" value="always" />
<param name="src" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=201001-codemash-100115061138-phpapp02&amp;stripped_title=nosql-codemash-2010" />
<param name="allowfullscreen" value="true" /> <embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=201001-codemash-100115061138-phpapp02&amp;stripped_title=nosql-codemash-2010" type="application/x-shockwave-flash" height="355" width="425"></embed>
</object>
<div style="font-size: 11px; font-family: tahoma,arial; height: 26px; padding-top: 2px;">View more <a href="http://www.slideshare.net/" style="text-decoration: underline;">documents</a> from <a href="http://www.slideshare.net/bscofield" style="text-decoration: underline;">Ben Scofield</a>.</div>
</div>

	
</p>

<p><a href="http://benscofield.com/codemash-recap">Permalink</a> 

	| <a href="http://benscofield.com/codemash-recap#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/21967/marmalade.png</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/KESzKKtucV</posterous:profileUrl>
        <posterous:firstName>Ben</posterous:firstName>
        <posterous:lastName>Scofield</posterous:lastName>
        <posterous:nickName>Ben</posterous:nickName>
        <posterous:displayName>Ben Scofield</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Mon, 11 Jan 2010 12:00:00 -0800</pubDate>
      <title>Design-first development</title>
      <link>http://benscofield.com/design-first-development</link>
      <guid>http://benscofield.com/design-first-development</guid>
      <description>
        <![CDATA[<p>
	<p>The first RubyConf talk I gave was entitled&nbsp;<a href="http://rubyconf2007.confreaks.com/d3t1p6_cleanliness_is_next_to_domain_specificity.html"><em>Cleanliness Is Next to Domain-Specificity</em></a>; in it, I spoke about DSLs, and gave an example of how you might want to create one (I also spent some time talking about regional variation in&nbsp;<em>Little Bunny Foo Foo</em>, but that's neither here nor there). At the time, I said that the best way to design a DSL was to write out what you wanted it to look like, and then write the code that made that functional.  I've since become convinced that this process is in fact the best way to design&nbsp;<em>any </em>code, not just DSLs. API? Write out how you want to call it, then write the code that responds to those calls. Routing in a web app? Write out the URLs you want people to hit, then create the code and routes that will make those work. A web page? Design the page, build it out into HTML, and then write the code that makes it live. Each of these is an example of design-first development.  You may be wondering if I'm abandoning the lean/agile fold for waterfall with this idea. Happily, I'm not. If you think about it, this is how TDD (or BDD) works: you write a test or spec that runs some code (in the process, designing how you'll interact with the code), and then you write the code that makes it pass. The sort of design I'm talking out isn't fossilized in spec documents, but is actually executable when you finish writing the code to make it work.  The key to all of this is realizing that design happens at a number of different levels. In the examples above, I described design the level of writing code (DSL), of integrating with systems (API), of browser interaction (routing), and&nbsp;of user interface (web page).  I think that more and more people are realizing the power of this approach at various levels, but I'm convinced that recognizing each of those levels as an instance of using design-first development may provide better insights into the process overall.</p>
	
</p>

<p><a href="http://benscofield.com/design-first-development">Permalink</a> 

	| <a href="http://benscofield.com/design-first-development#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/21967/marmalade.png</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/KESzKKtucV</posterous:profileUrl>
        <posterous:firstName>Ben</posterous:firstName>
        <posterous:lastName>Scofield</posterous:lastName>
        <posterous:nickName>Ben</posterous:nickName>
        <posterous:displayName>Ben Scofield</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Thu, 07 Jan 2010 12:00:00 -0800</pubDate>
      <title>Practice isn't fun</title>
      <link>http://benscofield.com/practice-isnt-fun</link>
      <guid>http://benscofield.com/practice-isnt-fun</guid>
      <description>
        <![CDATA[<p>
	<p>It's a new year, and it's about time for a hard truth: practice, when done properly, isn't fun.  I'd love to be able to tell you that it is &ndash; that the transcendent joy you get when you practice a skill gives you the best feeling in the world &ndash; but that's not true, and if you pursue that end you're going to misuse your practice time.  The father of the analysis of practice is Anders Ericsson; his&nbsp;<a href="http://projects.ict.usc.edu/itw/gel/EricssonDeliberatePracticePR93.pdf">1993 paper</a> on deliberate practice is a must-read for anyone interested in mastery. In that paper, he distinguishes three different sorts of activity:</p>
<ul>
<li>Work is the execution of a skill for an external reward (for instance, a paycheck)</li>
<li>Play is the execution of a skill for an internal reward (because it makes you happy)</li>
<li>Deliberate practice is the execution of a skill specifically to improve at that skill</li>
</ul>
<p>Those distinctions alone leave open the possibility that practice could be fun, but when you start to dig into the depths of activities that are specifically designed to help you improve a particular skill, it turns out that they share very little with the general activities you see in play (or in work, for that matter).  Daniel Coyle provides an example of this in&nbsp;<em><a href="http://www.amazon.com/gp/product/055380684X?ie=UTF8&amp;tag=culanncom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=055380684X">The Talent Code</a>. </em>He describes a video of a schoolgirl practicing the clarinet. She's an average player, but during one six-minute section of the video, she practices deliberately, and improves markedly as a result. Watching the session, however, you'd be hard-pressed to understand why this particular bit was important, because it certainly doesn't look like she's enjoying herself &ndash; where later in the session she's playing through tunes, here she's constantly stopping and starting. It doesn't sound like music, or what we naively think of as practice, but it's the best thing she could be doing.  The point is that the actions that produce the most improvement aren't closely related to the more common performances of a skill. In a martial art, you may practice a single turn hundreds or thousands of times in order to perfect a tiny piece of a long form. The practice itself isn't fun, which means we have to trick ourselves into enjoying it by considering the future rewards.  Aside for developers: one consequence of this finding is that side-projects don't cut it as practice. If you want to improve in your technology and you think you'll do it in the course of building some application that you have a need for, you're heading down the wrong path. What eventually happens is that the external reward (of having some tool that you want to use) will inevitably overtake the skill-improvement aspects of the process, and, while you'll end up with something useful, you won't have improved as a developer nearly as much as if you'd spent that time practicing more effectively.</p>
	
</p>

<p><a href="http://benscofield.com/practice-isnt-fun">Permalink</a> 

	| <a href="http://benscofield.com/practice-isnt-fun#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/21967/marmalade.png</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/KESzKKtucV</posterous:profileUrl>
        <posterous:firstName>Ben</posterous:firstName>
        <posterous:lastName>Scofield</posterous:lastName>
        <posterous:nickName>Ben</posterous:nickName>
        <posterous:displayName>Ben Scofield</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Mon, 04 Jan 2010 12:00:00 -0800</pubDate>
      <title>My five-year anniversary with Ruby</title>
      <link>http://benscofield.com/my-five-year-anniversary-with-ruby</link>
      <guid>http://benscofield.com/my-five-year-anniversary-with-ruby</guid>
      <description>
        <![CDATA[<p>
	<p>My five-year anniversary with&nbsp;<a href="http://www.viget.com/">Viget Labs</a> is approaching quickly &ndash; I started here back in February 2005. Before I reach that milestone, though, there's another that's been at least as influential in my life: this month is my five year anniversary of using Ruby and Rails. I started experimenting with 'em during my last month at Nextel, when I was using classic ASP and C# in the office and looking for PHP jobs (which, to bring it back around, led me to Viget).  I really only played with Rails for a few months, but by mid-2005 I'd gotten deep enough into it that I started talking about it at the office. Even more importantly, I was able to bring concepts from Rails into my PHP projects, which made for visibly better code. By 2006, people got tired enough of me pointing out how easy it would be to build the next project in Rails, so we tried it out on a client, and the rest fell into place very quickly.  Aside from that, though, Ruby's been very good to me, personally. It's allowed me to&nbsp;<a href="http://benscofield.com/speaking">speak internationally</a>,&nbsp;<a href="http://www.amazon.com/gp/product/1590599942?ie=UTF8&amp;tag=culanncom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1590599942">write a book</a>,&nbsp;<a href="http://developer-day.com/">organize an event series</a>,&nbsp;<a href="http://benscofield.com/2009/10/railsconf-2010/">co-chair a global conference</a>, and (last, but far from least) meet and befriend some amazing, brilliant people. I can honestly say that starting with Ruby and Rails five years ago was one of the best decisions I made in the last decade &ndash; and while I don't expect to work in Ruby forever, I hope that every technology I use in the future has a community as devoted to excellence and civility as this one.</p>
	
</p>

<p><a href="http://benscofield.com/my-five-year-anniversary-with-ruby">Permalink</a> 

	| <a href="http://benscofield.com/my-five-year-anniversary-with-ruby#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/21967/marmalade.png</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/KESzKKtucV</posterous:profileUrl>
        <posterous:firstName>Ben</posterous:firstName>
        <posterous:lastName>Scofield</posterous:lastName>
        <posterous:nickName>Ben</posterous:nickName>
        <posterous:displayName>Ben Scofield</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Mon, 28 Dec 2009 12:00:00 -0800</pubDate>
      <title>Weekly goals</title>
      <link>http://benscofield.com/weekly-goals</link>
      <guid>http://benscofield.com/weekly-goals</guid>
      <description>
        <![CDATA[<p>
	<p>In light of the impending new year, I thought I'd offer an alternative to&nbsp;the associated flood of well-intentioned but ultimately-doomed resolutions: weekly goals. (And yes, I&nbsp;<a href="http://www.viget.com/extend/developer-resolutions-for-2010/">contributed</a> to the flood myself. Color me somewhat hypocritical.)  I see several problems with annual resolutions, all related to their length. When you're making year-long goals, it's extremely difficult to figure out exactly what is possible, so you're less likely to set appropriately difficult (but still achievable) targets. Even when you succeed in that, however, the size of the goals can be intimidating, so it's harder to get started. Weekly goals deal with both of these issues &ndash; it's much easier to figure out how much you can do, and it's simpler to see how to tackle a smaller goal. In addition, the feedback cycle is so much shorter that you can easily adjust your goal-setting from week to week, which means that it's possible to&nbsp;<em>improve </em>at goal setting in a reasonable timeframe.  What does this mean? Well, take one of the most popular resolutions: losing weight. The first obstacle is moving from a vague "lose weight" to something more concrete, but what's the appropriate target? It's all too easy to shoot too high when your primary knowledge about weight loss comes from&nbsp;<em>The Biggest Loser. </em>Even if you figure out a reachable target, having your goal be "lose fifty pounds this year," can be intimidating all on its own. Larger goals are harder to get your mind around; at times, it can be hard to figure out how best to get going.  Contrast that with the weekly version. If you're aiming to lose a pound a week, that means you need to burn 3500 calories more than you take in for the week. With a solid target, it's much easier to plan out how to do it &ndash; pass up dessert here and there, eat less calories in snacks, park farther away from the door, and before you know it you're meeting your goal. At a weekly level, you can also experiment &ndash; see just how much better or worse you do by replacing a steak with a salad, etc.  Of course, this points to a useful strategy: you can still make your ill-defined annual resolutions, but back them up with weekly goals to help you make the longer-term goals work. Good luck, and happy new year!</p>
	
</p>

<p><a href="http://benscofield.com/weekly-goals">Permalink</a> 

	| <a href="http://benscofield.com/weekly-goals#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/21967/marmalade.png</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/KESzKKtucV</posterous:profileUrl>
        <posterous:firstName>Ben</posterous:firstName>
        <posterous:lastName>Scofield</posterous:lastName>
        <posterous:nickName>Ben</posterous:nickName>
        <posterous:displayName>Ben Scofield</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Tue, 22 Dec 2009 12:00:00 -0800</pubDate>
      <title>The flood of ideas</title>
      <link>http://benscofield.com/the-flood-of-ideas</link>
      <guid>http://benscofield.com/the-flood-of-ideas</guid>
      <description>
        <![CDATA[<p>
	<p><a href="http://sethgodin.typepad.com/seths_blog/2009/12/fear-of-bad-ideas.html">Seth's post</a> yesterday struck a chord with me, as it reminded me of how I felt a few months ago. At the time, I was posting extremely regularly here in the blog, and it seemed like ideas were flowing easily &ndash; my idea notebooks in <a href="http://www.evernote.com">Evernote</a> were overflowing. This continued into November, even when I turned away from the blog in favor of working on a book proposal. I was still writing things down, however, and that kept the ideas flowing.  Towards the end of November, however, I took a break from writing (RubyConf, travel, and a few other things intervened). At first, the idea flood continued &ndash; I essentially ignored them, and for a time they continued to build, until I felt an almost-physical pressure. Finally, I gave in and recorded a dozen or so into trusty Evernote, but by then the damage was done, and what had been a constant stream of ideas (both good and bad) ended up more akin to a floodplain than a flood.  It's taken some effort, but I'm finally getting back into things, and I'm wiser for the experience now. Ideas seem to be one of those "rich getting richer" phenomena, where the people who respect and encourage the flow of all ideas are the ones who end up having more of them. So, if you haven't tried, start carrying a notebook or a voice recorder around, and record all those things that pop into your head. Who knows which one of them might be amazing, and end up changing your life?</p>
	
</p>

<p><a href="http://benscofield.com/the-flood-of-ideas">Permalink</a> 

	| <a href="http://benscofield.com/the-flood-of-ideas#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/21967/marmalade.png</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/KESzKKtucV</posterous:profileUrl>
        <posterous:firstName>Ben</posterous:firstName>
        <posterous:lastName>Scofield</posterous:lastName>
        <posterous:nickName>Ben</posterous:nickName>
        <posterous:displayName>Ben Scofield</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Fri, 18 Dec 2009 12:00:00 -0800</pubDate>
      <title>Irreversibility</title>
      <link>http://benscofield.com/irreversibility</link>
      <guid>http://benscofield.com/irreversibility</guid>
      <description>
        <![CDATA[<p>
	<p>I'm generally a pretty calm guy. We've all got pet peeves, though, and one of my occurs all too frequently. I'm talking about people who think their decisions and mistakes while driving are irreversible. You know, people who cut across three lanes of traffic to make a left turn into a mall parking lot, when they could easily make a u-turn at the next light - that sort of thing. In the grand scheme of things it's clearly trivial, but it never fails to tick me off.  I discovered the&nbsp;<a href="http://en.wikipedia.org/wiki/Myers-Briggs_Type_Indicator">Myers-Briggs</a> personality inventory nearly fifteen years ago (I'm an&nbsp;<a href="http://en.wikipedia.org/wiki/INTP">INTP</a>, thanks for asking), and one of the dimensions it evaluates is very much related to the idea that decisions are irreversible. People range from perceiving to judging (I know, they're pretty awful names for the trait, but go with it) - where perceivers typically put off making a decision, and judgers tend to prefer having things settled.  I mentioned I'm an INTP, where the P stands for perceiver. Given the above brief description, then, you might expect me to be on the side of the irreversible-deciders, but in fact reversibility makes being a perceiver much easier. What better way to decide what to do could there be than actually&nbsp;<em>making </em>a provisional decision and seeing what happens? This has parallels in all sorts of fields: <a href="http://www.startuplessonslearned.com/2009/08/minimum-viable-product-guide.html">minimum viable products</a>,&nbsp;<a href="http://en.wikipedia.org/wiki/Agile_software_development">agile development</a>,&nbsp;<a href="http://www.thekitchn.com/thekitchn/tips-techniques/weekend-cooking-on-tasting-while-cooking-050250">tasting while cooking</a> - they're all predicated on committing to a course of action as little as possible, and being able to adjust (or even reverse) that commitment as necessary.  I think we'd all be a lot happier if we realized that relatively little in life is irreversible - and who knows what you may discover by trying something out without the fear of having committed to the wrong course forever.</p>
	
</p>

<p><a href="http://benscofield.com/irreversibility">Permalink</a> 

	| <a href="http://benscofield.com/irreversibility#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/21967/marmalade.png</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/KESzKKtucV</posterous:profileUrl>
        <posterous:firstName>Ben</posterous:firstName>
        <posterous:lastName>Scofield</posterous:lastName>
        <posterous:nickName>Ben</posterous:nickName>
        <posterous:displayName>Ben Scofield</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Sat, 12 Dec 2009 16:36:00 -0800</pubDate>
      <title>Failure is bad.</title>
      <link>http://benscofield.com/failure-is-bad</link>
      <guid>http://benscofield.com/failure-is-bad</guid>
      <description>
        <![CDATA[<p>
	<p>I just read&nbsp;<a href="http://learntoduck.com/startups/too-much-failure">a post from Micah Baldwin</a> that I found very interesting, so here's a quick response:  Failure is bad.  Success is good.  Sure, failure can teach you valuable lessons - but so can success, and success has the added benefit of&nbsp;<em>being success</em>.  What the "failure is good" mentality misses is that failure is good&nbsp;<em>only as a means to future success</em>. Micah's friend did exactly the right thing: he used his past failures to guide him to the choice that he perceives has a greater potential for success. In my book, that merits much more than a, "Fair enough." Anything else would be actively courting failure &ndash; mistaking the process for the goal, and forgetting the&nbsp;<a href="http://benscofield.com/2009/10/follow-through/">lessons of follow-through</a>.</p>
	
</p>

<p><a href="http://benscofield.com/failure-is-bad">Permalink</a> 

	| <a href="http://benscofield.com/failure-is-bad#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/21967/marmalade.png</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/KESzKKtucV</posterous:profileUrl>
        <posterous:firstName>Ben</posterous:firstName>
        <posterous:lastName>Scofield</posterous:lastName>
        <posterous:nickName>Ben</posterous:nickName>
        <posterous:displayName>Ben Scofield</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Mon, 23 Nov 2009 11:30:00 -0800</pubDate>
      <title>NoSQL talk report</title>
      <link>http://benscofield.com/nosql-talk-report</link>
      <guid>http://benscofield.com/nosql-talk-report</guid>
      <description>
        <![CDATA[<p>
	<p>I've given my <a href="http://benscofield.com/speaking/#comics-is-hard">"Comics" Is Hard</a> talk about five times now, and the feedback consistently fell into one of two buckets:</p>
<ul>
<li>Some people wanted to see more of the domain modeling part, either because they still weren't convinced that comics, etc., are hard to model relationally, or they enjoyed seeing me get riled up.</li>
<li>Other people wanted to see more of the alternative database part. Generally, these people already knew that some domains were hard to model, or they had other needs that were pushing them towards a NoSQL solution and they wanted more background and examples.</li>
</ul>
<p>Given that feedback, I finally bit the bullet and split the talk into two, each of which will hopefully please one audience. <a href="http://rubyconf.org">RubyConf</a> was the first time I've given either of these, and I'm thinking that <em>NoSQL: Death to Relational Databases(?)</em> was a success.  First, the slides:</p>
<div style="text-align: left;"><a href="http://www.slideshare.net/bscofield/nosql-death-to-relational-databases" title="NoSQL: Death to Relational Databases(?)" style="font: 14px Helvetica,Arial,Sans-serif; display: block; margin: 12px 0 3px 0; text-decoration: underline;">NoSQL: Death to Relational Databases(?)</a>
<object height="355" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425">
<param name="allowFullScreen" value="true" />
<param name="allowScriptAccess" value="always" />
<param name="src" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=200911-rubyconf-091121083739-phpapp02&amp;stripped_title=nosql-death-to-relational-databases" />
<param name="allowfullscreen" value="true" /> <embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=200911-rubyconf-091121083739-phpapp02&amp;stripped_title=nosql-death-to-relational-databases" type="application/x-shockwave-flash" height="355" width="425"></embed>
</object>
<div style="font-size: 11px; font-family: tahoma,arial; height: 26px; padding-top: 2px;">View more <a href="http://www.slideshare.net/" style="text-decoration: underline;">documents</a> from <a href="http://www.slideshare.net/bscofield" style="text-decoration: underline;">Ben Scofield</a>.</div>
</div>
<p>I think the slides from this talk are more capable of standing alone than many of my more recent decks, so I won't go into much detail here. Basically, I spoke about five reasons people are looking at NoSQL solutions now, described four major families (key-value stores, column- and document-oriented databases, and graph databases), showed how those families generally stack up for the aforementioned reasons, and gave a quick example of how to use one or two systems from each family (e.g., Redis, Cassandra, MongoDB, Neo4J), all before wrapping up by describing several scenarios that might demand hybrid solutions.  I tried a couple of different things in this talk. I've looked at integrating the backchannel before (taking questions over Twitter, etc.), but with the conference wifi in a pretty bad state that wasn't possible. I've also been thinking about ways to keep the backchannel going after the talk itself, which Twitter, IRC, and the like can't handle. To that end, I've set up a Google Wave for the talk - if you'd like to join in the discussion, try <a href="http://www.google.com/s2/photos/public/AIbEiAIAAABECIrg5YK09Pny_gEiC3ZjYXJkX3Bob3RvKig3NTgyZGY5ZmZiNTE4MDNkOGYyMjUwMzZkODgwZGI0ZmUzYjg4ZDZjMAEJXYLjFtcJbkQKwUsylX9NmHRGDw">this link</a> (if it doesn't work, you can search on 'with:public NoSQL Death to Relational Databases' and it should pop up).  I also decided to provide a few explicit next steps for the audience. Much too often, speakers leave their goals &ndash; what they want the audience to do as a result of their talk &ndash; implicit, expecting the audience to pick it up by osmosis and be instantly motivated to do it. Unfortunately, that never really happens, so I went ahead and stated my goals outright.  I got some great face-to-face feedback after the talk, and I was very happy with how it went. <a href="http://speakerrate.com/talks/1806-nosql-death-to-relational-databases">SpeakerRate</a> hasn't been as uniformly positive, however, and I'm afraid that the wifi situation prevented a number of people who attended from rating and/or leaving a comment &ndash; at the moment, I've only got nine ratings, when the room was mostly full. All in all, though, I'm encouraged by the talk, and I'm looking forward to giving it again (updated, of course) at <a href="http://codemash.org/">CodeMash</a> in January.</p>

	
</p>

<p><a href="http://benscofield.com/nosql-talk-report">Permalink</a> 

	| <a href="http://benscofield.com/nosql-talk-report#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/21967/marmalade.png</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/KESzKKtucV</posterous:profileUrl>
        <posterous:firstName>Ben</posterous:firstName>
        <posterous:lastName>Scofield</posterous:lastName>
        <posterous:nickName>Ben</posterous:nickName>
        <posterous:displayName>Ben Scofield</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Sat, 14 Nov 2009 15:04:00 -0800</pubDate>
      <title>Twitter lists and the App Store</title>
      <link>http://benscofield.com/twitter-lists-and-the-app-store</link>
      <guid>http://benscofield.com/twitter-lists-and-the-app-store</guid>
      <description>
        <![CDATA[<p>
	<p><span><span style="color: #000000; font-size: small;"><span style="font-size: small;">Twitter's lists are a fascinating new feature, and people are using them in a bewildering variety of ways. I think one of the most unexpected effects they've had, though, has been the exposure of yet another problem with Apple's App Store approval process: it's&nbsp;<strong>just not agile enough</strong>.</span></span></span> <span><span style="color: #000000; font-size: small;"><span style="font-size: small;"><span><span style="color: #000000; font-size: small;"><span style="font-size: small;">Say I was selling a Twitter client on the App Store. In an ideal world (read: the web), the primary bottleneck to delivering a new version of the product is the development time &ndash; Twitter releases lists, I burn the midnight oil a bit to incorporate them into my app, and I'm done.</span></span></span></span></span></span> <span><span style="color: #000000; font-size: small;"><span style="font-size: small;"><span><span style="color: #000000; font-size: small;"><span style="font-size: small;">When you're developing for the iPhone, however, the main bottleneck isn't the development time, but the approval process. Every update to the core functionality of the application has go through the approval queue just like a new application, which means that it can be weeks or months before it gets onto your customers' phones. (Or never, as has been the case with&nbsp;<a href="http://daringfireball.net/linked/2009/11/13/app-store-rogue-amoeba">a recently rejected app update</a>.)</span></span></span></span></span></span> <span><span style="color: #000000; font-size: small;"><span style="font-size: small;"><span><span style="color: #000000; font-size: small;"><span style="font-size: small;">Similarly, entirely new applications face the same problem.&nbsp;<a href="http://www.avc.com/">Fred Wilson</a> just posted a&nbsp;<a href="http://www.avc.com/a_vc/2009/11/twitter-list-iphone-apps.html">Twitter list-powered application idea</a>, but there's no way a native app could be released to the public quickly to take advantage of it.</span></span></span></span></span></span> <span><span style="color: #000000; font-size: small;"><span style="font-size: small;"><span><span style="color: #000000; font-size: small;"><span style="font-size: small;">This has always been something of a problem for desktop development, of course &ndash; particularly before online patch distribution &ndash; but the iPhone has taken it to new heights. Web clients were able to add support for lists as quickly as they could push their developers, but native applications are left to lose their audience until Apple deigns to approve their updates. I'm surprised that the effect isn't greater, actually, since the web-based Twitter clients should be promoting the heck out of mobile-optimized views of their sites with list functionality.&nbsp;<a href="http://scobleizer.com/">Scoble</a>'s favored way of interacting with Twitter is a&nbsp;<a href="http://seesmic.com/app/">web-based client</a>,&nbsp;<a href="http://scobleizer.com/2009/11/13/twitter-lists-lifechangin/">in part because of its list support</a> (see the last paragraph).</span></span></span></span></span></span> <span><span style="color: #000000; font-size: small;"><span style="font-size: small;"><span><span style="color: #000000; font-size: small;"><span style="font-size: small;">This is just one more problem with the App Store approval process, but it has the potential to be one of the most serious. As more and more mobile applications rely on web services for their functionality, the mismatch in time-to-market between the moderated App Store market and the quick-as-you-can web ecosystem will cause more (and more serious) problems.</span></span></span></span></span></span></p>
	
</p>

<p><a href="http://benscofield.com/twitter-lists-and-the-app-store">Permalink</a> 

	| <a href="http://benscofield.com/twitter-lists-and-the-app-store#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/21967/marmalade.png</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/KESzKKtucV</posterous:profileUrl>
        <posterous:firstName>Ben</posterous:firstName>
        <posterous:lastName>Scofield</posterous:lastName>
        <posterous:nickName>Ben</posterous:nickName>
        <posterous:displayName>Ben Scofield</posterous:displayName>
      </posterous:author>
    </item>
  </channel>
</rss>

