<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>Paul's techie blog</title>
    <link>http://blogofpaul.merecomplexities.com/articles</link>
    <pubDate>Fri, 14 Oct 2011 11:04:11 GMT</pubDate>
    <description>Paul's blog.</description>
    <language>en-gb</language>
    
    <feedburner:info uri="paulstechieblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://paulwilson.blogspot.com/atom.xml" /><feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site.</feedburner:browserFriendly><item>
      <title>Having a CI server != Continuous Integration</title>
      <link>http://feedproxy.google.com/~r/PaulsTechieBlog/~3/2AzC0rUr3EY/272</link>
      <description>&lt;blockquote&gt;
&lt;p&gt;Although Continuous Integration is a practice that requires no particular tooling to deploy, we&amp;#8217;ve found that it is useful to use a Continuous Integration server. &amp;#8211; &lt;a href="http://martinfowler.com/articles/continuousIntegration.html"&gt;Martin Fowler&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The map is not the territory. The tool is not the practice. Having a Continuous Integration Server is not the same as continuously integrating. Continuously integrating means that your team is:-&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;working on the same source control branch&lt;/li&gt;
	&lt;li&gt;checking in and pushing frequently, ie several times a day&lt;/li&gt;
	&lt;li&gt;only pushing working code that keeps the test clean&lt;/li&gt;
	&lt;li&gt;avoiding long-lived feature branches&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A CI server is a useful but not essential tool for continuous integration; there are teams running a CI server that are not continuously integrating.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/PaulsTechieBlog/~4/2AzC0rUr3EY" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 14 Oct 2011 11:04:11 GMT</pubDate>
      <guid isPermaLink="false">http://blogofpaul.merecomplexities.com/articles/272</guid>
    <feedburner:origLink>http://blogofpaul.merecomplexities.com/articles/272</feedburner:origLink></item>
    <item>
      <title>Nordic Ruby 2011 - Summary of Day 1</title>
      <link>http://feedproxy.google.com/~r/PaulsTechieBlog/~3/6_XGVIPqNqU/271</link>
      <description>&lt;p&gt;Nordic Ruby is a well crafted conference. The overwhelming impression that I have is of calm attention to detail. The organisers &lt;a href="https://twitter.com/cjkihlbom"&gt;CJ&lt;/a&gt; and &lt;a href="http://twitter.com/lilly"&gt;Lilly&lt;/a&gt; have done a superb job.  The conference has been much more than just the scheduled talks, but they are what I am focussing on here.&lt;/p&gt;
