<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">

  <title><![CDATA[Steven Harman]]></title>
  
  <link href="http://www.stevenharman.net/" />
  <updated>2012-05-16T16:34:06+00:00</updated>
  <id>http://www.stevenharman.net/</id>
  <author>
    <name><![CDATA[Steven Harman]]></name>
    <email><![CDATA[hello@stevenharman.net]]></email>
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/stevenharman" /><feedburner:info uri="stevenharman" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by/2.0/" /><logo>http://creativecommons.org/images/public/somerights20.gif</logo><xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" /><feedburner:emailServiceId>stevenharman</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fstevenharman" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fstevenharman" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2Fstevenharman" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/stevenharman" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fstevenharman" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fstevenharman" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fstevenharman" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://my.feedlounge.com/external/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2Fstevenharman" src="http://static.feedlounge.com/buttons/subscribe_0.gif">Subscribe with FeedLounge</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2Fstevenharman" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><entry>
    <title type="html"><![CDATA[The accepts_nested_attributes_for Un-Solution]]></title>
    <link href="http://www.stevenharman.net/the-accepts_nested_attributes_for-un-solution" />
    <updated>2012-05-15T21:50:00+00:00</updated>
    <id>http://www.stevenharman.net/the-accepts_nested_attributes_for-un-solution</id>
    <content type="html">&lt;p&gt;&lt;img class="right" src="http://www.stevenharman.net/images/posts/merry-go-round.png" title="&amp;#34;merry go round&amp;#34;" alt="&amp;#34;merry go round&amp;#34;"&gt;&lt;/p&gt;

&lt;p&gt;Why does Rails&amp;#8217; &lt;code&gt;accepts_nested_attributes_for&lt;/code&gt; approach always feel so darned
&lt;em&gt;wrong&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;My suspicion is that it feels wrong because it likely is wrong - or at least it
is likely the wrong tool for the job.&lt;/p&gt;

&lt;h3&gt;An example&lt;/h3&gt;

&lt;p&gt;An accounting of a recent ride I took into the &lt;code&gt;accepts_nested_attributes_for&lt;/code&gt;
merry go round.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;In order to create a Message, I have to first create the Conversation it&amp;#8217;s a
part of.&lt;/p&gt;

&lt;p&gt;This sounds like an explicit workflow, so I&amp;#8217;ll model it that way.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8230; hours later &amp;#8230;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;FFFUUU, this is too complicated! There must be an easier, more Rails-y way.&lt;/p&gt;

&lt;p&gt;I know, Conversations can &lt;code&gt;accepts_nested_attributes_for :messages&lt;/code&gt;. Brilliant!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8230; hours later &amp;#8230;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;FFFUUU, this is too complicated! There must be a simpler way.&lt;/p&gt;

&lt;p&gt;I know, rather than shoehorning this into an overly-coupled mess I&amp;#8217;ll model
it as an explicit workflow!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FML&lt;/strong&gt;.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Remember, &lt;a href="http://www.confreaks.com/videos/860-railsconf2012-keynote-simplicity-matters" title="Simplicity Matters."&gt;easy is not the same thing as simple&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;image via: &lt;a href="http://blog.lolitanie.com/index.php/archives/2006/01/29/oh-oh-oh-merry-go-round/"&gt;lolitanie.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=yyCbtNrcAKk:66tEmUGMxf4:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=yyCbtNrcAKk:66tEmUGMxf4:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=yyCbtNrcAKk:66tEmUGMxf4:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=yyCbtNrcAKk:66tEmUGMxf4:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=yyCbtNrcAKk:66tEmUGMxf4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=yyCbtNrcAKk:66tEmUGMxf4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/yyCbtNrcAKk" height="1" width="1"/&gt;</content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[From Testing to Test First to Test Driven]]></title>
    <link href="http://www.stevenharman.net/from-testing-to-test-first-to-test-driven" />
    <updated>2012-05-08T11:16:00+00:00</updated>
    <id>http://www.stevenharman.net/from-testing-to-test-first-to-test-driven</id>
    <content type="html">&lt;p&gt;When I started writing tests, around 2005, I was stoked just to have the tests.&lt;/p&gt;

&lt;p&gt;When I started writing tests first, around 2006, I was excited because I was
&lt;em&gt;Doing The TDD&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;A couple of years later I found that writing tests was getting really painful.
Painful because they were so damn hard to set up, and painful because I had to
wait &lt;em&gt;too damn long&lt;/em&gt; (on the order of 10-15 minutes) for the test suite to
run. I reacted to the pain by changing how I write my tests; I discovered mock
objects. My tests got faster, but they were still painful.&lt;/p&gt;

&lt;h3&gt;A realization&lt;/h3&gt;

&lt;p&gt;In 2008 I was talking with &lt;a href="http://coreyhaines.com/" title="The Software Journeyman"&gt;Corey Haines&lt;/a&gt; about test pain, object
oriented design, and &amp;#8220;listening&amp;#8221; to the former to influence the latter.
&lt;a href="http://scottbellware.com"&gt;Scott Bellware&lt;/a&gt; also contributed much insight, forcing me to really
think about what I hoped to gain from writing tests.&lt;/p&gt;

&lt;p&gt;Those conversations help to crystallized it for me: the root cause of the pain
was not the tests, but the design of the code under test. I had been doing
test-&lt;em&gt;first development&lt;/em&gt;, not test-&lt;strong&gt;driven design&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In the years since I&amp;#8217;ve honed my technique for driving design by listening to
tests and I continue to seek out the ideas and experiences of other
&lt;a href="https://www.destroyallsoftware.com/screencasts" title="Screencasts for Serious Developers"&gt;fast test fanatics&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Ruby and Rails communities have accelerated this path for many. I would
say it&amp;#8217;s not uncommon for new folks to get started where I was in 2005 or
2006. What&amp;#8217;s more exciting is the growing numbers who are starting to feel
some pain in how they test. The next step is to become more aware of that
pain; lower your pain threshold and then make it stop hurting!&lt;/p&gt;

&lt;h3&gt;It&amp;#8217;s a journey&lt;/h3&gt;

&lt;p&gt;It was by no means an overnight endeavour. It literally took years of work for
me to figure this out, and I&amp;#8217;m both happy and proud to say that &lt;em&gt;I&amp;#8217;m still
learning&lt;/em&gt;.  I hope by putting my experience out there yours can be better,
faster, MOAR!&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=JrCkh4qcnzo:2HynrkVxWGM:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=JrCkh4qcnzo:2HynrkVxWGM:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=JrCkh4qcnzo:2HynrkVxWGM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=JrCkh4qcnzo:2HynrkVxWGM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=JrCkh4qcnzo:2HynrkVxWGM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=JrCkh4qcnzo:2HynrkVxWGM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/JrCkh4qcnzo" height="1" width="1"/&gt;</content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Another Git Repository Visualization, Just for Fun.]]></title>
    <link href="http://www.stevenharman.net/another-git-visualization-for-fun" />
    <updated>2011-07-01T21:46:00+00:00</updated>
    <id>http://www.stevenharman.net/another-git-visualization-for-fun</id>
    <content type="html">&lt;p&gt;I’ve created visualizations for Git repositories before – the one tracked a &lt;a href="http://www.stevenharman.net/gain-new-insights-by-visualizing-what-youve-already-got" title="Gain New Insights by Visualizing What You’ve Already Got"&gt;product from its first commit through launch&lt;/a&gt;. And while I still think there is some information and insight to be gleaned from such visualizations, the real reason I like to make them is&amp;#8230; I think they&amp;#8217;re neat.&lt;/p&gt;

