<?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>DCI that respects the method cache</title>
          <description>&lt;p&gt;Ryan Bates sent this pithy tweet earlier today:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.skitch.com/20111125-jbkx9wnasfh264sppd5guyef7n.jpg&quot;&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve been toying with DCI lately.  But the techniques spelled out to date &lt;a href=&quot;http://andrzejonsoftware.blogspot.com/2011/02/dci-and-rails.html&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;http://saturnflyer.com/blog/jim/2011/10/04/oop-dci-and-ruby-what-your-system-is-vs-what-your-system-does/&quot;&gt;here&lt;/a&gt; use Object.extend.  Extending an object blows away the method cache, slightly reducing performance.  &lt;/p&gt;

&lt;p&gt;So, as I lazed in bed, reading this tweet while dreaming of turkey to come, it hits me: instead of implementing the Delegator pattern through extend, let&amp;#8217;s just use an actual Delegator object.&lt;/p&gt;

&lt;p&gt;Simple example below based on the usage of &lt;a href=&quot;https://github.com/rubypair/rubypair/blob/master/app/models/user/new_user_provisioner.rb&quot;&gt;NewUserProvisioner&lt;/a&gt; within &lt;a href=&quot;http://rubypair.com&quot;&gt;RubyPair&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Our good friend &lt;a href=&quot;http://www.ruby-doc.org/stdlib-1.9.2/libdoc/delegate/rdoc/SimpleDelegator.html&quot;&gt;SimpleDelegator&lt;/a&gt; is defined in &amp;#8220;delegate.rb&amp;#8221; in stdlib, courtesy of &lt;a href=&quot;http://blog.grayproductions.net/&quot;&gt;James Edward Gray II&lt;/a&gt;.&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/1392671.js&quot;&gt; &lt;/script&gt;</description>
          <pubDate>Thu, 24 Nov 2011 18:25:44 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2011/11/24/dci-that-respects-the-method-cache/</guid>
          <link>http://evan.tiggerpalace.com/articles/2011/11/24/dci-that-respects-the-method-cache/</link>
        </item>
    
        <item>
          <title>Some people call me "the remote pairing guy"...</title>
          <description>&lt;p&gt;I&amp;#8217;ve been remote pairing with folks for a couple of years now.  However, it&amp;#8217;s only the past few months that I decided that heavyweight application-based solutions just weren&amp;#8217;t working for me.&lt;/p&gt;

&lt;h2&gt;Expectatons&lt;/h2&gt;

&lt;p&gt;I expect my remote pairing experience to be as close to in person as possible.  To that extent, what I desire is:&lt;/p&gt;

&lt;h4&gt;Responsive&lt;/h4&gt;

&lt;p&gt;When I, or my pair, types, I expect to see it on screen in near real-time.  Even a one second delay is potentially too much.&lt;/p&gt;

&lt;h4&gt;Low bandwidth requirement&lt;/h4&gt;

&lt;p&gt;I often pair with people on the opposite side of the country.  Higher bandwidth solutions tend to suffer more due to lack of bandwidth&lt;/p&gt;

&lt;h4&gt;Audio and Video&lt;/h4&gt;

&lt;p&gt;I need to be able to both hear &lt;strong&gt;&lt;em&gt;and see&lt;/strong&gt;&lt;/em&gt; my pair when pairing whenever possible.  Without video, body language can&amp;#8217;t be communicated.&lt;/p&gt;

&lt;p&gt;For instance, ever noticed how you will often gesticulate when you&amp;#8217;re on the phone.  Feels stupid, right?  It&amp;#8217;s human, it&amp;#8217;s communication, and so it matters to pairing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;I need my video of my pair, and vice versa, whenever I can get it.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;FYI, I tend to place the video of my pair just beneath the camera on my screen.  I also work to keep the video o my pair visible at all times.  More on that in a bit.&lt;/p&gt;

&lt;h4&gt;Modular&lt;/h4&gt;

&lt;p&gt;The above two reasons mean that I need to be able to pick and choose which features of my pairing environment I&amp;#8217;ll use based on internet weather.  All-in-one solutions dont lend themselves well to this.&lt;/p&gt;

&lt;h4&gt;Cost&lt;/h4&gt;

&lt;p&gt;I don&amp;#8217;t want my pairs to have to pay for extra products or services to pair with me.&lt;/p&gt;

&lt;h4&gt;Learning curve&lt;/h4&gt;

&lt;p&gt;I want to use well-known and usable tools so that my pairs aren&amp;#8217;t wasting time fighting the tools when they should be pairing with me.&lt;/p&gt;

&lt;h2&gt;I&amp;#8217;ve tried&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;VNC&lt;/li&gt;
&lt;li&gt;Teamviewer&lt;/li&gt;
&lt;li&gt;Mac OS X Screensharing&lt;/li&gt;
&lt;li&gt;Skype Screensharing&lt;/li&gt;
&lt;li&gt;Google Plus Screensharing &amp;amp; Hangouts&lt;/li&gt;
&lt;li&gt;Tmux&lt;/li&gt;
&lt;li&gt;Screen&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these have let me down.&lt;/p&gt;

&lt;h4&gt;VNC (and Mac Screensharing)&lt;/h4&gt;