&lt;h2&gt;Git Hub Flavoured Ruby &amp;#8211; &lt;a href="http://twitter.com/mojombo"&gt;Tom Preston-Werner&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Tom Preston-Werner gave us some concrete engineering practices and tools, honed during the development of &lt;a href="https://github.com"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://tom.preston-werner.com/2010/08/23/readme-driven-development.html"&gt;Readme Driven Development&lt;/a&gt; is a simple idea: writing the &lt;em&gt;Readme&lt;/em&gt; before writing any code for a project forces you to clarify the goals and do just enough planning.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://tomdoc.org/"&gt;TomDoc&lt;/a&gt; provides more structure to class and method documentation than &lt;a href="http://rdoc.sourceforge.net/"&gt;RDoc&lt;/a&gt; in a more readable form that &lt;a href="http://yardoc.org/"&gt;&lt;span class="caps"&gt;YARD&lt;/span&gt;&lt;/a&gt;. A nice feature is the ability to mark a method as part of a project&amp;#8217;s public &lt;span class="caps"&gt;API&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Using &lt;a href="http://semver.org/"&gt;Sematic Versioning&lt;/a&gt;, particularly for Gems, helps keep your clients from dependency hell. In a nutshell, semantic versioning is &lt;em&gt;Major.Minor.Patch&lt;/em&gt;, and only major version increments may break backwards compatibility.  This way you can use &lt;a href="http://robots.thoughtbot.com/post/2508037841/twiddle-wakka"&gt;Twiddle Wakka&lt;/a&gt; in your Gemfile with confidence.&lt;/p&gt;
&lt;p&gt;This was all good stuff, but the next idea is dynamite: &lt;em&gt;Make Believe Open Source&lt;/em&gt; is a superb concept for modularising projects; rather than writing monolithic applications, pretend that every area of functionality is going to be open sourced, and split it into a separate module/gem. The &lt;em&gt;Path&lt;/em&gt; element on a &lt;a href="http://gembundler.com/"&gt;Bundler&lt;/a&gt; can be a useful way of getting started. I am looking forward to see how this works with Rails.&lt;/p&gt;
&lt;h2&gt;&lt;span class="caps"&gt;API&lt;/span&gt; Design Matters &amp;#8211; &lt;a href="http://twitter.com/aeden"&gt;Anthony Eden&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Good APIs should be suffient, powerful, consistent, clear, convenient, and complete. They should demonstrate the &lt;a href="http://en.wikipedia.org/wiki/Principle_of_least_astonishment"&gt;Principle of Least Surprise&lt;/a&gt;, and be economical with concepts.  The best &lt;span class="caps"&gt;API&lt;/span&gt; is no &lt;span class="caps"&gt;API&lt;/span&gt;, meaning if you can get away with (say) implementing Enumberable then do just that.&lt;/p&gt;
&lt;h2&gt;Bridging the gap &amp;#8211; Using Javascript in Rails to write &lt;span class="caps"&gt;DRY&lt;/span&gt; rich client applications &amp;#8211; &lt;a href="http://twitter.com/torbenschroeder"&gt;Thorben Schröder&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;How do you eliminate duplication when you have similar code implemented in JavaScript in the browser and Ruby on the server?  Jon Crosby addressed this with his &lt;a href="http://confreaks.net/videos/167-rubyconf2009-embracing-collaboration-with-jruby-and-javascript"&gt;2009 RubyConf talk&lt;/a&gt;, settling at the time with JRuby and Rhino.  Thorben demonstrated that this can now be done by embedding &lt;a href="http://code.google.com/p/v8/"&gt;V8&lt;/a&gt; in &lt;span class="caps"&gt;MRI&lt;/span&gt;, using &lt;a href="https://github.com/cowboyd/therubyracer"&gt;therubyracer&lt;/a&gt; and &lt;a href="http://www.commonjs.org/"&gt;CommonJS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I can not help the (slightly) uncomfortable feeling that this leads us to writing the server side of web apps in JavaScript (or CoffeeScript).&lt;/p&gt;
&lt;h2&gt;The Limited Red Society &amp;#8211; &lt;a href="http://twitter.com/josephwilk"&gt;Joseph Wilk&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A lovely short talk by Joseph, on using feedback provided by metrics to minimise the red part of the Red-Green-Refactor cycle. Joseph demonstrated &lt;em&gt;Red&lt;/em&gt; to be synonymous with the &lt;em&gt;Work In Progress&lt;/em&gt; concept of &lt;a href="http://en.wikipedia.org/wiki/Lean_manufacturing"&gt;Lean&lt;/a&gt;: while the code is Red it can not be integrated.&lt;/p&gt;
&lt;h2&gt;Must It Always Be About Sex? &amp;#8211; &lt;a href="http://twitter.com/jaw6"&gt;Joshua Wehner&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Not only did Joshua call out the Ruby community&amp;#8217;s Sex, Race, and Age imbalance.  By citing research that demonstrates that more diverse teams perform better, he showed that the imbalance is harmful. Suggestions to mitigate the imbalance included anonymising job applications, and even GitHub profiles, to prevent (research demonstrated) unconscious bias based on applicants names.&lt;/p&gt;
&lt;p&gt;This deserves a much longer post, but in the meantime it is well worth a look at &lt;a href="http://twitter.com/coolaunterin"&gt;Erin O&amp;#8217;Brien&amp;#8217;s&lt;/a&gt; talk at The Scottish Ruby Conference, &lt;a href="http://confreaks.net/videos/567-scotlandruby2011-where-are-all-the-women"&gt;Where Are All The Women&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Infinte Date &amp;#8211; Finite Solutions &amp;#8211; &lt;a href="http://twitter.com/daksis"&gt;Randall Thomas&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Maths, whisky, &lt;a href="http://en.wikipedia.org/wiki/Bayesian_inference"&gt;Bayesian Statistics&lt;/a&gt;, and recreating Bach. What more could a talk need?&lt;/p&gt;
&lt;h2&gt;Taking Back Education &amp;#8211; &lt;a href="http://twitter.com/objo"&gt;Joe O&amp;#8217;Brien&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Joe argues that Computer Science education is largely broken, and how we should fix it, citing the wide educational background of many effective Ruby Developers and the apprenticeship  programmes of &lt;a href="http://edgecase.com/"&gt;EdgeCase&lt;/a&gt; and other boutique Ruby development shops.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/PaulsTechieBlog/~4/6_XGVIPqNqU" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 18 Jun 2011 17:08:23 GMT</pubDate>
      <guid isPermaLink="false">http://blogofpaul.merecomplexities.com/articles/271</guid>
    <feedburner:origLink>http://blogofpaul.merecomplexities.com/articles/271</feedburner:origLink></item>
    <item>
      <title>I should write</title>
      <link>http://feedproxy.google.com/~r/PaulsTechieBlog/~3/kC3HHxLKegQ/270</link>
      <description>&lt;p&gt;It&amp;#8217;s over 18 months since my last blog post, about &lt;a href="http://confreaks.net/events/rubyconf2009/"&gt;RubyConf 2009&lt;/a&gt;.  There&amp;#8217;s a lot happened since then, including two &lt;a href="http://scottishrubyconference.com/posts"&gt;Scottish Ruby Conferences&lt;/a&gt; that I jointly organise, &lt;a href="http://confreaks.net/events/rubyconf2010/"&gt;RubyConf 2010&lt;/a&gt; that I &lt;a href="http://confreaks.net/videos/458-rubyconf2010-automated-acceptance-testing-the-vietnam-of-test-driven-development"&gt;spoke at&lt;/a&gt;, and the rise of &lt;a href="http://edgecase.com/"&gt;EdgeCase&lt;/a&gt; in the UK which I am very much part of.&lt;/p&gt;