&lt;p&gt;To celebrate launching the latest incarnation of &lt;a href="http://versionone.com/" title="VersionOne - it's pronounced Agilé"&gt;VersionOne&lt;/a&gt;, I made another visualization! This one tracks all changes made in our Git repository that occurred between our last major release (in late February) right through the very last commit that made it into the &lt;a href="http://www.versionone.com/release/2011/spring/" title="VersionOne Spring 2011 Release"&gt;Spring 2011 release&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Wow… that really sounded like a sales pitch, didn’t it? I hate sales pitches!&lt;/p&gt;

&lt;p&gt;Enough of that. Enjoy!&lt;/p&gt;

&lt;object width="560" height="315"&gt;&lt;param name="movie" value="http://www.youtube.com/v/fYv9XgzY9Cc?version=3&amp;amp;hl=en_US&amp;amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/fYv9XgzY9Cc?version=3&amp;amp;hl=en_US&amp;amp;rel=0" type="application/x-shockwave-flash" width="560" height="315" allowscriptaccess="always" allowfullscreen="true"&gt;&lt;/embed&gt;&lt;/object&gt;



&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=Tjd0f69Gd74:AGukKG77PB8:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=Tjd0f69Gd74:AGukKG77PB8:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=Tjd0f69Gd74:AGukKG77PB8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=Tjd0f69Gd74:AGukKG77PB8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=Tjd0f69Gd74:AGukKG77PB8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=Tjd0f69Gd74:AGukKG77PB8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/Tjd0f69Gd74" height="1" width="1"/&gt;</content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Git Pull with Automatic Rebase]]></title>
    <link href="http://www.stevenharman.net/git-pull-with-automatic-rebase" />
    <updated>2011-06-09T22:57:00+00:00</updated>
    <id>http://www.stevenharman.net/git-pull-with-automatic-rebase</id>
    <content type="html">&lt;p&gt;To rebase, or not to rebase - for me its not really a question. I
generally prefer a clean, linear commit history. Why? Because merge bubbles make
history confusing, noisy, break &lt;code&gt;git bisect&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://skitch.com/stevenharman/fdhm5/y-u-no-rebase"&gt;&lt;img class="thumbnail right" src="https://img.skitch.com/20110609-jhy91eh42t193wquj6ryi91ura.preview.jpg" title="Y U NO REBASE!?!" alt="y-u-no-rebase"&gt;&lt;/a&gt;
Don&amp;#8217;t believe me? Check out the pretty log to the right. See all
those merge bubbles in there? &lt;em&gt;Eww!&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;The Why?&lt;/h3&gt;


&lt;p&gt;The workflow that caused those merges was as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;git pull&lt;/code&gt; (to bring local up to date)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;hackity-hack&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git commit&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git pull&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git push&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;By default &lt;code&gt;git pull&lt;/code&gt; will fetch any new commits from the remote, and
then merge any local changes in, resulting in the merge bubbles.&lt;/p&gt;

&lt;!-- more --&gt;




&lt;h3&gt;A better approach&lt;/h3&gt;


&lt;p&gt;I typically use the same workflow as above with one tweak. Rather than &lt;code&gt;git
pull&lt;/code&gt; I use &lt;code&gt;git pull --rebase&lt;/code&gt; which will fetch the remote commits,
and rebase your commits on top of the new commits from the remote. This is the
&amp;acirc;&amp;euro;&amp;oelig;re-writing&amp;acirc;&amp;euro; of history folks often talk about.&lt;/p&gt;

&lt;h3&gt;Make it better, automatically!&lt;/h3&gt;


&lt;p&gt;You can tell git to use rebase, rather than merge, in one of two ways, depending on
your situation.&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;Force all new branches to automatically use rebase  &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='line'&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git config branch.autosetuprebase always
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;You can add the &lt;code&gt;--global&lt;/code&gt; switch to have all future branches, in all
repositories on this machine, behave this way.&lt;/p&gt;

&lt;figure class='code'&gt;&lt;figcaption&gt;&lt;span&gt;Force existing branches to use rebase.  &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class="highlight"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line-number'&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='line'&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git config branch.*branch-name*.rebase &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;




&lt;h3&gt;Get more info&lt;/h3&gt;


&lt;p&gt;Be sure to check out the &lt;a title="git-config Manual Page" href=
"http://www.kernel.org/pub/software/scm/git/docs/git-config.html" rel="external"&gt;git
man pages&lt;/a&gt; for more info on what those options mean and when you may or may not want
to use them.&lt;/p&gt;

&lt;p&gt;You might also want to check out my &lt;a title="Git Workflows" href=
"https://github.com/stevenharman/git-workflows" rel="external"&gt;Git Workflows repository
on The GitHubs&lt;/a&gt; where you can find a Keynote presentation (or PDF in the Downloads)
explaining &lt;code&gt;git rebase&lt;/code&gt; vs. &lt;code&gt;git merge&lt;/code&gt; Complete with
pictures!&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=EYmDvp2DyAk:5q2BE-usAJc:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=EYmDvp2DyAk:5q2BE-usAJc:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=EYmDvp2DyAk:5q2BE-usAJc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=EYmDvp2DyAk:5q2BE-usAJc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=EYmDvp2DyAk:5q2BE-usAJc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=EYmDvp2DyAk:5q2BE-usAJc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/EYmDvp2DyAk" height="1" width="1"/&gt;</content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[An Io Language Vim Plugin]]></title>
    <link href="http://www.stevenharman.net/an-io-language-vim-plugin" />
    <updated>2011-02-11T16:27:00+00:00</updated>
    <id>http://www.stevenharman.net/an-io-language-vim-plugin</id>
    <content type="html">&lt;p&gt;Who here doesn&amp;#8217;t enjoy a little color in their life? I know I do, especially when
used to highlight the syntax of a language - as anyone who&amp;#8217;s been around me while
downing a few pints can attest!&lt;/p&gt;

&lt;h3&gt;Learning, Io, and Vim&lt;/h3&gt;


&lt;p&gt;&lt;a href="http://www.stevenharman.net/images/posts/io-syntax.png"&gt;&lt;img class="left" src="http://www.stevenharman.net/images/posts/io-syntax-thumb.png" title="Io Syntax Highlighting in Vim" &gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In an attempt to feed our insatiable desire to learn, a
few of us at &lt;a title="VersionOne: Simplifying Software Delivery" href=
"http://versionone.com" rel="external"&gt;VersionOne&lt;/a&gt; are doing a book club on
&lt;a title="Seven Languages in Seven Weeks: A Pragmatic Guide to Learning Programming Languages"
href=
"http://www.amazon.com/gp/product/193435659X?ie=UTF8&amp;amp;tag=stevenharman-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=193435659X"
rel="external"&gt;Seven Languages in Seven Weeks&lt;/a&gt;. We&amp;#8217;re currently working on chapter
2: &lt;a title="Io Language" href="http://iolanguage.com/" rel="external"&gt;Io&lt;/a&gt;. My
current favorite editor is Vim. I wanted syntax highlighting for Io, in Vim.&lt;/p&gt;

