<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jeff Perrin</title>
	<atom:link href="http://jeffperrin.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://jeffperrin.com</link>
	<description>Jump the Fence or Walk Around</description>
	<lastBuildDate>Wed, 30 Dec 2009 16:11:57 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>On Winter Bike Commuting in Calgary</title>
		<link>http://jeffperrin.com/2009/12/30/on-winter-bike-commuting-in-calgary/</link>
		<comments>http://jeffperrin.com/2009/12/30/on-winter-bike-commuting-in-calgary/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 16:11:57 +0000</pubDate>
		<dc:creator>Jeff Perrin</dc:creator>
				<category><![CDATA[cycling]]></category>

		<guid isPermaLink="false">http://jeffperrin.com/?p=216</guid>
		<description><![CDATA[I started riding to work in the winter months last year, mainly because I was enjoying it so much in the spring/summer/fall that I figured it had to be fun in the winter as well. A few lessons were learned that I&#8217;m now trying to apply to this season.
If you can ski in it, you [...]]]></description>
			<content:encoded><![CDATA[<p>I started riding to work in the winter months last year, mainly because I was enjoying it so much in the spring/summer/fall that I figured it had to be fun in the winter as well. A few lessons were learned that I&#8217;m now trying to apply to this season.</p>
<h3>If you can ski in it, you can ride in it</h3>
<p>People give you strange looks when you tell them you rode in to work on your bicycle when it&#8217;s -10 degrees celsius outside. But these same people don&#8217;t think it&#8217;s odd to head out to the ski hill in the same weather, bundle up, sit on a cold chair suspended 50 feet above the ground for 15 minutes, race down a snowy hill at high speed, rinse, repeat. All the same rules regarding layering, clothing materials and equipment that help keep a downhill skier comfortable in low temperatures also apply while biking in the city. If anything, biking is easier due to the fact that you&#8217;re always moving. By the time I get to work (a 12km ride) I&#8217;m always hot &amp; sweaty, regardless of the outside temperature.</p>
<h3>Studs are your bestest friend ever</h3>
<p>Last year I commuted in the winter on a mountain bike with studded tires (<a href="http://www.schwalbetires.com/node/1368">Schwalbe Snow Studs</a>, if you must know). These are what I&#8217;ll call &#8220;half-assing it&#8221; as far as studded tires are concerned. The Snow Studs have two rows of carbide studs that aren&#8217;t always touching the ground (this is by design). The end result for me was a few wipe outs, and a lot of dainty route-choosing ballet. One morning while attempting to negotiate a particularly icy section of path (behind Rocky View Hospital) I was passed by a guy riding on <em>real</em> studded tires like I was standing still and he didn&#8217;t even notice there was ice on the ground. Lesson learned. This year I&#8217;ve resolved to upgrade to some <a href="http://www.schwalbetires.com/marathon_winter">Schwalbe Marathon Winters</a>, which are a little more serious as far as stud count is concerned.</p>
<h3>Some maintenance may be required</h3>
<p>With all the crap that gets on the road in the winter months, it&#8217;s no surprise that some of it ends up on your bike. If I didn&#8217;t clean the bike off after at least every couple of rides I&#8217;d have a seized up chain and poorly performing derailleurs on my hands. Now, I have nothing against cleaning, but doing it in your garage in the winter cold is really shitty.</p>
<h3>Big hills don&#8217;t mix well with icy brakes</h3>
<p>My mountain bike had a set of &#8220;standard&#8221; rim brakes, just like most 10 year old $500 bikes do. These were more than enough in the summer, but get a little ice and snow on your rims and suddenly big fast downhills aren&#8217;t so much fun.</p>
<h3>So what did I do about it?</h3>
<p>I tried to address every one of these issues in one form or another:</p>
<ul>
<li>I got some new shoes (<a href="http://www.mec.ca/Products/product_detail.jsp?PRODUCT&lt;&gt;prd_id=845524442622974&amp;FOLDER&lt;&gt;folder_id=2534374302692667&amp;bmUID=1262187857618">Five Ten Impacts</a>) which help to keep the feet warm and with grip on icy pathways.</li>
<li>I&#8217;ve been collecting <a href="http://www.icebreaker.com/site/index.html">Icebreaker</a> merino wool clothing to wear during the ride. This stuff is not only warm, but it <em>does not stink</em>. Ever. It&#8217;s ridiculous how much this stuff doesn&#8217;t stink. Well worth the price, Icebreaker clothing has supplanted Patagonia base layers for me.</li>
<li>Cheap ski goggles should help keep my face warm. I got a pair of cheap $20 goggles with clear lenses for when it&#8217;s dark out.</li>
<li><a href="http://www.schwalbetires.com/marathon_winter">Schwalbe Marathon Winters</a> are at the bike shop ready to be picked up. I got a pair of 700c 35mms.</li>
<li>As for the rest of the issues&#8230; I hope to have solved them with the <a href="http://www.trekbikes.com/us/en/bikes/urban/soho/soho/">Trek Soho</a>:<img class="alignnone size-full wp-image-219" title="Trek Soho" src="http://jeffperrin.com/wp-content/uploads/2009/12/TrekSoho.jpg" alt="Trek Soho" width="500" height="325" />This bike has all the attributes I was looking for in a winter bike: Roller brakes and internal 8-speed hub are basically sealed to the elements, so there shouldn&#8217;t be any degradation in performance due to winter conditions. The more upright position and flat platform pedals should make me nice and stable, yet able to safely bail if things get sketchy. Plus it comes with fenders, a coffee mug, and has mounts for my <a href="http://www.topeak.com/products/Racks">Topeak rack</a>. If it holds up well, it looks like the perfect bike (my fingers are crossed).</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://jeffperrin.com/2009/12/30/on-winter-bike-commuting-in-calgary/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Development Methodology &#8220;Renovation&#8221;</title>
		<link>http://jeffperrin.com/2009/10/31/development-methodology-renovation/</link>
		<comments>http://jeffperrin.com/2009/10/31/development-methodology-renovation/#comments</comments>
		<pubDate>Sun, 01 Nov 2009 00:14:43 +0000</pubDate>
		<dc:creator>Jeff Perrin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jeffperrin.com/?p=210</guid>
		<description><![CDATA[I was watching Holmes on Homes today and got to thinking about parallels (or lack of them) between renovating and building a home vs developing a software application. Some of what I was thinking ties in with the &#8220;software development as craftsmanship&#8221; discussion that pops up every now and then, but mainly this is just [...]]]></description>
			<content:encoded><![CDATA[<p>I was watching <a href="http://en.wikipedia.org/wiki/Holmes_on_Homes">Holmes on Homes</a> today and got to thinking about parallels (or lack of them) between renovating and building a home vs developing a software application. Some of what I was thinking ties in with the &#8220;<a href="http://www.infoq.com/presentations/craftmanship-ethics">software development as craftsmanship</a>&#8221; discussion that pops up every now and then, but mainly this is just a brain dump.</p>
<p>First off, let&#8217;s set this up. What I&#8217;m thinking is that a &#8220;software application&#8221; maps directly to a &#8220;home renovation project&#8221; or just actually building a new home. Here are some of the obvious parallels:</p>
<ul>
<li>In a home building project you have a general contractor who oversees the entire operation, hiring other contractors or bringing in employees as needed. Software projects will generally have some sort of equivalent &#8220;lead/architect&#8221; role.</li>
<li>Both projects would have clients that most likely have no idea what&#8217;s going on. They see the end result and have no way of knowing whether that result will last 2 months or 2o years. Generally, as long as the finished product looks pretty and seems to do what&#8217;s required the developers/renovators will get paid.</li>
<li>Size matters in both professions. Anybody can hack their way through installing new countertops or building a simple CRUD web app, but the bigger and more complex the problem gets, the more professionalism and care is required. I&#8217;ll take a calculated leap and say that many of the problem projects in both professions happen because somebody who can &#8220;install a new faucet&#8221; gets it in their heads that they can also &#8220;renovate the entire basement&#8221; using the same amount of knowledge and preparation.</li>
</ul>
<p>I&#8217;m sure there&#8217;s a few more parallels, but you get the idea. Now let&#8217;s focus on some differences&#8230;</p>
<ul>
<li>A general contractor doing a home renovation will bring in &#8220;specialists&#8221; to work on individual pieces of the project, whereas many software projects are made up of &#8220;generalists&#8221;. As programmers, we are often tasked with developing business logic, writing html, security, usability, system administration, deployment, testing, etc. Just look at the range of what&#8217;s required in the average job posting for a software developer. This is obviously not true in all cases, but in general this is what I think is happening out there.</li>
<li>The home building industry has these crazy things called &#8220;inspections&#8221; that are supposed to ensure the builders don&#8217;t pull some crazy shit that could endanger the client. Imagine code inspections (by an honest inspector we hope) and how they could protect a client&#8230; An inspector could obviously not be expected to know if the application is running a calculation correctly, but that is the <em>one </em>thing that a client <em>can </em>confirm. An inspector could, however, check for <em>signs of incompetence</em> such as SQL injection vulnerabilities, obvious spaghetti code, code duplication, lack of tests, poorly designed databases, mangled HTML, obvious usability disasters and so on. Once notified of the issues, the client would be able to take action as they see fit.</li>
</ul>
<p>My thinking is that, at least in my own experience, the best project I&#8217;ve worked on (in terms of happiness of the client and its likelihood of being maintainable for years to come) was the project that was most similar to a successful home reno project. We had a UI specialist, a bunch of developers focused mainly on the business logic, and testers. Other &#8220;specialists&#8221; were brought in as needed for database tuning and system admin type work. An &#8220;inspector&#8221; even came to the project at one stage. This inspector was <a href="http://blog.sym-link.com/">Eric Evans</a>, who showed up and observed the project for a week and delivered a report on what was good and what could be improved. This visit seemed to be largely positive (I showed up a few months after he came so I can&#8217;t know for sure) in the sense that it gave the development team some reassurance and some focus on what could be improved. I&#8217;m not sure what the clients got out of it.</p>
<p>I&#8217;m wondering if a working on a new project with the goal of running it consciously more like a home reno project could improve things. For example:</p>
<ul>
<li>Think of hiring for &#8220;concerns&#8221; instead of technologies (ie; security &amp; usability instead of Java &amp; Struts).</li>
<li>Have a defined &#8220;general contractor&#8221; role that is in place to hire and fit all the pieces together.</li>
<li>Allow the specialists to come and go. There&#8217;s no need to keep everyone around all the time. Call them in when there is a need.</li>
</ul>
<p>Based on my own limited experience I think doing software development as a home renovation could really work, especially when it comes to focusing on roles and quality. Should <em>any </em>project be open to an SQL injection attack ever? Hell no, there&#8217;s just no excuse for that kind of incompetence. But so many are&#8230; Inspections and specialists might be one way to mitigate this.</p>
<p>In closing, I&#8217;d like to hear other people&#8217;s thoughts on this. If it&#8217;s already been said before (better hopefully), I&#8217;d like to read more about it.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffperrin.com/2009/10/31/development-methodology-renovation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Snippets</title>
		<link>http://jeffperrin.com/2009/07/09/snippets/</link>
		<comments>http://jeffperrin.com/2009/07/09/snippets/#comments</comments>
		<pubDate>Fri, 10 Jul 2009 01:31:24 +0000</pubDate>
		<dc:creator>Jeff Perrin</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://jeffperrin.com/?p=204</guid>
		<description><![CDATA[After a spirited bout with rubygems&#8230; I have these:

gem list -d gem_name
gem uninstall --install-dir ~/.gem/ruby/1.8 gem_name -a

The first one describes a gem, including the location in which each version is installed. The second will uninstall all versions of a gem from the specified location.
I fought hard for those.
]]></description>
			<content:encoded><![CDATA[<p>After a spirited bout with rubygems&#8230; I have these:</p>
<pre>
gem list -d gem_name
gem uninstall --install-dir ~/.gem/ruby/1.8 gem_name -a
</pre>
<p>The first one describes a gem, including the <em>location in which each version is installed</em>. The second will uninstall all versions of a gem from the specified location.</p>
<p>I fought hard for those.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffperrin.com/2009/07/09/snippets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Object Mother Testing Pattern in Rails</title>
		<link>http://jeffperrin.com/2009/07/08/object-mother-testing-pattern-in-rails/</link>
		<comments>http://jeffperrin.com/2009/07/08/object-mother-testing-pattern-in-rails/#comments</comments>
		<pubDate>Thu, 09 Jul 2009 03:21:40 +0000</pubDate>
		<dc:creator>Jeff Perrin</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://jeffperrin.com/?p=197</guid>
		<description><![CDATA[Over the years I was working in Java at CGI, I became used to the Object Mother pattern of test setup. Despite the fact that it can break down when objects and their relationships get complicated, it is something that works quite well on smaller projects. At CGI we implemented it like this:

One factory per [...]]]></description>
			<content:encoded><![CDATA[<p>Over the years I was working in Java at CGI, I became used to the <a href="http://martinfowler.com/bliki/ObjectMother.html">Object Mother</a> pattern of test setup. Despite the fact that it can break down when objects and their relationships get complicated, it is something that works quite well on smaller projects. At CGI we implemented it like this:</p>
<ul>
<li>One factory per type of object being created</li>
<li>Each factory has a <em>createNewValid</em> method that creates a valid object that can be saved to the database. This method does not persist the object.</li>
<li>Each factory also has a <em>createAnonymous</em> method that calls <em>createNewValid</em> and then saves the object.</li>
</ul>
<p>Rails has a number of plugins that do something similar, but <a href="http://github.com/flogic/object_daddy/tree/master">object_daddy</a> is the closest to what I was looking for. It follows the same pattern, calling the creation methods <em>spawn</em> and <em>generate</em> instead. It also allows you to customize the look of a valid object by letting you pass in a block that can modify the object&#8217;s state. This eliminates a <em>huge</em> problem with our implementation at CGI, where we had hundreds of slightly different <em>createNewValid</em> and <em>createAnonymous</em> methods depending on the scenario we were trying to set up.</p>
<p>Unfortunately I had a couple of problems with object_daddy. The first is that the <em>generate</em> method saves the object <em>before</em> it yields to a passed in block. Thus, when you call <em>User.generate { |u| u.name = &#8216;Fred&#8217; }</em> you get an object with a name of Fred, but that name is <em>not</em> yet persisted. That was a minor issue, though.</p>
<p>I also had a problem when I tried creating multiple objects with object_daddy within the same setup. I would get an error stating that attributes had already been added for a class, and couldn&#8217;t figure out what the heck was going on. It could be just me (probably is), but I found the source code very hard to follow for something that should be pretty simple. Since I&#8217;m new to Ruby, I figured I&#8217;d just try doing it myself from scratch and maybe learn something in the process.</p>
<p>Enter <a href="http://github.com/jeffperrin/object_mother/tree/master">object_mother</a>. Right now it&#8217;s just about as basic as can be. I can think of numerous ways to improve it, but for now I&#8217;m pretty happy. Here&#8217;s the source in it&#8217;s entirety:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">module</span> ObjectMother
  <span style="color:#9966CC; font-weight:bold;">class</span> Factory
    @@index = <span style="color:#006666;">0</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">spawn</span>
      <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#996600;">'No create method specified'</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">populate</span><span style="color:#006600; font-weight:bold;">&#40;</span>model<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#996600;">'No populate method specified for '</span> <span style="color:#006600; font-weight:bold;">+</span> model.<span style="color:#9900CC;">to_s</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">to_hash</span><span style="color:#006600; font-weight:bold;">&#40;</span>model<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#996600;">'No to_hash method specified'</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">unique</span><span style="color:#006600; font-weight:bold;">&#40;</span>val<span style="color:#006600; font-weight:bold;">&#41;</span>
      @@index <span style="color:#006600; font-weight:bold;">+</span>= <span style="color:#006666;">1</span>
      val.<span style="color:#9900CC;">to_s</span> <span style="color:#006600; font-weight:bold;">+</span> @@index.<span style="color:#9900CC;">to_s</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">unique_email</span><span style="color:#006600; font-weight:bold;">&#40;</span>val<span style="color:#006600; font-weight:bold;">&#41;</span>
      user, domain = val.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'@'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      unique<span style="color:#006600; font-weight:bold;">&#40;</span>user<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">'@'</span> <span style="color:#006600; font-weight:bold;">+</span> domain
    <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">create</span>
      obj = spawn
      populate<span style="color:#006600; font-weight:bold;">&#40;</span>obj<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">yield</span> obj <span style="color:#9966CC; font-weight:bold;">if</span> block_given?
      obj
    <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">create</span>!<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&amp;</span>block<span style="color:#006600; font-weight:bold;">&#41;</span>
      obj = create<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&amp;</span>block<span style="color:#006600; font-weight:bold;">&#41;</span>
      obj.<span style="color:#9900CC;">save</span>!
      obj
    <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">create_as_hash</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&amp;</span>block<span style="color:#006600; font-weight:bold;">&#41;</span>
      obj = create<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&amp;</span>block<span style="color:#006600; font-weight:bold;">&#41;</span>
      to_hash obj
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>All the major concepts are there; <em>create</em> equals <em>createNewValid</em> and <em>create!</em> is the same as <em>createAnonymous</em>. There&#8217;s also a <em>create_as_hash</em> method for converting a valid object to a params hash when you&#8217;re doing <em>post :create</em> type stuff in functional tests. Currently, you utilize the Factory by sub-classing in your rails app somewhere (I&#8217;m just using test_helper.rb for now). Here&#8217;s an example: </p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> AreaFactory <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ObjectMother::Factory</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">spawn</span>
    Area.<span style="color:#9900CC;">new</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">populate</span><span style="color:#006600; font-weight:bold;">&#40;</span>model<span style="color:#006600; font-weight:bold;">&#41;</span>
    model.<span style="color:#9900CC;">name</span> = unique<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'SW'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    model.<span style="color:#9900CC;">city</span> = CityFactory.<span style="color:#9900CC;">create</span>!
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>The <em>spawn</em> method just creates a blank instance of the class each individual factory deals with and could definitely be inferred (baby steps, I&#8217;ll get to that once the annoyance factor gets higher). Overriding <em>populate</em> is where the attributes of a valid model object are set.</p>
<p>Overall, this is really just what I wanted, and the basic code is only a few simple lines of ruby. I&#8217;ll add some smarts in eventually (ie; inferring the class to spawn, creating hashes automatically, giving the user a default place to put Factories, making sure that passing blocks actually works), but for the time being I&#8217;m pretty happy.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffperrin.com/2009/07/08/object-mother-testing-pattern-in-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Just Be Honest and Tell the Truth</title>
		<link>http://jeffperrin.com/2009/06/24/just-be-honest-and-tell-the-truth/</link>
		<comments>http://jeffperrin.com/2009/06/24/just-be-honest-and-tell-the-truth/#comments</comments>
		<pubDate>Thu, 25 Jun 2009 00:25:05 +0000</pubDate>
		<dc:creator>Jeff Perrin</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Radness]]></category>

		<guid isPermaLink="false">http://jeffperrin.com/?p=193</guid>
		<description><![CDATA[I just read Ron Jefferies latest post entitled My Named Cloud is Better Than Your Named Cloud and it got me riled up enough to post something I&#8217;ve been meaning to write about for at least a couple of years. His post touches on the point I&#8217;d wanted to make, but doesn&#8217;t quite say it [...]]]></description>
			<content:encoded><![CDATA[<p>I just read Ron Jefferies latest post entitled <a href="http://xprogramming.com/blog/needles/my-named-cloud-is-better-than-your-named-cloud.htm">My Named Cloud is Better Than Your Named Cloud</a> and it got me riled up enough to post something I&#8217;ve been meaning to write about for at least a couple of years. His post touches on the point I&#8217;d wanted to make, but doesn&#8217;t quite say it as simply as I think it can be said. Here&#8217;s what I&#8217;m thinking:</p>
<blockquote><p>If we could just always be honest with ourselves, as people, team members and organizations, software development wouldn&#8217;t be that hard.</p></blockquote>
<p>There. Simple. Think about it for a second. All this stuff that we label and group together under <em>methodologies</em> and <em>processes</em> is really there so that we can do <em>One Thing.</em> This one thing, I&#8217;m assuming, is usually to create software that fulfills a need.</p>
<p>Let&#8217;s pretend that a software team has been assembled to create an application that fulfills such a need. They&#8217;ve chosen to use the XP methodology while writing this application. I&#8217;ll go through some of the tenets of XP and run them through my <em>honesty filter</em>:</p>
<ol>
<li>Pair programming: The team realizes that people will come and go on a project for good (quit, fired, etc), or for short periods of time (maternity leave, vacation, illness, etc). They want to minimize the risk, so they make sure everyone is familiar with every piece of the code base. They also realize that sometimes even the best developers do stupid shit for no good reason, and believe that having two sets of eyes on the screen at all times will lessen the likely hood of this happening.</li>
<li>TDD: The team realizes that writing software is <em>hard</em>, and that stuff that worked last week will have to be changed this week. Since they want to ensure that stuff they worked on earlier still works when they make these changes, they write tests, and ensure that no code gets checked in unless all the tests are passing. They also hope that these tests provide some form of documentation to any developers (and perhaps users/clients) that may come later or who never worked on the feature originally.</li>
<li>Incremental design: The team realizes that there are unforeseen forces that may threaten a project at any given time. A big project entails a large amount of risk for both clients and developers. If features can be developed in incremental fashion, hopefully in an order representing the importance of each feature, then risks can be mitigated. The team is always working with a <em>usable application</em>, so that if something comes up that stops the project, at least the client will have <em>something</em> to work with.</li>
</ol>
<p>Now obviously there is more to XP than what I&#8217;ve listed. The point is that those three things exist to handle a need that most teams, if they are really <em>honest with themselves</em> have:</p>
<ol>
<li>Knowledge transfer. Nobody wants to have to rely on one person to get something done. Sooner or later, this always bites us in the ass. Pairing is <em>one way</em> to handle this.
</li>
<li>Developed features continue working. Nothing is more frustrating (to users and developers) than having something that used to work perfectly stop working. Testing is <em>one way</em> to handle this.</li>
<li>The need to guarantee that <em>something</em> will come out of all the money we&#8217;re spending. What happens if the development shop you&#8217;ve contracted goes bankrupt before they&#8217;ve finished your application? Incremental design is <em>one way</em> to handle this.</li>
</ol>
<p>Listen. We have methodologies and processes for a reason (I hope). Some of these processes may work for you. However, maybe only some parts of a process work for you. The point is, it&#8217;s not about the process. If you can understand why you&#8217;re using a particular piece of a process, you can assess whether it&#8217;s useful for your team. Who cares whether you&#8217;re doing XP, Scrum, Lean, Kanban, Waterfall, or Hack &#8216;n&#8217; Slash. Those are just names. Identify your pain points, problems, worries, etc, and <em>try to fix them</em>. Honestly.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffperrin.com/2009/06/24/just-be-honest-and-tell-the-truth/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails, Nested Forms and collection_select</title>
		<link>http://jeffperrin.com/2009/06/04/rails-nested-forms-and-collection_select/</link>
		<comments>http://jeffperrin.com/2009/06/04/rails-nested-forms-and-collection_select/#comments</comments>
		<pubDate>Thu, 04 Jun 2009 04:12:45 +0000</pubDate>
		<dc:creator>Jeff Perrin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[rails nested forms collection_select]]></category>

		<guid isPermaLink="false">http://jeffperrin.com/?p=177</guid>
		<description><![CDATA[I spent a bit of time on this tonight and thought I&#8217;d post about it.

I have a Property model that has a has_one relationship with an Address model. I want to be able to CRUD these two objects as one single entity, however. Luckily, nested forms were recently introduced into Rails 2.3.2 and they seemed [...]]]></description>
			<content:encoded><![CDATA[<p>I spent a bit of time on this tonight and thought I&#8217;d post about it.</p>
<p>
I have a Property model that has a <em>has_one </em>relationship with an Address model. I want to be able to CRUD these two objects as one single entity, however. Luckily, nested forms were recently introduced into Rails 2.3.2 and they seemed like they&#8217;d simplify the whole process. Which they did once I put everything together. First, my models:
</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Property <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>attributes=<span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">super</span>
    <span style="color:#008000; font-style:italic;">#we override the initialize method and ensure we always have </span>
    <span style="color:#008000; font-style:italic;">#an address instance created. This makes sure we don't get any</span>
    <span style="color:#008000; font-style:italic;">#nil reference errors in our forms</span>
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">build_address</span> <span style="color:#9966CC; font-weight:bold;">unless</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">address</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;">#accepts_nested_attributes_for enables the property's address object</span>
  <span style="color:#008000; font-style:italic;">#to be updated at the same time as the property object</span>
  accepts_nested_attributes_for <span style="color:#ff3333; font-weight:bold;">:address</span>, <span style="color:#ff3333; font-weight:bold;">:allow_destroy</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Address <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  has_one <span style="color:#ff3333; font-weight:bold;">:property</span>
  <span style="color:#008000; font-style:italic;"># the Address model has a :city string column that will get populated from</span>
  <span style="color:#008000; font-style:italic;"># a drop-down list in our view</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>
This is the basic stuff that any tutorial on nested forms in Rails will tell you about, with the exception of creating a default instance of the address in the property constructor. This is most likely specific to the <em>has_one</em> case. Most of the examples I have seen deal only with <em>has_many</em>, where behind the scenes rails creates an empty list and we&#8217;ll never end up with nil reference errors in our view. This was the first issue I had to solve. Now let&#8217;s move on to our <em>new.html.erb</em> view:
</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&lt;%</span> form_for <span style="color:#0066ff; font-weight:bold;">@property</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  <span style="color:#006600; font-weight:bold;">&lt;%</span>= f.<span style="color:#9900CC;">error_messages</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  &lt;p&gt;
    <span style="color:#006600; font-weight:bold;">&lt;%</span>= f.<span style="color:#9900CC;">label</span> <span style="color:#ff3333; font-weight:bold;">:name</span>, <span style="color:#996600;">&quot;Title&quot;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
    <span style="color:#006600; font-weight:bold;">&lt;%</span>= f.<span style="color:#9900CC;">text_field</span> <span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  &lt;/p&gt;
  &lt;p&gt;
    <span style="color:#006600; font-weight:bold;">&lt;%</span> f.<span style="color:#9900CC;">fields_for</span> <span style="color:#ff3333; font-weight:bold;">:address</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>af<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
      &lt;p&gt;
        <span style="color:#006600; font-weight:bold;">&lt;%</span>= af.<span style="color:#9900CC;">label</span> <span style="color:#ff3333; font-weight:bold;">:address_one</span>, <span style="color:#996600;">&quot;Address One&quot;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
        <span style="color:#006600; font-weight:bold;">&lt;%</span>= af.<span style="color:#9900CC;">text_field</span> <span style="color:#ff3333; font-weight:bold;">:address_one</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
      &lt;/p&gt;
      &lt;p&gt;
        <span style="color:#006600; font-weight:bold;">&lt;%</span>= af.<span style="color:#9900CC;">label</span> <span style="color:#ff3333; font-weight:bold;">:city</span>, <span style="color:#996600;">&quot;City&quot;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
        <span style="color:#006600; font-weight:bold;">&lt;%</span>= af.<span style="color:#9900CC;">collection_select</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:city</span>, City.<span style="color:#9900CC;">all</span>, <span style="color:#ff3333; font-weight:bold;">:name</span>, <span style="color:#ff3333; font-weight:bold;">:name</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
      &lt;/p&gt;
    <span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  &lt;/p&gt;
  &lt;p&gt;
    <span style="color:#006600; font-weight:bold;">&lt;%</span>= f.<span style="color:#9900CC;">submit</span> <span style="color:#996600;">'Create'</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  &lt;/p&gt;
<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">%&gt;</span></pre></div></div>

<p>The trick here is to make sure you qualify the <em>collection_select</em> for cities with the specific <em>fields_for</em> instance. If you don&#8217;t, the form will render and appear to be ok until you post to the <em>create</em> action or view the generated source:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">&lt;p&gt;
<span style="color:#006600; font-weight:bold;">&lt;%</span>= af.<span style="color:#9900CC;">label</span> <span style="color:#ff3333; font-weight:bold;">:city</span>, <span style="color:#996600;">&quot;City&quot;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
notice how I've removed the af. qualifier on collection select, and added in a
new parameter :address. This is how most tutorials show you how to use it
The problem with this is that the rendered html does not generate properly for
our nested form scenario
<span style="color:#006600; font-weight:bold;">&lt;%</span>=collection_select<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:address</span>, <span style="color:#ff3333; font-weight:bold;">:city</span>, City.<span style="color:#9900CC;">all</span>, <span style="color:#ff3333; font-weight:bold;">:name</span>, <span style="color:#ff3333; font-weight:bold;">:name</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
&lt;/p&gt;</pre></div></div>

<p>
Once you qualify the <em>collection_select</em> helper properly, you should get generated html that looks like this:
</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;label for=&quot;property_address_attributes_city&quot;&gt;City&lt;/label&gt;
        &lt;select id=&quot;property_address_attributes_city&quot; name=&quot;property[address_attributes][city]&quot;&gt;&lt;option value=&quot;Lethbridge&quot;&gt;Lethbridge&lt;/option&gt;&lt;/select&gt;</pre></div></div>

<p>Now when you post the form, Rails nested form magic just works. My controller looks just as you&#8217;d expect (ie; no different than the non-nested form scenario)
</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> create
    <span style="color:#0066ff; font-weight:bold;">@property</span> = Property.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:property</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span>
      <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@property</span>.<span style="color:#9900CC;">save</span>
        flash<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:notice</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">'Property was successfully created.'</span>
        <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#006600; font-weight:bold;">&#123;</span> redirect_to<span style="color:#006600; font-weight:bold;">&#40;</span>@property<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#9966CC; font-weight:bold;">else</span>
        <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:action</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;new&quot;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Hopefully I&#8217;ve explained this properly. Feel free to ask questions in the comments if I haven&#8217;t.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffperrin.com/2009/06/04/rails-nested-forms-and-collection_select/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Extending clearance</title>
		<link>http://jeffperrin.com/2009/05/27/extending-clearance/</link>
		<comments>http://jeffperrin.com/2009/05/27/extending-clearance/#comments</comments>
		<pubDate>Wed, 27 May 2009 05:07:23 +0000</pubDate>
		<dc:creator>Jeff Perrin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[clearance]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://jeffperrin.com/?p=172</guid>
		<description><![CDATA[I thought I&#8217;d try using clearance to handle authentication on the Rails app I&#8217;m developing. It seems pretty nice and basic, but I wanted to add a :name property on the user model (not for authentication, just for display purposes).
Once I&#8217;d created a migration to add the new column to the user model, I needed [...]]]></description>
			<content:encoded><![CDATA[<p>I thought I&#8217;d try using <a href="http://github.com/thoughtbot/clearance/tree/master">clearance</a> to handle authentication on the Rails app I&#8217;m developing. It seems pretty nice and basic, but I wanted to add a :name property on the user model (not for authentication, just for display purposes).</p>
<p>Once I&#8217;d created a migration to add the new column to the user model, I needed to add the field on the corresponding view so it could actually be input by a user. Since clearance is installed as a vendor gem/engine (still not sure what the difference is) the view files are located in the vendor directory. I figured updating these files wouldn&#8217;t be good, since they&#8217;d be overwritten if I ever had to update and unpack the gem.</p>
<p>It turns out all I had to do was copy the view files into my app under the views/user/ directory. I could then modify the files at will, and they would be used by Rails instead of the vendor files. One other gotcha was to make sure to add the attr_accessible :name declaration in my user.rb file (so Rails can do a mass assignment of the posted form items). My user.rb ended up looking like this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> User <span style="color:#006600; font-weight:bold;">&amp;</span>lt; <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  <span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#6666ff; font-weight:bold;">Clearance::User</span>
  has_many <span style="color:#ff3333; font-weight:bold;">:properties</span>
  attr_accessible <span style="color:#ff3333; font-weight:bold;">:name</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://jeffperrin.com/2009/05/27/extending-clearance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails Functional Testing Gotcha</title>
		<link>http://jeffperrin.com/2009/05/18/rails-functional-testing-gotcha/</link>
		<comments>http://jeffperrin.com/2009/05/18/rails-functional-testing-gotcha/#comments</comments>
		<pubDate>Mon, 18 May 2009 15:04:01 +0000</pubDate>
		<dc:creator>Jeff Perrin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://jeffperrin.com/?p=170</guid>
		<description><![CDATA[I just started writing my first real Rails app this weekend, and as I struggle along I thought I&#8217;d document where I&#8217;m tripping up.
My first order of business is to write functional tests on my controllers and views. For some reason I thought I&#8217;d give the tests (which inherit from ActionController::TestCase) descriptive class names like [...]]]></description>
			<content:encoded><![CDATA[<p>I just started writing my first real Rails app this weekend, and as I struggle along I thought I&#8217;d document where I&#8217;m tripping up.</p>
<p>My first order of business is to write functional tests on my controllers and views. For some reason I thought I&#8217;d give the tests (which inherit from <em>ActionController::TestCase</em>) descriptive class names like <em>PropertiesDashboardTest</em> instead of <em>PropertiesControllerTest</em>. I had tests running and passing before I renamed the test class, but then started getting this error:</p>
<p><em>RuntimeError: @controller is nil: make sure you set it in your test&#8217;s setup method.</em></p>
<p>It took me a while to realize that Rails auto-instantiates a controller instance based on the test name when you inherit from <em>ActionController::TestCase</em>. Since I don&#8217;t have a controller named <em>PropertiesDashboard.rb</em>, Rails can&#8217;t set one up in the test for me. Of course I&#8217;m doing this test-first, so a controller doesn&#8217;t even exist at this point. That also explains why my existing test started failing when I renamed it.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffperrin.com/2009/05/18/rails-functional-testing-gotcha/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New Ride</title>
		<link>http://jeffperrin.com/2009/03/01/new-ride/</link>
		<comments>http://jeffperrin.com/2009/03/01/new-ride/#comments</comments>
		<pubDate>Sun, 01 Mar 2009 19:36:06 +0000</pubDate>
		<dc:creator>Jeff Perrin</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[Radness]]></category>
		<category><![CDATA[cycling radness]]></category>

		<guid isPermaLink="false">http://jeffperrin.com/2009/03/01/new-ride/</guid>
		<description><![CDATA[I found my new ride for the summer, a one or two year old Cannondale cyclocross bike! Paid $850 for it, which almost feels like stealing. I can&#8217;t wait for spring.




]]></description>
			<content:encoded><![CDATA[<p>I found my new ride for the summer, a one or two year old Cannondale cyclocross bike! Paid $850 for it, which almost feels like stealing. I can&#8217;t wait for spring.</p>
<p><a href="http://jeffperrin.com/wp-content/uploads/2009/03/p-640-480-8126bcab-c179-44e8-be55-43d24b720170.jpeg"><img src="http://jeffperrin.com/wp-content/uploads/2009/03/p-640-480-8126bcab-c179-44e8-be55-43d24b720170.jpeg" alt="" width="225" height="300" class="alignnone size-full wp-image-364" /></a></p>
<p><a href="http://jeffperrin.com/wp-content/uploads/2009/03/p-640-480-a4663203-592a-4a67-b490-0245497a976c.jpeg"><img src="http://jeffperrin.com/wp-content/uploads/2009/03/p-640-480-a4663203-592a-4a67-b490-0245497a976c.jpeg" alt="" width="225" height="300" class="alignnone size-full wp-image-364" /></a></p>
<p><a href="http://jeffperrin.com/wp-content/uploads/2009/03/p-640-480-a56a3c16-cdae-43d8-91f0-13078e422853.jpeg"><img src="http://jeffperrin.com/wp-content/uploads/2009/03/p-640-480-a56a3c16-cdae-43d8-91f0-13078e422853.jpeg" alt="" width="225" height="300" class="alignnone size-full wp-image-364" /></a></p>
<p><a href="http://jeffperrin.com/wp-content/uploads/2009/03/l-640-480-40222efd-51cb-491a-94e0-dc065ee2784b.jpeg"><img src="http://jeffperrin.com/wp-content/uploads/2009/03/l-640-480-40222efd-51cb-491a-94e0-dc065ee2784b.jpeg" alt="" width="300" height="225" class="alignnone size-full wp-image-364" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://jeffperrin.com/2009/03/01/new-ride/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Forgetting Craftsmanship</title>
		<link>http://jeffperrin.com/2009/02/14/forgetting-craftsmanship/</link>
		<comments>http://jeffperrin.com/2009/02/14/forgetting-craftsmanship/#comments</comments>
		<pubDate>Sat, 14 Feb 2009 20:59:01 +0000</pubDate>
		<dc:creator>Jeff Perrin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jeffperrin.com/?p=161</guid>
		<description><![CDATA[Sergio Pereira has just posted a video of a speech by Bob Martin about Extreme Programming after ten years. It&#8217;s a fascinating presentation with a message that resonates with me in particular, since I&#8217;ve been a part of a software project for the past 3 1/2 years that has left craftsmanship behind while still keeping to the [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://devlicio.us/blogs/sergio_pereira/default.aspx">Sergio Pereira</a> has just posted a video of a speech by <a href="http://www.objectmentor.com/omTeam/martin_r.html">Bob Martin</a> about <a href="http://devlicio.us/blogs/sergio_pereira/archive/2009/02/14/video-xp-after-10-years-why-are-we-still-talking-about-it.aspx">Extreme Programming after ten years</a>. It&#8217;s a fascinating presentation with a message that resonates with me in particular, since I&#8217;ve been a part of a software project for the past 3 1/2 years that has left craftsmanship behind while still keeping to the trappings of Agile development (SCRUM in particular). The result has been tragic (to the code base), and the more people who learn from this, the better. Bob may have just inspired me to try to tell the story. But for now&#8230; Just watch the video.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffperrin.com/2009/02/14/forgetting-craftsmanship/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