&lt;p&gt;I am not alone in replacing my blog, with a &lt;a href="http://twitter.com/paulanthonywils"&gt;Twitter account&lt;/a&gt;. I do feel poorer for not publicly expressing myself in more than 140 characters.&lt;/p&gt;
&lt;p&gt;Writing similar to taking physical exercise: once I stop it gets very hard (and embarrassing) to start again.  Here goes an attempt to start again.  Wish me success.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/PaulsTechieBlog/~4/kC3HHxLKegQ" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 18 Jun 2011 04:59:38 GMT</pubDate>
      <guid isPermaLink="false">http://blogofpaul.merecomplexities.com/articles/270</guid>
    <feedburner:origLink>http://blogofpaul.merecomplexities.com/articles/270</feedburner:origLink></item>
    <item>
      <title> News from RubyConf 2009</title>
      <link>http://feedproxy.google.com/~r/PaulsTechieBlog/~3/g6z7EsUSI58/269</link>
      <description>&lt;div style="float:right"&gt;&lt;a href="http://bestc.am/PtSV"&gt;&lt;img src="http://s3.amazonaws.com/cjapps/images/138825/iphone.jpg" title="Why tribute" alt="Why tribute" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Q: What would you like to see in Ruby in 5 years? Matz: Smiles on everybody&amp;#8217;s face at RubyConf 2014.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I avoid using the word &amp;#8216;Awesome&amp;#8217;; I leave that to the kids.  &lt;a href="http://rubyconf.org"&gt;RubyConf 2009&lt;/a&gt; has been, well, pretty damn good. The quality of talks has been outstanding and the community is just superb.  Well done Chad, Kelly, and David for putting this together.  My favourite moment was when during this morning&amp;#8217;s Matz Q&amp;amp;A session someone asked whether we could have a __DIR__ constant to avoid the ugly File.dirname(__FILE__) that we often need to write.  There was a quick discussion in Japanese, followed by the answer &amp;#8216;Ok&amp;#8217;.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m not going to give a blow-by-blow account of the conference. The videos will be out soon on &lt;a href="http://www.confreaks.com/"&gt;Confreaks&lt;/a&gt;.  There were a few things that really excited me, though.  If I were to put a theme on the conference it would be Different Ruby, Fast Ruby, Interoperability, And Stuff That&amp;#8217;s Not Ruby.  There was a lot of non-&lt;a href="http://en.wikipedia.org/wiki/Ruby_MRI"&gt;&lt;span class="caps"&gt;MRI&lt;/span&gt;&lt;/a&gt; and hacked &lt;span class="caps"&gt;MRI&lt;/span&gt; around.&lt;/p&gt;
&lt;p&gt;Of course Charles Nutter and Thomas Enebo showed us just how fantastic a job that they are doing with &lt;a href="http://en.wikipedia.org/wiki/Ruby_MRI"&gt;JRuby&lt;/a&gt;.  &lt;a href="http://www.macruby.org/"&gt;MacRuby&lt;/a&gt; is getting even more interesting.  New to me was the focus on Server-Side development. &lt;a href="http://twitter.com/lrz"&gt;Laurent&lt;/a&gt; talked about custom Mac servers, using &lt;a href="http://en.wikipedia.org/wiki/Grand_Central_Dispatch"&gt;Grand Central Dispatch&lt;/a&gt; to give massive scaleability.   &lt;a href="http://rubini.us/"&gt;Rubinius&lt;/a&gt; is promising a 1.0rc1 next week (at last).  Apart from that there were several other talks on partial or full Ruby compiling.&lt;/p&gt;
&lt;p&gt;Scaling and performance made its way into quite a few sessions from Paul Dix&amp;#8217;s informative &amp;#8220;Synchronous Reads, Asynchronous Writes&amp;#8221;, to the &lt;a href="http://www.mongodb.org/display/DOCS/Home"&gt;MongoDB&lt;/a&gt; session, to Greg Pollock&amp;#8217;s Scaling Rails talk.  There are some great links to tools to help improve Rails app performance from Greg&amp;#8217;s talk &lt;a href="http://blog.envylabs.com/rubyconf09/"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The top talk that I regret missing was &lt;a href="http://blog.headius.com/"&gt;Charles Nutter&amp;#8217;s&lt;/a&gt; &lt;a href="http://blog.headius.com/2008/03/duby-type-inferred-ruby-like-jvm.html"&gt;Duby&lt;/a&gt; talk. The standard comment from that talk was something like &amp;#8220;I thought it was just Charlie&amp;#8217;s hobby, but that is really useful.&amp;#8221;  In is spare time Charlie has designed a Ruby-like language that can be easily &amp;#8220;compiled&amp;#8221; into a static language (ie Java).  The uses are pretty interesting.&lt;/p&gt;
&lt;p&gt;Tom Presont-Werner&amp;#8217;s presentation on &lt;a href="http://github.com/blog/531-introducing-bert-and-bert-rpc"&gt;Bert&lt;/a&gt; and &lt;a href="http://github.com/mojombo/ernie"&gt;Ernie&lt;/a&gt; introduced us to the interoperability theme. As &lt;span class="caps"&gt;JSON&lt;/span&gt; is to &lt;a href="http://en.wikipedia.org/wiki/JavaScript"&gt;JavaScript&lt;/a&gt; (kind-of).  Ernie is a superset of Erlang&amp;#8217;s &lt;a href="http://www.erlang.org/doc/apps/erts/erl_ext_dist.html"&gt;External Term Format&lt;/a&gt; distribution mechanism.  By extracting it from Erlang is gives us an efficient, simple and standard way to perform interprocess communication.  &lt;a href="http://github.com/mojombo/ernie"&gt;Ernie&lt;/a&gt; is a &lt;span class="caps"&gt;RPC&lt;/span&gt; server for handling &lt;span class="caps"&gt;BERT&lt;/span&gt; requests in Ruby.  Interop made it&amp;#8217;s way into the &lt;a href="http://mongodb.org"&gt;MongoDB&lt;/a&gt; talk with the &lt;span class="caps"&gt;BSON&lt;/span&gt; (binary &lt;span class="caps"&gt;JSON&lt;/span&gt;) protocol.&lt;/p&gt;
&lt;p&gt;Ben Scofield&amp;#8217;s NoSQL was a great round-up of the non-relational database options that are getting popular &amp;#8211; not just the Document Based and KV pairs, but Graph based and Column Oriented ones too.  If, like me, you know little about them you should look up Ben&amp;#8217;s talk when it is posted.&lt;/p&gt;
&lt;p&gt;And there is still so much more to say.  I haven&amp;#8217;t even mention the Arduino controlled airships, Jim Weirich&amp;#8217;s &lt;span class="caps"&gt;SOLID&lt;/span&gt; Ruby, and that 54 people took part in the &lt;a href="http://www.rubyconf5k.com/"&gt;5k run&lt;/a&gt;. (I came 20th).&lt;/p&gt;
&lt;p&gt;&lt;a href="http://img131.yfrog.com/i/bu9.jpg/"&gt;&lt;img src="http://img131.yfrog.com/img131/8493/bu9.jpg" title="Airship buzzes crowd" alt="Airship buzzes crowd" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; added more including pictures.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/PaulsTechieBlog/~4/g6z7EsUSI58" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 23 Nov 2009 00:12:30 GMT</pubDate>
      <guid isPermaLink="false">http://blogofpaul.merecomplexities.com/articles/269</guid>
    <feedburner:origLink>http://blogofpaul.merecomplexities.com/articles/269</feedburner:origLink></item>
    <item>
      <title>Most webapps are nails</title>
      <link>http://feedproxy.google.com/~r/PaulsTechieBlog/~3/rMHGsfcPfXA/268</link>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/tudor/16685089/" style="float:right;"&gt;&lt;img src="http://blogofpaul.merecomplexities.com/assets/16685089_7ee23a0a2c_m.jpg" title="Nails" alt="Nails" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The child who receives a hammer for Christmas will discover that everything needs pounding &amp;#8211; &lt;a href="http://www.geraldmweinberg.com/"&gt;Gerald Weinberg&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="http://skillsmatter.com/podcast/ajax-ria/fred-george-rails-is-a-hammer-keynote"&gt;Fred George&amp;#8217;s keynote&lt;/a&gt; at &amp;#8220;Rails Underground&amp;#8221; was titled &amp;#8220;Rails is an hammer&amp;#8221;.  It was along the &amp;#8220;grumpy old developer&amp;#8221; line that kids today jump to use all these fancy frameworks without considering whether they are appropriate to the job in hand. It&amp;#8217;s a fun spiel, and one I&amp;#8217;ve levelled against a lot of Java frameworks and libraries. Is Rails really inappropriate for most web applications? No, but it&amp;#8217;s worth asking the question.&lt;/p&gt;
