<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>The Hippy Hacker</title>
    <link>http://evan.tiggerpalace.com/rss/</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>On spreading heavenly glory</description>
    
    
        <item>
          <title>Write the first one ugly</title>
          <description>&lt;p&gt;The desire for perfection can paralyze software developers.  Sometimes we know the gist of what we want to write but not which names to use or the constructs to define.  So we stare at our blank screen and cogitate.  We ponder, pondering our pondering, and ponder our pondering of our pondering.&lt;/p&gt;

&lt;p&gt;To overcome paralysis, for small chunks of code, it is often better to just write whatever comes to mind &amp;#8211; no matter how awful it may seem at the time.  &lt;strong&gt;Give yourself permission to let the first version suck.&lt;/strong&gt;  You may even &lt;em&gt;*gasp*&lt;/em&gt; not &lt;a href=&quot;http://en.wikipedia.org/wiki/Test-driven_development&quot;&gt;TDD (&amp;#8220;Test Driven Development&amp;#8221;)&lt;/a&gt; it.  Just make it work.  Just do it.  You&amp;#8217;re only pushing bits around on a screen.  You can change it later!  For those of you who always &lt;em&gt;always&lt;/em&gt; &lt;strong&gt;always&lt;/strong&gt; test first, this may even feel a little liberating (while feeling a tad naughty in a good way).&lt;/p&gt;

&lt;p&gt;This is not software development technique.  This is a productivity technique, pure and simple, straight from the writing of David Allen of &lt;em&gt;Getting Things Done&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Also this is not &lt;em&gt;just&lt;/em&gt; &lt;a href=&quot;http://blog.energizedwork.com/2006/01/spike.html&quot;&gt;spiking&lt;/a&gt;.  Spiking is, essentially, prototyping a small problem area for learning purposes.  We&amp;#8217;re not going in planning to throw code away &amp;#8211; only our standards but only for a few minutes.&lt;/p&gt;

&lt;p&gt;At the very least, this approach will serve the same purpose as a spike.  You&amp;#8217;ll better bound the problem, you may have a partial or working solution, but you have concretely captured the problem at hand.  It sure beats the alternative of having an amorphous concept bouncing around your noggin.&lt;/p&gt;

&lt;p&gt;How often do I do this?  All of the time. For every piece of code, blog post, or email that I write, I blurt out whatever comes to mind first then I refactor (although, yes, I often, but not always TDD it when writing code).  And when I refactor, yes, my standards come back into play.  It works.  Try it.&lt;/p&gt;</description>
          <pubDate>Mon, 26 Jul 2010 15:17:28 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2010/07/26/write-the-first-one-ugly/</guid>
          <link>http://evan.tiggerpalace.com/articles/2010/07/26/write-the-first-one-ugly/</link>
        </item>
    
        <item>
          <title>Recruiting freelance help for your startup with equity</title>
          <description>&lt;p&gt;If you&amp;#8217;re reading this, you&amp;#8217;re probably looking for a few hands to work on your startup.  You&amp;#8217;re probably also tight on funds.  And, so, you&amp;#8217;re considering giving away a stake in your possibly yet-to-be-realized vision.&lt;/p&gt;

&lt;p&gt;Since I&amp;#8217;ve begun offering freelance services about a year ago, I&amp;#8217;ve had several customers offer to compensate me with equity.  I have yet to meet a single freelancer who took an engagement with a customer offering equity.  Most of us won&amp;#8217;t.  I never have.&lt;/p&gt;

&lt;p&gt;Once I hear &amp;#8220;equity&amp;#8221;, I&amp;#8217;m typically turned off like a switch.&lt;/p&gt;

&lt;p&gt;Freelancers, in particular, are in business for themselves.  Most of us don&amp;#8217;t want to be tied down to a single startup unless its ours.  We may even be looking to develop our own products.  &lt;/p&gt;

&lt;p&gt;Instead of payment, you&amp;#8217;re offering equity as compensation; effectively, you&amp;#8217;re asking us to invest in your startup.  Most startups don&amp;#8217;t have successful exits.  The common perspective, then, is that your equity offer is worth only the paper or electrons it&amp;#8217;s printed on.&lt;/p&gt;

