<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Continuous Thinking - Home</title>
  <id>tag:www.continuousthinking.com,2010:mephisto/</id>
  <generator version="0.7.3" uri="http://mephistoblog.com">Mephisto Noh-Varr</generator>
  <link href="http://www.continuousthinking.com/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://www.continuousthinking.com/" rel="alternate" type="text/html"/>
  <updated>2010-05-17T14:25:21Z</updated>
  <entry xml:base="http://www.continuousthinking.com/">
    <author>
      <name>zdennis</name>
    </author>
    <id>tag:www.continuousthinking.com,2010-05-17:652</id>
    <published>2010-05-17T01:54:00Z</published>
    <updated>2010-05-17T14:25:21Z</updated>
    <link href="http://www.continuousthinking.com/2010/5/17/daniel-parker-accident" rel="alternate" type="text/html"/>
    <title>Daniel Parker accident</title>
<summary type="html">&lt;p&gt;Daniel Parker, a colleague, friend, and coworker of mine passed away this evening. Daniel was competing in a triathlon on Friday night when he got into a biking accident. Daniel was airlifted to the University of Michigan hospital and underwent two surgeries between Friday night and Saturday, but during the second surgery they stopped because it wasn&#8217;t helping Daniel&#8217;s condition.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;Daniel Parker, a colleague, friend, and coworker of mine passed away this evening. Daniel was competing in a triathlon on Friday night when he got into a biking accident. Daniel was airlifted to the University of Michigan hospital and underwent two surgeries between Friday night and Saturday, but during the second surgery they stopped because it wasn&#8217;t helping Daniel&#8217;s condition.&lt;/p&gt;
&lt;p&gt;You may know his name if you&#8217;re a developer, because so was Daniel. You may know him from his work with Quickbooks and Ruby or maybe his GMail rubygem or one of his many other projects that he authored or contributed to.&lt;/p&gt;


	&lt;p&gt;You may know him as a Christian, because so was Daniel. While he wrote code because it was fun and he was quite good at it, he first and fore-most lived for the Lord.&lt;/p&gt;


	&lt;p&gt;You may know Daniel as a fervent competitor with a kind heart and a powerfully analytical mind. You may know Daniel for a number of other reasons, and if you didn&#8217;t know Daniel then I assure you, if you did, he would have left nothing but an impact of an honest, energetic, intelligent, warm hearted, analytical, yet loving person.&lt;/p&gt;


	&lt;p&gt;I knew Daniel because of his work in the Ruby community and in the Ruby community in the midwest and specifically Michigan. Last fall I attended GRGivecamp with Daniel. Four months ago, Daniel came and began working with me at Mutually Human Software. Daniel and I worked closely together for about 30 hours a week every week. Every day we&#8217;d pair program (or party as Daniel would call it). Almost every day we&#8217;d eat lunch together and talk &#8211; sometimes about work and sometimes about everything else in life. I never imagined that four months of my life with someone could have such an impact. That&#8217;s also the kind of person Daniel was &#8211; impactful in all the best ways.&lt;/p&gt;


	&lt;p&gt;Before I had ever met Daniel personally, my colleague John Hwang had told me that he was the kind of person we wanted to work with, not just the type of developer, but the kind of person. At first I was skeptical, but after I met and began workingw ith Daniel I knew John was right. Daniel was more then just a developer&#8212;he was human. He was the kind of spirit and person who anyone would want to build a team around. He was an amazing developer, but even more-so he was an exceptional person. It&#8217;s hard to believe that Daniel was only 23 years old.&lt;/p&gt;


	&lt;p&gt;I will miss you Daniel, as a friend, as a colleague, as a human. May your life go on to impact countless lives. I know you have impacted mine.&lt;/p&gt;


	&lt;p&gt;P.S. &#8211; when you get to heaven be sure to teach everyone Rook, they&#8217;ll love it just as much as you did when I introduced it to you. That will forever be a cherished night in my life.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.continuousthinking.com/">
    <author>
      <name>zdennis</name>
    </author>
    <id>tag:www.continuousthinking.com,2010-04-29:647</id>
    <published>2010-04-29T02:13:00Z</published>
    <updated>2010-04-29T02:14:41Z</updated>
    <link href="http://www.continuousthinking.com/2010/4/29/unix-tee-in-real-life" rel="alternate" type="text/html"/>
    <title>UNIX tee in real life</title>
<content type="html">
            &lt;p&gt;I wrote a nice little article on using the &lt;span class='caps'&gt;UNIX&lt;/span&gt; tee command in real life. If you&#8217;re wanting to see the purpose of tee or learn something new about bash, check it out:&lt;/p&gt;


	&lt;p&gt;&lt;a href='http://mutuallyhuman.com/2010/4/29/unix-tee-in-real-life'&gt;http://mutuallyhuman.com/2010/4/29/unix-tee-in-real-life&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Happy coding!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.continuousthinking.com/">
    <author>
      <name>zdennis</name>
    </author>
    <id>tag:www.continuousthinking.com,2010-04-09:646</id>
    <published>2010-04-09T03:44:00Z</published>
    <updated>2010-04-09T03:46:11Z</updated>
    <link href="http://www.continuousthinking.com/2010/4/9/activerecord-import-gets-basic-sqlite3-and-postgresql-support" rel="alternate" type="text/html"/>
    <title>activerecord-import gets basic SQLite3 and PostgreSQL support</title>