&lt;p&gt;The main charges against Rails are:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;it does not have a domain layer&lt;/li&gt;
	&lt;li&gt;the models are based on relational database tables rather than object design&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Does Rails not have a domain model?&lt;/h2&gt;
&lt;p&gt;This is good point that is not often made.  Having &lt;a href="http://en.wikipedia.org/wiki/Model–view–controller"&gt;&lt;span class="caps"&gt;MVC&lt;/span&gt;&lt;/a&gt; not the same as a layered architecture. As Jay Fields &amp;#8220;discovered&amp;#8221; that his  &lt;a href="http://blog.jayfields.com/2007/03/rails-presenter-pattern.html"&gt;Presenter Pattern&lt;/a&gt; was not sufficient for some applications it was &lt;a href="http://domaindrivendesign.org/"&gt;Domain Driven Design&lt;/a&gt; his team turned to concepts such as Services and Repositories. Nowhere does Rails mandate that ActiveRecord models should be accessed directly by controllers.&lt;/p&gt;
&lt;p&gt;Good domain models are tough.  It can take a long time working with an application before the right model is discovered.  Leaping to a model too early &amp;#8211; premature abstraction &amp;#8211; often leads to an inappropriate object architecture that it can be difficult to write your way out of and Byzantine back channels are needed for operations that do not fit the original design.&lt;/p&gt;
&lt;p&gt;Something that Rails has taught me is how far you can go with just &lt;span class="caps"&gt;MVC&lt;/span&gt; and a good framework.  I wouldn&amp;#8217;t say this for a typical Java web app, but you ain&amp;#8217;t gonna need a layered architecture.  Until you do need one.  Then won&amp;#8217;t be a big deal to refactor towards that, as long as you keep you&amp;#8217;ve kept your code clean, &lt;span class="caps"&gt;DRY&lt;/span&gt;, and well-tested.&lt;/p&gt;
&lt;h2&gt;Are Rails &amp;#8216;models&amp;#8217; are based on database tables?&lt;/h2&gt;
&lt;p&gt;This came up in the &lt;a href="http://upstream-berlin.com/2009/03/31/the-case-of-activerecord-vs-couchdb/"&gt;Scotland on Rails CouchDB controversy&lt;/a&gt;, and I dispute that Rails ActiveRecord models represent rows in relational database tables.  It&amp;#8217;s the other way round: relational databases happen to be the persistence mechanism for ActiveRecord; the database is subservient to the object model.  No-one normalises their Rails database; you might fret about keeping your objects &lt;span class="caps"&gt;DRY&lt;/span&gt; and separation of concerns but I doubt you look at your Rails DB worry about repeating attributes.  It&amp;#8217;s about associations, not relations and join tables.&lt;/p&gt;
&lt;p&gt;Admittedly, right now Rails is strongly bound to being back by a &lt;span class="caps"&gt;RDBMS&lt;/span&gt;, and there are some hoops to jump through if you want to use something else.  That does not stop a growing number of people using alternatives like &lt;a href="http://www.google.com/search?client=safari&amp;amp;rls=en-gb&amp;amp;q=couchdb+rails&amp;amp;ie=UTF-8&amp;amp;oe=UTF-8"&gt;CouchDB&lt;/a&gt;.  The promise of Rails 3 is that it will become trivial to swap in alternative Object Persistence mechanisms, so this will become less of an issue.&lt;/p&gt;
&lt;h2&gt;Given up on Rails yet?&lt;/h2&gt;
&lt;p&gt;Fred had some valid points, and it was fun to see how far he could get with vanilla Ruby, Sinatra, and persisting straight to disk.  I&amp;#8217;m still going to be reaching for Rails to solve most of my web app problems, though.  After all it&amp;#8217;s a pretty versatile hammer, and there&amp;#8217;s a lot of things that need pounding out there.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/PaulsTechieBlog/~4/rMHGsfcPfXA" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 31 Jul 2009 01:21:35 GMT</pubDate>
      <guid isPermaLink="false">http://blogofpaul.merecomplexities.com/articles/268</guid>
    <feedburner:origLink>http://blogofpaul.merecomplexities.com/articles/268</feedburner:origLink></item>
    <item>
      <title>Jet-lag is optional </title>
      <link>http://feedproxy.google.com/~r/PaulsTechieBlog/~3/mrgE6iPQtNE/267</link>
      <description>&lt;p&gt;A couple of months ago I had a one week one trip from Los Angeles, which promised to be a jet-lag nightmare: 5 days to adjust to the 8 hour difference and then fly home to suffer another 5 days. Luckily a couple of days before departure I caught a TV programme in which a theory on how to overcome jetlag was tried out on a couple of racing car engineers flying back from Atlanta to the UK: extrapolating from &lt;a href="http://www.reuters.com/article/domesticNews/idUSN2252042720080522?sp=true"&gt;research on mice&lt;/a&gt;, the theory was that by fasting for 16 hours the body&amp;#8217;s &amp;#8216;feeding clock&amp;#8217; takes over from the main &amp;#8217;circadian&amp;#8217;clock.&lt;/p&gt;