&lt;p&gt;You may be able to retain neophyte developers who are looking to build up their portfolio but you probably shouldn&amp;#8217;t.  Some of them will work, effectively, for free.  However, typically, you get what you pay for.  A novice developer is just as likely to give you negative productivity than a usable product.&lt;/p&gt;

&lt;p&gt;Before spending an hour telling us all about your glorious idea, first determine if you can possibly close us.  Pitch us as you would a real investor.  But you ought to be sure that we&amp;#8217;re at least open to the idea.  You&amp;#8217;re almost certainly wasting yours and your prospective developer&amp;#8217;s time if you don&amp;#8217;t first.  Again, most of us aren&amp;#8217;t interested.  You&amp;#8217;ll save yourself a lot of time by asking the simple question of &amp;#8220;will you work for equity?&amp;#8221; first.  Feel free to ignore this if you enjoy spending a lot of time pitching people and having nothing to show for it.&lt;/p&gt;

&lt;p&gt;Remember, you are asking us to become an investor.  Sell us on you.  Sell us on your idea.  &lt;a href=&quot;http://www.youtube.com/watch?v=TROhlThs9qY&quot;&gt;Coffee is for closers!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;object width=&quot;480&quot; height=&quot;385&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://www.youtube.com/v/TROhlThs9qY&amp;amp;hl=en_US&amp;amp;fs=1&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot;&gt;&lt;/param&gt;&lt;embed src=&quot;http://www.youtube.com/v/TROhlThs9qY&amp;amp;hl=en_US&amp;amp;fs=1&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;480&quot; height=&quot;385&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;

&lt;p&gt;Maybe, just maybe, you&amp;#8217;ll get a quality developer out of the process.  But you have to remember that you&amp;#8217;re asking that developer to be an investor.&lt;/p&gt;</description>
          <pubDate>Sun, 18 Jul 2010 15:24:06 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2010/07/18/recruiting-freelance-help-for-your-startup-with-equity/</guid>
          <link>http://evan.tiggerpalace.com/articles/2010/07/18/recruiting-freelance-help-for-your-startup-with-equity/</link>
        </item>
    
        <item>
          <title>"Business is business" is a dirty excuse</title>
          <description>&lt;p&gt;Over the past several months, while attempting to develop my previous business and now a new one, I&amp;#8217;ve immersed myself in books about entrepreneurship and marketing.  Most of them promote ideals that I already adhere to: authenticity, honesty, building trust, and the value of relationships.    I don&amp;#8217;t adhere to these principles out of a desire for fiscal success.  I adhere to them because it is who I am, win or lose.&lt;/p&gt;

&lt;p&gt;If you are the least immersed in popular culture then you have undoubtedly heard the phrase &amp;#8220;Business is business.&amp;#8221;  During my career, I&amp;#8217;ve encountered this phrase more often than I would like.  &lt;/p&gt;

&lt;p&gt;I am frustrated to occasionally see seemingly otherwise decent people descend to morally questionable depths when money becomes the issue at hand.  It is as though business is this separate world where Machiavelli is welcome even though in this other world that we call &amp;#8220;life&amp;#8221; he is not.&lt;/p&gt;

&lt;p&gt;If you&amp;#8217;ve seen the HBO series &amp;#8220;The Wire&amp;#8221;, &amp;#8220;Business is business&amp;#8221; is the sort of utterance that one of the corner drug dealers may say after ratting out a pal to save his own skin or gunning down a comrade who earned the ire of the kingpin.  It is an excuse for breaking social contracts in favor of financial gain.  It is a rationalization for what, in otherwise friendly company, is selfish and often unkind behavior.  It is a dirty excuse for blithe indifference.&lt;/p&gt;

&lt;p&gt;Instead, I prefer to say &amp;#8220;Business is personal&amp;#8221; &amp;#8211; because it is.&lt;/p&gt;

&lt;p&gt;If it&amp;#8217;s truly not about whether you win or lose but how you play the game then how we do business may provide the ultimate example of ourselves.  At stake is no less than the welfare of ourselves and our loved ones but also who we are: our moral character.&lt;/p&gt;

&lt;p&gt;What says more about who you are than how you treat other people when the stakes are high?&lt;/p&gt;