&lt;p&gt;I found a decent Vim script to get Io syntax highlighting, and then wrote a quick
&lt;code&gt;ftdetect&lt;/code&gt; script to set Io-related files to use the Io syntax. The
resulting vim-io plugin is currently embedded &lt;a title="vim-io: Io, for Vim!" href=
"https://github.com/stevenharman/config/tree/master/.vim/bundle/vim-io" rel=
"external"&gt;in my dotfiles on the GitHubs&lt;/a&gt;, but if there&amp;#8217;s interest I can pull them
out into a standalone plugin.&lt;/p&gt;

&lt;p&gt;Grab it, enjoy it, fork and improve it!&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=W0M2IQd65cM:1tjvILACWOA:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=W0M2IQd65cM:1tjvILACWOA:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=W0M2IQd65cM:1tjvILACWOA:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=W0M2IQd65cM:1tjvILACWOA:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=W0M2IQd65cM:1tjvILACWOA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=W0M2IQd65cM:1tjvILACWOA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/W0M2IQd65cM" height="1" width="1"/&gt;</content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Caps Lock is Dumb; Make it Useful]]></title>
    <link href="http://www.stevenharman.net/caps-lock-is-dumb-make-it-useful" />
    <updated>2011-01-20T12:00:00+00:00</updated>
    <id>http://www.stevenharman.net/caps-lock-is-dumb-make-it-useful</id>
    <content type="html">&lt;p&gt;I&amp;#8217;ve long thought that &lt;code&gt;Caps Lock&lt;/code&gt; was quite dumb. Yes, I&amp;#8217;m sure there
is some archaic reason it exists, but the truth is I don&amp;#8217;t care. I don&amp;#8217;t
find it useful and am annoyed that it&amp;#8217;s taking up valuable room on my &lt;a
title="The Home Row and Touch Typing"
href="http://en.wikipedia.org/wiki/Touch_typing" rel="external"&gt;Home
Row&lt;/a&gt;. The more I use Vim the more angry I get at the &lt;code&gt;Caps Lock&lt;/code&gt; key.&lt;/p&gt;

&lt;h3&gt;Making Caps Lock Useful, on The Mac&lt;/h3&gt;

&lt;p&gt;I long ago remapped &lt;code&gt;Caps Lock&lt;/code&gt; to &lt;code&gt;Esc&lt;/code&gt; on my Mac - which worked
great for &lt;a title="the missing editor" href="http://macromates.com/"
rel="external"&gt;TextMate&lt;/a&gt;. However, these days I spend the majority of
my time in &lt;a title="Vim for the Mac"
href="http://code.google.com/p/macvim/" rel="external"&gt;Vim&lt;/a&gt; or &lt;a
title="Zeee Shell" href="http://www.zsh.org/" rel="external"&gt;Zsh&lt;/a&gt; (in
Vim mode) where I&amp;#8217;d much prefer to have &lt;code&gt;Ctrl&lt;/code&gt; on my Home Row.
Remapping &lt;code&gt;Caps Lock&lt;/code&gt; to &lt;code&gt;Ctrl&lt;/code&gt; is trivial on OS X; it&amp;#8217;s baked in
via &lt;em&gt;System Preferences &gt; Keyboard Preferences &gt; Modifier Keys&lt;/em&gt;.&lt;/p&gt;

&lt;!-- more --&gt;


&lt;h3&gt;Making Caps Lock Useful, on The Windows&lt;/h3&gt;

&lt;p&gt;To my knowledge, there is nothing baked into the &lt;acronym
title="Operating System"&gt;OS&lt;/acronym&gt; that makes this easy, but there
are a handful of utilities that will let you remap most keys. I opted
for the Lo-Fi route - hacking the registry to remap &lt;code&gt;Caps Lock&lt;/code&gt; to
&lt;code&gt;Ctrl&lt;/code&gt;.&lt;/p&gt;

&lt;div&gt;&lt;script src='https://gist.github.com/788631.js?file='&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;pre&gt;&lt;code&gt;REGEDIT4
 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
 &amp;quot;Scancode Map&amp;quot;=hex:00,00,00,00,00,00,00,00,02,00,00,00,1d,00,3a,00,00,00,00,00
&lt;/code&gt;&lt;/pre&gt;&lt;/noscript&gt;&lt;/div&gt;


&lt;p&gt;To use it, just download/save the raw &lt;code&gt;.reg&lt;/code&gt; file to your Windows box,
and the run (double-click, whatever) it.&lt;/p&gt;

&lt;p&gt;And there you have it. Good bye, annoying &lt;code&gt;Caps Lock&lt;/code&gt;. Hello, useful
stuff!&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=yM0brZcUTlk:Pdpk64eU_1A:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=yM0brZcUTlk:Pdpk64eU_1A:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=yM0brZcUTlk:Pdpk64eU_1A:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=yM0brZcUTlk:Pdpk64eU_1A:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=yM0brZcUTlk:Pdpk64eU_1A:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=yM0brZcUTlk:Pdpk64eU_1A:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/yM0brZcUTlk" height="1" width="1"/&gt;</content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A First Step to Better User Experience: Thinking Like a Human]]></title>
    <link href="http://www.stevenharman.net/a-first-step-to-better-user-experience-thinking-like-a-human" />
    <updated>2010-12-08T12:18:00+00:00</updated>
    <id>http://www.stevenharman.net/a-first-step-to-better-user-experience-thinking-like-a-human</id>
    <content type="html">&lt;p&gt;As we strive to build more humane user experiences it is important to
not only consider what data to, or &lt;em&gt;not to&lt;/em&gt;, show, but also &lt;em&gt;how&lt;/em&gt; we
present that data.&lt;/p&gt;

&lt;p&gt;An example from our recent &lt;a title="VersionOne: Conversations"
href="http://versionone.com/Product/Collaboration.asp"
rel="external"&gt;Conversations&lt;/a&gt; feature is the date and time at which
portions of a conversation take place.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.stevenharman.net/images/posts/fuzzy-time.png"&gt;&lt;img class="left" src="http://www.stevenharman.net/images/posts/fuzzy-time-thumb.png" title="humate date and time via jquery.timeago" &gt;&lt;/a&gt;
Notice the two highlighted areas. The
tooltip shows fully-formatted, and much more precise information, with
the &amp;#8220;less than a minute ago&amp;#8221; text being a more fuzzy, human-friendly
presentation of the same data.&lt;/p&gt;

&lt;p&gt;There is no question that the precise data is valuable, but when it
comes to human users of a system, it may not be the most consumable
form. The full-fidelity information is still available to the user who
cares to engage the application, when he cares to engage it.&lt;/p&gt;

&lt;p&gt;Whether its fuzzy dates and time, or using avatars instead of user
names, or any number of other examples, the point is to &lt;em&gt;think&lt;/em&gt; about
the human experience when designing for, well, humans.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=XIf-Soxf2lA:LMmgBuvKXp8:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=XIf-Soxf2lA:LMmgBuvKXp8:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=XIf-Soxf2lA:LMmgBuvKXp8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=XIf-Soxf2lA:LMmgBuvKXp8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=XIf-Soxf2lA:LMmgBuvKXp8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=XIf-Soxf2lA:LMmgBuvKXp8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/XIf-Soxf2lA" height="1" width="1"/&gt;</content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A Handful of Git Workflows for the Agilist]]></title>
    <link href="http://www.stevenharman.net/a-handful-of-git-workflows-for-the-agilist" />
    <updated>2010-08-12T12:44:00+00:00</updated>
    <id>http://www.stevenharman.net/a-handful-of-git-workflows-for-the-agilist</id>
    <content type="html">&lt;p&gt;A few months back I gave &lt;a href="http://www.thepathtoagility.org/" title="the path to agility conference"&gt;little talk&lt;/a&gt; on the darling &lt;acronym
