<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>3hv</title>
	
	<link>http://www.3hv.co.uk/blog</link>
	<description>beautiful code for elegant web sites</description>
	<pubDate>Sat, 27 Dec 2008 01:01:11 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
	<language>en</language>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/3hv" type="application/rss+xml" /><feedburner:emailServiceId>1481457</feedburner:emailServiceId><feedburner:feedburnerHostname>http://www.feedburner.com</feedburner:feedburnerHostname><item>
		<title>The curious case of beauty in Ruby (or Rails vs Merb part 2)</title>
		<link>http://feeds.feedburner.com/~r/3hv/~3/495952538/</link>
		<comments>http://www.3hv.co.uk/blog/2008/12/27/the-curious-case-of-beauty-in-ruby-or-rails-vs-merb-part-2/#comments</comments>
		<pubDate>Sat, 27 Dec 2008 00:51:41 +0000</pubDate>
		<dc:creator>Rahoul Baruah</dc:creator>
		
		<category><![CDATA[Beautiful Code]]></category>

		<category><![CDATA[Designing Great Software]]></category>

		<category><![CDATA[General]]></category>

		<category><![CDATA[Ruby on Rails and Software Development]]></category>

		<guid isPermaLink="false">http://www.3hv.co.uk/blog/?p=349</guid>
		<description><![CDATA[I&#8217;m sure you&#8217;ve all heard the Rails 3 announcement.  When I first found out my initial reaction was &#8220;fuck me&#8220;.  But shortly after I was filled with a feeling of dread and general unease.  And I didn&#8217;t know why &#8230;.
Firstly, a bit of history.  
I first tried programming on a Commodore [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m sure you&#8217;ve all heard the <a href="http://weblog.rubyonrails.org/2008/12/23/merb-gets-merged-into-rails-3">Rails 3 announcement</a>.  When I first found out my initial reaction was &#8220;<a href="http://twitter.com/xbaz/status/1074944824">fuck me</a>&#8220;.  But shortly after I was filled with a feeling of <a href="http://twitter.com/xbaz/status/1076051798">dread and general unease</a>.  And I didn&#8217;t know why &#8230;.</p>
<p>Firstly, a bit of history.  </p>
<p>I first tried programming on a Commodore Vic 20, and then after that a C64.  C64 BASIC was very simple - if you wanted to do anything beyond PRINT statements you needed to POKE values into registers and control the hardware directly.  Great for learning how things actually worked.  And, to be fair, I was shit at it.  </p>
<p>But I do remember reading an article on a system called &#8220;Smalltalk&#8221; and its &#8220;Object Oriented Programming&#8221;.  Suddenly, programming made sense.  It read a bit like English.  You sent messages to the thing that knows how to answer your question.  It was like talking to people.  You ask Dave a <a href="http://www.eighteensixtyfive.co.uk">football</a> question.  You ask George a <a href="http://www.theresplendents.com">music</a> question.  Cos Dave knows crap all about music and George knows nothing about football.  </p>
<p>But, in those days, Smalltalk cost a fortune; there was no way a child like me could get hold of a Smalltalk environment.  So instead, I got hold of Turbo Pascal 6 With Objects (thanks Dad).  It was not Smalltalk but it read a bit like English and it had objects.  I played about with Turbo Pascal, went to university (where I didn&#8217;t do computing but did do some C++) and then got a job doing Delphi (Turbo Pascal for the 90s).  This object-oriented stuff really worked for me; I put a lot of effort into writing classes that had really simple public interfaces and with code that read like English.  And Pascal (the language underlying Delphi) was great for that.  Then I discovered Java, which meant I could write Delphi-like code but with having to deal with memory management.  I also discovered PHP, Python and Ruby.  None of which clicked with me; dynamic typing made me nervous (and PHP and Ruby seemed a bit ugly).  </p>
<p>However, I needed an ORM for a Delphi project and I thought I should try to copy an open source project.  Whilst searching I discovered Rails and thought &#8220;this is the one to copy&#8221;.  But a day into my &#8220;copy ActiveRecord into Delphi&#8221; plan I thought &#8220;this is just like Smalltalk&#8221;.  Why make an inferior copy when I can use something that&#8217;s not far off the Holy Grail.  Writing an application on Rails had the same effect on me as my original discovery of Smalltalk - it read like English, it felt fantastic.  So I gave up on Delphi and became a Rails programmer.  </p>
<p>What I liked about Rails was its emphasis on happiness.  When I wrote Rails code I felt like I was writing beautiful prose.  I would go back and refactor it until it read correctly.  This was not like pure Ruby, which was often ugly.  No; Rails had this idea about beauty in code that really got me excited.  It made me happy.  It also made decisions for me - put your code here, test it like this, set up your database this way.  But Rails had performance problems - so Merb was born.  A ground-up rewrite of many of Rails&#8217; ideas but with an emphasis on configurability and performance.  </p>
<p>Maybe it&#8217;s the <a href="http://engineyard.com">Engine Yard</a> connection (I turned Engine Yard down for a job because it didn&#8217;t &#8220;feel right&#8221;) - and now I work for <a href="http://www.brightbox.co.uk">Brightbox</a>, one of their competitors - but for some reason, every time I tried Merb I just couldn&#8217;t get into it.  It was weird.  Structurally and functionally it was the same as Rails - but it was Rails plus performance plus options.  And I didn&#8217;t like it.  I never got past the tutorials.  Merb emphasises clear and understandable code and was tested with RSpec (which I love).  Rails is hard to understand and uses Test::Unit (which is ugly).  But I love Rails and I can&#8217;t get into Merb.  I just couldn&#8217;t figure out why.  </p>
<p>Until today.  </p>
<p>Mr Hanson did a <a href="http://loudthinking.com/posts/37-bringing-merbs-providesdisplay-into-rails-3">blog post</a> on his first piece of Rails-Merb integration.  And something stood out at me.  As he was describing Merb&#8217;s provides/display functionality I noticed that I didn&#8217;t really &#8220;get it&#8221;.  <tt>provides</tt> made sense, but how does that relate to <tt>display</tt>.  Mr H addresses that directly: </p>
<blockquote><p>There were a couple of drawbacks with the provides/display duo, though, that we could deal with at the same time. The first was the lack of symmetry in the method names. The words &#8220;provides&#8221; and &#8220;display&#8221; doesn&#8217;t reflect their close relationship and if you throw in the fact that they&#8217;re actually both related to rendering, it&#8217;s gets even more muddy.</p></blockquote>
<p>And then he describes the Rails 3 version of the same functionality.  Instead of provides/display it becomes respond_to/respond_with.  In particular <tt>display @users</tt> becomes <tt>respond_with @users</tt>.  </p>
<p>It&#8217;s only a tiny thing.  Logically and functionally, they are exactly the same.  But DHH&#8217;s version has an emphasis <strong>on the words</strong> that are used.  How they couple together (display/provide versus respond_to/respond_with).  </p>
<p>And there is the reason that I was uneasy about Rails 3.  What if Rails lost this emphasis on the human factors - how the words mesh together - in the search of performance.  Merb is written functionally, Rails is written emotionally - Merb is about performance, Rails is about feelings.  </p>
<p>But DHH has made me feel much better about Rails 3 - he has shown that he will take Merb constructs and Railsify them, humanise them.  Because, although code is executed by computers, it is written, and more importantly, <em>read</em> by people like me.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.3hv.co.uk/blog/2008/12/27/the-curious-case-of-beauty-in-ruby-or-rails-vs-merb-part-2/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.3hv.co.uk/blog/2008/12/27/the-curious-case-of-beauty-in-ruby-or-rails-vs-merb-part-2/</feedburner:origLink></item>
		<item>
		<title>Writing tests for your controllers improves the design of your models</title>
		<link>http://feeds.feedburner.com/~r/3hv/~3/490758235/</link>
		<comments>http://www.3hv.co.uk/blog/2008/12/20/writing-tests-for-your-controllers-improves-the-design-of-your-models/#comments</comments>
		<pubDate>Sat, 20 Dec 2008 18:14:19 +0000</pubDate>
		<dc:creator>Rahoul Baruah</dc:creator>
		
		<category><![CDATA[Designing Great Software]]></category>

		<category><![CDATA[Ruby on Rails and Software Development]]></category>

		<category><![CDATA[Writing Reliable, Bug-Free Code]]></category>

		<guid isPermaLink="false">http://www.3hv.co.uk/blog/?p=342</guid>
		<description><![CDATA[I&#8217;ve recently been updating some old code - partly written by someone else, partly written by myself.  At the time, I thought I had written this code really well; looking back on it now, it looks awful.  Fair enough, I&#8217;ve learnt a lot - I want to look back on old code and [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve recently been updating some old code - partly written by someone else, partly written by myself.  At the time, I thought I had written this code really well; looking back on it now, it looks awful.  Fair enough, I&#8217;ve learnt a lot - I want to look back on old code and shudder.  But also, there is very poor test coverage on this app and the tests that there are are quite unwieldy due to an over-reliance on fixtures.  </p>
<p>So I&#8217;ve been reworking them all using <a href="http://rspec.info/">RSpec</a>, my fork of <a href="http://github.com/rahoulb/rspec-rails/tree">RSpec-Rails</a> and my <a href="http://github.com/rahoulb/object-factory/tree/master">Object Factory</a> (which means I can avoid fixtures).  </p>
<p>Most of the work involves writing a spec that mimics the current behaviour (by inspecting the code and trying to match all paths through it), then refactoring the code, using the spec to prove that I haven&#8217;t broken it.  </p>
<p>But some points have some really horrible code (and lots of it) within the controllers.  As you probably know, <a href="http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model">Skinny Controllers</a> is the Rails way - your application logic belongs in your models (as they <em>are</em> your application) - the controller should just find or create the relevant model, ask it to do something and then render the results.  </p>
<p>Because of this, I opted to just rewrite the actions in question.  </p>
<p>To do this I started by writing a <a href="http://github.com/aslakhellesoy/cucumber/wikis">Cucumber feature</a> describing things from the user&#8217;s point of view.  Actually writing the steps that match the feature was a lot of work; because Cucumber is a full stack test you have to deal with all the dependencies that your individual action has (for example, are you logged in with the correct permissions with all associated objects created and in the right state?).  </p>
<p>Then I wrote a controller spec.  Controller specs in RSpec should use mock objects; you don&#8217;t really want to test the models, you just want to prove that the controller finds or creates the right model, asks it to do something and renders the correct output at the end.  </p>
<p>So a typical spec looks something like this (note that this is not RESTful as it was an existing part of the application that I am about to change): </p>
<pre><code>
  it "should process an item" do
    @item = mock_model Item, :work_type => :buy_stuff, :quantity => 2

    on_getting :process_item, :id => '1' do
     Item.should_receive(:find).with('1').and_return(@item)
      @stuff = mock_model Stuff
      @item.should_receive(:process).and_return(@stuff)
    end

    assigns[:stuff].should == @stuff
    response.should be_success
    response.should render_template('admin/orders/process_item')
  end
</code></pre>
<p>This basically says: </p>
<ul>
<li>We have an item, of type &#8220;buy stuff&#8221; with a quantity</li>
<li>When the process_item action is called, we expect that the controller will try to find the item with the given id</li>
<li>Then we should call process on the item and it should give us some stuff</li>
<li>The stuff should be stored in an instance variable, called stuff</li>
<li>And a page should be successfully rendered using the process_item template</li>
</ul>
<p>That&#8217;s a pretty succinct explanation of what the controller should do - I can&#8217;t think of many ways of making that skinnier.  It also bears no resemblance to the actual implementation of the action - which currently looks something like this: </p>
<pre><code>
def process_work_item
    @item =Item.find(params[:id])
    case @item.product.class.to_s.underscore.to_sym
    when :buy_stuff
      @stuff = Stuff.build_item(@item)
      @stuff.setup_new
      render :action => :process_stuff
    when :update_stuff
      @item.stuff.prepare_for_update
      render :action => :update_stuff
    else
      render :status => 404, :text => "Item product type #{@item.product.class.to_s} unknown."
    end
rescue ActiveRecord::RecordNotFound
  render_not_found
end
</code></pre>
<p>Pretty complicated - and as new types of item are added we need to add more and more clauses to that case statement.  </p>
<p>First things first - I&#8217;ve said that we should call  &#8220;process&#8221; on the item class.  So I add a pending spec to the Item specification - this is to remind me that I&#8217;ve got some work to implement later on.  </p>
<pre><code>
  it "should process itself based upon its work type"
</code></pre>
<p>Then I rework the controller so that the controller spec passes.  </p>
<pre><code>
    @item =Item.find(params[:id])
    @stuff = @item.process
    render :template => "admin/orders/process_item"
</code></pre>
<p>Pretty simple huh?</p>
<p>What we have done is shifted the logic from the controller into this new &#8220;process&#8221; method on the Item.  We have made it so that the controller knows virtually nothing about the item - all it knows is how to find it and that it has a process method.  All the implementation details are now hidden within the Item, out of the way of the outside world.  </p>
<p>Through the use of mocking we can ignore actual implementations and concentrate on presenting ourselves as simply, and minimally, as possible to the outside world.  This reduces coupling, increases flexibility and makes our code easier to read.  Don&#8217;t you agree?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.3hv.co.uk/blog/2008/12/20/writing-tests-for-your-controllers-improves-the-design-of-your-models/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.3hv.co.uk/blog/2008/12/20/writing-tests-for-your-controllers-improves-the-design-of-your-models/</feedburner:origLink></item>
		<item>
		<title>Think Visibility</title>
		<link>http://feeds.feedburner.com/~r/3hv/~3/490740778/</link>
		<comments>http://www.3hv.co.uk/blog/2008/12/20/think-visibility/#comments</comments>
		<pubDate>Sat, 20 Dec 2008 18:12:12 +0000</pubDate>
		<dc:creator>Rahoul Baruah</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.3hv.co.uk/blog/?p=346</guid>
		<description><![CDATA[The irrepresible Dominic Hodgson is organising his very own conference in March 2009.  
It&#8217;s all about SEO, marketing and those dirty things us coders try not to get involved with   Of course, I will be there.  
So why not give Think Visibility a go?  You may just learn something.
]]></description>
			<content:encoded><![CDATA[<p>The irrepresible <a href="http://www.thehodge.co.uk/">Dominic Hodgson</a> is organising his very own conference in March 2009.  </p>
<p>It&#8217;s all about <a href="http://www.thinkvisibility.com/">SEO, marketing</a> and those dirty things us coders try not to get involved with <img src='http://www.3hv.co.uk/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  Of course, I will be there.  </p>
<p>So why not give <a href="http://www.thinkvisibility.com/">Think Visibility</a> a go?  You may just learn something.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.3hv.co.uk/blog/2008/12/20/think-visibility/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.3hv.co.uk/blog/2008/12/20/think-visibility/</feedburner:origLink></item>
		<item>
		<title>Coping with the VAT Change</title>
		<link>http://feeds.feedburner.com/~r/3hv/~3/464821894/</link>
		<comments>http://www.3hv.co.uk/blog/2008/11/25/coping-with-the-vat-change/#comments</comments>
		<pubDate>Tue, 25 Nov 2008 09:05:07 +0000</pubDate>
		<dc:creator>Rahoul Baruah</dc:creator>
		
		<category><![CDATA[Designing Great Software]]></category>

		<category><![CDATA[General]]></category>

		<category><![CDATA[Writing Reliable, Bug-Free Code]]></category>

		<guid isPermaLink="false">http://www.3hv.co.uk/blog/?p=333</guid>
		<description><![CDATA[There seems to be a lot of wailing and gnashing of teeth about the upcoming VAT change.  Especially as it is only a 13 month change and the rate will revert to 17.5% in 2010.  
However, it ought to be really simple (although I realise that this may be a bit late for [...]]]></description>
			<content:encoded><![CDATA[<p>There seems to be a lot of wailing and gnashing of teeth about the upcoming VAT change.  Especially as it is only a 13 month change and the rate will revert to 17.5% in 2010.  </p>
<p>However, it ought to be really simple (although I realise that this may be a bit late for some computer systems).  </p>
<h2>Never hard-code the VAT rate</h2>
<p>Have a Tax class that the rest of the system can ask when it needs the tax rate.  That way, you&#8217;ve only got one place to make the change.  </p>
<h2>Store the rate against your invoice lines</h2>
<p>Add a field to your invoice lines that stores the rate applicable for that line.  Populate this when the line is created.  That way, an invoice at tax point 30th November 2008 will have lines with a 17.5% stored against them, those created on the 1st December 2008 will have a 15% stored against them.  This keeps your most vital financial documents accurate over time.  </p>
<h2>Calculate the VAT as late as possible</h2>
<p>When calculating the VAT on an invoice do <em>not</em> do this: </p>
<pre><code>

value_excluding_vat = 0

vat = 0

value_including_vat = 0

for each line in my invoice

  value_excluding_vat += line.value

  vat += line.value * line.tax_rate

  value_including_vat += line.value + (line.value * line.tax_rate)

</code></pre>
<p>The problem here is that you are calculating the VAT on a per line basis and then summing the values.  This <em>will</em> lead to rounding errors - where your line values are a penny out from your totals.  </p>
<p>Instead you need to place each line into a &#8220;bucket&#8221; for its tax rate, sum all values for a given rate and then calculate the tax on that.  That way you are working on the largest numbers possible, reducing the risk of small decimal place discrepancies throwing your totals out.  </p>
<pre><code>

value_excluding_vat = 0

for each line in my invoice

  bucket = the_bucket_for line.vat

  bucket.value += line.value

  value_excluding_vat += line.value

vat = 0

for each bucket in my collection of buckets

  vat += bucket.value * bucket.rate

value_including_vat = value_excluding_vat + vat

</code></pre>
<h2>Have a Tax Band and Tax Rate model that deals with changes over time</h2>
<p>If you really want to have a &#8220;minimal administration&#8221; system for dealing with tax rate changes then you should switch your data model to have multiple Tax Band objects (as remember, there are multiple VAT bands - &#8220;standard&#8221; is 17.5/15%, &#8220;low&#8221; is 5%, &#8220;zero-rated&#8221; is 0% and &#8220;exempt&#8221; is also 0% but needs to be accounted for separately to &#8220;zero-rated&#8221;).  </p>
<p><a href="http://www.3hv.co.uk/blog/wp-content/uploads/2008/11/tax-rate-data-model.jpg"><img src="http://www.3hv.co.uk/blog/wp-content/uploads/2008/11/tax-rate-data-model.jpg" alt="A Data Model for dealing with variable tax bands and variable tax rates" title="tax-rate-data-model" width="112" height="202" class="size-medium wp-image-338" /></a>Each Tax Band object should have a set of Tax Rate objects hanging off it - where each Tax Rate has a percentage rate and a start and end date.  That way you can ask your &#8220;Standard Rate&#8221; tax object &#8220;what is the percentage on the 30th November 2008?&#8221; and it can give you the correct answer.  </p>
<p>That makes dealing with a change like this simple - you simply go to the &#8220;Standard Rate&#8221; object, find it&#8217;s current rate object and set its end date to 30th November 2008.  Then you add a new rate object to the &#8220;standard rate&#8221; of 15%, setting its start date to 1st December 2008, with an end date of 31st December 2009.  Lastly, add another 17.5% rate object, with a start date of 1st January 2010 and no end date.  </p>
<p>Update the rest of your systems to always ask the relevant tax object for the correct rate and tax rate changes will never be a headache again.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.3hv.co.uk/blog/2008/11/25/coping-with-the-vat-change/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.3hv.co.uk/blog/2008/11/25/coping-with-the-vat-change/</feedburner:origLink></item>
		<item>
		<title>Acceptance Testing in Ruby, Rails, RSpec and Cucumber</title>
		<link>http://feeds.feedburner.com/~r/3hv/~3/461017717/</link>
		<comments>http://www.3hv.co.uk/blog/2008/11/21/acceptance-testing-in-ruby-rails-rspec-and-cucumber/#comments</comments>
		<pubDate>Fri, 21 Nov 2008 18:16:13 +0000</pubDate>
		<dc:creator>Rahoul Baruah</dc:creator>
		
		<category><![CDATA[Beautiful Code]]></category>

		<category><![CDATA[Designing Great Software]]></category>

		<category><![CDATA[Ruby on Rails and Software Development]]></category>

		<category><![CDATA[Writing Reliable, Bug-Free Code]]></category>

		<guid isPermaLink="false">http://www.3hv.co.uk/blog/?p=328</guid>
		<description><![CDATA[I&#8217;ve written up a new post at the Brightbox blog detailing how we are using RSpec and Cucumber to build acceptance tests for the next generation Brightbox systems.
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve written up a new post at the <a href="http://blog.brightbox.co.uk/posts/using-rspec-cucumber-and-user-stories-to-build-our-internal-systems">Brightbox blog</a> detailing how we are using <a href="http://rspec.info/">RSpec</a> and <a href="http://github.com/aslakhellesoy/cucumber/tree/master">Cucumber</a> to build acceptance tests for the next generation Brightbox systems.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.3hv.co.uk/blog/2008/11/21/acceptance-testing-in-ruby-rails-rspec-and-cucumber/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.3hv.co.uk/blog/2008/11/21/acceptance-testing-in-ruby-rails-rspec-and-cucumber/</feedburner:origLink></item>
		<item>
		<title>Rails 2.1 and 2.2: CSRF vulnerability and work-around</title>
		<link>http://feeds.feedburner.com/~r/3hv/~3/458833953/</link>
		<comments>http://www.3hv.co.uk/blog/2008/11/19/rails-21-and-22-csrf-vulnerability-and-work-around/#comments</comments>
		<pubDate>Wed, 19 Nov 2008 21:17:04 +0000</pubDate>
		<dc:creator>Rahoul Baruah</dc:creator>
		
		<category><![CDATA[Ruby on Rails and Software Development]]></category>

		<guid isPermaLink="false">http://www.3hv.co.uk/blog/?p=325</guid>
		<description><![CDATA[I&#8217;ve done a quick write-up on the recent CSRF vulnerability on the Brightbox blog.
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve done a quick write-up on the recent <a href="http://www.rorsecurity.info/journal/2008/11/19/circumvent-rails-csrf-protection.html">CSRF vulnerability</a> on the <a href="http://blog.brightbox.co.uk/posts/rails-csrf-security-vulnerability">Brightbox blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.3hv.co.uk/blog/2008/11/19/rails-21-and-22-csrf-vulnerability-and-work-around/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.3hv.co.uk/blog/2008/11/19/rails-21-and-22-csrf-vulnerability-and-work-around/</feedburner:origLink></item>
		<item>
		<title>Rails vs Merb (updated)</title>
		<link>http://feeds.feedburner.com/~r/3hv/~3/457038387/</link>
		<comments>http://www.3hv.co.uk/blog/2008/11/18/rails-vs-merb/#comments</comments>
		<pubDate>Tue, 18 Nov 2008 10:30:04 +0000</pubDate>
		<dc:creator>Rahoul Baruah</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.3hv.co.uk/blog/?p=320</guid>
		<description><![CDATA[
What the fuck is this?  
Merb is launched and DHH suddenly has a load of &#8220;Rails Myths&#8221; posts up on his blog.  Like this sly little dig: 

it shows the great power of being an full-stack framework

Wycats responds with a slightly less sly dig: 

For the moment, these differences are the reason that [...]]]></description>
			<content:encoded><![CDATA[<div class="wp-caption alignnone" style="width: 560px"><a href="http://www.curtis.lassam.net/"><img alt="Ruby Programmers having a fight" src="http://curtis.lassam.net/comics/programmers.png" title="Programmers" width="550" height="770" /></a><p class="wp-caption-text">Ruby Programmers having a fight</p></div>
<p>What the fuck is <a href="http://www.reddit.com/r/ruby/comments/7d5u6/so_why_should_i_choose_merb_over_ruby_on_rails/">this</a>?  </p>
<p>Merb is launched and DHH suddenly has a load of &#8220;<a href="http://www.loudthinking.com/posts/29-the-rails-myths">Rails Myths</a>&#8221; posts up on his blog.  Like this sly little dig: </p>
<blockquote><p>
it shows the great power of being an full-stack framework
</p></blockquote>
<p>Wycats responds with a <a href="http://yehudakatz.com/2008/11/15/mythbusting-rails-is-not-a-monolith/">slightly less sly dig</a>: </p>
<blockquote><p>
For the moment, these differences are the reason that Rails will continue to dominate amongst developers seeking to build apps similar in scope to apps built by 37Signals. I suspect that Merb will pick up steam amongst developers looking to build innovative apps leveraging the latest and greatest Ruby techniques and libraries.
</p></blockquote>
<p>Zed <a href="http://www.zedshaw.com/blog/2008-11-13.html">responds angrily</a> to a mistake by DHH (which DHH <a href="http://www.loudthinking.com/posts/31-myth-2-rails-is-expected-to-crash-400-timesday">subsequently corrects</a>).  </p>
<p>I admit I&#8217;ve not had much time to look at Merb in detail; the times when I have played with it my impression has been &#8220;it&#8217;s much the same as Rails but done in a different (probably cleaner) way&#8221;.  I love the fact in Rails that everything comes in one bundle (apart from RSpec :-), I love the fact that Merb gives you choices (even though I don&#8217;t have the time to research those choices), I like the fact that the two frameworks are now feeding off each other.  </p>
<p>But the thing that impressed me most when I came to Rails was how nice and friendly the Ruby community was.  But, it would appear that that was an illusion and massive egos are in charge.  Discussion is good.  Adapting your ideas in the face of competition and change is good.  Having a massive pissing match because my framework is better than your framework is stupid.  I wish you would all just shut the fuck up.  </p>
<p>UPDATE: </p>
<p>And the <a href="http://hackety.org/2008/11/22/runningHot.html">fighting continues</a> - this time it&#8217;s _why versus Zed.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.3hv.co.uk/blog/2008/11/18/rails-vs-merb/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.3hv.co.uk/blog/2008/11/18/rails-vs-merb/</feedburner:origLink></item>
		<item>
		<title>Loading the MySQL drivers into GNU Smalltalk</title>
		<link>http://feeds.feedburner.com/~r/3hv/~3/452943307/</link>
		<comments>http://www.3hv.co.uk/blog/2008/11/14/loading-the-mysql-drivers-into-gnu-smalltalk/#comments</comments>
		<pubDate>Fri, 14 Nov 2008 12:50:04 +0000</pubDate>
		<dc:creator>Rahoul Baruah</dc:creator>
		
		<category><![CDATA[Beautiful Code]]></category>

		<category><![CDATA[Smalltalk]]></category>

		<guid isPermaLink="false">http://www.3hv.co.uk/blog/?p=310</guid>
		<description><![CDATA[It&#8217;s an unfortunate fact that many Open Source projects have documentation that is sadly lacking.  A case in point is GNU Smalltalk.  
Smalltalk is one of my favourite languages but a decent Smalltalk implementation that fits with your native window manager is hard to find.  The point of GNU Smalltalk is that [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s an unfortunate fact that many Open Source projects have documentation that is sadly lacking.  A case in point is GNU Smalltalk.  </p>
<p>Smalltalk is one of my favourite languages but a decent Smalltalk implementation that fits with your native window manager is hard to find.  The point of GNU Smalltalk is that it works &#8220;headlessly&#8221; (Smalltalk invented the graphical user-interface and the integrated development environment so this is quite a departure), so I can still use my favourite text editor and run stuff from the command line.  Just like Ruby!</p>
<p>However, it&#8217;s taken me a couple of hours to figure out how to simply connect to a database.  But now I have, here it is: </p>
<ul>
<li>Install GNU Smalltalk (in my case using MacPorts):<br />
    <code>sudo port install gst</code>
  </li>
<li>Start GNU Smalltalk and create a working image:<br />
<code>cd /Users/rahoulb/source/st<br />
gst<br />
st> ObjectMemory snapshot: 'work.im'.</code>
</li>
<li>Ctrl-D to exit Smalltalk and then restart using your new image:<br />
<code>gst -I work.im</code>
</li>
<li>Load the DBI database driver:<br />
<code>st> PackageLoader fileInPackage 'DBI'.</code><br />
Load the MySQL driver:<br />
<code>st> PackageLoader fileInPackage 'DBD-MySQL'.</code><br />
Save your image so you don&#8217;t need to reload these packages again:<br />
<code>st> ObjectMemory snapshot.</code>
</li>
<li>
Open a connection to your database:<br />
<code>st>con:= DBI.Connection connect: 'dbi:MySQL:dbname=mydatabase' user: 'myuser' password: 'mypassword'.</code><br />
Grab some data:<br />
<code>st>results:= con select: 'select name from customers limit 10;'</code>
</li>
<li>Bask in the glory of your data</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.3hv.co.uk/blog/2008/11/14/loading-the-mysql-drivers-into-gnu-smalltalk/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.3hv.co.uk/blog/2008/11/14/loading-the-mysql-drivers-into-gnu-smalltalk/</feedburner:origLink></item>
		<item>
		<title>TechieTubbies: podcasting about startups and techie stuff in Britain and around the world</title>
		<link>http://feeds.feedburner.com/~r/3hv/~3/448246787/</link>
		<comments>http://www.3hv.co.uk/blog/2008/11/10/techietubbies-podcasting-about-startups-and-techie-stuff-in-britain-and-around-the-world/#comments</comments>
		<pubDate>Mon, 10 Nov 2008 09:52:20 +0000</pubDate>
		<dc:creator>Rahoul Baruah</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.3hv.co.uk/blog/?p=308</guid>
		<description><![CDATA[The second episode of my new joint-venture, Techietubbies, performed with the irrepressible Dominic Hodgson, is now available.  It&#8217;s semi-regular half hour podcast where we discuss startups and technology news whilst giggling like children - probably not very professional but that&#8217;s the way we like it!
]]></description>
			<content:encoded><![CDATA[<p>The second episode of my new joint-venture, <a href="http://www.techietubbies.co.uk/podcast/">Techietubbies</a>, performed with the irrepressible <a href="http://www.thehodge.co.uk/">Dominic Hodgson</a>, is now available.  It&#8217;s semi-regular half hour podcast where we discuss startups and technology news whilst giggling like children - probably not very professional but that&#8217;s the way we like it!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.3hv.co.uk/blog/2008/11/10/techietubbies-podcasting-about-startups-and-techie-stuff-in-britain-and-around-the-world/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.3hv.co.uk/blog/2008/11/10/techietubbies-podcasting-about-startups-and-techie-stuff-in-britain-and-around-the-world/</feedburner:origLink></item>
		<item>
		<title>iPhone prevents irate customer</title>
		<link>http://feeds.feedburner.com/~r/3hv/~3/441457851/</link>
		<comments>http://www.3hv.co.uk/blog/2008/11/03/iphone-prevents-irate-customer/#comments</comments>
		<pubDate>Mon, 03 Nov 2008 22:47:39 +0000</pubDate>
		<dc:creator>Rahoul Baruah</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Managing Successful Projects]]></category>

		<guid isPermaLink="false">http://www.3hv.co.uk/blog/?p=303</guid>
		<description><![CDATA[I spent this weekend in the Lake District in the wet north-west of England.  A beautiful part of the world, but one lacking in 3G connectivity.  Not great for browsing (although Mobile Twitter and email were fine) but fantastic for battery life.  
On Sunday morning, I awoke to find an email from [...]]]></description>
			<content:encoded><![CDATA[<p>I spent this weekend in the Lake District in the wet north-west of England.  A beautiful part of the world, but one lacking in 3G connectivity.  Not great for browsing (although Mobile Twitter and email were fine) but fantastic for battery life.  </p>
<p>On Sunday morning, I awoke to find an email from a <a href="http://www.montastic.com/">web-site monitoring service</a> that I use, stating that a client site was down.  The email was sent at 5am.  It was now 10am and I had no computer, a mere GPRS connection and a hangover.  Not good.  </p>
<p>However, I fired up TouchTerm (an SSH client) on my iPhone and connected to the server in question.  Connect OK.  Good.  Then I type <code>sudo monit status</code> to find out what state the server is in.  All services running OK.  Then <code>cat /etc/apache2/sites-enabled/rails-mysite</code>.  This lets me examine the web-server configuration file; and I can prove to myself that I had set up aliases for the site (so that the same site is also available on an alternative web address).  I then used Mobile Safari to connect on the alternative addresses and everything works fine.  Lastly, I write an email to the client stating that the site is down but nothing at my end is wrong - could it be a DNS problem?  </p>
<p><div class="wp-caption alignleft" style="width: 460px"><img alt="iPhone with TouchTerm" src="http://www.dabbledoo.com/ee/images/uploads/appletell/TouchTerm.png" title="iPhone with TouchTerm" width="450" height="280" /><p class="wp-caption-text">iPhone with TouchTerm</p></div>Of course, there are many phones that can do this.  In fact I have had so-called &#8220;smartphones&#8221; for years - all of which are capable of connecting over SSH, over the web and over email.  But the iPhone is the first where I have actually used that capability, where it&#8217;s not so painful to use that I want to try it out.  </p>
<p>Later that day I got an email from the monitoring service stating that the site had returned.  And on Monday, the client tells me that their registrar had had a failure and all of their domain names had gone down for the day.  </p>
<p>Still, I think that&#8217;s pretty good; Sunday, with a hangover, pro-actively investigating a fault on a customer&#8217;s server, on a telephone and an antique net connection.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.3hv.co.uk/blog/2008/11/03/iphone-prevents-irate-customer/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.3hv.co.uk/blog/2008/11/03/iphone-prevents-irate-customer/</feedburner:origLink></item>
	</channel>
</rss>