&lt;p&gt;How do you want to be seen by the world?  How do you want to be remembered?&lt;/p&gt;</description>
          <pubDate>Fri, 16 Jul 2010 07:10:47 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2010/07/16/business-is-business-is-a-dirty-excuse/</guid>
          <link>http://evan.tiggerpalace.com/articles/2010/07/16/business-is-business-is-a-dirty-excuse/</link>
        </item>
    
        <item>
          <title>Why you should work with me</title>
          <description>&lt;p&gt;&lt;strong style=&quot;font-size=1.2em&quot;&gt;I believe in candor.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;I always give a straight answer.  Sometimes that answer isn&amp;#8217;t the one that you want to hear.  However, I believe that hiding the bad news from you only weakens our relationship and your project.&lt;/p&gt;

&lt;p&gt;&lt;strong style=&quot;font-size=1.2em&quot;&gt;I want to see you succeed.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;To that extent, I will help guide you through the process, providing my insight to add value to your business.  At any given time, if you&amp;#8217;d rather that I do it your way, I&amp;#8217;m open to it, because&amp;#8230;.&lt;/p&gt;

&lt;p&gt;&lt;strong style=&quot;font-size=1.2em&quot;&gt;I want my customers to be happy.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;Few software developers and consultant realize it, but the software development consulting business is, first and foremost, a customer service business.  If you&amp;#8217;re not happy then our relationship will not be mutually beneficial.  And I always seek the WIN-WIN.&lt;/p&gt;

&lt;p&gt;&lt;strong style=&quot;font-size=1.2em&quot;&gt;I ship.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;At the outset, we will agree on a release date/window for your product.  We will together prioritize the features that you need for your Minimum Viable Product.  This is part of the agile development methodology that I loosely follow.  This will also likely define your first release.  And it will ship on schedule.&lt;/p&gt;

&lt;p&gt;&lt;strong style=&quot;font-size=1.2em&quot;&gt;I believe in forging meaningful long term relationships&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;Engaging me alone, or with several of my peers, is not engaging a business but forging a relationship.  Good business is built upon the understanding and trust in that relationship.  The better that we understand one another, the better we will work together.  From day one, I am trying to understand you and your needs to better add value to your business.  Trust comes with everything else that I&amp;#8217;ve already cited above (e.g., candor, shipping).&lt;/p&gt;

&lt;p&gt;Please do feel free to &lt;strong&gt;contact me with opportunities at sleight42 AT gmail DOT com&lt;/strong&gt;. Subsitute the &amp;#8220;AT&amp;#8221; and &amp;#8220;DOT with &amp;#8220;@&amp;#8221; and &amp;#8220;.&amp;#8221; for the actual email address.&lt;/p&gt;</description>
          <pubDate>Mon, 21 Jun 2010 09:12:56 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2010/06/21/why-you-should-work-with-me/</guid>
          <link>http://evan.tiggerpalace.com/articles/2010/06/21/why-you-should-work-with-me/</link>
        </item>
    
        <item>
          <title>One-off/user-customized products in Spree</title>
          <description>&lt;p&gt;One of our clients sells customizable products.  He contracted us to write a webapp to facilitate the process for his customers.  We decided to go with Spree for the integrated eCommerce and order fulfillment capabilities.  Having &lt;a href=&quot;http://evan.tiggerpalace.com/articles/2009/04/24/how-i-hate-authorize-net-let-me-count-the-ways/&quot;&gt;written eCommerce&lt;/a&gt; &lt;a href=&quot;http://evan.tiggerpalace.com/articles/2009/05/22/really-never-ever-use-authorize-net/&quot;&gt;implementations before&lt;/a&gt;&amp;#8230;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/deerhunting.jpg&quot;&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;&amp;#8230; &lt;a href=&quot;spreecommerce.com/&quot;&gt;Spree&lt;/a&gt; sounded like a much better option.&lt;/p&gt;

&lt;p&gt;The trick then became how we would represent these user customized products.  As it turns out, Spree supports this in the model out of the box.  In Spree, products are represented by instances of the &lt;em&gt;Product&lt;/em&gt; class.  However, they can also be represented by &lt;em&gt;Variants&lt;/em&gt; of a &lt;em&gt;Product&lt;/em&gt;.  That is, a &lt;em&gt;Product&lt;/em&gt; has many &lt;em&gt;Variants&lt;/em&gt;.  &lt;em&gt;Variants&lt;/em&gt; can vary by price but they also can vary by &lt;em&gt;OptionValues&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I know: &lt;em&gt;OptionValues&lt;/em&gt; is quite a mouthful of generic stuff.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/supersizeme.jpg&quot;&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;But they&amp;#8217;re useful!  Let me explain.&lt;/p&gt;