&lt;p&gt;VNC and Mac Screensharing (allegedly VNC under the hood) are both bandwidth intensive, typically proving too unresponsive for sustained pairing.  On-screen updates often lag one to several seconds.&lt;/p&gt;

&lt;h4&gt;Teamviewer&lt;/h4&gt;

&lt;p&gt;Teamviewer is generally responsive.  &lt;/p&gt;

&lt;p&gt;But it&amp;#8217;s way too expensive!  A single license runs ~$700!  Sure, it&amp;#8217;s for life.  But then my pair has to have it as well.  Granted, Teamviewer is free for non-commercial use.&lt;/p&gt;

&lt;p&gt;I also had it crash a pair&amp;#8217;s Linux machine!  This did not give me good vibes.  Your mileage may vary.&lt;/p&gt;

&lt;h4&gt;Skype&lt;/h4&gt;

&lt;p&gt;Ah, Skype. How I love to hate you.&lt;/p&gt;

&lt;p&gt;The laundry list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Screensharing is unidirectional: My pair can see my desktop but they can&amp;#8217;t effect changes&lt;/li&gt;
&lt;li&gt;Frequent dropped connections&lt;/li&gt;
&lt;li&gt;Screensharing frequently hangs while audio continues to operate as normal.  This can only be corrected by dropping and restarting the call!  FAIL!&lt;/li&gt;
&lt;li&gt;Frequent compatibility issues with older versions of Skype&lt;/li&gt;
&lt;li&gt;Video may be the most bandwidth intensive of the tools I&amp;#8217;ve tried that provide video&lt;/li&gt;
&lt;li&gt;Skype 5 has one of the least usable interfaces ever conceived in the 21st century&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Just don&amp;#8217;t use it.  Really.  Don&amp;#8217;t.&lt;/p&gt;

&lt;h4&gt;Google Plus Screensharing &amp;amp; Hangouts&lt;/h4&gt;

&lt;p&gt;G+ is a different beast from Skype, though it has some similar features.&lt;/p&gt;

&lt;p&gt;G+ screensharing is also a strange beast.  It&amp;#8217;s a feature within G+ Hangouts, a group video chat provided by G+.  Like Skype, it&amp;#8217;s unidirectional.  I know, bummer, right?  But it&amp;#8217;s &lt;strong&gt;&lt;em&gt;extremely&lt;/strong&gt;&lt;/em&gt; responsive compared to Skype.  Alas, again, it&amp;#8217;s unidirectional.  That won&amp;#8217;t work.&lt;/p&gt;

&lt;p&gt;But G+&amp;#8217;s audio and video in Hangout is simply amazing.  And it&amp;#8217;s cross-platorm.  The only sad part is that it uses Flash; it&amp;#8217;s pretty CPU intensive.  For example, it would peg both cores on my 11&amp;#8221; Core 2 Duo Macbook Air.  &lt;/p&gt;

&lt;p&gt;Let me provided emphasis here: &lt;strong&gt;&lt;em&gt;I strongly prefer G+ Hangouts for my A/V while pairing&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h4&gt;Tmux/Screen&lt;/h4&gt;

&lt;p&gt;Tmux and GNU Screen are basically two different takes on the same idea.  &lt;/p&gt;

&lt;p&gt;They&amp;#8217;re session multiplexeres.  &lt;/p&gt;

&lt;p&gt;English, please? &lt;/p&gt;

&lt;p&gt;They let you open multiple shells within a single terminal shell.  You can also share the Screen/Tmux session via a socket with other users on the same machine.&lt;/p&gt;

&lt;p&gt;Again, for emphasis, &lt;strong&gt;&lt;em&gt;I use tmux whenever possible when pairing&lt;/strong&gt;&lt;/em&gt;.  I  have my pairs SSH into a machine under my control, fire up tmux, and off we go to the races!  My impression is that it&amp;#8217;s more a matter of taste; I&amp;#8217;ve seen Screen work as well.&lt;/p&gt;

&lt;p&gt;Delving into the details of SSH is a bit of scope for this article but you can read more about the basics &lt;a href=&quot;http://inside.mines.edu/~gmurray/HowTo/sshNotes.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Tmux (and screen) is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open source and easily acquired&lt;/li&gt;
&lt;li&gt;Extremely low bandwidth over SSH&lt;/li&gt;
&lt;li&gt;Most responsive option of the bunch&lt;/li&gt;
&lt;li&gt;Tmux has a shallow learning curve: it&amp;#8217;s easy to become productive with it quickly.  I&amp;#8217;ve seen numerous developers learn enough Tmux to be productive in it within a minute or two of explaining how to navigate between terminal sessions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Nut&amp;#8217;s n&amp;#8217; Bolts&lt;/h2&gt;

&lt;p&gt;As I mentioned above, the high level of my pairing stack is&amp;#8230;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;G+ Hangouts&lt;/li&gt;
&lt;li&gt;Tmux&lt;/li&gt;
&lt;li&gt;SSH&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;#8230; but there are few more parts to the equation.&lt;/p&gt;

&lt;h4&gt;I typically pair with people on a machine behind a router&lt;/h4&gt;

