<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>One-Banana Problem - Home</title>
  <id>tag:www.onebananaproblem.com,2010:mephisto/</id>
  <generator version="0.7.3" uri="http://mephistoblog.com">Mephisto Noh-Varr</generator>
  <link href="http://www.onebananaproblem.com/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://www.onebananaproblem.com/" rel="alternate" type="text/html"/>
  <updated>2010-09-04T17:42:26Z</updated>
  <entry xml:base="http://www.onebananaproblem.com/">
    <author>
      <name>code_monkey_steve</name>
    </author>
    <id>tag:www.onebananaproblem.com,2010-09-04:70</id>
    <published>2010-09-04T17:27:00Z</published>
    <updated>2010-09-04T17:42:26Z</updated>
    <link href="http://www.onebananaproblem.com/2010/9/4/autotest-and-ruby-1-9-2" rel="alternate" type="text/html"/>
    <title>Autotest and Ruby 1.9.2</title>
<content type="html">
            There&#8217;s a &lt;a href=&quot;http://rubyforge.org/tracker/index.php?func=detail&#38;aid=28113&#38;group_id=419&#38;atid=1678&quot;&gt;bug in autotest&lt;/a&gt; that prevents it from properly finding a project&#8217;s autotest discover file under Ruby 1.9.2.  Until an appropriate fix is made, you can work around it on the command line like so:
&lt;pre&gt;
  $ RUBYLIB='.' bundle exec autotest
&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://www.onebananaproblem.com/">
    <author>
      <name>code_monkey_steve</name>
    </author>
    <id>tag:www.onebananaproblem.com,2010-05-07:68</id>
    <published>2010-05-07T23:10:00Z</published>
    <updated>2010-05-07T23:13:52Z</updated>
    <link href="http://www.onebananaproblem.com/2010/5/7/ruby-gets-possessive" rel="alternate" type="text/html"/>
    <title>Ruby Gets Possessive</title>
<content type="html">
            &lt;p&gt;I debated whether this code snippet was significant enough to bother blogging about, but it is useful if for no other reason that as an example of one of the great features of Ruby: the ability to reopen any class, even a standard class, and add methods.&lt;/p&gt;


	&lt;p&gt;In this case, we needed a method to apply the English rules for the possessive apostrophy to a string, e.g. a person&#8217;s name.  I looked-up the rules on &lt;a href=&quot;http://en.wikipedia.org/wiki/Apostrophe#Singular_nouns_ending_with_an_.E2.80.9Cs.E2.80.9D_or_.E2.80.9Cz.E2.80.9D_sound&quot;&gt;Wikipedia&lt;/a&gt; and coded up the following three-liner:&lt;/p&gt;