&lt;p&gt;In Spree, a &lt;em&gt;Product&lt;/em&gt; can have multiple &lt;em&gt;OptionTypes&lt;/em&gt;.  Each &lt;em&gt;OptionType&lt;/em&gt; describes what amounts to a &lt;strong&gt;container for an enumeration&lt;/strong&gt;.  The &lt;em&gt;OptionType&lt;/em&gt; then has &lt;em&gt;OptionValues&lt;/em&gt;.  These &lt;em&gt;OptionValues&lt;/em&gt; are &lt;strong&gt;the values in that enumeration.&lt;/strong&gt;  And &lt;em&gt;Variants&lt;/em&gt; have many &lt;em&gt;OptionValues&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;When you put it all together, it looks something like this:&lt;/p&gt;

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

&lt;p&gt;Now that is one tasty burger!&lt;/p&gt;

&lt;p&gt;&lt;object width=&quot;560&quot; height=&quot;340&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://www.youtube.com/v/ecc0nbg9m-8&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;rel=0&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot;&gt;&lt;/param&gt;&lt;embed src=&quot;http://www.youtube.com/v/ecc0nbg9m-8&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;rel=0&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;560&quot; height=&quot;340&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;

&lt;p&gt;The only downside that I see is that, for one-off/user-customized products, at a minimum, you will be creating a &lt;em&gt;Variant&lt;/em&gt; with permutations of &lt;em&gt;OptionValues&lt;/em&gt; for each line item in a user&amp;#8217;s order containing a customized product resulting in a cluttered &lt;em&gt;products&lt;/em&gt; table.  If you&amp;#8217;re willing to do a little extra work, you could probably elaborate upon the Spree model to determine if a &lt;em&gt;Variant&lt;/em&gt; already exists with your desired permutation of &lt;em&gt;OptionValues&lt;/em&gt; before going off and creating one.&lt;/p&gt;

&lt;p&gt;So there you have it.&lt;/p&gt;</description>
          <pubDate>Sun, 21 Mar 2010 19:43:58 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2010/03/21/one-offuser-customized-products-in-spree/</guid>
          <link>http://evan.tiggerpalace.com/articles/2010/03/21/one-offuser-customized-products-in-spree/</link>
        </item>
    
        <item>
          <title>RVM + Bundler + RubyMine</title>
          <description>&lt;p&gt;On my current project, we needed to be able to use RVM with Bundler but we want access to our bundled gems from Rubymine.&lt;/p&gt;

&lt;p&gt;You&amp;#8217;re going to want to write an alias in your .bashrc/.zshrc/.&lt;em&gt;whatever&lt;/em&gt;shrc for this one. You can use most of the below:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;export PROJECT_PATH=the_path_to_your_Rails_project_using_bundler_goes_here
alias rubymine=&quot;rvm ruby-1.8.6-tv1_8_6_287 ;\
export GEM_HOME=#{PROJECT_PATH}/vendor/bundler_gems/ruby/1.8;\
export GEM_PATH=${GEM_HOME};/Applications/RubyMine\ 2.0.1.app/Contents/MacOS/rubymine&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What we&amp;#8217;re doing here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We then override the gem repo to point to our bundled gems (which are conveniently formatted as a gem repo)&lt;/li&gt;
&lt;li&gt;Then we fire up Ruby Mine with the above environment (Thanks to Brennan Dunn here).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now close and reopen your shell.&lt;/p&gt;

&lt;p&gt;From there, you go into RubyMine&amp;#8217;s settings, click on &amp;#8220;Add SDK&amp;#8221;&amp;#8230;&lt;/p&gt;

&lt;p&gt;&lt;img style=&quot;width: 100%&quot; src=&quot;http://img.skitch.com/20100129-bgwsh6pnj4kd3pk8pnuueybmuf.jpg&quot;/&gt;&lt;/p&gt;