&lt;p&gt;I use a &lt;a href=&quot;http://www.dd-wrt.com/site/index&quot;&gt;DD-WRT&lt;/a&gt; router.  DD-WRT is an open source router firmware that works on a whole range of off-the-shelf routers.  Among other awesome features, it has a nice built-in feature to keep &lt;a href=&quot;http://dyn.com/dns/&quot;&gt;DynDNS&lt;/a&gt; current with the router&amp;#8217;s internet-facing IP address.  Because, like many people, I lack a static internet IP address (they&amp;#8217;re just a tad finite, you know?), I use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A free DynDNS account&lt;/li&gt;
&lt;li&gt;Keep DynDNS updated through DD-WRT&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, because I control the router, I port forward SSH from the router to my internal machine of choice.  Advice here: don&amp;#8217;t keep your SSH on the well known port 22 for security reasons.&lt;/p&gt;

&lt;h4&gt;I use a Mac&lt;/h4&gt;

&lt;p&gt;While I can do a passing job of faking it as a Linux sys admin, I prefer not to.  Sorry, Linux peeps.&lt;/p&gt;

&lt;p&gt;That said, OS X has this handy little checkbox in the Sharing -&gt; Remote Login preferences to help you secure your SSH:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.skitch.com/20111017-thsp8fqbqs79gkg2edeqc58afb.jpg&quot; /&gt;&lt;/p&gt;

&lt;h4&gt;Working with SSH on a Mac&lt;/h4&gt;

&lt;p&gt;I also need to be able to easily add and remove users based on their SSH public keys.  Most importantly, I need to be able to tell OSX that these newly created users should be allowed to connect to my machine via SSH. This took a little bit of research and, frankly, is OS X arcana.  As such, I wrote a pair of quick-and-dirty scripts that automate the chore for me.&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/1293506.js?file=add_user.rb&quot;&gt; &lt;/script&gt;

&lt;script src=&quot;https://gist.github.com/1293356.js?file=remove_user.rb&quot;&gt;&lt;/script&gt;

&lt;h4&gt;Recap&lt;/h4&gt;

&lt;p&gt;My whole stack amounts to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;G+ for audio-video chat while pairing&lt;/li&gt;
&lt;li&gt;A shared Tmux session running on a Mac under my control made accessible via a DynDNS address hidden behind a DD-WRT router port forwarding SSH to the Mac with users provisioned/removed via a couple of scripts on an as-needed basis.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And, so, I bid you happy remote pairing!&lt;/p&gt;</description>
          <pubDate>Mon, 17 Oct 2011 12:23:56 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2011/10/17/some-people-call-me-the-remote-pairing-guy-/</guid>
          <link>http://evan.tiggerpalace.com/articles/2011/10/17/some-people-call-me-the-remote-pairing-guy-/</link>
        </item>
    
        <item>
          <title>Helping you fish better!</title>
          <description>&lt;p&gt;Helping you fish better!&lt;/p&gt;

&lt;p&gt;In one form or another, I&amp;#8217;ve been a contractor for the vasty majority of my career: building other people&amp;#8217;s software for them.  Along the way, I have mentored developers, &lt;a href=&quot;http://rubydcamp.org&quot;&gt;founded and continue to run a conference&lt;/a&gt; (now going into its fifth year) to enrich and educate both beginning developers and expert alike, have shared some of what I have learned along the way by speaking at user groups and conferences, and &lt;a href=&quot;rubypair.com&quot;&gt;regularly pair with distant developers to both educate, share with, socialize, and learn from them&lt;/a&gt; (I wrote most of RubyPair as well).&lt;/p&gt;

&lt;p&gt;This has led me to realize that I am happiest when I am helping eager developers improve their skills.  Seeing the &amp;#8220;eureka&amp;#8221; moments can only be described as a rush!&lt;/p&gt;

&lt;p&gt;A couple of months ago, I began setting aside at least 3 hours each week, when I&amp;#8217;m not on travel, to remote pair or otherwise consult with other developers on Open Source.  Again, that time is only for Open Source and not for commercial use.  I&amp;#8217;ve taught a lot.  I&amp;#8217;ve learned a few things.  I&amp;#8217;ve met some cool people who I wouldn&amp;#8217;t have otherwise.  It&amp;#8217;s been a blast!&lt;/p&gt;

&lt;p&gt;As the Chinese proverb goes:&lt;/p&gt;

&lt;p&gt;Give a man a fish and you feed him for a day. Teach a man to fish and you feed him for a lifetime.&lt;/p&gt;

&lt;p&gt;That&amp;#8217;s what I&amp;#8217;d been doing.  I simply had not put a label on it!  The mentoring, the conference and user group presentations, the (not-so-) occasional rant about why people should be writing their tests first and then move on to evolve a Test Driven Development discipline: it has all been about trying to help other developers get better.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;d blog but, while not a terrible writer, I don&amp;#8217;t have the writing bug as much as some. But, man, do I &lt;em&gt;ever&lt;/em&gt; love a good conversation or pairing session!&lt;/p&gt;

&lt;p&gt;I want to touch and enrich lives.  I want to help people fish, that is: write software, better!&lt;/p&gt;

&lt;p&gt;What only occurred to me a month ago was that this mentoring fills a real need.  I could make a living off of helping people have &amp;#8220;eureka&amp;#8221; moments!&lt;/p&gt;