&lt;p&gt;By not eating while travelling, then resuming normal meal times on arrival, we can adjust immediately to local time.  The experiment worked on the show and the presenter, a world-travelling journalist, claimed that it had subsequently worked for her.&lt;/p&gt;
&lt;p&gt;On the journeys to and from LA I fasted for around 16 hours, and it worked very well for me in both directions.  I slept from 22:00 to 06:00 on the first night in LA, and then later and longer on subsequent nights. In contrasts my compadres &lt;a href="http://twitter.com/alancfrancis"&gt;Alan&lt;/a&gt; and &lt;a href="http://twitter.com/bgswan"&gt;Brian&lt;/a&gt; both suffered quite badly from jetlag throughout the week.  &lt;a href="http://twitter.com/kevinmcdonagh"&gt;Kevin McDonagh&lt;/a&gt; tried the fasting trick on his trip to San Francisco for &lt;a href="http://code.google.com/events/io/"&gt;Google IO&lt;/a&gt; with similarly excellent results.&lt;/p&gt;
&lt;p&gt;In short, if you are willing to forego eating for a 16 hours, you can avoid days of jetlag. The main points are:-&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;do not eat on the journey &amp;#8211; the journalist presenting the &lt;span class="caps"&gt;BBC&lt;/span&gt; sleep programme claimed fasting on a 11 hour flight worked for her; I have only tried the whole 16 hour fast.&lt;/li&gt;
	&lt;li&gt;drink as much water as you like. I also drank a very small amount of orange juice, coffee, and Gin and Tonic on my flights without disastrous results &amp;#8211; your mileage may vary&lt;/li&gt;
	&lt;li&gt;start eating at normal meal times when you arrive&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Happy travelling, but don&amp;#8217;t come complaining to me about your circadian rhythms: it&amp;#8217;s all in your own hands.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/PaulsTechieBlog/~4/mrgE6iPQtNE" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 23 Jul 2009 23:17:44 GMT</pubDate>
      <guid isPermaLink="false">http://blogofpaul.merecomplexities.com/articles/267</guid>
    <feedburner:origLink>http://blogofpaul.merecomplexities.com/articles/267</feedburner:origLink></item>
    <item>
      <title>Smart Tests Are Dumb Tests</title>
      <link>http://feedproxy.google.com/~r/PaulsTechieBlog/~3/ubJxNFKZLRI/266</link>
      <description>&lt;p&gt;&lt;a href="http://www.kropserkel.com/horse_head_pillow.htm" style="float:right;"&gt;&lt;img src="http://blogofpaul.merecomplexities.com/assets/johnny-bravo-small.jpg" title="Johnny Bravo" alt="Johnny Bravo" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A question I hear a lot is &amp;#8220;don&amp;#8217;t you find your test code is pretty much a copy of your production code?&amp;#8221;  Digging deeper we this kind of test.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