title="Source Control Management"&gt;SCM&lt;/acronym&gt; tool of the Open Source
world, &lt;a href="http://git-scm.com/" title="Git: the fast version control system"&gt;Git&lt;/a&gt;. After the conference, the organizers asked for a copy
of the presentation materials I&amp;#8217;d used - something I usually find little
value in as the content of a discussion is far more than just the
collateral used.&lt;/p&gt;

&lt;p&gt;At any rate, I obliged, sent off a PDF, and have &lt;a href="http://github.com/stevenharman/git-workflows" title="a handful of Git workflows for the agilist"&gt;opened the talk up&lt;/a&gt;
for others to use and improve. You can find the source (Keynote
presentation, images, etc.) on GitHub. Fork and modify the talk to your
heart&amp;#8217;s content. ♡&lt;/p&gt;

&lt;p&gt;Oh, and the &lt;a href="http://github.com/stevenharman/git-workflows/downloads" title="download the PDF version"&gt;PDF is there&lt;/a&gt; too.&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=NElrmxeMm24:KHWHeJ6L--U:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=NElrmxeMm24:KHWHeJ6L--U:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=NElrmxeMm24:KHWHeJ6L--U:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=NElrmxeMm24:KHWHeJ6L--U:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=NElrmxeMm24:KHWHeJ6L--U:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=NElrmxeMm24:KHWHeJ6L--U:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/NElrmxeMm24" height="1" width="1"/&gt;</content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Want to Make Money? Make Getting Paid the Easy Part!]]></title>
    <link href="http://www.stevenharman.net/want-to-make-money-make-getting-paid-the-easy-part" />
    <updated>2010-04-07T12:52:00+00:00</updated>
    <id>http://www.stevenharman.net/want-to-make-money-make-getting-paid-the-easy-part</id>
    <content type="html">&lt;p&gt;At least half a dozen times in the past three days I&amp;#8217;ve been so annoyed
by the payment process for various goods and/or services that I either
didn&amp;#8217;t purchase the thing, or had a minor meltdown after the whole
ordeal was over.&lt;/p&gt;

&lt;p&gt;Why do merchants insist on making it so damned difficult for their
customers to get the goods?&lt;/p&gt;

&lt;h3&gt;A few frustrating examples&lt;/h3&gt;

&lt;p&gt;Ever been to a sporting event where the beer vendor only accept cash,
has no cash-register, and yet insists on charging a partial dollar
amount per unit of booze? $6.65 for a beer. Really? Just call it $7
and make the math easy for everyone. Or have a cash register at each
kiosk. Or, here&amp;#8217;s a novel idea, start accepting plastic!&lt;/p&gt;

&lt;p&gt;Need to renew your vehicle registration? Just do it online! But be
prepared to spend an extra $5 for the &lt;em&gt;convenience&lt;/em&gt; of, you knowâ€¦
actually giving them the money now rather than sending a check and them
having to pay someone to physically handle the thing.&lt;/p&gt;

&lt;h3&gt;Two simple rules for making money&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;If you&amp;#8217;re selling something someone wants: &lt;strong&gt;make it easy for them to
give you their money!&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;If you&amp;#8217;re selling something someone does not want: &lt;strong&gt;make them want
it!&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=gc3w3dTutEA:O5ZILyVFajg:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=gc3w3dTutEA:O5ZILyVFajg:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=gc3w3dTutEA:O5ZILyVFajg:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=gc3w3dTutEA:O5ZILyVFajg:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=gc3w3dTutEA:O5ZILyVFajg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=gc3w3dTutEA:O5ZILyVFajg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/gc3w3dTutEA" height="1" width="1"/&gt;</content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Gain New Insights by Visualizing What You’ve Already Got]]></title>
    <link href="http://www.stevenharman.net/gain-new-insights-by-visualizing-what-youve-already-got" />
    <updated>2010-02-24T22:32:00+00:00</updated>
    <id>http://www.stevenharman.net/gain-new-insights-by-visualizing-what-youve-already-got</id>
    <content type="html">&lt;p&gt;I don’t know about you, but I like pretty things. Things that engage me. Shiny things. I enjoy seeing &lt;em&gt;the same old thing&lt;/em&gt; in new and interesting ways. I suppose I’m just a visual kinda’ guy.&lt;/p&gt;

&lt;p&gt;Unfortunately, the desire for visual representation is at odds with the high bandwidth flood of information we’re subjected to these days. Even if we manage to trim the overwhelming flood of information down to a laser-focused stream, it still takes an immense amount of effort to make sense of it.&lt;/p&gt;

&lt;h3&gt;For example&lt;/h3&gt;


&lt;p&gt;For years the primary way we’ve looked at the activity or interaction within various source control management systems is via log files. Yep… plain, text-laden, indecipherable logs chock full of entries each a similitude of it’s predecessors.&lt;/p&gt;

&lt;object width="560" height="315"&gt;&lt;param name="movie" value="http://www.youtube.com/v/S_mMKXFaLaE?version=3&amp;amp;hl=en_US&amp;amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/S_mMKXFaLaE?version=3&amp;amp;hl=en_US&amp;amp;rel=0" type="application/x-shockwave-flash" width="560" height="315" allowscriptaccess="always" allowfullscreen="true"&gt;&lt;/embed&gt;&lt;/object&gt;




&lt;!-- more --&gt;


&lt;p&gt;However, thanks to projects like &lt;a title="Processing" href="http://processing.org/" rel="external"&gt;Processing&lt;/a&gt; there may be a change on the horizon. Using tools of their ilk we can build exciting new ways to &lt;em&gt;see&lt;/em&gt; and consume the vast seas of data we’re drowning in. By visualizing the data we are able to discover new and interesting patterns, behaviors, and insights.&lt;/p&gt;

&lt;h3&gt;An example&lt;/h3&gt;