&lt;p&gt;And, so, for anyone who is looking to improve: this one&amp;#8217;s for you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;DANGER WILL ROBINSON!  COMMERCIAL PITCH FOLLOWS!&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Via &lt;a href=&quot;http://tripledogdare.net&quot;&gt;Triple Dog Dare&lt;/a&gt; (I admit, I really need to update this page with more recent work but I&amp;#8217;ve been too busy!!!), over the past several months, &lt;a href=&quot;http://keas.com&quot;&gt;I have helped bootstrap one company from almost no Rails knowledge to a working application&lt;/a&gt;.  For another client, I&amp;#8217;ve provided occasional periodic one-on-one mentoring in building his web startup with Rails (shhhh&amp;#8230;.. it&amp;#8217;s a secret for now!).  For both, the majority of the collaboration has been online.  Although, for the former client, I&amp;#8217;ve occasional traveled out to San Fran to help them onsite.  San Fran is just such a terrible town to visit, after all &amp;#8211; and, yes, I&amp;#8217;m kidding; San Fran is pretty awesome.&lt;/p&gt;

&lt;p&gt;But, yes, most of the mentoring occurs online.  Sometimes I&amp;#8217;m answering questions via email, more often IM, doing a code review, or helping via VOIP or a remote pairing session.&lt;/p&gt;

&lt;p&gt;And, let me tell you, remote pairing works pretty darn well.  The technology is not only there but it&amp;#8217;s been there for some time.  Frankly, VOIP was the missing component for a long time.  The other technologies involved are tried and true *NIX apps.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ll write about remote pairing in a later post.  It&amp;#8217;s &lt;a href=&quot;rubypair.com/about&quot;&gt;been at the forefront of my mind a great deal lately&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you or a team you work with is new to Rails and you believe you would benefit from someone to shepherd you through the learning process, &lt;a href=&quot;mailto:hello@tripledogdare.net&quot;&gt;drop me a line&lt;/a&gt;!&lt;/p&gt;</description>
          <pubDate>Fri, 23 Sep 2011 15:29:04 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2011/09/23/helping-you-fish-better/</guid>
          <link>http://evan.tiggerpalace.com/articles/2011/09/23/helping-you-fish-better/</link>
        </item>
    
        <item>
          <title>The automated testing confessional</title>
          <description>&lt;p&gt;Hi, my name is Evan.  And I don&amp;#8217;t always start a new app by writing tests.&lt;/p&gt;

&lt;p&gt;There, I said it!  Crazy, right?  Well, ok, maybe within our test-obsessed Ruby world.&lt;/p&gt;

&lt;p&gt;As much as I promote automated testing and Test Driven Development, and you can call me a hypocrite, but I don&amp;#8217;t always TDD or even test first.  &lt;em&gt;Sometimes I just want to write some %#@&amp;amp;ing code!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;But here&amp;#8217;s the catch: it almost always bites me in the ass later.&lt;/p&gt;

&lt;p&gt;Take for example &lt;a href=&quot;http://rubypair.com&quot;&gt;Ruby Pair&lt;/a&gt;.  Ruby Pair is, currently, a humble little directory of people interested in pairing on Ruby, remotely or in-person, for fun or to work on open source.&lt;/p&gt;

&lt;p&gt;Bad Evan!  You only started writing tests a few weeks in!&lt;/p&gt;

&lt;p&gt;Now that I&amp;#8217;ve berated myself&amp;#8230;&lt;/p&gt;

&lt;p&gt;Ruby Pair hasn&amp;#8217;t been my full time job; it&amp;#8217;s been my hobby project for the past 3 weeks.  When I&amp;#8217;m working on a project for fun, or on my own dime, I&amp;#8217;m more likely to try to see how far I can get without automated tests.&lt;/p&gt;

&lt;p&gt;Why?  Because I&amp;#8217;m lazy, dammit!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;The key is to &lt;a href=&quot;http://c2.com/cgi/wiki?LazinessImpatienceHubris&quot;&gt;be lazy in a good way&lt;/a&gt;.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;RATHOLE&lt;/p&gt;

&lt;p&gt;So I have another confession: until I found Ruby, Perl was my favorite tool to avoid writing shell scripts.  I deplore writing shell scripts.  Sure, I live in the shell (zsh, thank you very much) on a daily basis but that doesn&amp;#8217;t mean that I have to code for the shell using the shell!&lt;/p&gt;

&lt;p&gt;/RATHOLE&lt;/p&gt;

&lt;p&gt;Larry Wall, the author of Perl, talks about the &amp;#8220;three great virtus of a programmer&amp;#8221;.  He lists laziness chiefly among them.  When Larry says &amp;#8220;laziness&amp;#8221;, he means the kind of lazy where you&amp;#8217;ll go to great lengths to avoid doing unecessary work later.&lt;/p&gt;

&lt;p&gt;Sounds a little like automated testing, if you think about it.&lt;/p&gt;

&lt;p&gt;When writing a new app, at first, it&amp;#8217;s almost always easier for me to begin by just banging out code.  How many times have you set up authentication in an application?  Or created a User class or a users table?  Pretty motherhood and apple pie, right?&lt;/p&gt;