def test_counts_the_correct_number_of_words
  sentence = 
    "The quick brown fox jumps over the lazy dog."
  expected_count = sentence.scan(/\w+/).size
  analyser = SentenceAnalyser.new(sentence)
  assert_equal expected_count, analyser.word_count
end
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Here&amp;#8217;s what I&amp;#8217;d write.&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
def test_counts_the_correct_number_of_words
  assert_equal 9, 
    SentenceAnalyser.new(
        "The quick brown fox jumps over the lazy dog.").word_count
end
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;The more work we make our tests do, the more likely we are to introduce mistakes in the test code; this can be especially dangerous if we use the same algorithm as in the production code as we can make the same mistake in both places.  And that&amp;#8217;s apart from the second test being shorter and easier to understand.&lt;/p&gt;
&lt;p&gt;So remember, kids, keep your tests dumb to keep them smart.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/PaulsTechieBlog/~4/ubJxNFKZLRI" height="1" width="1"/&gt;</description>
      <pubDate>Sun, 26 Jul 2009 14:50:29 GMT</pubDate>
      <guid isPermaLink="false">http://blogofpaul.merecomplexities.com/articles/266</guid>
    <feedburner:origLink>http://blogofpaul.merecomplexities.com/articles/266</feedburner:origLink></item>
    <item>
      <title>Technical Debt or When Metaphors Attack</title>
      <link>http://feedproxy.google.com/~r/PaulsTechieBlog/~3/BqcXNbBWQNo/265</link>
      <description>&lt;p&gt;&lt;a href="http://www.kropserkel.com/horse_head_pillow.htm" style="float:right;"&gt;&lt;img src="http://blogofpaul.merecomplexities.com/assets/horsehead.jpg" title="horse&amp;#39;s head" alt="horse&amp;#39;s head" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Technical Debt is a powerful metaphor: it describes code-quality shortcomings in financial terms; until the debt is paid off we pay interest, meaning that it takes longer to implement new features.  It&amp;#8217;s a useful metaphor, but has limits.  A few weeks ago I was annoyed when  a whole room of Agile consultants took seriously the idea of &amp;#8220;borrowing on code-quality&amp;#8221; to get a start-up off the ground, and then repaying the debt later (presumably by hiring consultants).  All my experience tells me that this is a disastrous strategy.   Such debt becomes incredibly expensive to pay off &amp;#8211; expensive in real cash.&lt;/p&gt;
&lt;p&gt;Ward Cunningham coined the Technical Debt metaphor.  He describes (&lt;a href="http://www.youtube.com/watch?v=pqeJFYwnkjE"&gt;on video&lt;/a&gt;) producing code without a complete understanding of the problem, as accumulating technical debt.  By writing the code early we increase our understanding of the system: as long as the debt is repaid, this is prudent borrowing.  It&amp;#8217;s quite like a business borrowing to invest in capital equipment and using the increase in revenue to pay off the debt.&lt;/p&gt;
&lt;p&gt;Metaphors are natural and useful thinking-tools.  A good metaphor, though, can be dangerously seductive.  We can be tempted to use it beyond its applicability.  A metaphorical vehicle cannot fully describe its topic: they need to differ for it to be a metaphor rather than a description.&lt;/p&gt;
&lt;p&gt;Recently Brian Marick &lt;a href="http://twitter.com/marick/status/144520758"&gt;suggested&lt;/a&gt; that metaphorical reasoning could be improved by listing  ways in which the metaphor differs from its topic.  Financial debt is easily quantifiable; technical debt is not.  Borrowing on code quality to get your product out quickly is more like begging favours from the Mafia than taking out a business loan.  The repayment terms are unknown, except that they will be entangling, larger, and more horrific than you can imagine.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/PaulsTechieBlog/~4/BqcXNbBWQNo" height="1" width="1"/&gt;</description>
      <pubDate>Sun, 05 Apr 2009 19:00:38 GMT</pubDate>
      <guid isPermaLink="false">http://blogofpaul.merecomplexities.com/articles/265</guid>
    <feedburner:origLink>http://blogofpaul.merecomplexities.com/articles/265</feedburner:origLink></item>
    <item>
      <title>New blog location</title>
      <link>http://feedproxy.google.com/~r/PaulsTechieBlog/~3/p-hHZRXqWdI/264</link>
      <description>&lt;p&gt;Because I can, I&amp;#8217;ve decided to move my blog to &lt;a href="http://blogofpaul.merecomplexities.com"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m hoping that it will be mostly seamless, with the &lt;a href="http://www.feedburner.com/"&gt;Feedburner&lt;/a&gt; &lt;span class="caps"&gt;RSS&lt;/span&gt; feed and redirects taking away the pain.  If it isn&amp;#8217;t, sorry.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/PaulsTechieBlog/~4/p-hHZRXqWdI" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 12 Mar 2009 13:45:05 GMT</pubDate>
      <guid isPermaLink="false">http://blogofpaul.merecomplexities.com/articles/264</guid>
    <feedburner:origLink>http://blogofpaul.merecomplexities.com/articles/264</feedburner:origLink></item>
    <item>
      <title>iPhone TDD using Google Toolbox and iphone_testify</title>
      <link>http://feedproxy.google.com/~r/PaulsTechieBlog/~3/IIwls6aJWpQ/263</link>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;p&gt;Previously, &lt;a href="/assets/2009/01/giving-up-on-rbiphonetest.html"&gt;we&amp;#8217;d decided to switch&lt;/a&gt; from using  Rbiphonetest to using &lt;a href="http://code.google.com/p/google-toolbox-for-mac/"&gt;Google toolbox for Mac&lt;/a&gt; code.  It&amp;#8217;s about time we got started.&lt;/p&gt;
 &lt;p&gt;To begin with we&amp;#8217;ll just set up an iPhone project for testing.  This will include automatically running all the tests every time &amp;#8211; just like autotest.&lt;/p&gt;
 &lt;h2&gt;Setting up the files&lt;/h2&gt;
 &lt;p&gt;Of course you&amp;#8217;ll need to be running &lt;span class="caps"&gt;OS X 10&lt;/span&gt;.5 (Leopard) and the latest iPhone &lt;span class="caps"&gt;&lt;span class="caps"&gt;SDK&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
 &lt;p&gt;Fire up XCode and create an iPhone OS project. (For the purposes of this example it doesn’t matter what type; a Utility app is as good as any). I&amp;#8217;ve written a &lt;a href="http://github.com/paulanthonywilson/iphone_testify/tree/master"&gt;Ruby Gem&lt;/a&gt; to help getting all the files in place, so we may as well use those. From the terminal go to your new application directory.&lt;/p&gt;
 &lt;p&gt;First we&amp;#8217;ll install the gem.  If you haven&amp;#8217;t already you will need to  to add github as a gem source.  (If you can&amp;#8217;t remember just enter &lt;em&gt;gem source&lt;/em&gt; and see if github is listed).&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