&lt;p&gt;&amp;#8230; unhide the hidden directories like so&amp;#8230;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://img.skitch.com/20100129-gir3rrwneykuxra1e4u2868f2e.jpg&quot;/&gt;&lt;/p&gt;

&lt;p&gt;&amp;#8230; then navigate to your Ruby VM and hit OK:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://img.skitch.com/20100129-bt1ycd7w6e8egmy5awys5xpfbk.jpg&quot;/&gt;&lt;/p&gt;

&lt;p&gt;Voila!&lt;/p&gt;</description>
          <pubDate>Fri, 29 Jan 2010 14:09:27 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2010/01/29/rvm-bundler-rubymine/</guid>
          <link>http://evan.tiggerpalace.com/articles/2010/01/29/rvm-bundler-rubymine/</link>
        </item>
    
        <item>
          <title>Mocking mocking (or "Why I am learning to hate isolating the unit under test")</title>
          <description>&lt;p&gt;Mocking basically sucks.&lt;/p&gt;

&lt;p&gt;There.  I said it.&lt;/p&gt;

&lt;p&gt;Using mocks in your tests almost always results in fragile tests.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;h2&gt;A case against mocking&lt;/h2&gt;

&lt;p&gt;Let&amp;#8217;s say that you&amp;#8217;re working on a hypothetical (simplified) financial application:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class AccountTest &amp;lt; ActiveSupport::TestCase
  setup do
    @balance = 42.00
    @account = factory_to_create_a_test_account :with_balance =&amp;gt; @balance
    @mock_bank_manager = mock(BankManager)
  end

  def test_overdrawing_account_sends_notification
    @mock_manager.expects(:notify_of, :overdrawn_account, :amount =&amp;gt; 1)
    @account.withdraw(@balance + 1)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The above example is attempting to illustrate how mocks can be useful for specifying a causal relationship.  &amp;#8220;Overdrawing the account&amp;#8221; results in &amp;#8220;notifying the bank manager of the amount over balance&amp;#8221;.&lt;/p&gt;

&lt;p&gt;Mocking seems like such a natural and even expressive way to design an API.  It&amp;#8217;s, quite literally, behavior driven development: your tests/specifications, where you are mocking the API, are helping you design the API itself!  That&amp;#8217;s terrific.&lt;/p&gt;

&lt;p&gt;So let&amp;#8217;s pretend that, like a good TDDer, I&amp;#8217;ve gone and implemented the BankManager class.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class BankManager
  def notify_of(event_type, options = {})
    case event_type:
    when :notify_of
      # send the notification
    when ...
      ...
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Perhaps I even wrote a test/spec for &lt;em&gt;BankManager&lt;/em&gt;.  But, then, in a fit of refactoring rage, I decide that I must have a second argument to &lt;em&gt;BankManager#notify_of&lt;/em&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class BankManager
  def notify_of(event_type, account, options = {})
    case event_type:
    when :notify_of
      # send the notification
    when ...
      ...
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Our old friend &lt;em&gt;AccountTest&lt;/em&gt; above will still pass because it&amp;#8217;s using a mock.  However, the API to &lt;em&gt;BankManager&lt;/em&gt; has changed; we want &lt;em&gt;AccountTest#test_overdrawing_account_sends_notification&lt;/em&gt; to fail!&lt;/p&gt;

&lt;p&gt;So, in short, mocking an internal API is a recipe for pain and (Ni!) woe.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;After you implement the API, you still have mocks lying around in the test that helped you mock out the API design in the first place.  This test is now fragile.  &lt;strong&gt;If the API changes, the tests containing the mocks will still pass!&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;You can double back and replace those mocks with actual calls to the API &lt;strong&gt;but you just made more work for yourself&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;Where mocking makes sense&lt;/h2&gt;

&lt;p&gt;In my experience, the only place that mocks have served me at all well is when I&amp;#8217;m interfacing with an external service from a unit test.  I certainly don&amp;#8217;t want my unit test invoking services beyond my own system.  I usually write an interface layer between my business logic and the external service.  In my unit tests, I then mock the interface layer only.  Testing integration with the external service, predictably, becomes a chore solely for the integration test.&lt;/p&gt;

&lt;h2&gt;We have the technology. We can rebuild it.&lt;/h2&gt;