<content type="html">
            &lt;p&gt;A few weeks back I started working on extracting the import functionality from ar-extensions into its own library. The initial extraction involved pulling out all of the MySQL functionality first, test by test, piece by piece. Well, tonight I pulled in the basic support for SQLite3 and PostgreSQL.&lt;/p&gt;


	&lt;p&gt;While it&#8217;s working great for MySQL, SQLite3, and PostgreSQL it has not been released as its own rubygem yet. I expect that to happen in the near-term future. In the meantime you can always check out the project on github:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href='http://github.com/zdennis/activerecord-import/'&gt;http://github.com/zdennis/activerecord-import/&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;In the past folks have emailed about sparse documentation. When the gem is released documentation will be provided by the github wiki ( &lt;a href='http://wiki.github.com/zdennis/activerecord-import/'&gt;http://wiki.github.com/zdennis/activerecord-import/&lt;/a&gt; ) and the most up-to-date will be provided in the &lt;span class='caps'&gt;RDOC&lt;/span&gt; itself.&lt;/p&gt;


	&lt;p&gt;I&#8217;ve ran some benchmarks recently against MySQL 5.1 and you can find the results here: &lt;a href='http://wiki.github.com/zdennis/activerecord-import/benchmarks'&gt;http://wiki.github.com/zdennis/activerecord-import/benchmarks&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;More to come!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.continuousthinking.com/">
    <author>
      <name>zdennis</name>
    </author>
    <id>tag:www.continuousthinking.com,2010-03-12:640</id>
    <published>2010-03-12T05:17:00Z</published>
    <updated>2010-03-12T05:17:30Z</updated>
    <link href="http://www.continuousthinking.com/2010/3/12/activerecord-import-updates" rel="alternate" type="text/html"/>
    <title>ActiveRecord Import Updates</title>
<content type="html">
            &lt;p&gt;Nearly four years ago I embarked on figuring out ActiveRecord internals enough so I could have a library which allowed me to perform bulk inserts of data in an optimized way based on the database adapter being used. Over those four years, I&#8217;ve maintained and updated the functionality with contributions from the community. A big thanks to Blythe Dunham, James Herdman, Gabe da Silveira, Thibaud Guillaume-Gentil,  Marcus Crafter, and Mark Van Holstyn.&lt;/p&gt;


	&lt;p&gt;Now that Rails is nearing a 3.0 release, it&#8217;s time for to revisit this import functionality, make it compatible with the heavily refactored and cleaned up ActiveRecord internals (thx Rails core team) and add some more polished features and implementation.&lt;/p&gt;


	&lt;p&gt;The import functionality which was in ActiveRecord::Extensions is being extracted into its own library, &lt;strong&gt;activerecord-import&lt;/strong&gt;. This library will be smaller and its only purpose will be to provide mass import functionality.&lt;/p&gt;


	&lt;p&gt;The work has already begun over on github: &lt;a href='http://github.com/zdennis/activerecord-import'&gt;http://github.com/zdennis/activerecord-import&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;I look forwarding to officially releasing this in the upcoming weeks!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.continuousthinking.com/">
    <author>
      <name>zdennis</name>
    </author>
    <id>tag:www.continuousthinking.com,2009-11-03:630</id>
    <published>2009-11-03T02:25:00Z</published>
    <updated>2009-11-03T15:55:14Z</updated>
    <link href="http://www.continuousthinking.com/2009/11/3/binary-chop-shop-in-scala" rel="alternate" type="text/html"/>
    <title>Binary Chop Shop in Scala</title>
<content type="html">
            &lt;p&gt;In an effort to start learning Scala again (i started in the summer then got busy) I decided to tackle a simple yet fun code kata from Dave Thomas called &lt;a href='http://codekata.pragprog.com/2007/01/kata_two_karate.html'&gt;karate chop&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;I ended up using &lt;a href='http://code.google.com/p/specs/'&gt;Specs&lt;/a&gt; to make sure I passed Dave Thomas&#8217;s test criteria. I&#8217;m sure my below two solutions (recursive and while loop) are quite clunky compared to someone who&#8217;s familiar with Scala, but the goal of this was to get something running and passing. In a week or two I&#8217;ll revisit again after learning some more things about Scala and hopefully be able to tidy things up a bit.&lt;/p&gt;


	&lt;p&gt;Anyways, here&#8217;s my code:&lt;/p&gt;