&lt;p&gt;The video to the right is an example of one such visualization I produced using &lt;a title="Gource - software version control visualization" href="http://code.google.com/p/gource/" rel="external"&gt;Gource&lt;/a&gt; to analyze the Git repository of one of the product’s we’ve build at &lt;a title="VersionOne: Simplifying Software Delivery" href="http://versionone.com/" rel="external"&gt;VersionOne&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For reference, each branch (line) is a different directory containing files. Each leaf (dot) is a file, and different file types (Ruby, JavaScript, C#, etc.) have different colors. Each contributor is represented by their name and Gravatar.  The colored lines that occasionally connect a contributor to a file are color coded to represent adds (green), changes (orange) and deletes (red).&lt;/p&gt;

&lt;p&gt;A few interesting things this visualization leads me to think about are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how much churn happens in various parts of the code base?&lt;/li&gt;
&lt;li&gt;where are we spending time?&lt;/li&gt;
&lt;li&gt;is new-feature work well isolated? (perhaps an indicator of composition)&lt;/li&gt;
&lt;li&gt;are there &lt;em&gt;specialists&lt;/em&gt; within the team?&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Do any interesting things pop to mind when you watch the video? Let me know by leaving a comment.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=CAw-JtzWHas:xb-kLb6__P4:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=CAw-JtzWHas:xb-kLb6__P4:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=CAw-JtzWHas:xb-kLb6__P4:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=CAw-JtzWHas:xb-kLb6__P4:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=CAw-JtzWHas:xb-kLb6__P4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=CAw-JtzWHas:xb-kLb6__P4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/CAw-JtzWHas" height="1" width="1"/&gt;</content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Why Don't We Ask Why?]]></title>
    <link href="http://www.stevenharman.net/why-dont-we-ask-why" />
    <updated>2010-02-18T12:58:00+00:00</updated>
    <id>http://www.stevenharman.net/why-dont-we-ask-why</id>
    <content type="html">&lt;p&gt;Have you ever thought about just how much time we software folk spend
focused on the technologies we&amp;#8217;re using, on implementation minutia,
and on all of the shiny new &lt;em&gt;solutions&lt;/em&gt; we &lt;em&gt;should&lt;/em&gt; be using?&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/marcobellucci/3534516458/" title="photo via: http://www.flickr.com/photos/marcobellucci/3534516458/"&gt;&lt;img class="right" src="http://www.stevenharman.net/images/posts/question-mark.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now contrast that with how often we stop to think about the &lt;strong&gt;Whys&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;Why are we being asked to solve &lt;em&gt;fizz-buzz-thing&lt;/em&gt;; do we understand the
motivation and context behind the problem, or are we fixated on how
we&amp;#8217;ll build the solution? Are we asking why a problem occurred, or are
we merely focused on how we fixed it, this time?&lt;/p&gt;

&lt;h3&gt;Why don&amp;#8217;t we ask &amp;#8220;Why?&amp;#8221;&lt;/h3&gt;

&lt;p&gt;Frankly, because we&amp;#8217;d rather spend our time in the comfortable arena
of &lt;strong&gt;how&lt;/strong&gt; than venture into the sometimes uneasy realm of &lt;strong&gt;why&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;She didn&amp;#8217;t want to know how a thing was done, but why. That can be&lt;br/&gt;embarrassing. You ask *Why* to a lot of things and you wind up&lt;br/&gt;very unhappy indeed, if you keep at it.&lt;br/&gt;- Captain Beatty&lt;/p&gt;&lt;footer&gt;&lt;strong&gt;Ray Bradburry&lt;/strong&gt; &lt;cite&gt;&lt;a href='http://www.amazon.com/dp/0345342968/?tag=stevenharman-20'&gt;Fahrenheit 451&lt;/a&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;




&lt;!-- more --&gt;


&lt;p&gt;Asking why often forces us to face the truth, and that truth can be
uncomfortable. We need to have the courage to face those truths and
coninue to ask why; we must have the &lt;a href="http://en.wikipedia.org/wiki/Extreme_Programming#Values" title="XP Values - Courage"&gt;courage&lt;/a&gt; to pop the why stack.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s only by asking why that we&amp;#8217;ll gain the understanding, insight,
and context necessary to effectively solve the problems we&amp;#8217;re faced
with, to grow, and to improve.&lt;/p&gt;

&lt;p&gt;So, &lt;em&gt;why&lt;/em&gt; are you reading this post? :)&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=mOx7N74tTQ0:Siub3_GnEl4:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=mOx7N74tTQ0:Siub3_GnEl4:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=mOx7N74tTQ0:Siub3_GnEl4:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=mOx7N74tTQ0:Siub3_GnEl4:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=mOx7N74tTQ0:Siub3_GnEl4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=mOx7N74tTQ0:Siub3_GnEl4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/mOx7N74tTQ0" height="1" width="1"/&gt;</content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[YAGNI Ain't What You Thing It Is]]></title>
    <link href="http://www.stevenharman.net/yagni-aint-what-you-think-it-is" />
    <updated>2010-01-07T13:33:00+00:00</updated>
    <id>http://www.stevenharman.net/yagni-aint-what-you-think-it-is</id>
    <content type="html">&lt;p&gt;In the software development vernacular the term &lt;acronym title="You
aren't gonna need it"&gt;YAGNI&lt;/acronym&gt; is often used as a device to put
down attempts at prematurely adding functionality - things which are
only speculatively required. This makes sense given that is basically
the &lt;a href="http://www.xprogramming.com/Practices/PracNotNeed.html" title="You're NOT gonna need it"&gt;definition&lt;/a&gt; that &lt;a href="http://www.xprogramming.com/" title="XProgramming : an Agile Software Development Resource"&gt;Ron Jeffries&lt;/a&gt; and our &lt;acronym
title="eXtreme Programming"&gt;XP&lt;/acronym&gt; forefathers came up with so
long ago.&lt;/p&gt;

&lt;h3&gt;Is that the whole story?&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/z6p6tist6/501709581/" title="photo via: http://www.flickr.com/photos/z6p6tist6/501709581/"&gt;&lt;img class="right" src="http://www.stevenharman.net/images/posts/stop-sign.jpg"&gt;&lt;/a&gt; In short, I don&amp;#8217;t think
so.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve long believed there was more to YAGNI than what had been
canonically defined and was commonly understood. However, until recently
I was never able to put my finger on what was missing.&lt;/p&gt;

&lt;p&gt;While listening to an episode of &lt;a href="http://www.cincomsmalltalk.com/blog/blogView?showComments=true&amp;amp;printTitle=Industry_Misinterpretations_164:_Going_for_the_Longball&amp;amp;entry=3436948975" title="Industry Misinterpretations 164: Going for the Longball"&gt;Industry Misinterpretations&lt;/a&gt; I
heard &lt;a href="http://www.threeriversinstitute.org/Kent%20Beck.htm" title="Kent Beck @ Three Rivers Institute"&gt;Kent Beck&lt;/a&gt; make a subtle point about the need to make progress
being more important than the completeness of the thing you&amp;#8217;re building
at the point you&amp;#8217;re building it.  Lending from this Kent&amp;#8217;s insight and
mixing in much of my own experience, I realized YAGNI is not about
delaying building things until you need them; it&amp;#8217;s that gaining real
experience in the problem domain, while making concrete progress, is
more important than trying to achieve a complete solution &lt;em&gt;right now&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Do you think it&amp;#8217;s too early to update the &lt;a href="http://en.wikipedia.org/wiki/You_ain't_gonna_need_it" title="You ain't gonna need it"&gt;Wikipedia article&lt;/a&gt;?&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=c-ECuwua8PM:gC-2kAzwn1M:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=c-ECuwua8PM:gC-2kAzwn1M:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=c-ECuwua8PM:gC-2kAzwn1M:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=c-ECuwua8PM:gC-2kAzwn1M:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=c-ECuwua8PM:gC-2kAzwn1M:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=c-ECuwua8PM:gC-2kAzwn1M:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/c-ECuwua8PM" height="1" width="1"/&gt;</content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[OMG, Better Rake (for .net)!]]></title>
    <link href="http://www.stevenharman.net/omg-better-rake-for-dot-net" />
    <updated>2009-11-23T13:58:00+00:00</updated>
    <id>http://www.stevenharman.net/omg-better-rake-for-dot-net</id>
    <content type="html">&lt;p&gt;If you ask me, when it comes tools for writing automated build scripts
nothing packs more bang for the buck than &lt;a href="http://rake.rubyforge.org/" title="Rake - Ruby Make"&gt;Rake&lt;/a&gt;. Until recently,
using Rake to build .net solutions required a magic concoction of hacked
together scripts which rarely exhibited Ruby&amp;#8217;s appreciation for beauty
nor Rake&amp;#8217;s spirit of simplicity.&lt;/p&gt;