&lt;p&gt;I believe that there is a better path: one that will let us have our mocking cake but now force us to eat brittle tests.  I&amp;#8217;ve had some ideas about this on the back burner for about a year now.  However, I hope to have something concrete to discuss in a few weeks.&lt;/p&gt;</description>
          <pubDate>Mon, 25 Jan 2010 20:47:11 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2010/01/25/mocking-mocking-or-why-i-am-learning-to-hate-isolating-the-unit-under-test/</guid>
          <link>http://evan.tiggerpalace.com/articles/2010/01/25/mocking-mocking-or-why-i-am-learning-to-hate-isolating-the-unit-under-test/</link>
        </item>
    
        <item>
          <title>On Craftsmanship and Practice</title>
          <description>&lt;p&gt;Reading a passage from the &amp;#8220;E-Myth Contractor&amp;#8221; got me to thinking about how we practice (when we practice) our skills that we apply on a regular basis.&lt;/p&gt;

&lt;p&gt;When we practice our craft, performing &amp;#8220;katas&amp;#8221; as they have come to be called, why do we perform them on arcane problems such as Langdon&amp;#8217;s Ant or Conway&amp;#8217;s Game of Life?&lt;/p&gt;

&lt;p&gt;You don&amp;#8217;t encounter these problems in your day-to-day work.&lt;/p&gt;

&lt;p&gt;I agree that solving these problems a few times over may improve your overall problem solving skills.  But that&amp;#8217;s only true until you settle on an optimal implementation.&lt;/p&gt;

&lt;p&gt;Given the above then there seems to be greater value in routinely exercising what we consider routine.  &lt;/p&gt;

&lt;p&gt;If I can build a signup, login,and forgotten password capability, a text-based search across multiple model objects, or a recurring payment ecommerce system rapidly and reliably, isn&amp;#8217;t that more valuable to most customers than finding clever ways to move a hypothetical ant around a grid?  These are the sorts of tasks that we routinely encounter in our work.  Or perhaps not.  Maybe you typically employ a CMS to expedite these chores.  This is because craftsmen use tools to work in their craft.  &lt;/p&gt;

&lt;p&gt;So you should be practicing with those same tools.&lt;/p&gt;

&lt;p&gt;If you have a good toolbox, full of tools ideally suited to solving problems your typical problems, then these tools are your weapons.  Each tool probably does certain things better than others.  You should then practice &amp;#8220;weapon katas.&amp;#8221;&lt;/p&gt;

&lt;p&gt;You should master your tools.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s assume for a moment that your current project/product/service du jour is not a unique and special snowflake.  If what we do is a craft, then repetition and understanding of the routine tasks should enable us to deliver faster, more reliably, and more consistently.&lt;/p&gt;

&lt;p&gt;Perhaps studying Langdon&amp;#8217;s and Conway&amp;#8217;s, ultimately, is a study of basic forms, i.e. this is how I BDD something different.  Once we grasp these basic forms, it is then time to move on to how we employ our tools, i.e., our favorite plugins and gems, until we&amp;#8217;ve mastered those as well.&lt;/p&gt;

&lt;p&gt;Doesn&amp;#8217;t this make us better craftsmen?&lt;/p&gt;

&lt;p&gt;&amp;#8230; that is, until someone introduces a better weapon.&lt;/p&gt;

&lt;p&gt;I freely admit that this is not how I currently practice.  I feel that my basic form is solid.  Howver, I admit, I do need to better acquaint myself with my weapons.  As of now, this is what I intend to practice.  I will try to report on how it goes.&lt;/p&gt;</description>
          <pubDate>Mon, 11 Jan 2010 23:26:06 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2010/01/11/on-craftsmanship-and-practice/</guid>
          <link>http://evan.tiggerpalace.com/articles/2010/01/11/on-craftsmanship-and-practice/</link>
        </item>
    
        <item>
          <title>Shouldn't developer tools be for developers first?</title>
          <description>&lt;p&gt;As (I believe) Jonas Nicklas pointed out in response to &lt;a href=&quot;http://robots.thoughtbot.com/post/304910866/history-ruby-integration-testing&quot;&gt;ThoughtBot&amp;#8217;s post on integration testing&lt;/a&gt;, &lt;a href=&quot;http://cukes.info/&quot;&gt;Cucumber&lt;/a&gt; is largely ineffectual in a project until you build up a library of domain-specific matchers and their respective code blocks.&lt;/p&gt;