&lt;iframe width=&quot;420&quot; height=&quot;345&quot; src=&quot;http://www.youtube.com/embed/j_qQ7WvZ3QM&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;So you&amp;#8217;re writing your code, you think everything&amp;#8217;s fine, everything&amp;#8217;s good.  Then the next thing you know, you&amp;#8217;re on fire!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ahem&lt;/em&gt; Ok, I mean &amp;#8220;you discover that your code base is a flying spaghetti monster&amp;#8221;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://evan.tiggerpalace.com/files/spaghetti_monster.jpeg&quot; style=&quot;width: 50%;&quot;&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;My point is twofold:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;You don&amp;#8217;t miss something until it&amp;#8217;s no longer there.  It is important and reasonable to sometimes avoid writing automated tests.&lt;/strong&gt;&lt;/em&gt;  Now don&amp;#8217;t go and use that as an excuse to your momma if you get busted for it.  Occasionally skipping your automated tests is a healthy way to develop an appreciation for them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Not every piece of code should necessarily be tested.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;BLASPHEMY!&lt;/strong&gt;&lt;/em&gt;  Right?&lt;/p&gt;

&lt;p&gt;Well, not really&amp;#8230;&lt;/p&gt;

&lt;p&gt;Have you ever tested every path in your application?  If you say &amp;#8220;yes&amp;#8221; then that application must have been no larger than a few methods.&lt;/p&gt;

&lt;p&gt;Instead, we pick and choose what to test.  We do it all of the time.&lt;/p&gt;

&lt;p&gt;Typically, most of us write tests for the happy path.  &lt;em&gt;&amp;#8220;What&amp;#8217;s the happy path?&amp;#8221;&lt;/em&gt;, I&amp;#8217;m occasionally asked.  It&amp;#8217;s that magical case when all of your inputs are valid, all of your external dependencies are met, and so everything works as expected.  Everything else is a &amp;#8220;sad path&amp;#8221; a.k.a. &amp;#8220;degenerate&amp;#8221; or &amp;#8220;edge&amp;#8221; case.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;&amp;#8220;What not to test&amp;#8221; is a heuristic that varies from project to project.  Personally, I decide what not to test based on the (1) risk and (2) impact of failure of the particular component/feature.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A couple of anncecdotal examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;ALMOST ALWAYS TEST&lt;/strong&gt;&lt;/em&gt;: Whenever I&amp;#8217;m dealing with currencies, virtual or otherwise, I&amp;#8217;m writing a test.  Few things tick off a user faster than mishandling their money!&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;RARELY TEST&lt;/strong&gt;&lt;/em&gt;: Authentication?  Psh!  I&amp;#8217;ve set up Devise enough times.  For the happy path, it&amp;#8217;s easy!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you&amp;#8217;re not familiar with the basic ideas behind &lt;a href=&quot;http://en.wikipedia.org/wiki/Risk_management&quot;&gt;risk management&lt;/a&gt; (and you&amp;#8217;re too lazy to follow that Wikipedia link), use this rule of thumb: just how confident are you that your code will work?  How bad will it be if it doesn&amp;#8217;t?  Listen to your Jiminy Cricket.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://evan.tiggerpalace.com/files/jiminy_cricket.jpeg&quot;&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;To sum up: not TDDing or writing your tests first is a decision.  If you&amp;#8217;re going to make that decision, do it in an informed way.  Occasionally, writing code without tests serves as a useful touchstone to remind us why we write tests and use TDD.&lt;/p&gt;</description>
          <pubDate>Sun, 04 Sep 2011 07:23:59 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2011/09/04/the-automated-testing-confessional/</guid>
          <link>http://evan.tiggerpalace.com/articles/2011/09/04/the-automated-testing-confessional/</link>
        </item>
    
        <item>
          <title>Getting free</title>
          <description>&lt;p&gt;I often find myself talking with people who are talented but unfulfilled in their career.  I tend to ask them what they love or what frustrates them enough that they&amp;#8217;d love to fix it.  Those are the two ideas that motivate me.  What can I make better or what pisses me off enough that I feel compelled to do something about it.&lt;/p&gt;

&lt;p&gt;The conversation often follows the same route.  The other person has some ideas.  Who doesn&amp;#8217;t?  So I challenge them: I ask them why they&amp;#8217;re not pursuing those ideas already.  I tend to hear something like &amp;#8220;I have a mortgage to pay&amp;#8221;, &amp;#8220;I&amp;#8217;m in too much debt&amp;#8221;, or &amp;#8220;my wife/husband would kill me&amp;#8221;.  What do all of these have in common?&lt;/p&gt;

&lt;p&gt;Most people are extremely attached to their standard of living.&lt;/p&gt;

&lt;p&gt;&amp;#8220;Money is a dissatisfier&amp;#8221;, my father would tell me.  When you don&amp;#8217;t have enough to be comfortable, life is hard.  When you have more than you need to maintain a comfortable standard of living, it is easy to fall prey to the notion that the crap that you buy is essential to your happiness.&lt;/p&gt;