&lt;p&gt;Luckily our buddy &lt;a rel="met friend"
href="http://www.lostechies.com/blogs/derickbailey/" title="Derick
Bailey's blog"&gt;Derick Bailey&lt;/a&gt; decided it was time to bite the bullet
and start building some &lt;em&gt;&lt;a href="http://www.lostechies.com/blogs/derickbailey/archive/2009/09/17/how-a-net-developer-hacked-out-a-rake-task.aspx" title="How A .NET Developer Hacked Out a Rake Task"&gt;real Rake tasks&lt;/a&gt;&lt;/em&gt; that were special suited
for building .net code. The result is &lt;a href="http://github.com/derickbailey/Albacore" title="Albacore: A Suite Of Rake Build Tasks For .NET Solutions"&gt;Albacore&lt;/a&gt;.&lt;/p&gt;

&lt;!-- more --&gt;


&lt;h3&gt;Using Rake for .net &lt;acronym title="In Real Life"&gt;IRL&lt;/acronym&gt;&lt;/h3&gt;

&lt;p&gt;I&amp;#8217;ve been using Rake to &lt;a href="http://stevenharman.net/blog/archive/2009/05/29/being-lazy-with-rake.aspx" title="Being Lazy with Rake"&gt;be lazy&lt;/a&gt; for a while. And we, the
&lt;a href="http://versionone.com/" title="VersionOne: Simplifying Software Delivery"&gt;VersionOne&lt;/a&gt; dudes &amp;amp; dudettes, have been using it to help automate
our &lt;acronym title="Continuous Integration"&gt;CI&lt;/acronym&gt; builds for over
a year now. And just last week we started ditching much of our
hacky-Rake-script inventory in favor of more concise, tested, and
readable Rake tasks via Albacore.&lt;/p&gt;

&lt;p&gt;During the migration I&amp;#8217;ve run into a few small hitches here and there,
but nothing that I couldn&amp;#8217;t track down, write a test for, and fix
within a couple of &lt;a href="http://www.infoq.com/news/2009/09/Pomodoro" title="Pomodoro - An Agile Approach to Time Management"&gt;tomatoes&lt;/a&gt;. In one case I discovered an issue,
called Derick to confirm, suggested a fix, and had a new Albacore Gem
published within a couple of hours. &lt;em&gt;Hawt!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Albacore already has a decent number of tasks baked in, and the list is
growing all the time!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://wiki.github.com/derickbailey/Albacore/assemblyinfotask"&gt;AssemblyInfoTask&lt;/a&gt; - Generate an AssemblyInfo.cs file.
Currently only supports C#&lt;/li&gt;
&lt;li&gt;&lt;a href="http://wiki.github.com/derickbailey/Albacore/expandtemplatestask"&gt;ExpandTemplatesTask&lt;/a&gt; - expand template files with #{setting}
markers, using YAML configuration files as the data&lt;/li&gt;
&lt;li&gt;&lt;a href="http://wiki.github.com/derickbailey/Albacore/ncoverconsoletask"&gt;NCoverConsoleTask&lt;/a&gt; - Run code coverage analysis through NCover&amp;#8217;s &lt;code&gt;NCover.Console&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://wiki.github.com/derickbailey/Albacore/ncoverreporttask"&gt;NCoverReportTask&lt;/a&gt; - Check code coverage and get detailed
reports through NCover&amp;#8217;s &lt;code&gt;NCover.Reporting&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;NUnitTask - run NUnit test suites&lt;/li&gt;
&lt;li&gt;&lt;a href="http://wiki.github.com/derickbailey/Albacore/msbuildtask"&gt;MSBuildTask&lt;/a&gt; - Build a Visual Studio solution (&lt;code&gt;.sln&lt;/code&gt;) or
MSBuild file&lt;/li&gt;
&lt;li&gt;&lt;a href="http://wiki.github.com/derickbailey/Albacore/renametask"&gt;Rename Task&lt;/a&gt; - Rename a file&lt;/li&gt;
&lt;li&gt;&lt;a href="http://wiki.github.com/derickbailey/Albacore/sftptask"&gt;SftpTask&lt;/a&gt; - Upload a file to a remote server via secure FTP
connection&lt;/li&gt;
&lt;li&gt;&lt;a href="http://wiki.github.com/derickbailey/Albacore/sqlcmdtask"&gt;SQLCmdTask&lt;/a&gt; - Run scripts and other commands through SQL
Server&amp;#8217;s &lt;code&gt;sqlcmd.exe&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://wiki.github.com/derickbailey/Albacore/sshtask"&gt;SshTask&lt;/a&gt; - Run a command on a remote system via a secure
shell connection&lt;/li&gt;
&lt;li&gt;&lt;a href="http://wiki.github.com/derickbailey/Albacore/ziptask"&gt;ZipTask&lt;/a&gt; - Package your build artifacts into a .zip for
easier distribution source data&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Contribute!&lt;/h3&gt;

&lt;p&gt;As we move more and more of our custom stuff over I&amp;#8217;ll continue to add
features to Albacore, enhancing the great work the core team is doing.
In fact, I&amp;#8217;m already planning a &lt;a href="http://github.com/derickbailey/Albacore/issues/#issue/27" title="Albacore::NAntTask - for migrating to Rake"&gt;NAnt task&lt;/a&gt; to help those folks in
the process of migrating from an existing NAnt-based build script to
Rake. Look for it soon!&lt;/p&gt;

&lt;h3&gt;Resources&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://github.com/derickbailey/Albacore" title="Albacore: A Suite of Rake Build Tasks For .Net Solutions"&gt;Albacore on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://wiki.github.com/derickbailey/Albacore" title="Albacore Wiki"&gt;Albacore Wiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://codebetter.com/blogs/david_laribee/archive/2008/08/25/omg-rake.aspx" title="OMG Rake!"&gt;OMG Rake!&lt;/a&gt; - The original post which first inspired many to
use Rake with .net&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=vP0UwcaRI9E:FtVdo87ITxM:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=vP0UwcaRI9E:FtVdo87ITxM:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=vP0UwcaRI9E:FtVdo87ITxM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=vP0UwcaRI9E:FtVdo87ITxM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=vP0UwcaRI9E:FtVdo87ITxM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=vP0UwcaRI9E:FtVdo87ITxM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/vP0UwcaRI9E" height="1" width="1"/&gt;</content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Reading Code is Key to Writing Good Code]]></title>
    <link href="http://www.stevenharman.net/reading-code-is-key-to-writing-good-code" />
    <updated>2009-11-18T14:06:00+00:00</updated>
    <id>http://www.stevenharman.net/reading-code-is-key-to-writing-good-code</id>
    <content type="html">&lt;p&gt;As humans we seem to have an innate desire for structure in our lives. Structure permeates through our societies; it&amp;#8217;s found within our families, education systems, governments, etc. I suppose it&amp;#8217;s no surprise then that we also seek to &lt;em&gt;force&lt;/em&gt; structure upon the work that we, as software developers, do.&lt;/p&gt;

&lt;p&gt;The problem is the work we do isn&amp;#8217;t structured. It is not deterministic. There is no grand blue print, process, nor methodology that we can follow to pay dirt.&lt;/p&gt;

&lt;p&gt;We live in a chaotic and complex world that is itself continuously changing and adapting.&lt;/p&gt;