sudo gem update --system
gem source -a http://gems.github.com
&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;Either way, install the gem.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
sudo gem install paulanthonywilson-iphone_testify
&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;Then run the &lt;em&gt;iphone_testify&lt;/em&gt; command.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
iphone_testify
&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;This adds the google unit testing code to the google_testing directory, creates a directory for the UnitTests.  There&amp;#8217;s also a &lt;em&gt;Rakefile_&lt;/em&gt; and an &lt;em&gt;autoiphonetest.rb&lt;/em&gt;, and we&amp;#8217;ll get round to those later.&lt;/p&gt;
 &lt;h2&gt;Setting up XCode&lt;/h2&gt;
 &lt;p&gt;There&amp;#8217;s a few things you need to do in XCode.  The gem doesn&amp;#8217;t do this yet, but I&amp;#8217;m working on it.&lt;/p&gt;
 &lt;p&gt;Create a new Target called Unit Test.  Right click on &lt;em&gt;Targets&lt;/em&gt; in the left pane.  Choose an &amp;#8220;iPhone OS&amp;#8221; Application target and call it &amp;#8220;Unit Test&amp;#8221;.&lt;/p&gt;
 &lt;p&gt;&lt;img title="adding an xcode target" src="/assets/objc_unit_testing_tutorial/adding_xcode_target.png" alt="adding an xcode target" /&gt;&lt;/p&gt;
 &lt;p&gt;Right click on the &lt;em&gt;Unit Test&lt;/em&gt; target and choose &amp;#8220;Add&amp;#8212;&amp;gt; Existing Files&amp;#8221;.  Select all the files in the &lt;em&gt;google_testing&lt;/em&gt; directory (or at least all the .h and .m files).&lt;/p&gt;
 &lt;p&gt;&lt;img title="add google files" src="/assets/objc_unit_testing_tutorial/adding_google_testing_files.png" alt="add google files" /&gt;&lt;/p&gt;
 &lt;p&gt;(If you&amp;#8217;re feeling tidy, which I hope you are, you probably want to add these to a &amp;#8220;google_testing&amp;#8221; group as well.)&lt;/p&gt;
 &lt;p&gt;Right click on the &lt;em&gt;Unit Test&lt;/em&gt; target again, to add a  &amp;#8220;new run script build phase&amp;#8221;.&lt;/p&gt;
 &lt;p&gt;&lt;img title="add new build phase" src="/assets/objc_unit_testing_tutorial/new_build_phase.png" alt="add new build phase" /&gt;&lt;/p&gt;
 &lt;p&gt;Set the script to be &lt;em&gt;google_testing/RunIPhoneUnitTest.sh&lt;/em&gt;.&lt;/p&gt;
 &lt;p&gt;&lt;img title="build phase run script" src="/assets/objc_unit_testing_tutorial/run_script.png" alt="build phase run script" /&gt;&lt;/p&gt;
 &lt;p&gt;Add a group in which to keep your unit tests.  Right click on the group and set the path to be &lt;em&gt;UnitTests&lt;/em&gt;, so that the test classes will go where we expect on the file system.&lt;/p&gt;
 &lt;p&gt;&lt;img title="unit tests group" src="/assets/objc_unit_testing_tutorial/unit_test_group.png" alt="unit tests group" /&gt;&lt;/p&gt;
 &lt;p&gt;That&amp;#8217;s all a bit of faff.  I am hoping to automate the xcode part: you can stay tuned by watching &lt;a href="http://github.com/paulanthonywilson/iphone_testify/tree/master"&gt;iphone_testify&lt;/a&gt; on Github.&lt;/p&gt;
 &lt;h2&gt;Write a test&lt;/h2&gt;
 &lt;p&gt;Let&amp;#8217;s write a dummy test, just to get us started.  Right click on your &lt;em&gt;UnitTests&lt;/em&gt; group and add a new file (&lt;em&gt;iPhone OS Cocoa Touch Classes &amp;#8211; NSObject subclass&lt;/em&gt;).  Let&amp;#8217;s call it &lt;em&gt;BlahTest.m&lt;/em&gt;.  Add it only to the &lt;em&gt;Unit Test&lt;/em&gt; target. Uncheck &amp;#8220;Also create BlahTest.h&amp;#8221;: you don&amp;#8217;t need a header.&lt;/p&gt;
 &lt;p&gt;&lt;img title="adding dummy unit test" src="/assets/objc_unit_testing_tutorial/add_unit_test.png" alt="adding dummy unit test" /&gt;&lt;/p&gt;
 &lt;p&gt;Edit the &lt;em&gt;BlahTest.m&lt;/em&gt; to extend SenTestCase:-&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
#import "../google_testing/GTMSenTestCase.h" 

@interface BlahTest : SenTestCase
@end

@implementation BlahTest

@end
&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;Note that we&amp;#8217;ve included the interface definition in the implementation file: there&amp;#8217;s nothing to stop you using a separate header file, but there&amp;#8217;s not a lot of point.  Let&amp;#8217;s add a failing test.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
@implementation BlahTest

-(void) testSomething{
    NSString *actual = @"hello matey";
    STAssertEqualStrings(@"hi mate", actual, nil);
}

@end
&lt;/code&gt;&lt;/pre&gt;
 &lt;h3&gt;Run through XCode&lt;/h3&gt;
 &lt;p&gt;The tests are &amp;#8216;run&amp;#8217; as part of the build and failures are reported as build failures.  In XCode set the target to &amp;#8220;Unit Test&amp;#8221; and build.&lt;/p&gt;
 &lt;p&gt;&lt;img title="failing test in xcode" src="/assets/objc_unit_testing_tutorial/xcode_failing_test.png" alt="failing test in xcode" /&gt;&lt;/p&gt;
 &lt;h3&gt;Run through Rake and &lt;em&gt;autoiphonetest.rb&lt;/em&gt;&lt;/h3&gt;
 &lt;p&gt;Running &lt;em&gt;iphone_testify&lt;/em&gt; also provides you with a Rakefile for building/running the test target.  From the command line in your project directory just run&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
rake
&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;&lt;img title="failing test in rake" src="/assets/objc_unit_testing_tutorial/rake_failing_test.png" alt="failing test in rake" /&gt;&lt;/p&gt;
 &lt;p&gt;Even better, run&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
./autoiphonetest.rb
&lt;/code&gt;&lt;/pre&gt;
 &lt;p&gt;This will build/run the unit tests evertime a change is detected in the &lt;em&gt;Classes&lt;/em&gt; or &lt;em&gt;UnitTests&lt;/em&gt; directory.  The automatic running of unit tests does wonders for flow.&lt;/p&gt;
 &lt;p&gt;The &lt;em&gt;rake&lt;/em&gt; and &lt;em&gt;autoiphonetest.rb&lt;/em&gt; builds will inform you of the state of the tests using &lt;a href="http://growl.info"&gt;Growl&lt;/a&gt;: to take advantage of this you will need to have &lt;a href="http://growl.info"&gt;Growl&lt;/a&gt; and &lt;a href="http://growl.info/extras.php"&gt;growlnotify&lt;/a&gt; installed.  In order to work around a bug in &lt;em&gt;growlnotify&lt;/em&gt;, you need to enable &amp;#8220;Listen for incoming network connections&amp;#8221; in the &lt;em&gt;Network&lt;/em&gt; pane of the &lt;em&gt;Growl&lt;/em&gt; &lt;em&gt;System Preferences&lt;/em&gt;.&lt;/p&gt;
 &lt;p&gt;Now we&amp;#8217;re set up running with &lt;em&gt;autoiphonetest.rb&lt;/em&gt;, let&amp;#8217;s fix our test and see our pass notification; I&amp;#8217;ll leave the test fixing as an exercise for the reader.&lt;/p&gt;
 &lt;p&gt;&lt;img title="passing" src="/assets/objc_unit_testing_tutorial/autopass.png" alt="passing" /&gt;&lt;/p&gt;
 &lt;p&gt;That&amp;#8217;s it for now.  In our next instalment we&amp;#8217;ll look at building up or Twitter application using &lt;em&gt;Objective-C&lt;/em&gt; unit tests.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Corrected a couple of bugs:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;The target must be called &lt;em&gt;Unit Test&lt;/em&gt; (not &lt;em&gt;Unit Test&lt;strong&gt;s&lt;/strong&gt;&lt;/em&gt;) to work with my gem&lt;/li&gt;
	&lt;li&gt;I ought to have used &lt;em&gt;STAssertEqualStrings&lt;/em&gt; for comparing strings (not &lt;em&gt;STAssertEquals&lt;/em&gt;).&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/PaulsTechieBlog/~4/IIwls6aJWpQ" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 22 Apr 2009 10:27:53 GMT</pubDate>
      <guid isPermaLink="false">http://blogofpaul.merecomplexities.com/articles/263</guid>
    <feedburner:origLink>http://blogofpaul.merecomplexities.com/articles/263</feedburner:origLink></item>
  </channel>
</rss>