&lt;p&gt;What this represents is external domain-specific language design via regular expression.&lt;/p&gt;

&lt;p&gt;The reasonable use of this is to facilitate the expression of desired behaviors by non-developers. For example, I have tell of organizations where QA people, for instance, write automated acceptance tests using Cucumber.&lt;/p&gt;

&lt;p&gt;I share the Cucumber team&amp;#8217;s belief that customer communication is essential. That&amp;#8217;s facilitated, in Cucumber, by writing features in plain text (Gherkin). Cost is saved when issues are addressed in specs versus code &amp;#8211; likely why the waterfall model was so popular at first. It&amp;#8217;s just common sense. &lt;/p&gt;

&lt;p&gt;It&amp;#8217;s a form of risk management.&lt;/p&gt;

&lt;p&gt;Every feature goes hand in hand with the risk that it will fail to be implemented to meet customer expectation. A risk becomes an issue, in this case, when a feature is implemented in a fashion differing from the customer&amp;#8217;s expectation. The earlier that risk is mitigated, the less money/effort/time is wasted on the project handling risks that manifest into issues.&lt;/p&gt;

&lt;p&gt;One way of mitigating that risk is to communicate to the customer how that feature will behave in the language of the customer&amp;#8217;s domain.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://coulda.tiggerpalace.com&quot;&gt;Coulda&lt;/a&gt; solves the same problem. It has a rake task for marshaling the Feature, contained Scenarios, and all of the statements (Givens/Whens/Thens) into plain text.&lt;/p&gt;

&lt;p&gt;However, Coulda shares many of the considerations Dan cites above:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&amp;#8220;Features&amp;#8221; are just Test::Unit::TestCases &lt;/li&gt;
&lt;li&gt;&amp;#8220;Scenarios&amp;#8221; are just tests&lt;/li&gt;
&lt;li&gt;&amp;#8220;Statements&amp;#8221; (Given/When/Then) are just steps taken within a particular test&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When I use Coulda on a project (I&amp;#8217;ve used it on the job at this point), I don&amp;#8217;t start with the intent of building a language. I know that I probably will, because I have, as my work progresses. I start by writing pending Features, pending Scenarios, pending Statements, and then I begin putting flesh on the bones. I refactor my tests. When I encounter duplication within a Feature, I Extract Method. When I encounter duplication across Features, I Extract Module (I&amp;#8217;m guessing that&amp;#8217;s in Ruby Refactoring but you likely get the intent: I create a module, move my method into the module, and include the module in my Coulda Features), and so on.&lt;/p&gt;

&lt;p&gt;What bothers me so much about so many libraries, in general, is that they try to solve all of my problems. &lt;/p&gt;

&lt;p&gt;That&amp;#8217;s great but I don&amp;#8217;t want that. Just like I don&amp;#8217;t want to buy a car with a 500hp engine because I simply won&amp;#8217;t need it. I just need a car.&lt;/p&gt;

&lt;p&gt;So I kept Coulda simple. If you need more, great, then write it! If you find that you need the same thing repeatedly, great, make a new gem from it!&lt;/p&gt;

&lt;p&gt;Automate what you need to do often. If you have an edge case, keep it out of your libraries, thank you! My brain has a hard enough time absorbing the ever-increasing size of the Rails API (and this from a guy who worked in J2EE hell for years).&lt;/p&gt;

&lt;p&gt;Remember, these are the kinds of practices that gave us Rails. Don&amp;#8217;t try to solve everyone&amp;#8217;s problems. Focus on the frequently recurring problems. Scratch your own itch (I did!).&lt;/p&gt;</description>
          <pubDate>Mon, 04 Jan 2010 22:45:18 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2010/01/04/shouldnt-developer-tools-be-for-developers-first/</guid>
          <link>http://evan.tiggerpalace.com/articles/2010/01/04/shouldnt-developer-tools-be-for-developers-first/</link>
        </item>
    
        <item>
          <title>"Grid" layout in Android</title>
          <description>&lt;p&gt;You know how your mother (or, in this case, your front end developer friends/colleagues) always say &amp;#8220;never use a table for formatting unless you&amp;#8217;re really making a table&amp;#8221;&lt;/p&gt;