&lt;p&gt;Software product development is a creative activity taking place in the midst of that complex and adaptive world. So doesn&amp;#8217;t it make sense that we, as software developers, might benefit from admitting that we are indeed doing creative, unstructured, adaptive work? &lt;em&gt;I sure think so!&lt;/em&gt;&lt;/p&gt;

&lt;!-- more --&gt;


&lt;h3&gt;Looking outward for inspiration&lt;/h3&gt;

&lt;p&gt;I&amp;#8217;ve recently been looking outward to other creative professions and trades for inspiration and insights into how they work. One thing I&amp;#8217;ve realized is that those folks spend an immense amount of time studying and seeking inspiration from the work of others both within and outside their own field.&lt;/p&gt;

&lt;p&gt;For example, a musician doesn&amp;#8217;t just sit in his garage all day, banging out albums. He listens to and is influenced by the music of many other musicians. An author doesn&amp;#8217;t simply site down and write manuscript after manuscript. She spends countless hours reading the classics, studying the words, flow, and style of other authors. The same thing goes for painters, actors, architects, etc. And all of these people are constantly immersing them selves in works outside their area; musicians reading Hemingway, singer/song writers studying Salvador Dali, painters listening to Mozart, cats and dogs living together&amp;#8230;&lt;/p&gt;

&lt;p&gt;How arrogant of we programmers then to think that we won&amp;#8217;t, or don&amp;#8217;t, benefit from reading code written by - &lt;em&gt;gasp&lt;/em&gt; - someone else!&lt;/p&gt;

&lt;h3&gt;Read, learn, and be inspired&lt;/h3&gt;

&lt;p&gt;&lt;img class="right" src="http://www.stevenharman.net/images/posts/text.jpg" title="Yay for reading!" &gt;
In my experience we spend a great deal more time reading code than actually &lt;em&gt;writing&lt;/em&gt; it. Whether it be the code you wrote just a few minutes ago or something you&amp;#8217;ve inherited and are now maintaining, you&amp;#8217;re reading it. Of course, that&amp;#8217;s only considering the motive of reading code because you&amp;#8217;re currently working with.&lt;/p&gt;

&lt;p&gt;The greatest motivator for reading code is the opportunity it provides for learning and serving as a source of inspiration. Reading code exposes you to techniques, view points, styles, idioms, and algorithms that you may not have otherwise come across.&lt;/p&gt;

&lt;p&gt;In my own career it was by reading code written in Ruby that I first started to develop an appreciation for beauty and aesthetics in code. It also opened me to new ways of thinking about problems and exposed many pains and frictions with the techniques I had been using to that point.&lt;/p&gt;

&lt;h3&gt;Where to start?&lt;/h3&gt;

&lt;p&gt;I realize it&amp;#8217;s probably obvious, but I&amp;#8217;m going to say it anyhow - a great way to start reading other&amp;#8217;s code is to pull down an Open Source project and dive in. Of course, that&amp;#8217;s not to say that all Open Source code bases are necessarily examples of great code&amp;#8217; so you might also want to leverage your network to find examples. Or, use your Google-fu to see what others are reading. Or maybe check out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://katas.softwarecraftsmanship.org/" title="Software Craftsmanship - Katas"&gt;Katacasts&lt;/a&gt; by &lt;a title="Corey Haines" href="http://www.coreyhaines.com/" rel="friend met"&gt;Corey Haines&lt;/a&gt; and Chris Parsons&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.hanselman.com/blog/CategoryView.aspx?category=Source+Code"&gt;The Weekly Source Code&lt;/a&gt; series by &lt;a title="Scott Hanselman's Computer Zen" href="http://www.hanselman.com" rel="colleague met"&gt;Scott Hanselman&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=0To4JveBVh0:sfFmURmtT9w:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=0To4JveBVh0:sfFmURmtT9w:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=0To4JveBVh0:sfFmURmtT9w:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=0To4JveBVh0:sfFmURmtT9w:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=0To4JveBVh0:sfFmURmtT9w:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=0To4JveBVh0:sfFmURmtT9w:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/0To4JveBVh0" height="1" width="1"/&gt;</content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Prefer Dependency Injection to Service Location]]></title>
    <link href="http://www.stevenharman.net/prefer-dependency-injection-to-service-location" />
    <updated>2009-09-25T14:17:00+00:00</updated>
    <id>http://www.stevenharman.net/prefer-dependency-injection-to-service-location</id>
    <content type="html">&lt;p&gt;There is currently a thread running over in the StructureMap Users mailing list asking &lt;a href="http://groups.google.com/group/structuremap-users/browse_thread/thread/2ee1a7eab03d7f2a"&gt;if we really need constructor injection&lt;/a&gt; when using an Inversion of Control container. Before any one rips off on a rant let me say that I worked with &lt;a title="JonKruger.com" href="http://www.jonkruger.com/" rel="friend met co-worker"&gt;Jon&lt;/a&gt; in my former life and I&amp;#8217;m fairly certain he&amp;#8217;s merely conducting a thought experiment, trying to sure up his own beliefs. A worthwhile exercise, if you ask me.&lt;/p&gt;

&lt;p&gt;At any rate, I have a few points I wanted to throw out there; most of them basic and mere reiterations of the words of others, but I&amp;#8217;m gong to do it anyhow!&lt;/p&gt;

&lt;!-- more --&gt;


&lt;h3&gt;The question at hand&lt;/h3&gt;