&amp;lt;script src=&quot;http://gist.github.com/394055.js&quot;&gt;&amp;lt;/script&gt;

	&lt;p&gt;Now in my site I can do things like:&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
  &quot;Steve&quot;.possessive + &quot; Profile&quot;  ==  &quot;Steve's Profile&quot; 
  &quot;Alex&quot;.possessive + &quot; Profile&quot;  ==  &quot;Alex' Profile&quot; 
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;(Cross-posted to the &lt;a href=&quot;http://conceivian.com/insights&quot;&gt;Conceivian Blog&lt;/a&gt;)&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.onebananaproblem.com/">
    <author>
      <name>code_monkey_steve</name>
    </author>
    <id>tag:www.onebananaproblem.com,2010-02-27:66</id>
    <published>2010-02-27T00:45:00Z</published>
    <updated>2010-02-27T06:02:45Z</updated>
    <link href="http://www.onebananaproblem.com/2010/2/27/swing-from-tree-to-tree" rel="alternate" type="text/html"/>
    <title>Swinging from Tree to Tree</title>
<content type="html">
            &lt;p&gt;Last time I updated this blog it was the night before starting a new job, and on the eve of starting yet-another new job, I thought it would be a good time to recap.&lt;/p&gt;


	&lt;h3&gt;The Old&lt;/h3&gt;


	&lt;p&gt;At the beginning of the year I started work at &lt;a href=&quot;http://sponsaurus.com/&quot;&gt;Sponsaurus&lt;/a&gt;, a little sports-sponsorship management start-up working out of the &lt;a href=&quot;http://startpad.org/&quot;&gt;StartPad&lt;/a&gt; offices.  The idea was good, the people were great, and building a site from scratch using the latest-and-greatest toys was addictively fun.  Things that were &#8220;20 pounds of awesome in a 10 pound bag&#8221;&amp;nbsp;:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;CEO&lt;/span&gt; &lt;a href=&quot;http://www.linkedin.com/in/bhenry&quot;&gt;Bruce P. Henry&lt;/a&gt;, and co-developer and fellow Kashless alum &lt;a href=&quot;http://www.linkedin.com/in/johnpostlethwait&quot;&gt;John Postlethwait&lt;/a&gt;.  Working with them was always great fun, and I would happily do so again anytime.&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://www.mongodb.org/&quot;&gt;MongoDB&lt;/a&gt;, as provided by &lt;a href=&quot;http://mongohq.com&quot;&gt;MongoHQ&lt;/a&gt;, and the &lt;a href=&quot;http://railstips.org/blog/archives/2009/06/27/mongomapper-the-rad-mongo-wrapper&quot;&gt;MongoMapper&lt;/a&gt; ODM.  I&#8217;ve raved about Mongo before, but it was the first time I&#8217;d used it in production.  &lt;/li&gt;
		&lt;li&gt;The &lt;a href=&quot;http://wiki.github.com/hassox/warden/&quot;&gt;Warden&lt;/a&gt; and &lt;a href=&quot;http://github.com/plataformatec/devise&quot;&gt;Devise&lt;/a&gt; authentication framework.  It was especially useful in that it works well with Mongo, and allows user accounts to be scoped, when serving multiple virtual sites.&lt;/li&gt;
		&lt;li&gt;The &lt;a href=&quot;http://heroku.com/&quot;&gt;Heroku&lt;/a&gt; Ruby cloud-hosting service.  MongoMapper&#8217;s  
John Nunemaker puts it best in &lt;a href=&quot;http://railstips.org/blog/archives/2009/11/08/youre-an-idiot-for-not-using-heroku/&quot;&gt;You&#8217;re an Idiot for Not Using Heroku&lt;/a&gt;.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;To my great disappointment, Sponsaurus&#8217; first round of funding fell-through, and they were forced to suspend development after just three weeks.  So it was back to job hunting, but with the added wrinkle of having fallen madly in love with the start-up lifestyle.  I was dreading having to take just any old code monkey job to pay the bills.&lt;/p&gt;


	&lt;h3&gt;The New&lt;/h3&gt;


	&lt;p&gt;It&#8217;s not at all lost on me that almost all of my coding gigs have come as recommendations from friends-of-friends.  In the latest case, Bruce introduced me to &lt;a href=&quot;http://www.conceivian.com/&quot;&gt;Conceivian&lt;/a&gt;, a custom Rails shop in Redmond, and I&#8217;m now their Lead Developer.  They specialize in building prototype websites for other start-up companies, which means an endless supply of green-fields coding projects to feed my start-up addiction.  It&#8217;s also a small team, which means little-to-no politics (yuk).  So here goes &#8230;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.onebananaproblem.com/">
    <author>
      <name>code_monkey_steve</name>
    </author>
    <id>tag:www.onebananaproblem.com,2010-01-01:65</id>
    <published>2010-01-01T01:51:00Z</published>
    <updated>2010-01-01T01:52:08Z</updated>
    <link href="http://www.onebananaproblem.com/2010/1/1/json-and-the-args-or-not" rel="alternate" type="text/html"/>
    <title>JSON and the Args (or Not)</title>
<content type="html">
            &lt;p&gt;(Admittedly not my best work, but it&#8217;s hard coming up with &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; puns)&lt;/p&gt;


	&lt;p&gt;Playing with &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; Document Stores has led me down the path to a few other exciting &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; toys.  The first is &#8230;&lt;/p&gt;


	&lt;h1&gt;&lt;a href=&quot;http://json-schema.org&quot;&gt;&lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; Schema&lt;/a&gt;&lt;/h1&gt;


	&lt;p&gt;Just like &lt;a href=&quot;http://www.w3.org/XML/Schema&quot;&gt;&lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; Schema&lt;/a&gt;, &lt;a href=&quot;http://json-schema.org&quot;&gt;&lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; Schema&lt;/a&gt; allows you to specify (in &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; form) the semantics of a particular &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; data structure.  While in theory the schema is useful for validation, in practice validation just sucks up too much &lt;span class=&quot;caps&quot;&gt;CPU&lt;/span&gt; time to be worth the trouble.  Where things get really interesting is the possibility of automatically generating user interfaces that compose &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt;-based messages behind the scenes.  There&#8217;s just one thing missing &#8230;&lt;/p&gt;


	&lt;h1&gt;&lt;a href=&quot;http://groups.google.com/group/json-schema/web/service-mapping-description-proposal&quot; title=&quot;SMD&quot;&gt;Service Mapping Description&lt;/a&gt;&lt;/h1&gt;


	&lt;p&gt;Ta-da! &lt;a href=&quot;http://groups.google.com/group/json-schema/web/service-mapping-description-proposal&quot;&gt;&lt;span class=&quot;caps&quot;&gt;SMD&lt;/span&gt;&lt;/a&gt; allows you to describe all of the methods of a web service using  &lt;a href=&quot;http://json-schema.org/&quot;&gt;&lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; Schema&lt;/a&gt; to describe each method&#8217;s parameters. It supports a variety of transports and envelopes from simple GETs or POSTs up through RESTful resources and &lt;a href=&quot;http://en.wikipedia.org/wiki/JSON-RPC&quot;&gt;&lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt;-RPC&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;The beauty of all of this is that it allows for services (web and otherwise) to advertise its functionality in user- and computer-readable ways.  It has the potential to be a generic communication mechanism between disparate bits of software (potentially controlling hardware), allowing us to virtually wire-up appliance X to service Y through user interface Z, without any of them having prior knowledge of each other.  Pretty sweet.&lt;/p&gt;


	&lt;h1&gt;You Are &lt;code&gt;'Here':{}&lt;/code&gt; ...&lt;/h1&gt;


	&lt;p&gt;One last bit of &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; goodness: &lt;a href=&quot;http://en.wikipedia.org/wiki/GeoJSON&quot;&gt;GeoJSON&lt;/a&gt;.  As you might expect, it&#8217;s a standard for representing geographic information in &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt;.  It&#8217;s already the de facto standard, and supported by just about everybody.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.onebananaproblem.com/">
    <author>
      <name>code_monkey_steve</name>
    </author>
    <id>tag:www.onebananaproblem.com,2009-11-23:63</id>
    <published>2009-11-23T20:13:00Z</published>
    <updated>2009-11-23T20:14:37Z</updated>
    <link href="http://www.onebananaproblem.com/2009/11/23/long-time-no-blog" rel="alternate" type="text/html"/>
    <title>Long Time, No Blog</title>
<content type="html">
            &lt;p&gt;It seems to work out that when I&#8217;m most busy coding, I have the least time to blog (and vice-versa).  That&#8217;s my official excuse for it being two months since my last update: work has been busy.&lt;/p&gt;


	&lt;p&gt;First, at the beginning of October, me and the Kashless Krew  went to &lt;a href=&quot;http://www.alohaonrails.com/&quot;&gt;AlohaOnRails&lt;/a&gt;, my first Ruby/Rails conference in sunny (read: &#8220;sweltering&#8221;) O&#8217;ahu, Hawai&#8217;i:&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;http://www.onebananaproblem.com/assets/2009/11/23/8824_814865316318_10700776_46239972_2328810_n.jpg&quot; height=&quot;227&quot; width=&quot;302&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;The conference was a lot of fun: got to hear about some neat Rails tech and meet some of the &lt;a href=&quot;http://onestepback.org/&quot;&gt;rock stars&lt;/a&gt; in the Ruby world.&lt;/p&gt;


	&lt;p&gt;I&#8217;ve also been continuing my exploration of &lt;a href=&quot;http://en.wikipedia.org/wiki/NoSQL&quot;&gt;No-SQL&lt;/a&gt; databases.  While I still love the design of &lt;a href=&quot;http://couchdb.apache.org/&quot;&gt;CouchDB&lt;/a&gt;, I&#8217;ve been playing with &lt;a href=&quot;http://www.mongodb.org/&quot;&gt;MongoDB&lt;/a&gt; and &lt;a href=&quot;http://railstips.org/2009/6/27/mongomapper-the-rad-mongo-wrapper&quot;&gt;MongoMapper&lt;/a&gt;.  Mongo is a bit more mature, even if it does still have a whiff of the &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt; smell about it.  I&#8217;ll have more Useful Information about that later.&lt;/p&gt;


	&lt;p&gt;The other thing I&#8217;ve been learning is the &lt;a href=&quot;http://rspec.info/&quot;&gt;RSpec&lt;/a&gt; testing framework.  When I first looked into it a few years back, I found the RSpec syntax unwieldy compared with Test::Unit.  But after having to do various hacky things to make Shoulda run decently (e.g. &lt;a href=&quot;http://github.com/lifo/fast_context&quot;&gt;fast_context&lt;/a&gt;) and even contemplating writing my own framework (the now defunct &lt;a href=&quot;http://github.com/CodeMonkeySteve/mustard&quot;&gt;Mustard&lt;/a&gt;), I&#8217;ve come to appreciate the RSpec Way and can&#8217;t see myself ever going back.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.onebananaproblem.com/">
    <author>
      <name>code_monkey_steve</name>
    </author>
    <id>tag:www.onebananaproblem.com,2009-09-21:62</id>
    <published>2009-09-21T17:50:00Z</published>
    <updated>2009-09-23T23:18:59Z</updated>
    <link href="http://www.onebananaproblem.com/2009/9/21/safe-mailing-with-safe_mail" rel="alternate" type="text/html"/>
    <title>Safe Mailing with mail_safe</title>
<content type="html">
            &lt;p&gt;Working on a production website can be a bit nerve-wracking, especially when it comes to testing features that send email as a side effect: one little bug could wind up spamming all of your precious users.  Of course, Rails has the basic safety feature of simply disabling mail delivery in certain environments (i.e. test and development), but that&#8217;s no good because sometimes you do want to test that mail is actually delivered, just without having to worry that it&#8217;s delivered to live users.&lt;/p&gt;


	&lt;p&gt;Enter &lt;a href=&quot;http://github.com/myronmarston/mail_safe&quot;&gt;mail_safe&lt;/a&gt;, a handy little gem written by my co-worker Myron.  Instead of disabling mail delivery environment-wide, mail_safe allows you to define one or more domains for which mail should be delivered, and a catch-all address for those that shouldn&#8217;t.  This allows for testing with a real account (if it&#8217;s in the appropriate domain), while still keeping you secure against unintentional spam.&lt;/p&gt;


	&lt;p&gt;Once you&#8217;ve started using it, you&#8217;ll wonder how you ever slept soundly without it.  It&#8217;s the sort of thing that should probably be included in the Rails core (IMNSHO).&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.onebananaproblem.com/">
    <author>
      <name>code_monkey_steve</name>
    </author>
    <id>tag:www.onebananaproblem.com,2009-09-17:61</id>
    <published>2009-09-17T19:53:00Z</published>
    <updated>2009-09-17T19:54:07Z</updated>
    <link href="http://www.onebananaproblem.com/2009/9/17/string-conversions-in-ruby" rel="alternate" type="text/html"/>
    <title>String Conversions in Ruby</title>
<content type="html">
            Here&#8217;s a tip so simple and elegant it&#8217;s amazing I ever got along without it.  Consider &lt;code&gt;String#to_f&lt;/code&gt;:
&lt;pre&gt;&lt;code&gt;  --&amp;gt; '12.34'.to_f
  ==&amp;gt; 12.34
&lt;/code&gt;&lt;/pre&gt;

Which works great, so long as the string is a valid number, but if not:
&lt;pre&gt;&lt;code&gt;  --&amp;gt; 'splat'.to_f
  ==&amp;gt; 0.0
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&lt;code&gt;#to_f&lt;/code&gt; doesn&#8217;t throw an exception with invalid input, making it dangerous to use with any user-supplied data.  I&#8217;ve seen various solutions that involve regular expressions, but these are kludgy and don&#8217;t handle all proper numeric representations.&lt;/p&gt;


Fortunately, Ruby provides type-cast-style methods to do proper conversions with validation:
&lt;pre&gt;&lt;code&gt;  --&amp;gt; Float('12.34')
  ==&amp;gt; 12.34
  --&amp;gt; Float('splat')
  ArgumentError: invalid value for Float(): &quot;splat&quot; 
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;It might look weird, until you realize that &lt;code&gt;Float&lt;/code&gt; is both a class (&lt;code&gt;::Float&lt;/code&gt;) and a kernel method (&lt;code&gt;Kernel.Float&lt;/code&gt;).  There are also methods for converting to an &lt;code&gt;Integer&lt;/code&gt;, &lt;code&gt;Array&lt;/code&gt;, or even back to a &lt;code&gt;String&lt;/code&gt; (which is essentially just &lt;code&gt;#to_s&lt;/code&gt;).&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.onebananaproblem.com/">
    <author>
      <name>code_monkey_steve</name>
    </author>
    <id>tag:www.onebananaproblem.com,2009-07-27:53</id>
    <published>2009-07-27T00:31:00Z</published>
    <updated>2009-07-27T00:34:02Z</updated>
    <link href="http://www.onebananaproblem.com/2009/7/27/i-hate-shoulda-but-i-blame-test-unit" rel="alternate" type="text/html"/>
    <title>I Hate Shoulda (But I Blame Test::Unit)</title>
<content type="html">
            &lt;p&gt;I hate Shoulda.&lt;/p&gt;


	&lt;p&gt;But I blame Test::Unit.&lt;/p&gt;


	&lt;p&gt;Because Test::Unit can&#8217;t scale.&lt;/p&gt;


	&lt;p&gt;There, I&#8217;ve said it. It wasn&#8217;t easy, I drank the &lt;a href=&quot;http://en.wikipedia.org/wiki/Test-driven_development&quot;&gt;&lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt;&lt;/a&gt; Cool-Aid a long time ago, and never looked back.  But the fact of the matter is that &lt;a href=&quot;http://ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html&quot;&gt;Test::Unit&lt;/a&gt; is rotten from the very core, and it makes the seductive &lt;a href=&quot;http://thoughtbot.com/projects/shoulda&quot;&gt;Shoulda&lt;/a&gt; features nothing but bitter lies.  Let me demonstrate:&lt;/p&gt;


	&lt;h2&gt;Hopeful Optimism&lt;/h2&gt;


Take a sufficiently-contrived test, where you create some object and verify some of its properties:
&lt;pre&gt;&lt;code&gt;require 'test/unit'
require 'shoulda'

class Numeric
  def even? ; (self % 2).zero?    ; end
  def odd?  ; (self % 2).nonzero? ; end
end

class OddNumberTest &amp;lt; Test::Unit::TestCase
  context 'an odd number'  do
    setup do
      # create object
      @n = 97 ; sleep 1
    end

    should('be true')     {  assert  @n        }
    should('be odd')      {  assert  @n.odd?   }
    should('not be even') {  assert !@n.even?  }
  end
end
&lt;/code&gt;&lt;/pre&gt;

Now, someone naive in the ways of Test::Unit, might expect this test to take approximately &lt;em&gt;one second&lt;/em&gt; to execute, right?  After all, it&#8217;s only the object creation that takes any time (in these examples, the &lt;code&gt;sleep 1&lt;/code&gt; represents some non-trivial database or network operation).  So we run it, and &#8230;
&lt;pre&gt;&lt;code&gt;$ ruby -rubygems ./why_shoulda_sucks.rb
Loaded suite why_shoulda_sucks
Started
...
Finished in 3.006617 seconds.
3 tests, 3 assertions, 0 failures, 0 errors
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&#8220;&lt;strong&gt;Three seconds&lt;/strong&gt;?  Why did it take so long?!&#8221;, our poor naive tester cries.  Because, expecting Shoulda to act like a Domain-Specific Language (as all Right-Thinking Rubyists would), he doesn&#8217;t realize that under the covers it&#8217;s just creating three different Test::Unit tests.  So what&#8217;s so bad about Test::Unit?&lt;/p&gt;


	&lt;h2&gt;A Sense of Dread&lt;/h2&gt;


What&#8217;s so bad about Test::Unit is that it makes the following assumptions:
	&lt;ul&gt;
	&lt;li&gt;Each test may be run in any order, not the order define (in fact, it&#8217;s in sorted order by test name)&lt;/li&gt;
		&lt;li&gt;Each test may modify the state at any time, not just in the &lt;code&gt;setup&lt;/code&gt; function&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Therefore, the &lt;code&gt;setup&lt;/code&gt; (and &lt;code&gt;teardown&lt;/code&gt;) functions must be called &lt;strong&gt;for every test&lt;/strong&gt;, whether they really need it or not.&lt;/p&gt;


So instead of:
&lt;pre&gt;  setup
  should be true
  should be odd
  should not be even
  (teardown)&lt;/pre&gt;

We get:
&lt;pre&gt;  setup
  should be true
  (teardown)
  (setup)
  should be odd
  (teardown)
  (setup)
  should not be even
  (teardown)
  (setup)
&lt;/pre&gt;

	&lt;p&gt;That&#8217;s a lot of extraneous setting-up and tearing-down, and since those are the parts that actually do stuff (as opposed to the assertions themselves), that&#8217;s the slowest part of the test.&lt;/p&gt;


	&lt;h2&gt;Crushing Disappointment&lt;/h2&gt;


The greatest features in Shoulda (as opposed to, say, &lt;a href=&quot;http://rspec.info/&quot;&gt;RSpec&lt;/a&gt;) is the ability to use &lt;em&gt;nested contexts&lt;/em&gt;.  This lets us do sub-tests that inherit their parent context&#8217;s state, but roll-back their own changes.  So let&#8217;s add one:
&lt;pre&gt;&lt;code&gt;class OddNumberTest &amp;lt; Test::Unit::TestCase
  context 'an odd number'  do
    setup do
      # create object
      @n = 97 ; sleep 1
    end
    should('be true')     {  assert  @n        }
    should('be odd')      {  assert  @n.odd?   }
    should('not be even') {  assert !@n.even?  }

    context 'add one' do
      setup do
        # modify object
        @n += 1 ; sleep 1
      end
      should('be true')    {  assert  @n        }
      should('be even')    {  assert  @n.even?  }
      should('not be odd') {  assert !@n.odd?   }
    end

    should('still be odd')  {  assert @n.odd?  }
  end
&lt;/code&gt;&lt;/pre&gt;

Again, on first glance you might expect this test to take &lt;em&gt;two seconds&lt;/em&gt;, but actually:
&lt;pre&gt;&lt;code&gt;$ ruby -rubygems ./why_shoulda_sucks.rb
Loaded suite why_shoulda_sucks
Started
.......
Finished in 10.014666 seconds.
7 tests, 7 assertions, 0 failures, 0 errors
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&lt;strong&gt;Ten seconds&lt;/strong&gt;, over &lt;strong&gt;five times&lt;/strong&gt; what it really should be if Test::Unit was just smart enough execute the tests in the order given, and perform the &lt;code&gt;setup&lt;/code&gt; and &lt;code&gt;teardown&lt;/code&gt; appropriately.&lt;/p&gt;


	&lt;h2&gt;The Test::Unit &lt;a href=&quot;http://en.wikipedia.org/wiki/Fail_whale&quot;&gt;Fail Whale&lt;/a&gt;&lt;/h2&gt;


And that&#8217;s just with one level of nesting.  If we try an even slight-complicated test, with several contexts nested even only a few deep:
&lt;pre&gt;&lt;code&gt;class OddNumberTest &amp;lt; Test::Unit::TestCase
  context 'an odd number'  do
    setup do
      # create object
      @n = 97 ; sleep 1
    end
    should('be true')     {  assert  @n        }
    should('be odd')      {  assert  @n.odd?   }
    should('not be even') {  assert !@n.even?  }

    context 'add one' do
      setup do
        # modify object
        @n += 1 ; sleep 1
      end
      should('be true')    {  assert  @n        }
      should('be even')    {  assert  @n.even?   }
      should('not be odd') {  assert !@n.odd?  }

      context 'subtract one' do
        setup do
          # modify object
          @n -= 1 ; sleep 1
        end
        should('be true')     {  assert  @n        }
        should('be odd')      {  assert  @n.odd?   }
        should('not be even') {  assert !@n.even?  }
      end
    end

    should('still be odd')  {  assert @n.odd?  }

    context 'multiply by two' do
      setup do
        # modify object
        @n *= 2 ; sleep 1
      end
      should 'be true'    do  assert  @n        end
      should 'be even'    do  assert  @n.even?  end
      should 'not be odd' do  assert !@n.odd?   end
    end

    should('even still be odd')  {  assert @n.odd?  }
  end
end
&lt;/code&gt;&lt;/pre&gt;

Can you say &#8220;exponential growth&#8221;?
&lt;pre&gt;&lt;code&gt;$ ruby -rubygems ./why_shoulda_sucks.rb
Loaded suite why_shoulda_sucks
Started
.......
Finished in 26.048316 seconds.
14 tests, 14 assertions, 0 failures, 0 errors
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&lt;strong&gt;26 seconds&lt;/strong&gt;, that&#8217;s &lt;strong&gt;six times&lt;/strong&gt; longer than it should take.&lt;/p&gt;


	&lt;h2&gt;You Think That&#8217;s Bad?&lt;/h2&gt;


Now that I&#8217;m working at a Real Ruby Shop, I&#8217;ve gotten to experience the joy of having thousands of tests to make sure I haven&#8217;t done something stupid.  But I also get to experience the pain of running all these tests under this profoundly inefficient framework:
&lt;pre&gt;&lt;code&gt;$ rake test:units test:functionals test:integration
Finished in 1042.379506 seconds.
2141 tests, 4576 assertions, 0 failures, 0 errors

Finished in 578.284529 seconds.
613 tests, 896 assertions, 0 failures, 0 errors

Finished in 34.538012 seconds.
22 tests, 65 assertions, 0 failures, 0 errors
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Almost &lt;strong&gt;half an hour&lt;/strong&gt; on a decent system, &lt;strong&gt;over 50 minutes&lt;/strong&gt; on our Continuous Integration server.  That&#8217;s an awful lot of waiting.&lt;/p&gt;


	&lt;h2&gt;Screw You Guys, I&#8217;m Going Home&lt;/h2&gt;


&lt;a href=&quot;http://rubyrags.com/products/10&quot;&gt;Fork You&lt;/a&gt; then, I&#8217;ll make my own testing framework that keeps track of dependencies and instantiates them in the most efficient way (&lt;a href=&quot;http://www.mahalo.com/bender-quotes&quot;&gt;and blackjack, and hookers!&lt;/a&gt;) .  And while I&#8217;m at it:
	&lt;ul&gt;
	&lt;li&gt;&#8220;Should&#8221; is &lt;a href=&quot;http://www.faqs.org/rfcs/rfc2119.html&quot;&gt;not the correct word&lt;/a&gt; .  &#8220;Must&#8221; is the correct word (plus, less typing).&lt;/li&gt;
		&lt;li&gt;If a test fails, it should not run any other tests in that context.  They&#8217;ll almost certainly also fail and unhelpfully spam you with error messages.&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://www.faqs.org/rfcs/rfc2119.html&quot;&gt;Autotest&lt;/a&gt; should be baked right in, so that if a subset of the tests fail, I should be able to re-run just the failing tests, which will in turn only instantiate the necessary prerequisites, and in the most efficient order.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;So far I have a proof-of-concept project on GitHub called &lt;a href=&quot;http://github.com/CodeMonkeySteve/mustard&quot;&gt;Mustard&lt;/a&gt; .  I&#8217;m going to start migrating my other projects to it from Shoulda and will write more on the subject later.  Watch this space &#8230;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.onebananaproblem.com/">
    <author>
      <name>code_monkey_steve</name>
    </author>
    <id>tag:www.onebananaproblem.com,2009-06-16:52</id>
    <published>2009-06-16T05:26:00Z</published>
    <updated>2009-06-16T05:28:31Z</updated>
    <link href="http://www.onebananaproblem.com/2009/6/16/all-your-data-base" rel="alternate" type="text/html"/>
    <title>All Your (Data)Base ...</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/greenem/11696663/&quot;&gt;&lt;img src=&quot;http://www.onebananaproblem.com/assets/2009/6/16/network-graph.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;After failing to make &lt;a href=&quot;http://couchdb.apache.org/&quot;&gt;CouchDB&lt;/a&gt; doing anything useful, and being completely unwilling to go back to &lt;a href=&quot;http://en.wikipedia.org/wiki/Sql&quot;&gt;1974&lt;/a&gt; I decided to go back and revisit my assumptions.  Both of my current home projects are essentially attempts to treat real-world interactions as &lt;a href=&quot;http://en.wikipedia.org/wiki/Routing&quot;&gt;Routing Problems&lt;/a&gt;, but after doing some research, I decided that was one wheel I didn&#8217;t even want to attempt to reinvent (graph theory is not my specialty).&lt;/p&gt;


	&lt;p&gt;Somewhere along the way, I discovered what I really needed was a &lt;em&gt;Graph Database&lt;/em&gt;.  That led me to apparently the only significant implementation: &lt;a href=&quot;http://neo4j.org/&quot;&gt;Neo4j&lt;/a&gt;, an embedded Java graph database. But I&#8217;d rather juggle flaming porcupines than touch Java again &#8230; and thanks to &lt;a href=&quot;http://en.wikipedia.org/wiki/Jruby&quot;&gt;JRuby&lt;/a&gt; and the &lt;a href=&quot;http://github.com/andreasronge/neo4j&quot;&gt;neo4j gem&lt;/a&gt;, I don&#8217;t have to!  Yay!&lt;/p&gt;


	&lt;p&gt;So if your problem domain is graph-like, you should definitely checkout &lt;a href=&quot;http://github.com/andreasronge/neo4j&quot;&gt;neo4j&lt;/a&gt;, it&#8217;s looking like a seriously sweet storage solution.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.onebananaproblem.com/">
    <author>
      <name>code_monkey_steve</name>
    </author>
    <id>tag:www.onebananaproblem.com,2009-05-26:50</id>
    <published>2009-05-26T18:12:00Z</published>
    <updated>2009-05-26T18:17:51Z</updated>
    <link href="http://www.onebananaproblem.com/2009/5/26/couch-trouble" rel="alternate" type="text/html"/>
    <title>Couch Trouble</title>
<content type="html">
            &lt;p&gt;I&#8217;ve been wrangling with CouchDB for a few weeks now, and it&#8217;s starting to feel a bit like this:&lt;/p&gt;


&amp;lt;object height=&quot;344&quot; width=&quot;425&quot;&gt;&amp;lt;param name=&quot;movie&quot; value=&quot;http://www.youtube.com/v/vSTJL1ikxXY&#38;hl=en&#38;fs=1&quot;&gt;&amp;lt;/param&gt;&amp;lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;&gt;&amp;lt;/param&gt;&amp;lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot;&gt;&amp;lt;/param&gt;&amp;lt;embed allowfullscreen=&quot;true&quot; type=&quot;application/x-shockwave-flash&quot; src=&quot;http://www.youtube.com/v/vSTJL1ikxXY&#38;hl=en&#38;fs=1&quot; allowscriptaccess=&quot;always&quot; height=&quot;344&quot; width=&quot;425&quot;&gt;&amp;lt;/embed&gt;&amp;lt;/object&gt;

	&lt;p&gt;(Ooh, my first embedded video.  Feel the Web 2.0 Awesome-ness-age-ality).&lt;/p&gt;


First, let me say that I can&#8217;t really blame CouchDB for any of my troubles, which are essentially:
	&lt;ul&gt;
	&lt;li&gt;There are a excess of Ruby/Rails gems for accessing CouchDB, all of whom have different dependencies and do things in slightly different ways.  I&#8217;m sure that eventually a consensus will emerge on the best Ruby/CouchDB way of doing things, but it hasn&#8217;t happened yet.&lt;/li&gt;
		&lt;li&gt;CouchDB is not yet 1.0, so the design can support &lt;a href=&quot;http://couchdb.apache.org/docs/overview.html&quot;&gt;lots of spiffy features&lt;/a&gt; that &lt;em&gt;don&#8217;t actually exist yet&lt;/em&gt;.  Specifically, the lack of partial replication stalled my attempts at using Couch for a distributed media server project.&lt;/li&gt;
		&lt;li&gt;CouchDB doesn&#8217;t work perfectly for absolutely everything (whoda thunkit?).  My other big project (more on that later) isn&#8217;t really Document-Oriented, no matter how much I try to beat it flat.  I&#8217;m now thinking Git is actually be best storage solution, and if you understand Gits internals well enough, you&#8217;ll see how mind-warping that concept is.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;So I think I&#8217;ll put CouchDB down for a while, at least until 1.0, or until I run across a project where it&#8217;s appropriate.  Of course, it&#8217;s still a gazillion times better than any &lt;span class=&quot;caps&quot;&gt;RDBMS&lt;/span&gt; &#8230;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.onebananaproblem.com/">
    <author>
      <name>code_monkey_steve</name>
    </author>
    <id>tag:www.onebananaproblem.com,2009-05-13:48</id>
    <published>2009-05-13T20:52:00Z</published>
    <updated>2009-05-13T21:09:15Z</updated>
    <link href="http://www.onebananaproblem.com/2009/5/13/couchdb-testing-tip" rel="alternate" type="text/html"/>
    <title>CouchDB Testing Tip</title>
<content type="html">
            &lt;p&gt;Finished my first stab at converting my current toy project from AR to CouchDB, and so far so good.  I ran into an issue where associations aren&#8217;t getting saved, but I&#8217;m most likely just doing something stupid.&lt;/p&gt;


One minor annoyance is that, unlike ActiveRecord, the test database doesn&#8217;t get purged and after a while can get cluttered with randomly-generated fixtures&lt;sup&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.  No problem, just drop in this little Rake task to recreate the DB on each run:
&lt;pre&gt;&lt;code&gt;
# lib/tasks/couchdb.rake
require File.expand_path( RAILS_ROOT + '/config/environment' )
require 'couch_potato'

task 'couchdb:test:purge'  do
  CouchPotato::Config.database_name = 
    YAML::load(File.read(Rails.root.to_s + '/config/couchdb.yml'))['test']
  CouchPotato.couchrest_database.recreate!
end
task 'db:test:purge' =&amp;gt; 'couchdb:test:purge'
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&lt;sup&gt;1&lt;/sup&gt; BTW, have I mentioned how cool &lt;a href=&quot;http://github.com/thoughtbot/factory_girl&quot;&gt;factory_girl&lt;/a&gt; is?  Another new tool for my bag of tricks.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.onebananaproblem.com/">
    <author>
      <name>code_monkey_steve</name>
    </author>
    <id>tag:www.onebananaproblem.com,2009-05-12:47</id>
    <published>2009-05-12T18:49:00Z</published>
    <updated>2009-05-13T23:36:22Z</updated>
    <link href="http://www.onebananaproblem.com/2009/5/12/couchdb-frankie-says-relax" rel="alternate" type="text/html"/>
    <title>CouchDB: Frankie Says Relax</title>
<content type="html">
            &lt;p&gt;I&#8217;m falling in love (or at least lust) with &lt;a href=&quot;http://couchdb.apache.org/&quot;&gt;CouchDB&lt;/a&gt;, especially after seeing this &lt;a href=&quot;http://aac2009.confreaks.com/07-feb-2009-16-00-relaxing-with-couchdb-will-leinweber.html&quot;&gt;presentation at &lt;span class=&quot;caps&quot;&gt;AAC&lt;/span&gt;&lt;/a&gt; and this &lt;a href=&quot;http://barkingiguana.com/2008/08/30/jan-lehnardt-talks-to-the-bbc-about-couchdb&quot;&gt;presentation for the &lt;span class=&quot;caps&quot;&gt;BBC&lt;/span&gt;&lt;/a&gt;.  My summary: &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; document storage, sliced-and-diced with Javascript &lt;a href=&quot;http://en.wikipedia.org/wiki/Map_reduce&quot;&gt;MapReduce&lt;/a&gt;, all served on a RESTful platter.&lt;/p&gt;


	&lt;p&gt;As a long-time &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; fanboy, the lack of schema in &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; makes me a bit twitchy, and using Javascript as a query language just looks a lttle wrong.  But I see the advantages to the document-centric model (versioning, replication, access control) and MapReduce is definitely the Wave of the &lt;del&gt;Future&lt;/del&gt; Present.  It looks like you can encapsulate all of your model logic in views, so I&#8217;m not sure if an explicit schema is really even necessary.  The more I learn about &lt;a href=&quot;http://upstream-berlin.com/2009/03/31/the-case-of-activerecord-vs-couchdb/&quot;&gt;That Way of doing things&lt;/a&gt;, the more it grows on me.&lt;/p&gt;


	&lt;p&gt;So how do we make CouchDB play nicely with Rails?  I first tried &lt;a href=&quot;http://github.com/arunthampi/activecouch&quot;&gt;activecouch&lt;/a&gt;, but found its lack of Ruby-type casts and one-database-per-model scheme irritating.  &lt;a href=&quot;http://github.com/langalex/couch_potato&quot;&gt;couch_potato&lt;/a&gt; definitely looks slicker, but there seems to be quite a few  &lt;a href=&quot;http://github.com/search?type=Repositories&#38;language=rb&#38;q=couchdb&quot;&gt;other CouchDB interfaces&lt;/a&gt; out there that might be just as good or better.  I see this as a good sign that many others also see CouchDB&#8217;s potential, and are experimenting with ways to deal with it in a Ruby Way.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.onebananaproblem.com/">
    <author>
      <name>code_monkey_steve</name>
    </author>
    <id>tag:www.onebananaproblem.com,2009-05-05:46</id>
    <published>2009-05-05T17:07:00Z</published>
    <updated>2009-05-07T17:14:01Z</updated>
    <link href="http://www.onebananaproblem.com/2009/5/5/word-of-the-day" rel="alternate" type="text/html"/>
    <title>Word of the Day: Connascence</title>
<content type="html">
            &lt;a href=&quot;http://www.thefreedictionary.com/Connascence&quot;&gt;Connascence&lt;/a&gt;
&lt;blockquote&gt;
Con-nas-cence
n.    1.    The common birth of two or more at the same time; production of two or more together.
    2.    That which is born or produced with another.
    3.    The act of growing together.
&lt;/blockquote&gt;

	&lt;p&gt;From Jim Weirich&#8217;s intriguing &lt;a href=&quot;http://aac2009.confreaks.com/&quot;&gt;acts_as_conference&lt;/a&gt; presentation on &lt;a href=&quot;http://aac2009.confreaks.com/06-feb-2009-11-00-the-grand-unified-theory-jim-weirich.html&quot;&gt;The Grand Unified Theory of Software Development&lt;/a&gt; .&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.onebananaproblem.com/">
    <author>
      <name>code_monkey_steve</name>
    </author>
    <id>tag:www.onebananaproblem.com,2009-04-29:45</id>
    <published>2009-04-29T22:25:00Z</published>
    <updated>2009-04-29T22:44:10Z</updated>
    <link href="http://www.onebananaproblem.com/2009/4/29/seattle-rb-and-goruco-wisdom" rel="alternate" type="text/html"/>
    <title>Seattle.rb and GoRuCo Wisdom</title>
<content type="html">
            &lt;p&gt;Finally got around to attending the &lt;a href=&quot;http://www.seattlerb.org/&quot;&gt;Seattle Ruby Brigade&lt;/a&gt; last night, although I feel a bit silly about forgetting to bring my laptop to &#8220;Hack Night&#8221;.  Still, I had interesting conversations with &lt;a href=&quot;http://rwldesign.com/&quot;&gt;Ryan Lonac&lt;/a&gt; about all things Ruby, with someone (a Jennifer) who could actually make use of &lt;span class=&quot;caps&quot;&gt;MP3&lt;/span&gt; validation if I added it to &lt;a href=&quot;http://github.com/CodeMonkeySteve/assert_valid_content&quot;&gt;assert_valid_content&lt;/a&gt;, and with a couple of other cool people who&#8217;s names my brain was too feeble to retain.&lt;/p&gt;


	&lt;p&gt;Still working my way through the &lt;a href=&quot;http://podcast.rubyonrails.org/&quot;&gt;Ruby on Rails Podcast&lt;/a&gt; (up up to 2009 already!).  It doesn&#8217;t help that I found the &lt;a href=&quot;http://railsenvy.com/&quot;&gt;Rails Envy Podcast&lt;/a&gt;, which is another interesting time-sink.  Along the way I also discovered &lt;a href=&quot;http://goruco2008.confreaks.com/index.html&quot;&gt;video from GoRuCo 2008&lt;/a&gt; and found the presentation from &lt;a href=&quot;http://goruco2008.confreaks.com/02_bowkett.html&quot;&gt;Giles Bowkett&lt;/a&gt; equal parts brilliant and hilarious.&lt;/p&gt;


	&lt;p&gt;Finally, I&#8217;ve refactored my &lt;a href=&quot;http://www.onebananaproblem.com/assets/2009/4/29/resume.pdf&quot;&gt;resume&lt;/a&gt; to show of my Mad Ruby Skillz a bit more.  If anyone out there knows anyone out there who&#8217;s looking for a Serious Ruby/Rails Geek, please pass it along and have them drop me a line.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.onebananaproblem.com/">
    <author>
      <name>code_monkey_steve</name>
    </author>
    <id>tag:www.onebananaproblem.com,2009-04-28:42</id>
    <published>2009-04-28T16:48:00Z</published>
    <updated>2009-05-07T17:14:11Z</updated>
    <link href="http://www.onebananaproblem.com/2009/4/28/word-of-the-day" rel="alternate" type="text/html"/>
    <title>Word of the Day: Duck-punching</title>
<content type="html">
            &lt;p&gt;I may be showing how out of date I am with the Rubyverse, but I just discovered &lt;a href=&quot;http://en.wikipedia.org/wiki/Duck_punching&quot;&gt;Duck Punching&lt;/a&gt;:&lt;/p&gt;


&lt;blockquote&gt;Well, I was just totally sold by Adam, the idea being that if it walks like a duck and talks like a duck, it’s a duck, right? So if this duck is not giving you the noise that you want, you’ve got to just punch that duck until it returns what you expect.
– Patrick Ewing&lt;/blockquote&gt;

	&lt;p&gt;Awesome.&lt;/p&gt;


	&lt;p&gt;As for &lt;a href=&quot;http://pratalife.blogspot.com/2008/08/show-whale.html&quot;&gt;show the whale&lt;/a&gt;: meh.&lt;/p&gt;
          </content>  </entry>
</feed>