&lt;p&gt;That may be true for HTML.  However, it doesn&amp;#8217;t seem to hold when you&amp;#8217;re working with Google&amp;#8217;s Android.&lt;/p&gt;

&lt;p&gt;You see, now that I have a shiny new Motorola Droid (see my previous post), I&amp;#8217;m now working with Android in my spare time.&lt;/p&gt;

&lt;p&gt;I was struggling with using Android&amp;#8217;s UI XML to layout a simple login page.  And I was going nuts.&lt;/p&gt;

&lt;p&gt;I was trying to use A &lt;em&gt;LinearLayout&lt;/em&gt; containing several &lt;em&gt;RelativeLayout&lt;/em&gt;s, one for each row.  &amp;#8220;Row&amp;#8221; should have been the clue.&lt;/p&gt;

&lt;p&gt;After poking through the PragProg &lt;strong&gt;Hello, Android&lt;/strong&gt; book for a bit, I found an example later in the book that used a &lt;em&gt;TableLayout&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That was my aha moment.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;TableLayout&lt;/em&gt; is pretty simple to use.  It is designed to contain several &lt;em&gt;TableRow&lt;/em&gt; (a &lt;em&gt;ViewGroup&lt;/em&gt; child as are other &lt;em&gt;*Layouts&lt;/em&gt;).  A &lt;em&gt;TableRow&lt;/em&gt; looks thus:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
  &lt;pre&gt;
&amp;lt;TableLayout
  android:layout&lt;em&gt;width=&quot;fill&lt;/em&gt;parent&quot; 
  android:layout&lt;em&gt;height=&quot;wrap&lt;/em&gt;content&quot;
  android:stretchColumns=&quot;1&quot; 
  android:padding=&quot;10dip&quot; &amp;gt;
  &amp;lt;TableRow
    android:layout_marginBottom=&quot;10dip&quot;&amp;gt;
    &amp;lt;TextView
      android:id=&quot;@+id/login_label&quot;&lt;br/&gt;
      android:layout&lt;em&gt;height=&quot;wrap&lt;/em&gt;content&quot; 
      android:text=&quot;@string/login&quot; /&amp;gt;
    &amp;lt;EditText
      android:id=&quot;@+id/login_field&quot; 
      android:layout&lt;em&gt;width=&quot;fill&lt;/em&gt;parent&quot; 
      android:layout&lt;em&gt;height=&quot;wrap&lt;/em&gt;content&quot; 
      android:lines=&quot;1&quot; /&amp;gt;
  &amp;lt;/TableRow&amp;gt;
  &amp;lt;TableRow
    android:layout_marginBottom=&quot;10dip&quot;&amp;gt;
    &amp;lt;TextView
      android:id=&quot;@+id/password_label&quot; 
      android:layout&lt;em&gt;height=&quot;wrap&lt;/em&gt;content&quot; 
      android:text=&quot;@string/password&quot; /&amp;gt;
    &amp;lt;EditText
      android:id=&quot;@+id/password_field&quot; 
      android:layout&lt;em&gt;width=&quot;fill&lt;/em&gt;parent&quot; 
      android:layout&lt;em&gt;height=&quot;wrap&lt;/em&gt;content&quot; 
      android:lines=&quot;1&quot; /&amp;gt;
  &amp;lt;/TableRow&amp;gt;&lt;br/&gt;
&amp;lt;/TableLayout&amp;gt;
  &lt;/pre&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;android:layout_marginBottom&lt;/em&gt; attributes on the &lt;em&gt;TableRow&lt;/em&gt;s are entirely optional.  However, odds are that you will want to add some sort of formatting to your &lt;em&gt;TableRow&lt;/em&gt;s.&lt;/p&gt;

&lt;p&gt;Incidentally, there may be DRYer ways of representing rows in Android XML (i.e., something similar to a Rails partial); however, admittedly, I&amp;#8217;m still very much learning Android.&lt;/p&gt;</description>
          <pubDate>Sat, 28 Nov 2009 15:09:25 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2009/11/28/grid-layout-in-android/</guid>
          <link>http://evan.tiggerpalace.com/articles/2009/11/28/grid-layout-in-android/</link>
        </item>
    
    
  </channel>
</rss>