&lt;p&gt;I would encourage you to go read the full thread (it&amp;#8217;s a quick read&amp;#8230; 4 minutes, tops!), but knowing many of you are lazy like me, I&amp;#8217;ll reprint Jon&amp;#8217;s original question here.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Again, please go read the full thread so you have the full context.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Whenever I tell people about StructureMap (or using &lt;acronym title="Dependency Injection"&gt;DI&lt;/acronym&gt; in general), I mention that two of the benefits are that (a) StructureMap will create objects and all their dependencies for you and (b) it enables you to fake out the dependencies in a test.&lt;/p&gt;&lt;p&gt;Why do we need constructor injection to do this?  I can call `ObjectFactory.GetInstance()` anytime I want and it will work.  And I could leave SM configured for my tests and call `ObjectFactory.Inject()` to stub things out.&lt;/p&gt;&lt;p&gt;So theoretically, I wouldn&amp;#8217;t even need constructor injection, right?&lt;/p&gt;&lt;footer&gt;&lt;strong&gt;Jon Kruger&lt;/strong&gt; &lt;cite&gt;&lt;a href='http://groups.google.com/group/structuremap-users/browse_thread/thread/2ee1a7eab03d7f2a'&gt;StructureMap ML_&lt;/a&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;


&lt;h3&gt;Let&amp;#8217;s get the jargon down&lt;/h3&gt;

&lt;p&gt;To be clear, Jon proposing using &lt;a href="http://martinfowler.com/articles/injection.html#UsingAServiceLocator" title="Using a Service Locator"&gt;Service Location&lt;/a&gt; rather than &lt;a href="http://en.wikipedia.org/wiki/Dependency_injection" title="Dependency Injection"&gt;Dependency Injection&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;While Service location is better than &lt;a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/07/03/how-not-to-do-dependency-injection-in-nerddinner.aspx"&gt;poor-man&amp;#8217;s DI&lt;/a&gt;, using it as suggested above is still introducing a high degree of coupling as all of these classes now have an opaque and highly concrete dependency on the container. This is effectively creating a new form of &lt;code&gt;Global&lt;/code&gt;. &lt;em&gt;Eww!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The key to using Service Location within &lt;strong&gt;new code&lt;/strong&gt; is to keep it tucked away in the deepest, darkest corners of your infrastructure. For example, if you&amp;#8217;re building something on the asp.net mvc stack, you might use Service Location within a custom &lt;code&gt;IControllerFactory&lt;/code&gt; to create each of your controllers.&lt;/p&gt;

&lt;p&gt;If you&amp;#8217;re dealing with &lt;strong&gt;legacy code&lt;/strong&gt;, full of concrete dependencies, you might use Service Location as technique for teasing things apart with a goal of decreased hard coupling. In the end this may result in wholesale replacement of some modules.&lt;/p&gt;

&lt;p&gt;When it comes to Dependency Injection and dependencies in general, I agree with &lt;a href="http://blog.scottbellware.com/" rel="friend met"&gt;Scott Bellware&amp;#8217;s&lt;/a&gt; point of view; make your &lt;a href="http://codebetter.com/blogs/scott.bellware/archive/2007/06/28/164867.aspx" title="Dependency Patterns: Optional Dependencies and Primal Dependencies"&gt;dependencies explicit &amp;amp; transparent&lt;/a&gt; by requiring them in the constructor. My gut reaction is also to avoid translucent (setter-injected) dependencies as they make it harder to tell what dependencies an object will need to do its job - the shape of the object isn&amp;#8217;t as clear as with explicit constructor dependencies.&lt;/p&gt;

&lt;h3&gt;Feeling the friction&lt;/h3&gt;

&lt;p&gt;I tend to be lazy and prefer to feel friction of poor design early so I can change direction quickly. For example, when a constructor gets too large it&amp;#8217;s a signal to stop and consider &lt;a href="http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod" title="Uncle Bob's Principles of Object Oriented Design"&gt;Single Responsibility Principle, Separation of Concerns, etc&lt;/a&gt;. In a similar vein, I don&amp;#8217;t usually advocate use of an &lt;a href="http://www.lostechies.com/blogs/joshuaflanagan/archive/2009/02/03/auto-mocking-explained.aspx" title="Auto-mocking Explained"&gt;auto-mocking container&lt;/a&gt;. Or at least not for folks who&amp;#8217;ve not yet acquired a strong nose for design and simplicity; the friction helps keep you on the rails.&lt;/p&gt;

&lt;p&gt;Later in the tread Jon mentions some friction he&amp;#8217;s been feeling when setting up the &lt;a href="http://stevenharman.net/blog/archive/2009/05/27/toward-a-better-use-of-context-specification.aspx" title="Toward a Better Use of Context/Specification"&gt;context&lt;/a&gt; of his tests (or specs). Namely he&amp;#8217;s having to set up and inject a lot of concrete objects for interaction within his unit tests. To me this is an indication that those tests may actually be integration tests. After all, they are flexing the integration of a several modules in concert, right?&lt;/p&gt;

&lt;p&gt;I say, call them what they are, fire up the fully configured container, and move on.&lt;/p&gt;

&lt;p&gt;I prefer to make the implicit explicit, to be able easily see the shape of an object, and in getting forced feedback when my design starts to slip off the rails.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=SKMk2TjGiLc:fRSPNvOoaj8:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=SKMk2TjGiLc:fRSPNvOoaj8:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=SKMk2TjGiLc:fRSPNvOoaj8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=SKMk2TjGiLc:fRSPNvOoaj8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=SKMk2TjGiLc:fRSPNvOoaj8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=SKMk2TjGiLc:fRSPNvOoaj8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/SKMk2TjGiLc" height="1" width="1"/&gt;</content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How-To: Ctrl + Alt + Del in Remote Desktop]]></title>
    <link href="http://www.stevenharman.net/how-to-ctrl--alt--del-in-remote-desktop" />
    <updated>2007-08-29T12:11:00+00:00</updated>
    <id>http://www.stevenharman.net/how-to-ctrl–alt–del-in-remote-desktop</id>
    <content type="html">&lt;p&gt;I’m a fan of &lt;a href="http://en.wikipedia.org/wiki/Remote_Desktop_Protocol" title="Remote Desktop Protocol"&gt;Microsoft’s Remote Desktop&lt;/a&gt;; it’s built into
Windows and allows me to quickly and easily administer a remote box from
the comfort of my own work station. I use it at my house to administer
the headless servers on my home network, the &lt;a href="http://subtextproject.com" title="Subtext Project"&gt;Subtext&lt;/a&gt; build
server, and the co-located &lt;a href="http://veloc-it.com" title="VelocIT - We Deliver IT"&gt;VelocIT&lt;/a&gt; servers.&lt;/p&gt;

&lt;h3&gt;Gotta’ love that magic!&lt;/h3&gt;

&lt;p&gt;&lt;img class="left" src="http://www.stevenharman.net/images/posts/virtual-pc-ctrl-alt-del.png" title="&amp;#34;Ctrl + Alt + Del in Virtual PC&amp;#34;" alt="&amp;#34;Ctrl + Alt + Del in Virtual PC&amp;#34;"&gt;&lt;/p&gt;

&lt;p&gt;Today a &lt;a href="http://www.micahdylan.com/" title="Micah Dylan"&gt;co-worker&lt;/a&gt; asked me how to send the infamous &lt;code&gt;Control + Alt +
Delete&lt;/code&gt; keystroke combination to a machine he was working on via &lt;abbr
title="Remote Display (or Desktop) Protocol"&gt;RDP&lt;/abbr&gt;. This is a pretty
common keystroke to use when trying administer windows… it does have uses other
than just killing the box.&lt;/p&gt;

&lt;p&gt;With &lt;a href="http://www.microsoft.com/windows/products/winfamily/virtualpc/" title="Microsoft Virtual PC"&gt;Virtual PC&lt;/a&gt; there is menu item to send the keystrokes on to the
virtual box. Go to the &lt;em&gt;Action&lt;/em&gt; menu and select the &lt;code&gt;Ctrl + Alt + Del&lt;/code&gt;
option.&lt;/p&gt;

&lt;h3&gt;And with Remote Desktop?&lt;/h3&gt;

&lt;p&gt;&lt;img class="right" src="http://www.stevenharman.net/images/posts/ctrl-alt-del.gif" title="&amp;#34;The only keyboard you'll ever need&amp;#34;" alt="&amp;#34;The only keyboard you'll ever need&amp;#34;"&gt;&lt;/p&gt;

&lt;p&gt;Well it’s not quite as obvious. Actually it’s not an obvious solution at all…
hell it might not even be documented!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For the record, since I already knew the answer I decided to be lazy
and didn’t bother to search the tubes for any official documentation.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To send the &lt;code&gt;Ctrl + Alt + Del&lt;/code&gt; keystroke combination via RDP you actually need
to use&amp;#8230;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Ctrl + Alt + End&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;WTF? &lt;em&gt;That&lt;/em&gt; sure is intuitive!&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=fFATJxzzxx4:GVHNAywBEsE:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=fFATJxzzxx4:GVHNAywBEsE:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=fFATJxzzxx4:GVHNAywBEsE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=fFATJxzzxx4:GVHNAywBEsE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/stevenharman?a=fFATJxzzxx4:GVHNAywBEsE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/stevenharman?i=fFATJxzzxx4:GVHNAywBEsE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/stevenharman/~4/fFATJxzzxx4" height="1" width="1"/&gt;</content>
  </entry>
  
</feed>