&lt;p&gt;Before I continue, just a little about me.  I was raised in a simple middle class family. My father worked for the government (he&amp;#8217;s retired since) and my mother is a piano teacher.  Admittedly, my parents spoiled me to the extent that they could while I was a youngster.  This probably contributed to my previously poor understanding of the value of money but don&amp;#8217;t tell them that.  They still feel guilty about it sometimes.  But, hey, I turned out OK after all.  I was more fortunate than some: my parents saved for me to attend college. Ultimately, this meant that I exited college without debt.  I always pay my credit card every month, much to the chagrin of credit card companies.  The only loan that I maintain is a modest mortgage.&lt;/p&gt;

&lt;p&gt;Now back to my point.&lt;/p&gt;

&lt;p&gt;Just before my wife and I relocated from Northern Virginia, we had a $450,000 home with a third-acre in Vienna, two cars, several computers, three cats, and a giant television.  But it didn&amp;#8217;t start that way.  That&amp;#8217;s just how we were three years ago.&lt;/p&gt;

&lt;p&gt;When I made my decision to seek fulfillment over income, just over three years ago, I quickly learned that, unlike the US government, the private sector pays according to market forces.  The US government, in its infinite wisdom, generally pigeon holes people into buckets based on years of experience and some other factors, e.g., how many and the specific kinds of acronyms following your name.  Those buckets largely determine your earning potential.&lt;/p&gt;

&lt;p&gt;Leaving the government sector, I had almost no &amp;#8220;portfolio&amp;#8221; to show, just a single tiny OSS project, and no presence in the market.&lt;/p&gt;

&lt;p&gt;This left me with a decision:have a  rewarding job that pays about half  of my cushy government contracting salary or continue on as I was.  I chose the former, took the paycut, and I have not regretted it even for a moment.&lt;/p&gt;

&lt;p&gt;My great epiphany, in my first year of living here in Ocean Pines, MD was this: happiness is not determined by income or material possessions.  I long held to this belief but I didn&amp;#8217;t &lt;strong&gt;&lt;em&gt;understand&lt;/strong&gt;&lt;/em&gt; it, at a gut level, until two years ago.  You probably don&amp;#8217;t grok it either unless you came from a poor upbringing or have had to suddenly put the fiscal belt on much tighter due to circumstances.&lt;/p&gt;

&lt;p&gt;You don&amp;#8217;t need the expensive house. You can probably live somewhere cheaper.  Your debt doesn&amp;#8217;t keep you from saving money.  If you&amp;#8217;re reading this then you&amp;#8217;re probably also self-identify as a &amp;#8220;geek&amp;#8221;, &amp;#8220;nerd&amp;#8221; or similar.  You don&amp;#8217;t need all of that fancy Apple hardware; you can get by on cheaper and use Linux. You don&amp;#8217;t need that iPhone/Android phone with it&amp;#8217;s nearly $100/month plan; a feature phone with a calling card will satisfy most emergency needs.&lt;/p&gt;

&lt;p&gt;Write a list. Decide what is essential.  I mean &lt;strong&gt;&lt;em&gt;absolutely essential&lt;/strong&gt;&lt;/em&gt;.  Then write another list: what possessions will you be unhappy without.  I mean &lt;strong&gt;&lt;em&gt;genuinely unhappy&lt;/strong&gt;&lt;/em&gt;.  Now how much do you need to save each year to feel safe and secure?&lt;/p&gt;

&lt;p&gt;If you got rid of everything else, how much less would you be spending per month?  Congratulations!  You probably just found a way to largely break free of the establishment.&lt;/p&gt;

&lt;p&gt;Given a reasonable intellect, contemporary skills, and a reasonable but modest definition of &amp;#8220;comfort&amp;#8221;, the less money you need to spend.  That means there&amp;#8217;s less money that you need to earn.  Less time spent earning means more time for perhaps the most important of preoccupations: realizing your potential.&lt;/p&gt;</description>
          <pubDate>Sun, 28 Aug 2011 16:52:34 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2011/08/28/getting-free/</guid>
          <link>http://evan.tiggerpalace.com/articles/2011/08/28/getting-free/</link>
        </item>
    
        <item>
          <title>Lone Star Ruby Conf 2011 "More DSL, Less Pain" Presentation Slides</title>
          <description>&lt;p&gt;You can find the slides from my LSRC 2011 presentation &lt;a href=&quot;http://evan.tiggerpalace.com/files/yourdsl.pdf&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;</description>
          <pubDate>Fri, 12 Aug 2011 16:51:49 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2011/08/12/lone-star-ruby-conf-2011-more-dsl-less-pain-presentation-slides/</guid>
          <link>http://evan.tiggerpalace.com/articles/2011/08/12/lone-star-ruby-conf-2011-more-dsl-less-pain-presentation-slides/</link>
        </item>
    
        <item>
          <title>Contemplating performant acceptance testing</title>
          <description>&lt;h1&gt;The symptom&lt;/h1&gt;

&lt;p&gt;Rack app acceptance tests are slow.&lt;/p&gt;

&lt;h1&gt;The problem&lt;/h1&gt;

&lt;p&gt;Acceptance tests add value by exercising the complete system.  In doing so, scenarios within acceptance tests reiterate upon previously tested features of the system.&lt;/p&gt;

&lt;h1&gt;Example&lt;/h1&gt;

&lt;p&gt;This is, perhaps, the most simple example.&lt;/p&gt;

&lt;p&gt;Given an acceptance test that demonstrates the ability for a user to create an account
When I write another feature for user, with an account, to authenticate
Then my new feature&amp;#8217;s acceptance test will require the user to first create an account&lt;/p&gt;

&lt;h2&gt;Explanation&lt;/h2&gt;

&lt;p&gt;Most current acceptance testing practices would have us retread this ground.  This is the essence of why acceptance testing is slow: most Rack app acceptance tests exercise the entire Rack app stack several times.  This is done in order to acrete the desired &amp;#8220;setup&amp;#8221; state within the test to actually &lt;strong&gt;&lt;em&gt;perform the test&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h1&gt;Hypothesis&lt;/h1&gt;

&lt;p&gt;Why don&amp;#8217;t we treat a test suite like a real build process?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Express ordered lists of dependencies between acceptance tests&lt;/li&gt;
&lt;li&gt;Each &lt;strong&gt;&lt;em&gt;successful&lt;/strong&gt;&lt;/em&gt; test records the changes that it made to the database and the HTTP session&lt;/li&gt;
&lt;li&gt;Before executing a given acceptance test, the recorded state changes are played back into the database and http session&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Now&lt;/em&gt; we can acceptance test as normal&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This should allow for acceptance tests to execute a minimal number of trips through the Rack stack.  This would, I hope, increase acceptance test execution time geometrically if not by an order of magnitude on the whole.&lt;/p&gt;

&lt;h1&gt;Your Thoughts?&lt;/h1&gt;

&lt;p&gt;These are just words: a brain dump of an idea that I had in the shower this morning.  I&amp;#8217;d love to see (maybe, OMG, write?) a Rack=specific way to facilitate this that could be used by Coulda, Cucumber, etc.&lt;/p&gt;</description>
          <pubDate>Fri, 12 Aug 2011 09:05:06 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2011/08/12/contemplating-performant-acceptance-testing/</guid>
          <link>http://evan.tiggerpalace.com/articles/2011/08/12/contemplating-performant-acceptance-testing/</link>
        </item>
    
        <item>
          <title>Help me give back</title>
          <description>&lt;p&gt;For those of you who have found any of my blog posts, conference presentations, pairing with me, or rants from me in other contexts to be of value, I need your help.&lt;/p&gt;

&lt;p&gt;I live in Worcester County: perhaps the poorest county in the state of Maryland. The unemployment here is worse than the already depressing national average. &lt;/p&gt;

&lt;p&gt;Sadly, the local educational system emphasizes anemic tech skills. While they recently began offering an online-only Ruby course, they don&amp;#8217;t offer one on their campus. Nor do they offer a Ruby on Rails course. I approached them 3 years ago to allow me to teach a Rails course and was rebuffed.&lt;/p&gt;

&lt;p&gt;This is the year that they&amp;#8217;ll have a Rails course.  I don&amp;#8217;t care if I or someone else teaches it.  Although I don&amp;#8217;t know anyone who does Ruby or Rails within 150 miles of here.  That means that it&amp;#8217;s probably me.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m trying to convince the community college that the economic demand is there. If their prospective students aren&amp;#8217;t asking for the skills then the skills should be marketed better to the students.&lt;/p&gt;

&lt;p&gt;So now I need your help.&lt;/p&gt;

&lt;p&gt;Please let me know if you&amp;#8217;d be willing to act as a reference as I attempt to win the community college over.&lt;/p&gt;

&lt;p&gt;Thanks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UPDATED&lt;/strong&gt;: You can best help by writing a comment on this post about what, when, and where you learned something from me and what you thought of my ability to teach.  Thanks!  The sudden outpouring of support has been as surprising as it is appreciated!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UPDATED2&lt;/strong&gt;: Please do mention a little about yourself as well for context.&lt;/p&gt;</description>
          <pubDate>Sat, 16 Jul 2011 11:44:10 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2011/07/16/help-me-give-back/</guid>
          <link>http://evan.tiggerpalace.com/articles/2011/07/16/help-me-give-back/</link>
        </item>
    
        <item>
          <title>Knowing when (and not) to suggest removing the beans</title>
          <description>&lt;p&gt;Last night, I happened upon &lt;a href=&quot;http://news.ycombinator.com/item?id=2745773&quot;&gt;this delightful article&lt;/a&gt; thanks to Hacker News.  Within it, the author, a consultant not unlike myself, relates a story given him by a mentor.  In it, in short, the storyteller&amp;#8217;s client does what can only be summarized by irationally and willingly &amp;#8220;stepping in it&amp;#8221;.&lt;/p&gt;

&lt;p&gt;From this, the storyteller relates his First Rule of Consulting: &amp;#8220;No matter how much you try, you can’t stop people from sticking beans up their nose.&amp;#8221;  In other words, sometimes otherwise rational people will knowingly and willingly do things that, to you, would seem insane.&lt;/p&gt;

&lt;p&gt;This story stuck with me.  &lt;/p&gt;

&lt;p&gt;You see, I&amp;#8217;ve contracted to the US Federal Government for many years and I&amp;#8217;ve witnessed a lot of fail.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://files.sharenator.com/swat_team_fail_government_army_intel_search_engine_Army_Fails-s425x300-69908.jpg&quot;/&gt;&lt;/p&gt;

&lt;p&gt;But I digress; this article isn&amp;#8217;t about the US Government.  This article is about determining when to give advice.&lt;/p&gt;

&lt;h1&gt;Watching the beans go up&lt;/h1&gt;

&lt;p&gt;While I&amp;#8217;m &amp;#8220;only a consultant&amp;#8221;, I care about my clients.  I hate seeing people stick beans up their nose: it looks damn uncomfortable and its an unfortunate use of some possibly good beans.&lt;/p&gt;

&lt;p&gt;Of course, I&amp;#8217;ll humbly suggest that this may be a poor use of their beans.  However, sometimes the client isn&amp;#8217;t open to advice on the matter.  And, sometimes, they&amp;#8217;re right not to be.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s only fair to admit: I don&amp;#8217;t know everything about my clients.  &lt;a href=&quot;http://www.geraldmweinberg.com/Site/Home.html&quot;&gt;Gerry Weinberg&lt;/a&gt; would probably argue that I shouldn&amp;#8217;t try to.  Even so, while I may see Beans Nose United (a new soccer team?), they may see The Mona Lisa.  And they may be right.&lt;/p&gt;

&lt;p&gt;But this article is about when they&amp;#8217;re not.&lt;/p&gt;

&lt;h1&gt;Planning the intervention&lt;/h1&gt;

&lt;p&gt;The article I cited above suggests asking &amp;#8220;So, how [are those beans in your sinus cavities] working for you? Did [they] do everything you’d hoped?”&lt;/p&gt;

&lt;p&gt;That&amp;#8217;s a fine (and hilarious) start.  It&amp;#8217;s possible that the response may be &amp;#8220;this really REALLY hurts!&amp;#8221; at which point any humane individual would provide Kleenex or refer them to a rhinoplasty surgeon.&lt;/p&gt;

&lt;p&gt;However, most people (and I&amp;#8217;ll include myself here) are reluctant to immediately admit failure.  Maybe tilting our head just so could make our nose hurt less.  Mouth breathing could provide some relief as well.  Now we&amp;#8217;re bargaining.&lt;/p&gt;

&lt;p&gt;The consultant must approach with patience.  A younger, more rash version of myself would rush in (and has before) with something like: &amp;#8220;You have beans up your nose, fer crying out loud!  Blow your nose, dammit!&amp;#8221;  &lt;/p&gt;

&lt;p&gt;This is not a good way to endear yourself to your client.&lt;/p&gt;

&lt;p&gt;With a little age (eventually) came some wisdom.  I&amp;#8217;ve since learned to ask questions instead of leaping to offer advice.  Yes, sometimes even with the calmness of a yoga instructor.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://www.toplessrobot.com/yoda_biography_3.jpg&quot;/&gt;&lt;/p&gt;

&lt;p&gt;(Ok, so a badass yoga instructor)&lt;/p&gt;

&lt;p&gt;And, perhaps a few days or a week later, I&amp;#8217;d ask, &amp;#8220;How is your nose feeling today?&amp;#8221;&lt;/p&gt;

&lt;p&gt;I admit I&amp;#8217;m pretty sure that I know the answer already.  I expect to hear, &amp;#8220;It bloody hurts!&amp;#8221;.  But that may not be the answer that I receive.  And that&amp;#8217;s the two-fold point: (1) Has the client started to accept that they made the wrong decision or (2) do I have the wrong sense of the situation.  If the former, we&amp;#8217;ve found our opening.&lt;/p&gt;

&lt;h1&gt;Intervening&lt;/h1&gt;

&lt;p&gt;This would be a good time to find a private place to further inquire about their nasal discomfort.&lt;/p&gt;

&lt;p&gt;Be gentle!  We&amp;#8217;re dealing with the soft sensitive tissue of the nasal cavities (or, eschewing the metaphor via this aside, our clients feelings/self-image)!  Rushing directly to extract the beans could result in severe trauama!  Don&amp;#8217;t. Reach. For. The. Forceps!!!&lt;/p&gt;

&lt;p&gt;At this point, your client has signaled you that they realize they&amp;#8217;re in a bind.  You&amp;#8217;re finally on the same page.  And, odds are, your client already knows solution.  Now it&amp;#8217;s safe to offer a few gentle suggestions and ask some more probing questions&lt;/p&gt;

&lt;p&gt;Thus begins your journey, hand-in-hand, down the path to a legume-free and more productive client.&lt;/p&gt;</description>
          <pubDate>Sun, 10 Jul 2011 12:09:44 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2011/07/10/knowing-when-and-not-to-suggest-removing-the-beans/</guid>
          <link>http://evan.tiggerpalace.com/articles/2011/07/10/knowing-when-and-not-to-suggest-removing-the-beans/</link>
        </item>
    
        <item>
          <title>Fiddling with Redis sorting</title>
          <description>&lt;p&gt;Nick Quaranto&amp;#8217;s excellent Redis talk at Mountain West Ruby Conference particularly captured my fancy when he demonstrated Redis sort.  An audience member asked whether it was possible to chain the result of gets on a sort.  Redis&amp;#8217; documentation is excellent; however, the &lt;a href=&quot;http://redis.io/commands/sort&quot;&gt;entry on multiple gets in a sort&lt;/a&gt; was just a touch unclear.&lt;/p&gt;

&lt;p&gt;During a break today at MWRC, I through together this quick example.  I&amp;#8217;m also posting it here as someone on Twitter questioned my conclusions (as I do myself).  Provided below:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/875305.js?file=redis_sort_get_chaining.rb&quot;&gt;&lt;/script&gt;</description>
          <pubDate>Thu, 17 Mar 2011 15:52:36 GMT</pubDate>
          <guid>http://evan.tiggerpalace.com/articles/2011/03/17/fiddling-with-redis-sorting/</guid>
          <link>http://evan.tiggerpalace.com/articles/2011/03/17/fiddling-with-redis-sorting/</link>
        </item>
    
    
  </channel>
</rss>