&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;35&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;42&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;class BinaryChopShop {&lt;tt&gt;
&lt;/tt&gt;  def chopRecursive(target: Int, list: List[Int], args: Int*): Int = {&lt;tt&gt;
&lt;/tt&gt;    if(list.isEmpty) return -1;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    val offset = if(args.isEmpty) 0 else args.first;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    if(list.size == 1){&lt;tt&gt;
&lt;/tt&gt;      return if(list.first == target) offset else -1; &lt;tt&gt;
&lt;/tt&gt;    } else {&lt;tt&gt;
&lt;/tt&gt;      val index = list.size / 2;&lt;tt&gt;
&lt;/tt&gt;      val value = list(index);&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;      if(target &amp;lt; value)&lt;tt&gt;
&lt;/tt&gt;        return chopRecursive(target, list.slice(0, index), offset);&lt;tt&gt;
&lt;/tt&gt;      else&lt;tt&gt;
&lt;/tt&gt;        return chopRecursive(target, list.slice(index, list.size), offset + index);&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;  }&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  def chopWhile(target: Int, list: List[Int]):Int = {&lt;tt&gt;
&lt;/tt&gt;    var nlist = list;&lt;tt&gt;
&lt;/tt&gt;    var offset = 0;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    while(!nlist.isEmpty){&lt;tt&gt;
&lt;/tt&gt;      if(nlist.size == 1){&lt;tt&gt;
&lt;/tt&gt;        return if(nlist.first == target) offset else -1;&lt;tt&gt;
&lt;/tt&gt;      }&lt;tt&gt;
&lt;/tt&gt;      &lt;tt&gt;
&lt;/tt&gt;      val index = nlist.size / 2;&lt;tt&gt;
&lt;/tt&gt;      val value = nlist(index);&lt;tt&gt;
&lt;/tt&gt;      &lt;tt&gt;
&lt;/tt&gt;      if(target == value) return index + offset;&lt;tt&gt;
&lt;/tt&gt;      if(target &amp;lt; value){&lt;tt&gt;
&lt;/tt&gt;        nlist = nlist.slice(0, index);&lt;tt&gt;
&lt;/tt&gt;      } else {&lt;tt&gt;
&lt;/tt&gt;        offset += index&lt;tt&gt;
&lt;/tt&gt;        nlist = nlist.slice(index, nlist.size);&lt;tt&gt;
&lt;/tt&gt;      }&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;    return -1;&lt;tt&gt;
&lt;/tt&gt;  }  &lt;tt&gt;
&lt;/tt&gt;}&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
          </content>  </entry>
  <entry xml:base="http://www.continuousthinking.com/">
    <author>
      <name>zdennis</name>
    </author>
    <id>tag:www.continuousthinking.com,2009-10-17:629</id>
    <published>2009-10-17T20:16:00Z</published>
    <updated>2009-10-17T20:18:14Z</updated>
    <link href="http://www.continuousthinking.com/2009/10/17/summary-of-thoughts-on-data-and-migrations" rel="alternate" type="text/html"/>
    <title>Summary of thoughts on data and migrations</title>
<content type="html">
            &lt;p&gt;I shared a summary of my thoughts today with my project team (we&#8217;re distributed, multi-national team)... and I thought what the heck why not share with the rest of the world to.  Here goes&#8230;&lt;/p&gt;


	&lt;p&gt;I&#8217;m not sure what everyone&#8217;s conventions or views are on handling the removal of data in the app that is no longer used, so here are some of the guidelines I follow to help promote sharing and consistency.&lt;/p&gt;


	&lt;h2&gt;Seed data&lt;/h2&gt;


	&lt;p&gt;To load data that has to exist for the application to run, I like to use seed data and I am a big fan of Michael Bleigh&#8217;s seed-fu plugin. Seed data should be setup so that it can be loaded at any point during the lifetime of an application. It should not destroy data that leaves orphaned data and it should not duplicate data.&lt;/p&gt;


	&lt;h2&gt;Updating data&lt;/h2&gt;


	&lt;p&gt;I like to use migrations to update existing data. If the migration and data update is complex and irreversible I will add a unit test around the migration because due to the high risk of causing irreversible damage (unless a full DB backup is loaded).&lt;/p&gt;


	&lt;h2&gt;Updating application-required data&lt;/h2&gt;


	&lt;p&gt;When the data that the application depends on changes (ie; the seed data) I tend to update both the seed files as well as add a migration to properly handle any existing data, whether this means removing the data, marking it as delete or inactive, etc.&lt;/p&gt;


	&lt;h2&gt;Updating data&lt;/h2&gt;


	&lt;p&gt;In development modifying data directly through MySQL or ruby scripts is much more forgivable and often very fast and efficient. We have no risk of causing users of the application harm or loss of data. Once something is figured out I like to either add a seed-file and/or a migration if it&#8217;s a change that needs to get made on staging and production.&lt;/p&gt;


	&lt;p&gt;In staging modifying data directly is less appealing because staging is supposed to represent what happens when we go to production. If we have to modify data directly in staging then we&#8217;ll probably have to modify it in production, so a migration and/or seed-file is a better place to track the change. I find it tempting sometimes to script/console and modify data directly.&lt;/p&gt;


	&lt;p&gt;A problem with this is that we risk screwing up staging for folks who are using it to preview features, check out bug fixes, etc. I find it better to dump the database and pull it over to my local development machine. Once I have it I can load it up locally, recreate the issue, and do whatever I need to do to find the source of the issue. This removes the risk that you fill further break staging for any users using it. Once I find the issue if I need to I will add/update a migration and/or seed file.&lt;/p&gt;


	&lt;p&gt;In production modifying data directly is super dangerous. It&#8217;s a change that occurs outside of version control and potentially without being run in development and/or staging which could catch bugs in the updates. The risk of causing irrevocable damage is so high I think doing this should be avoided.&lt;/p&gt;


	&lt;p&gt;I find it&#8217;s always been better to take an extra few minutes to make sure the fix is right and then to deploy, then it is to make a quick fix directly in production and find the change caused new issues. Production should never turn into a debugging sandbox. Pulling over a backup if necessary is safer and allows us developers more freedom to freely change the data to find the appropriate fix.&lt;/p&gt;


	&lt;h2&gt;If you have to use script/console not MySQL&lt;/h2&gt;


	&lt;p&gt;If you find you need to update data directly it&#8217;s better to use script/console, then by touching the database directly using MySQL. For example, Scott once asked me to change his user name. Changing his user name was a very low risk change, so I loaded up script/console and made it.&lt;/p&gt;


	&lt;p&gt;The benefit of script/console is that you let all of the rules and validations inside the application be run when you make the change. If I had made Scott&#8217;s username too short, too long, include inadmissable characters I would not find out if I did it directly through MySQL, unless I had duplicated all of the logic in MySQL stored procedures and triggers (which I cringe at the thought of).&lt;/p&gt;


	&lt;h2&gt;Conclusion&lt;/h2&gt;


	&lt;p&gt;Well, that&#8217;s pretty much a summary of my personal guidelines when it comes to dealing with data updates, migrations, seed-files, etc. If you have any other guidelines you follow that you find helpful please share. I think being on the same page here will help us as we push forward.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.continuousthinking.com/">
    <author>
      <name>zdennis</name>
    </author>
    <id>tag:www.continuousthinking.com,2009-10-01:597</id>
    <published>2009-10-01T01:15:00Z</published>
    <updated>2009-11-02T01:12:04Z</updated>
    <link href="http://www.continuousthinking.com/2009/10/1/git-review" rel="alternate" type="text/html"/>
    <title>git review</title>
<content type="html">
            &lt;p&gt;I&#8217;ve gotten into the habit of review code that comes down from every other developer, rather than blindly merging in. For a while I was typing &#8220;git log master..origin/master&#8221; but it became to tedious to type out. I&#8217;ve updated my .gitconfig to provide the following alias:&lt;/p&gt;


&lt;pre&gt;
[alias]
  review = !&quot;git log  master..origin/master&quot; 
&lt;/pre&gt;

	&lt;p&gt;Now I can simply say:&lt;/p&gt;


&lt;pre&gt;
git review
&lt;/pre&gt;

	&lt;p&gt;If you want to view actual code changes rather than simply the changelog just add the -p flag:&lt;/p&gt;


&lt;pre&gt;
git review -p
&lt;/pre&gt;

	&lt;p&gt;A little nicer.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.continuousthinking.com/">
    <author>
      <name>zdennis</name>
    </author>
    <id>tag:www.continuousthinking.com,2009-05-28:590</id>
    <published>2009-05-28T07:38:00Z</published>
    <updated>2009-05-28T07:43:02Z</updated>
    <link href="http://www.continuousthinking.com/2009/5/28/bdd-not-so-much-really-part-ii" rel="alternate" type="text/html"/>
    <title>BDD not so much, really? Part II</title>
<summary type="html">&lt;p&gt;I think there&#8217;s a confusion that &lt;span class='caps'&gt;BDD&lt;/span&gt; == toolset (ie. Cucumber, Cucumber+RSpec, rspec). That needs to stop. &lt;span class='caps'&gt;BDD&lt;/span&gt; is an approach to software development. You drive your software by focusing on behaviour. This is usually done by focusing on behaviour from the outside-in. This starts by identifying the behaviour of the application, then driving inward until you get down to the low level components.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;I think there&#8217;s a confusion that &lt;span class='caps'&gt;BDD&lt;/span&gt; == toolset (ie. Cucumber, Cucumber+RSpec, rspec). That needs to stop. &lt;span class='caps'&gt;BDD&lt;/span&gt; is an approach to software development. You drive your software by focusing on behaviour. This is usually done by focusing on behaviour from the outside-in. This starts by identifying the behaviour of the application, then driving inward until you get down to the low level components.&lt;/p&gt;
&lt;p&gt;Focusing on behaviour may yield different tools throughout the process. Cucumber and RSpec are just two examples. You could very well use Cucumber plus test/unit, or perhaps just RSpec, or maybe nothing at all. These are just tools to support a development style. They are &lt;span class='caps'&gt;NOT&lt;/span&gt; the development style themselves. You can use Cucumber in a way that doesn&#8217;t support &lt;span class='caps'&gt;BDD&lt;/span&gt;. Same goes for RSpec and any other tool.&lt;/p&gt;


	&lt;p&gt;I realize there are people who don&#8217;t buy into the RSpec philosophy. To them it&#8217;s just another take on unit testing. I do buy into RSpec. From day one RSpec&#8217;s goal has been to be a &lt;span class='caps'&gt;BDD&lt;/span&gt; tool that tries to get the words right. Can you use xUnit libraries in a way to achieve the same affect? Yes you can, but most of those usages have been heavily influenced by RSpec which was built on the ideas and motivation for &lt;span class='caps'&gt;BDD&lt;/span&gt; and &#8220;getting the words right&#8221;.&lt;/p&gt;


	&lt;p&gt;Without this focus many of the high level test/unit style add-ons (especially in the ruby world like context, shoulda, test/spec, etc.) wouldn&#8217;t exist. So to me, this makes the subtle differences very important as it changed how everyone wrote their tests.&lt;/p&gt;


	&lt;p&gt;For me personally, testing is an activity after you write code. I find it refreshing to talk about writing code examples to drive design and tests to talk about actual testing. Perhaps it could be phrased as, you start with examples and when you&#8217;re done you end up with tests. Similar to starting with user stories and ending up with features. Right now that works in my head, but it&#8217;s late and I may need to revisit that thought after a few hours of sleep.&lt;/p&gt;


	&lt;p&gt;Example is just a better word then test to. When you talk to someone and you don&#8217;t understand what they&#8217;re talking about you don&#8217;t say, &#8220;give me a test&#8221;, you say, &#8220;give me an example&#8221;. Well, that language is more natural. You are providing an example of how something should work. This example ends up providing regression (test) value once its implemented, but you didn&#8217;t start with a test, you started with an example of the code you wanted.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.continuousthinking.com/">
    <author>
      <name>zdennis</name>
    </author>
    <id>tag:www.continuousthinking.com,2009-05-28:589</id>
    <published>2009-05-28T06:05:00Z</published>
    <updated>2009-05-29T15:19:47Z</updated>
    <link href="http://www.continuousthinking.com/2009/5/28/bdd-not-so-much-really" rel="alternate" type="text/html"/>
    <title>BDD not so much, really?</title>
<content type="html">
            &lt;p&gt;&lt;strong&gt;Updated May 29, 2009&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;This rant is in response to &lt;a href='http://robertlally.com/post/bdd-not-so-much'&gt;http://robertlally.com/post/bdd-not-so-much&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;&lt;span class='caps'&gt;BDD&lt;/span&gt; didn&#8217;t start off as a replacement for &lt;span class='caps'&gt;TDD&lt;/span&gt;. It started off a way to better understand and explain the process of &lt;span class='caps'&gt;TDD&lt;/span&gt;. The name change as I understand it was to communicate the intent of &lt;span class='caps'&gt;TDD&lt;/span&gt; in a clearer and more direct way. You&#8217;re not writing tests for the sake of writing tests, you&#8217;re driving behaviour. Focus on the behaviour you want to achieve first and foremost. Use that behaviour as the driving force for your examples (or tests).&lt;/p&gt;


	&lt;p&gt;Corey Haines nailed it on his comment to the same post, &#8220;BDD is no longer a replacement for &lt;span class='caps'&gt;TDD&lt;/span&gt;, but, rather it is a workflow for creating a system that more closely resembles what the client is looking for.&#8221; I think two of best tools which exist to support the &lt;span class='caps'&gt;BDD&lt;/span&gt; workflow of outside-in are Cucumber and RSpec. Cucumber for higher level system behaviour and RSpec for driving lower level design.&lt;/p&gt;


	&lt;p&gt;In the article, the author criticizes the &#8220;should&#8221; language. Rather than simply scoffing at the idea of replacing &#8220;assert&#8221; with &#8220;should&#8221;, I tend to think about it in terms of natural communication. The reason I like &#8220;should&#8221; language over &#8220;assert&#8221; language is that when I&#8217;m communicating with another developer I don&#8217;t say, &#8220;assert equal one day to do things good&#8221;. That doesn&#8217;t make any sense. I say, &#8220;one day to do things to should be good&#8221;. It&#8217;s much more natural for me to write closer to the language I think and communicate than it is to translate it to assertion-speak. I want to communicate in my code more closely to how I communicate to other people.&lt;/p&gt;


	&lt;p&gt;While the term &lt;span class='caps'&gt;BDD&lt;/span&gt; is a few years old it takes a while for dialogue to happen, and understanding to occur. I&#8217;m sure a lot of people hear about &lt;span class='caps'&gt;BDD&lt;/span&gt;, read about it from Dan North&#8217;s &lt;a href='http://dannorth.net/introducing-bdd'&gt;Introducing &lt;span class='caps'&gt;BDD&lt;/span&gt;&lt;/a&gt; . &lt;span class='caps'&gt;BDD&lt;/span&gt; started as a way to explain and better understand &lt;span class='caps'&gt;BDD&lt;/span&gt;, but what I think was realized was that it was much more than simply &lt;span class='caps'&gt;TDD&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;Many tools are emerging which claim to support &lt;span class='caps'&gt;BDD&lt;/span&gt;-style development. It&#8217;s important to note that &lt;span class='caps'&gt;BDD&lt;/span&gt; isn&#8217;t the tool. You can have many tools support &lt;span class='caps'&gt;BDD&lt;/span&gt; style development in different ways and to different degrees. Although a good tools makes any process easier, what makes &lt;span class='caps'&gt;BDD&lt;/span&gt; is the mindset you have and how you go about writing software. Certain tools emerged with this in mind and are thus labeled &lt;span class='caps'&gt;BDD&lt;/span&gt; tools. Cucumber, RSpec, and JBehave are some examples.&lt;/p&gt;


	&lt;p&gt;The article mistakingly sheds Cucumber in the light of solely driving the design of code and suggests its a bad tool to do that. Of course it is! It is not a tool intended to drive the design of your code from a low level. It is to communicate in plain text how the application should behave. The plain text is something that is business readable, something that adds value not at the code design level, but at a higher level: communication and understanding requirements!&lt;/p&gt;


	&lt;p&gt;Cucumber is equivalent to a high level integration test for those of you who come from a testing background. It runs the entire application (or whatever can be reached through automation, different types of systems have different limitations). It works in combination with a tool used to drive out the design of your application using lower level code examples. For example, RSpec.&lt;/p&gt;


	&lt;p&gt;The #1 output of &lt;span class='caps'&gt;BDD&lt;/span&gt; is a working application that is behaving as expected. In addition to that you have an application-level regression suite in which you can run against the code base at any time. You also end up with smaller, more focused code examples which provide regression against isolated behaviour of the system.&lt;/p&gt;


	&lt;p&gt;Combined, you end up with documentation at two critical aspects. The first is business readable scenarios that the system supports. The second is developer documentation made up of the lower level code examples. Since these are often written more clearly than assert-style syntax it&#8217;s easy to produce human readable behaviour specifications for focused pieces of behaviour. And in the end you have a repeatable process which allows you to confidently produce the working software.&lt;/p&gt;


	&lt;p&gt;I also don&#8217;t see where &lt;span class='caps'&gt;UML&lt;/span&gt; to &lt;span class='caps'&gt;BDD&lt;/span&gt; comparisons make any sense. &lt;span class='caps'&gt;UML&lt;/span&gt; is a modeling language. &lt;span class='caps'&gt;BDD&lt;/span&gt; is more of an approach or methodology. A more accurate comparison would be plain text scenarios vs. &lt;span class='caps'&gt;UML&lt;/span&gt;. Although that makes little sense as a comparison because &lt;span class='caps'&gt;UML&lt;/span&gt; is not something you can give a non technical person to write, read, and edit.&lt;/p&gt;


	&lt;p&gt;&lt;span class='caps'&gt;BDD&lt;/span&gt; by itself doesn&#8217;t fix any problems. It provides an approach which focuses on behaviour first. To me, there&#8217;s no point in building a low level library if you&#8217;re not aware what higher level problem you&#8217;re solving or objective you&#8217;re adding value to. This boils down to a person still has to &#8220;do the work&#8221; to make it successful.&lt;/p&gt;


	&lt;p&gt;At the end of the day though I cannot speak for anyone else except myself. Shifting my focus on behaviour rather than &#8220;tests&#8221; led me to write better code examples. Often times I would write less of these because I was writing better examples. It&#8217;s also helped improve communication between myself and my team, customers, and other developers. &lt;span class='caps'&gt;BDD&lt;/span&gt; may evolve into something else, or perhaps a new perspective will come around that will take the world by storm. I am all about continuous learning and improvement. And I invite any ideas Mr. Lally or anyone else brings to the table.&lt;/p&gt;


	&lt;p&gt;Also, &lt;span class='caps'&gt;BDD&lt;/span&gt; never claimed to be &lt;span class='caps'&gt;THE&lt;/span&gt; answer. Any process that claims to be &lt;span class='caps'&gt;THE&lt;/span&gt; answer will surely not be &lt;span class='caps'&gt;THE&lt;/span&gt; answer for everyone in all situations. &lt;span class='caps'&gt;BDD&lt;/span&gt; has been an answer for many people though and as of now it will continue to be an answer for me in how I work.&lt;/p&gt;


	&lt;p&gt;A good resource worth checking out for &lt;span class='caps'&gt;BDD&lt;/span&gt;, it&#8217;s philosophy, and how to apply it in practice is &lt;a href='http://www.pragprog.com/titles/achbd/the-rspec-book'&gt;The RSpec Book&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.continuousthinking.com/">
    <author>
      <name>zdennis</name>
    </author>
    <id>tag:www.continuousthinking.com,2009-05-09:588</id>
    <published>2009-05-09T03:18:00Z</published>
    <updated>2009-05-09T03:18:53Z</updated>
    <link href="http://www.continuousthinking.com/2009/5/9/rspec-cucumber-ml-email-etiquette" rel="alternate" type="text/html"/>
    <title>rspec/cucumber ML email etiquette</title>
<content type="html">
            &lt;p&gt;&lt;a href='http://blog.aslakhellesoy.com/'&gt;Aslak Hellesoy&lt;/a&gt; &lt;a href='http://www.ruby-forum.com/topic/186233'&gt;requested&lt;/a&gt; on the rspec/cucumber mailing list the other day that folks stop top posting. His words:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;I find it really hard to follow conversations that use top posting (http://en.wikipedia.org/wiki/Posting_style). If you have a [Cucumber] topic, please respond with inline comments. And use plain text email &#8211; not html.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;I agree with Aslak&#8217;s request for the most part. There are times when top posting is perfectly acceptable, but those are too often blurred by the countless times where people are just plain lazy. While most of the replies have been rather humorous in response a couple recent replies have the look of actual requests to the community: snip out things not pertaining to your reply and the removal signatures.&lt;/p&gt;


	&lt;p&gt;The only part I don&#8217;t agree with is the text email. I&#8217;m sorry, but if you use an email client which can&#8217;t show html, or can&#8217;t not show the html part of an email then you need to find a new email client. I have the feeling Aslak was referring to folks that only send &lt;span class='caps'&gt;HTML&lt;/span&gt; email, void of a plain text part. If that&#8217;s the case I am in full agreement with his request.&lt;/p&gt;


	&lt;p&gt;Aslak&#8217;s request was well intended and thoughtfully brought about. I hope the replies stop before there is a giant list of dos and donts, followed by a flamewar that will most likely have a negative impact on such a wonderful community.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.continuousthinking.com/">
    <author>
      <name>zdennis</name>
    </author>
    <id>tag:www.continuousthinking.com,2009-04-28:587</id>
    <published>2009-04-28T10:02:00Z</published>
    <updated>2009-04-28T10:03:10Z</updated>
    <category term="ruby"/>
    <link href="http://www.continuousthinking.com/2009/4/28/rspactor-love-cucumber" rel="alternate" type="text/html"/>
    <title>RSpactor, love Cucumber</title>
<content type="html">
            &lt;p&gt;If &lt;a href='http://rubyphunk.com/tags/rspactor'&gt;RSpactor&lt;/a&gt; loved Cucumber it&#8217;d be even more amazing. From the &lt;a href='http://github.com/rubyphunk/rspactor/issues/#issue/1'&gt;ticket&lt;/a&gt; request:&lt;/p&gt;


&lt;pre&gt;
It would be amazing if RSpactor integrated with Cucumber although 
it would need to be a different than how it currently works with 
RSpec. Now that Cucumber has tag support I think this good be done 
in a reasonable way that improved the developer workflow for 
projects that utilized Cucumber.

Here's an example. When I am working on changing how money is 
managed in my app I know that I want to run the features tagged 
@accounting. At the start of my work it'd be great if I could 
add the @accounting tag to RSpactor so it would run those 
features after it successfully ran specs. 

Perhaps there would also be a preference setting which auto 
ran the Cucumber scenarios after specs ran, or one that forced 
you to manually hit play. Although if you had typed in tags, 
it the play button would run cucumber with those tags. 
&lt;/pre&gt;

	&lt;p&gt;Got a better idea for Cucumber integration? Join the discussion! &lt;a href='http://github.com/rubyphunk/rspactor/issues/#issue/1'&gt;http://github.com/rubyphunk/rspactor/issues/#issue/1&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.continuousthinking.com/">
    <author>
      <name>zdennis</name>
    </author>
    <id>tag:www.continuousthinking.com,2009-04-08:586</id>
    <published>2009-04-08T01:15:00Z</published>
    <updated>2009-04-09T21:12:36Z</updated>
    <link href="http://www.continuousthinking.com/2009/4/8/managing-client-expectations" rel="alternate" type="text/html"/>
    <title>Managing Client Expectations</title>
<content type="html">
            &lt;p&gt;Managing client expectations is simple, but like most things simple&#8212;it&#8217;s very 
hard to do, do right, and do consistently. I think this is a common problem
in today&#8217;s web development companies. The industry has a lot of young, creative,
and smart people building companies with little to no experience in customer
relations. For every person who is naturally gifted or good at managing
client expectations there are probably several more people who just don&#8217;t get it. And 
the worst part, is that they probably aren&#8217;t aware of the fact that they don&#8217;t get it.&lt;/p&gt;


	&lt;p&gt;I&#8217;m one of those young, creative, and somewhat smart people in the industry
trying to build a &lt;a href='http://www.mutuallyhuman.com'&gt;company&lt;/a&gt; in the web industry, but this is an issue that
has been nagging me for months, and it&#8217;s to the point where I feel like 
it needs to be shouted from the mountain tops (although this blog is probably more like a anthill). 
It may not be the best business
decision on my part since it encourages competing companies
to become better. If they do it will make us humans work that much harder.&lt;/p&gt;


	&lt;p&gt;I&#8217;m sorry to say it, but few web development companies seem to do a good job of 
development and a good job of managing client expectations. Maybe your company is good at development, but
stinks at managing client expectations. Or maybe it&#8217;s the other way around and you are great with the customer,
but your team is a bunch of junior developers who crank out crap. Oddly enough, if your company falls into
the latter you have a much better chance of being successful and surviving than the former.&lt;/p&gt;


	&lt;p&gt;Before look at some of the effects of managing (and failing to manage) client expectations let&#8217;s start with a simple definition:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Managing client expectations is the ability communicate proactively with the client in a reasonable and realistic manner that allows them to take ownership of decisions that may affect their project or business.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Managing client expectations is about communicating honestly, openly, and often with the client. It requires informing them of things that have the potential to impact their business or their project. I use the term &lt;em&gt;proactive&lt;/em&gt; in the definition because you&#8217;re not doing it right if you do something and than communicate after the fact. Heck, doing that is like this the plumber who came to your house and failed to manage your expectations:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;A plumber comes to your house to fix your toilet. At first glance it looks like it&#8217;ll take an hour to do so you set aside $100 on the counter to cover the cost and leave so the plumber can work in peace. While working the plumber discovers a much bigger plumbing problem. He&#8217;s really in the zone though, so rather than calling you he just does what&#8217;s necessary to fix the issue. You get home later in the day, and on the counter you see your $100. Next to it is an invoice for $2,200 and a note that reads: &lt;em&gt;I ran into a bigger problem, but I was really in the zone so I replaced the plumbing in the basement because it would have had to have been done.&lt;/em&gt;&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Do you feel the plumber did a good job of managing your expectations? Would you hire that plumber back? Would you pay the bill? I would answer three hell nos. Yet, many web developers and young web entrepreneurs find this perfectly acceptable and they wouldn&#8217;t think twice about doing it. To them it&#8217;s just how you move a project along its merry little way.&lt;/p&gt;


	&lt;p&gt;For folks who aren&#8217;t aware this is a problem&#8212;&lt;em&gt;it is a problem and you should stop doing it&lt;/em&gt;. For folks who do it and know they do it, &lt;em&gt;wake up&lt;/em&gt;, its unhealthy for your client, you, and your business.&lt;/p&gt;


	&lt;p&gt;I think it&#8217;s universal knowledge that finding a new client is more costly then keeping a client. Every time you interact
with a client you have a chance to increase or decrease your likelihood of keeping them as a client. When you manage
their expectations well you will most likely keep them. Here are three general reasons why:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;build a healthy relationship&lt;/li&gt;
		&lt;li&gt;build trust&lt;/li&gt;
		&lt;li&gt;empower the client, giving them ownership&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h2&gt;Positive effects of managing client expectations&lt;/h2&gt;


	&lt;h3&gt;Build a healthy relationship&lt;/h3&gt;


	&lt;p&gt;Every time you interact with a client you have the ability to build a slightly better relationship. Setting clear expectations with the client with good solid communication strengthens the bond between you and your customer. Customers who have a healthy relationship w/their suppliers are not likely to jump ship.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;A new developer joins your team. Every time you work with him you notice he takes the time do things right rather than just quick. He also seem to ask questions and raise questions at all the right times. You find yourself comfortable working with him and before you know if you even think that you do better when working with him. When the developer&#8217;s 90 day review comes up you&#8217;re first to speak up and ask the team to keep him.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;h3&gt;Build trust&lt;/h3&gt;


	&lt;p&gt;Part of building a healthy relationship is trust. To me, trust is like trying to level a character in EverQuest. As you build up stats and level you gain a new skill or perhaps a new magic. The higher you level the more your character is capable of. The same is true for the relationship with a client. As you achieve new levels of trust with your client you achieve new capabilities for doing things. Perhaps your client sends you more work. Perhaps your client refers you to his peers and to other companies. Perhaps your client invites you to more business-oriented meetings because he wants you involved in streamlining technical aspects of their business. Perhaps you become the goto shop for your client&#8217;s organization. Without trust this is not possible.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;A new developer joins your team. After the first few months of working with her you find she is a good, honest, hard working, and capable developer. You build up trust in her as a developer. A potential client comes in and you need to send over a couple developers to help kick off the first Planning Game and do some story estimation. You send her. You know she&#8217;ll do a good job, ask questions, and be honest.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;h3&gt;Empower the client, giving them ownership&lt;/h3&gt;


	&lt;p&gt;Empowering the client is something that we really need to do a better job of in our industry. Managing a clients expectations lets the client own the decisions that need to be made that impact their project or business. These decisions are not ours to make, they are our clients. When the client owns the decisions, they own the project, they own the direction of the project. This isn&#8217;t to say we don&#8217;t guide or assist our clients in finding that direction. This is one of the many reasons we are often hired, however, when a client gives you permission to make decisions for them, &lt;em&gt;they made that decision&lt;/em&gt;. When that&#8217;s not the case and we make decisions for the clients we are simply being lazy and bad vendors.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;As a developer who practices Behaviour Driven Development I want my customers to own the scenarios that are written to drive the development of an application. The customer may physically write any of the scenarios. I may type them while sitting with the client, or during a phone call, but I am merely being a scribe. They own the scenarios. I never want the customer to feel that scenarios are written simply to translate business speak to technical speak, I want the customer to own the scenarios so its clear to them what they are paying me to build. Doing this empowers the client, it gives them ownership. They are usually much more engaged in the project when this happens.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;h2&gt;Negative effects of failing to manage client expectations&lt;/h2&gt;


	&lt;p&gt;Now, when you don&#8217;t manage client expectations you can have the opposite effect:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;hurt the relationship&lt;/li&gt;
		&lt;li&gt;lose trust &lt;/li&gt;
		&lt;li&gt;empower yourself, taking ownership away from the client&lt;/li&gt;
		&lt;li&gt;increase the risk you negatively impact the clients business&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h3&gt;Hurt the relationship&lt;/h3&gt;


	&lt;p&gt;Not managing client expectations hurts the relationship. You may get away with it once, twice, or even three times, but sooner or later you will guess wrong and your customer will be ticked off. This is usually when they start looking for a new vendor.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Your customer has a feature they want added. You estimate 50 hours. It ends up taking you 110 hours. You don&#8217;t tell the client, you simply send them a bill. The customer is ticked, he asks that you stop working until the bill can be addressed. He wants to do a phone call with you to dispute the bill. Your customer is not happy.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;h3&gt;Lose trust&lt;/h3&gt;


	&lt;p&gt;Losing trust is a part of hurting a relationship, but trust is so important on its own. Most companies want to be a partner with the client. They want the client to leverage their expertise in solving a problem. If we don&#8217;t have that kind of relationship we lack the trust required for the customer to to utilize us in that way.
Every time we fail to manage a client&#8217;s expectations we lose a level of trust. At some point its gone, and we&#8217;re out of the picture.&lt;/p&gt;


	&lt;h3&gt;Empower yourself, taking ownership away from the client&lt;/h3&gt;


	&lt;p&gt;Making decisions that affect the client&#8217;s project or business are a big no no. It takes ownership away from the client and only empowers yourself, but that empowerment only lasts a short while. You may have won the battle, but you will surely lose the war. First of all, decisions that impact the client&#8217;s project or business are theirs to make&#8212;not yours. Sometimes an emergency arises, the app is down! Chaos ensues! What to do? One of the very first things you do is call your client and give them the ability to say &#8220;no, don&#8217;t fix it&#8221;. Even though that answer may be highly unlikely, its not your decision to make, unless you have an arrangement with your client to make those decisions. Perhaps you have an agreement which covers what to do in those circumstances. If you do, more power to you. If you don&#8217;t, you may want to consider getting one.&lt;/p&gt;


	&lt;p&gt;Maybe you&#8217;re wondering what happens if you can&#8217;t reach the client? Do you wait to fix it until they call you back? I would say that depends on the nature of the issue. At minimum you should leave a voicemail and send a quick email, both which have your contact information. Doing this allows you to do everything reasonably possible to contact the client of the issue. And it may add 30 seconds to 2 minutes of overhead. This is usually reasonable. However, this is one of those times where it depends based on the relationship you have with your client. Fixing the issue first and responding later may be acceptable based on your arrangement. My belief is that if that&#8217;s not your arrangement than you should be contacting your client. Well, you should be contacting them anyways&#8212;that&#8217;s just being a good vendor.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;The client&#8217;s site goes down. You get a call from one of their programmers (not a decision maker or gold owner) about it. You log in, evaluate, and decide to tackle it. Some time later you get it fixed! Woot! Invigorating, wasn&#8217;t it? Then you send a bill to the client. The person who pays the bill and has decision making power for paying the bill is very upset. Why a $1,200 bill? And why wasn&#8217;t he made aware of it? He heard from his one of his programmers their was an issue, but that it got resolved, why is the vendor sending a bill?!!&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;h3&gt;Increase the risk you negatively impact the clients business&lt;/h3&gt;


	&lt;p&gt;Every time you make a reckless decision on behalf of your client without having some kind of prior arrangement or relationship in place you increase the risk that you will negatively impact their project or business. These are risks that are not yours to own, they are your clients. They always deserve the ability to say &#8220;no&#8221; even if it seems highly unlikely. The only time they shouldn&#8217;t have that option is if someone&#8217;s physical health is in immediate danger, but I haven&#8217;t seen any webapps running medical equipment, handling stop lights, or coordinating the release of water at Hoover Dam.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.continuousthinking.com/">
    <author>
      <name>zdennis</name>
    </author>
    <id>tag:www.continuousthinking.com,2009-04-03:585</id>
    <published>2009-04-03T02:30:00Z</published>
    <updated>2009-04-03T02:31:11Z</updated>
    <link href="http://www.continuousthinking.com/2009/4/3/bdd-w-rails-class" rel="alternate" type="text/html"/>
    <title>BDD w/Rails Class</title>
<content type="html">
            &lt;p&gt;Shortly after RailsConf and while &lt;a href='http://www.pragprog.com/titles/achbd/the-rspec-book'&gt;The RSpec Book&lt;/a&gt; is hitting the printers I&#8217;m going to be teaching a &lt;span class='caps'&gt;BDD&lt;/span&gt; w/Rails class with the amazing guys at &lt;a href='http://www.collectiveidea.com'&gt;Collective Idea&lt;/a&gt;&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Official announcement &#8211; &lt;a href='http://mutuallyhuman.com/2009/4/3/bdd-with-rails-class'&gt;http://mutuallyhuman.com/2009/4/3/bdd-with-rails-class&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;Offical Course  &#8211; &lt;a href='http://ideafoundry.info/behavior-driven-development'&gt;http://ideafoundry.info/behavior-driven-development&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Hope to see you there!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.continuousthinking.com/">
    <author>
      <name>zdennis</name>
    </author>
    <id>tag:www.continuousthinking.com,2009-03-20:583</id>
    <published>2009-03-20T00:00:00Z</published>
    <updated>2009-03-20T00:01:19Z</updated>
    <link href="http://www.continuousthinking.com/2009/3/20/scenario-observation" rel="alternate" type="text/html"/>
    <title>Scenario Observation</title>
<content type="html">
            &lt;p&gt;One of the hardest things about being the developer and the scenario
writer is that we&#8217;re in the thick of it. Once we get something written
down we want to get it to work and then move on. This may involve copy
and pasting part of an existing scenario to just get the job done. We
get antsy.&lt;/p&gt;


	&lt;p&gt;One of the benefits of having the customer (or someone else) write the
scenario is that we get to be the critic and not the author. We can
focus on the scenario and ask questions like: does it read well? Is it
doing too much? Is doing little? Can I understand its intent? etc.
etc.&lt;/p&gt;


	&lt;p&gt;When working with a pair our pair should really challenge us to write
good, communicating, intention revealing scenarios (just like they
should be doing with code). This can be hard when we are working solo
because we may just be staring at the screen for too long, and we
can&#8217;t see the forest for the trees. If that&#8217;s the case grab someone
else for a quick review, even if it&#8217;s after you finish implementing
the scenario. Refactoring applies to scenarios to.&lt;/p&gt;


	&lt;p&gt;Scenarios are like code, if we don&#8217;t tend them well, they will grow
messy and hard to maintain. We are best served to spend a little time
upfront to keep them tidy rather than wait until we have hundreds of
steps that don&#8217;t do a good job of communicating and require people to
have to read through all of the step definitions to figure it out.&lt;/p&gt;


	&lt;p&gt;Go forth and code! ;)&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.continuousthinking.com/">
    <author>
      <name>zdennis</name>
    </author>
    <id>tag:www.continuousthinking.com,2009-03-17:582</id>
    <published>2009-03-17T02:09:00Z</published>
    <updated>2009-03-17T02:09:53Z</updated>
    <link href="http://www.continuousthinking.com/2009/3/17/ar-extensions-0-8-2-released" rel="alternate" type="text/html"/>
    <title>ar-extensions 0.8.2 released</title>
<content type="html">
            &lt;p&gt;ar-extensions 0.8.2 is released. This release fixes compatibility issues with Rails 2.3.1 and Rails 2.3.2. It should show up soon at a rubygems mirror near you.&lt;/p&gt;


	&lt;p&gt;Thanks to Stephen Heuer, Glenn Rempe, and Michael Murray.&lt;/p&gt;


&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;gem install ar-extensions -v &lt;span class='fl'&gt;0.8&lt;/span&gt;.&lt;span class='i'&gt;2&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
          </content>  </entry>
</feed>
