<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>flow</title>
    <link>http://flow.handle.it</link>
    <language>en</language>
    <webMaster>jk@handle.it (HandleIT)</webMaster>
    <copyright>Copyright 2007-2010</copyright>
    <ttl>60</ttl>
    <pubDate>Tue, 23 Feb 2010 11:30:00 GMT</pubDate>
    <description>efficacy is never forced</description>
    <item>
      <title>Ruby 1.8 and 1.9 living in harmony</title>
      <link>http://flow.handle.it/past/2010/2/20/ruby_18_and_19_living/</link>
      <pubDate>Sat, 20 Feb 2010 15:14:00 GMT</pubDate>
      <guid>http://flow.handle.it/past/2010/2/20/ruby_18_and_19_living/</guid>
      <author>jk@handle.it (Jason King)</author>
      <description>&lt;p&gt;I&amp;#8217;m running on OSX, and using MacPorts for all my un-Apple needs.  So, no, getting Ruby 1.9 installed was not complex at all, the suffix is the default in MacPorts, so I just ended up with a ruby1.9 executable.&lt;/p&gt;

&lt;p&gt;The kicker comes because Rails, and all its little generator friends, do one of two things.  Either they are just hardcoded to use &lt;code&gt;#!/usr/bin/env ruby&lt;/code&gt; or they set that line to whatever version of Ruby you happen to be using when you install/generate/make them the first time, which will be either what I&amp;#8217;ve just written or &lt;code&gt;#!/usr/bin/env ruby1.9&lt;/code&gt; or (like rails) an actual hard coded path to your MacPorts ruby executable.&lt;/p&gt;

&lt;p&gt;Ok, not really a big problem there, until you want to test your application, generator, plugin, gem, whatever against the other ruby on your system.  What do you do?  Go through and make sure you change all the relevant shebangs?  Works fine until you miss one.  You&amp;#8217;re really testing your &lt;code&gt;sed&lt;/code&gt; fu, not your Ruby fu.&lt;/p&gt;

&lt;p&gt;And then what happens when, like me, you&amp;#8217;re just so used to typing &lt;code&gt;irb&lt;/code&gt; or &lt;code&gt;ri&lt;/code&gt; that you&amp;#8217;re constantly tripping over the &lt;em&gt;&amp;#8220;Oh, yeah, that&amp;#8217;s over in the 1.9 stuff.&amp;#8221;&lt;/em&gt; problem?&lt;/p&gt;

&lt;p&gt;Well, then you know it&amp;#8217;s time to roll out your &lt;code&gt;bash&lt;/code&gt; fu.  Ewk!&lt;/p&gt;

&lt;p&gt;I rolled up these bash functions to switch my MacPorts installation from 1.8 to 1.9 by taking all the binaries that are part of the &lt;code&gt;ruby&lt;/code&gt; macports install and moving them to suffixed files, and then symlinking the bare names to either 1.8 or 1.9 (which IMHO should &lt;strong&gt;always&lt;/strong&gt; be how languages are installed).&lt;/p&gt;

&lt;script src="http://gist.github.com/310185.js"&gt;&lt;/script&gt;


&lt;p&gt;So, dependencies?  It depends on you having macports - it uses that to get the list of files that have been added to the relevant bin directory.  You could replace that in the for loop with something else to give you those filenames.&lt;/p&gt;

&lt;p&gt;That&amp;#8217;s it.&lt;/p&gt;

&lt;p&gt;Hmm, or it would be it if I said: run r18 to switch to Ruby 1.8 and run r19 to switch to Ruby 1.9.  Also - warning - this runs sudo, so understand what you&amp;#8217;re running before typing in your password.&lt;/p&gt;</description>
      <category domain="http://flow.handle.it/past/tags/18">18</category>
      <category domain="http://flow.handle.it/past/tags/19">19</category>
      <category domain="http://flow.handle.it/past/tags/macports">macports</category>
      <category domain="http://flow.handle.it/past/tags/osx">osx</category>
      <category domain="http://flow.handle.it/past/tags/ruby">ruby</category>
    </item>
    <item>
      <title>jquery in Rails3</title>
      <link>http://flow.handle.it/past/2010/2/9/jquery_in_rails/</link>
      <pubDate>Tue, 09 Feb 2010 01:09:00 GMT</pubDate>
      <guid>http://flow.handle.it/past/2010/2/9/jquery_in_rails/</guid>
      <author>jk@handle.it (Jason King)</author>
      <description>&lt;p&gt;There are two things you want to sort out in Rails3 to get jquery humming along really nicely.&lt;/p&gt;

&lt;p&gt;Firstly is the &lt;a href="http://en.wikipedia.org/wiki/Unobtrusive_JavaScript"&gt;UJS&lt;/a&gt;.  Rails3 has done great things in replacing all the inline JS with UJS and nice semantic XHTML - but, of course, they ship with the Prototype version of this UJS file.&lt;/p&gt;

&lt;p&gt;You&amp;#8217;ll want to just overwrite the &lt;code&gt;public/javascripts/rails.js&lt;/code&gt; file in your project with &lt;a href="http://github.com/rails/jquery-ujs"&gt;the jquery version from github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So the next step would be to add the &lt;code&gt;javascript_include_tag&lt;/code&gt; to all your layouts, and if you&amp;#8217;re a jquery fan then you&amp;#8217;re probably used to something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;javascript_include_tag 'jquery', 'jquery-ui', 'rails', 'application'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;At best, if you have only one layout, that&amp;#8217;s ugly.  When you begin to get more than one layout, you&amp;#8217;re un-DRY, or you&amp;#8217;re writing your own helper to wrap that up.  It just gets uglier.  Especially when compared to the Prototype equivalent:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;javascript_include_tag :defaults
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;How do we get this &lt;em&gt;logical&lt;/em&gt; grouping of JS files?&lt;/p&gt;

&lt;p&gt;Well, I might just be the last one at the party here, but I couldn&amp;#8217;t find anything online, or anything obvious in the help, for how to DRY this up.  A quick dig in the source revealed the answer though.  Somewhere in your init files (in Rails3 I have this in &lt;code&gt;config/application.rb&lt;/code&gt; - but this will work in previous versions of Rails too) you can register what&amp;#8217;s called an expansion, like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ActionView::Helpers::AssetTagHelper.register_javascript_expansion \
  :jquery =&amp;gt; %w/jquery jquery-ui rails application/
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So then in your layouts you can use that expansion like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;javascript_include_tag :jquery
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Much nicer, and very simple to update in a central &lt;em&gt;config&lt;/em&gt; location, should you wish.&lt;/p&gt;</description>
      <category domain="http://flow.handle.it/past/tags/javascript">javascript</category>
      <category domain="http://flow.handle.it/past/tags/jquery">jquery</category>
      <category domain="http://flow.handle.it/past/tags/rails">rails</category>
      <category domain="http://flow.handle.it/past/tags/rails2">rails2</category>
      <category domain="http://flow.handle.it/past/tags/rails3">rails3</category>
      <category domain="http://flow.handle.it/past/tags/ruby">ruby</category>
    </item>
    <item>
      <title>git really is better than svn</title>
      <link>http://flow.handle.it/past/2010/1/26/git_really_is_better_than/</link>
      <pubDate>Tue, 26 Jan 2010 01:33:00 GMT</pubDate>
      <guid>http://flow.handle.it/past/2010/1/26/git_really_is_better_than/</guid>
      <author>jk@handle.it (Jason King)</author>
      <description>&lt;p&gt;For many months when git (or really when github) first arrived on the scene I heard nothing else from all the fanboys than how great git was, how crap svn was, and that everyone who was anyone was using git now.  That sort of zealous response to new software or services always gives me pause.&lt;/p&gt;

&lt;p&gt;Inevitably, I&amp;#8217;d ask one of the fanboys why they recommended git over svn, and usually they would come up with one of two standard &amp;#8220;reasons&amp;#8221;&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;Git handled branching much better than svn&lt;/li&gt;
&lt;li&gt;Git was distributed and therefore cool&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;I had rejected the first immediately - if you&amp;#8217;re familiar with svn, have a shell script or two to wrap up the repetitive task of retrieving the full URL from &lt;code&gt;svn status&lt;/code&gt;, know about &lt;code&gt;svn switch !!:$&lt;/code&gt; and especially if you had svn 1.6 with branch tracking, then really svn is very good at branching too.&lt;/p&gt;

&lt;p&gt;I had rejected the second for any situation where this wasn&amp;#8217;t important - like 99% of corporate situations where you have your own svn server sitting on a 100mb/s LAN.&lt;/p&gt;

&lt;p&gt;Unfortunately, &lt;strong&gt;no one ever mentioned the &lt;em&gt;real&lt;/em&gt; advantages of git over svn&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;Time to try git&lt;/h2&gt;

&lt;p&gt;I began a new role in San Diego, and we have some developers in Tijuana who have a very sketchy internet connection that can be down for many hours at a time.  Sounded to me like one of the 1% of times when having a distributed SCM might prove useful.  So in I dove.&lt;/p&gt;

&lt;h2&gt;The real advantages of git over svn&lt;/h2&gt;

&lt;p&gt;The fanboys would have had me totally sold had they mentioned these things.&lt;/p&gt;

&lt;h3&gt;1. You can split during commit&lt;/h3&gt;

&lt;p&gt;This sequence of events happens &lt;strong&gt;so&lt;/strong&gt; often that it&amp;#8217;s really nice to have it supported as a first class citizen in your SCM.  You begin working on an issue, let&amp;#8217;s call it &lt;em&gt;&amp;#8220;password recovery&amp;#8221;&lt;/em&gt; and as you&amp;#8217;re working you notice some hard coded URLs in some template files and you fix those, and you notice some poorly named variables and you fix those, and you notice some debug code and you remove that, and you finish your work only to realize that you now have a working directory that contains more than one logical unit of work.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git add --patch .
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Tadaa - you can now use an interactive mechanism to stage your commit, picking the files &lt;strong&gt;or even changed lines within files&lt;/strong&gt; that are specific to each logical unit of work.  Then commit that, with an appropriate comment and move on to the next commit in the same way.  So in our example we can pick and choose which files, and lines within files, that we want as part of our &lt;em&gt;&amp;#8220;password recovery&amp;#8221;&lt;/em&gt; commit, commit that, then pick and choose the variable naming fixes, commit those, etc..&lt;/p&gt;

&lt;p&gt;We end up with a useful history with change-specific commits.  This alone would have sold me on git.&lt;/p&gt;

&lt;h3&gt;2. You amend/edit a previous commit&lt;/h3&gt;

&lt;p&gt;You&amp;#8217;re adding the &lt;em&gt;&amp;#8220;password recovery&amp;#8221;&lt;/em&gt; feature, editing away, and you make your commit.  Then you notice a new file that you forgot to add in.  No &lt;code&gt;svnadmin&lt;/code&gt; required, no dirty history, instead you just stage the file ready for commit, and then amend the previous commit:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git commit --amend
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You get the opportunity to edit the comment if you need to, and a totally new history is created in your repository.&lt;/p&gt;

&lt;p&gt;One of the advantages of having a distributed system is that if you&amp;#8217;ve not pushed that commit to any other developers yet, then you can fix your own repository up without adversely affecting anyone else.&lt;/p&gt;

&lt;h3&gt;3. You can undo previous commits&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;--amend&lt;/code&gt; option is really just a convenient layer around the ability to fully reverse our a previous commit.  You can do this yourself with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git reset HEAD^
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will reset your repository to how it was one before the HEAD (that&amp;#8217;s what the &lt;code&gt;^&lt;/code&gt; means).  Your files in your working directory will remain untouched, it just changes the repository so that it no longer has the commit recorded.  You can then re-edit, reorganize, whatever you want before committing what you &lt;em&gt;actually&lt;/em&gt; wanted in your repository.&lt;/p&gt;

&lt;h3&gt;Many more&lt;/h3&gt;

&lt;p&gt;There are many more very nice things that you can do with git.&lt;/p&gt;

&lt;p&gt;Some are simple things, like that creating a new repository is very cheap and quick, so you end up doing it for things that you wouldn&amp;#8217;t necessarily bother with for svn.  It&amp;#8217;s also done in place by default, as opposed to svn where you have to do the checkout/add trick to make a repository in place.&lt;/p&gt;

&lt;p&gt;Some are quite complex things, like &lt;code&gt;bisect&lt;/code&gt; is an incredible tool for easily tracking down which version a bug was introduced in.  You &lt;em&gt;could&lt;/em&gt; do it with svn too, but it ships with git - ready to go.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s definitely worth a try whenever you can justify it :)&lt;/p&gt;</description>
      <category domain="http://flow.handle.it/past/tags/git">git</category>
      <category domain="http://flow.handle.it/past/tags/scm">scm</category>
      <category domain="http://flow.handle.it/past/tags/svn">svn</category>
    </item>
    <item>
      <title>Simpler test output with turn</title>
      <link>http://flow.handle.it/past/2009/5/26/simpler_test_output_with_turn/</link>
      <pubDate>Tue, 26 May 2009 05:09:00 GMT</pubDate>
      <guid>http://flow.handle.it/past/2009/5/26/simpler_test_output_with_turn/</guid>
      <author>jk@handle.it (Jason King)</author>
      <description>&lt;p&gt;This is a small thing, but sometimes those small things can really make a huge difference.  This is one of those.&lt;/p&gt;

&lt;p&gt;As your suite of tests grow, especially in those large applications, you often end up with an error output that looks something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;..........F..............F.....E....FFF...F..........
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And then following that is a huge list of error details.  Scrolling through that is a pain, and even with &lt;code&gt;redgreen&lt;/code&gt; active your visual cues are at a minimum when looking through that output.&lt;/p&gt;

&lt;p&gt;Thankfully this also annoyed &lt;a href="http://github.com/TwP"&gt;Tim Pease&lt;/a&gt; who came up with &lt;a href="http://github.com/TwP/turn"&gt;a very pleasant alternative called turn&lt;/a&gt;.  You can install it as a gem, and then just add:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'turn'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Into your test helper and you&amp;#8217;ll see much simpler and comprehensible output from your test output.&lt;/p&gt;</description>
      <category domain="http://flow.handle.it/past/tags/TestUnit">TestUnit</category>
      <category domain="http://flow.handle.it/past/tags/test">test</category>
    </item>
    <item>
      <title>A few more things in the Rails console</title>
      <link>http://flow.handle.it/past/2009/5/2/a_few_more_things_in/</link>
      <pubDate>Sat, 02 May 2009 04:01:00 GMT</pubDate>
      <guid>http://flow.handle.it/past/2009/5/2/a_few_more_things_in/</guid>
      <author>jk@handle.it (Jason King)</author>
      <description>&lt;p&gt;Almost immediately after posting &lt;a href="http://flow.handle.it/past/2009/3/31/a_couple_of_things_in/"&gt;my last post on the Rails console&lt;/a&gt; a few more things came to mind.  It has taken me this long to blog again :)&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s pick up from where we left off in the previous post with&amp;#8230;&lt;/p&gt;&lt;h2&gt;Thing 6: reload!&lt;/h2&gt;

&lt;p&gt;I can&amp;#8217;t believe I forgot this one in the first post, this is one of the most useful methods in the console.  The &lt;code&gt;reload!&lt;/code&gt; method reloads your Rails application, so after you make change to your app you just run &lt;code&gt;reload!&lt;/code&gt; to pick up your new changes.  No more restarting your console and losing all your history.  Simple, but really effective.&lt;/p&gt;

&lt;h2&gt;Thing 7: the &amp;#8211;debugger option&lt;/h2&gt;

&lt;p&gt;Prerequisite for this to work, as with all ruby debugging, is to have the &lt;code&gt;ruby-debug&lt;/code&gt; gem installed, so before we begin:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sudo gem install ruby-debug
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then, when you start your console with the &lt;code&gt;--debugger&lt;/code&gt; option (which you can shorten to &lt;code&gt;-d&lt;/code&gt;) you get your Rails console run under the debugger:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ console -d
=&amp;gt; Debugger enabled
Loading development environment (Rails 2.3.2)
&amp;gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, what does this mean?  Well, now you have the debugger available, so let&amp;#8217;s make a very simple model:&lt;/p&gt;

&lt;h3&gt;app/models/foo.rb&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;class Foo &amp;lt; ActiveRecord::Base
  def foo(foo)
    puts foo.upcase
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So now in our console we want to stick a breakpoint into that model, we can either edit the &lt;code&gt;app/models/foo.rb&lt;/code&gt; file and put in a call to the &lt;code&gt;debugger&lt;/code&gt; method, or more simply we can just call the &lt;code&gt;debugger&lt;/code&gt; method in the console and put in the breakpoint there:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; debugger
/opt/local/lib/ruby/1.8/irb/context.rb:163
@last_value = value
(rdb:1) b Foo#foo
Breakpoint 1 at Foo::foo
(rdb:1) c
=&amp;gt; 1
&amp;gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Only weird thing here to note is that when we call &lt;code&gt;debugger&lt;/code&gt; we actually cause rdebug to break in the middle of the irb code.  This also happens, as you&amp;#8217;ll see below, as we step through code - when we come out of our own code, we end up debugging the console/irb code itself.  Just something to be aware of and not get freaked out at.&lt;/p&gt;

&lt;p&gt;So, now that we have that breakpoint set, let&amp;#8217;s run some code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; Foo.new.foo('bar')
Breakpoint 1 at Foo:foo
.../app/models/foo.rb:2
def foo(foo)
(rdb:1) l
[-3, 6] in .../app/models/foo.rb
   1  class Foo &amp;lt; ActiveRecord::Base
=&amp;gt; 2    def foo(foo)
   3      puts foo.upcase
   4    end
   5  end
(rdb:1) n
.../app/models/foo.rb:3
puts foo.upcase
(rdb:1) pp foo
"bar"
(rdb:1) n
BAR
/opt/local/lib/ruby/1.8/irb/context.rb:163
@last_value = value
(rdb:1) c
=&amp;gt; nil
&amp;gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, here we instantiate a &lt;code&gt;Foo&lt;/code&gt; object and send the &lt;code&gt;foo&lt;/code&gt; method to it with the &lt;code&gt;"bar"&lt;/code&gt; argument.  You can see that our breakpoint is hit and we&amp;#8217;re prompted with the &lt;code&gt;(rdb:1)&lt;/code&gt; prompt.  I issue the &lt;code&gt;l&lt;/code&gt; command (short for &lt;code&gt;list&lt;/code&gt;) to see where I am in the code, and then the &lt;code&gt;n&lt;/code&gt; (short for &lt;code&gt;next&lt;/code&gt;) to step over the next statement.  I&amp;#8217;m able to &lt;code&gt;pp&lt;/code&gt; the &lt;code&gt;foo&lt;/code&gt; parameter to see its value, and then I &lt;code&gt;n&lt;/code&gt; again and we see the output of that &lt;code&gt;puts&lt;/code&gt; call.&lt;/p&gt;

&lt;p&gt;Then, as I mentioned previously, we exit our own code, but the debugger doesn&amp;#8217;t exit.  As you can see we end up on line 163 of &lt;code&gt;irb/context.rb&lt;/code&gt; - you&amp;#8217;ll get used to seeing this, it means that we&amp;#8217;re back out of our code.  So I just enter the &lt;code&gt;c&lt;/code&gt; command (short for &lt;code&gt;continue&lt;/code&gt;) and the code continues to run and returns me back to my console prompt.&lt;/p&gt;

&lt;p&gt;Ok, fairly simple.  That breakpoint will stay in the debugger until we explicitly &lt;code&gt;delete&lt;/code&gt; it (or restart our console session).  On to the next thing&amp;#8230;&lt;/p&gt;

&lt;h2&gt;Thing 8: helper method&lt;/h2&gt;

&lt;p&gt;There are plenty of times when you&amp;#8217;re seeing something unexpected in your browser and want to use your console to work out what&amp;#8217;s going on.  Sometimes you want to take a look at the output of a view helper, because something&amp;#8217;s just not fitting.&lt;/p&gt;

&lt;p&gt;Enter the &lt;code&gt;helper&lt;/code&gt; method.  This is built-in to your console session.  You won&amp;#8217;t be able to call any helper that needs to make a URL like form_for, but you still have a lot available to you.  As a simple, and trivial example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; helper.number_to_currency( 45.234445 )
=&amp;gt; "$45.23"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can get a little fancier by setting instance variables in the &lt;code&gt;helper&lt;/code&gt; instance, like so (I&amp;#8217;ve added a &lt;code&gt;name&lt;/code&gt; field to my &lt;code&gt;Foo&lt;/code&gt; model/table):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; helper.instance_variable_set( :@foo, Foo.new( :name =&amp;gt; 'foo bar' ) )
=&amp;gt; #&amp;lt;Foo id: nil, name: "foo bar", created_at: nil, updated_at: nil&amp;gt;
&amp;gt;&amp;gt; helper.text_field :foo, :name
=&amp;gt; "&amp;lt;input id=\"foo_name\" name=\"foo[name]\" size=\"30\" type=\"text\" value=\"foo bar\" /&amp;gt;"
&amp;gt;&amp;gt; puts _
&amp;lt;input id="foo_name" name="foo[name]" size="30" type="text" value="foo bar" /&amp;gt;
=&amp;gt; nil
&amp;gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Very nice, yes, I like :)  Next thing&amp;#8230;&lt;/p&gt;

&lt;h2&gt;Thing 9: readline support ^R&lt;/h2&gt;

&lt;p&gt;On systems that have &lt;em&gt;readline&lt;/em&gt; the console session will have &lt;em&gt;readline&lt;/em&gt; support rolled in.  There are many things which this brings you, emacs editing of your lines, configuration through your &lt;code&gt;~/.inputrc&lt;/code&gt; file, all the juicy goodness.  One thing which is generally always available in all readline distributions is the ^R mapping to the readline macro &lt;code&gt;history-search-backward&lt;/code&gt; which means that you can hit ^R (Control+R) and start typing any part of a previous (within that console session) line and readline will search backwards through your history and present you with the options.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s hard to demonstrate this without being live, so really - just try this yourself.  Run some commands, and then hit Ctrl+R and start typing part of one of those previous commands, you&amp;#8217;ll see what readline magic is :)&lt;/p&gt;

&lt;h2&gt;Thing 10: adjust your $PATH&lt;/h2&gt;

&lt;p&gt;Finally, a really tiny one.  Not sure how this applies to Windows because I&amp;#8217;m not sure what Windows has in its RAILS_ROOT/script directory.&lt;/p&gt;

&lt;p&gt;You see, time and again, people doing this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ruby script/console
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And in fact, the same for generators and other scripts:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ruby script/generator model Foo name:string
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Unless you have a very broken Ruby or Rails installation, then on any shebang system you can drop the &lt;code&gt;ruby&lt;/code&gt; - everything in your &lt;code&gt;script/&lt;/code&gt;directory will be executable, and so it can be run directly.  But then, for the truly lazy (like me) why not go one step further and add &lt;code&gt;./script&lt;/code&gt; to your PATH so that when you&amp;#8217;re in your RAILS_ROOT directory you can just type the command directly.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ echo 'export PATH=./script:$PATH' &amp;gt;&amp;gt; ~/.bashrc
$ source ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, now you are all set to run those &lt;code&gt;script/*&lt;/code&gt; scripts directly:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ console -d
...
$ generate model Foo name:string
...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Etc..&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;I hope those make your life a lot simpler.  I&amp;#8217;ll settle for just a little simpler.  Have fun.&lt;/p&gt;</description>
      <category domain="http://flow.handle.it/past/tags/console">console</category>
      <category domain="http://flow.handle.it/past/tags/debugger">debugger</category>
      <category domain="http://flow.handle.it/past/tags/irb">irb</category>
      <category domain="http://flow.handle.it/past/tags/rdebug">rdebug</category>
      <category domain="http://flow.handle.it/past/tags/readline">readline</category>
      <category domain="http://flow.handle.it/past/tags/ruby">ruby</category>
      <category domain="http://flow.handle.it/past/tags/rubydebug">rubydebug</category>
    </item>
    <item>
      <title>When REST doesn't fit</title>
      <link>http://flow.handle.it/past/2009/4/29/when_rest_doesnt_fit/</link>
      <pubDate>Wed, 29 Apr 2009 06:39:00 GMT</pubDate>
      <guid>http://flow.handle.it/past/2009/4/29/when_rest_doesnt_fit/</guid>
      <author>jk@handle.it (Jason King)</author>
      <description>&lt;p&gt;So, those of you that know me know that I&amp;#8217;m no REST zealot.  I think there are many times when it&amp;#8217;s better to use a non-REST controller.  Simplicity of URLs, succinctness of controller, etc..&lt;/p&gt;

&lt;p&gt;One example that I&amp;#8217;ve just come across is a questionnaire which doesn&amp;#8217;t really map to REST.  For a start I never want to expose this controller via an API, the process flow also doesn&amp;#8217;t follow REST at all, sure I want a new questionnaire completed, but that&amp;#8217;s it.  I don&amp;#8217;t want to be able to show, edit/update or delete.&lt;/p&gt;&lt;p&gt;I also want some nice and simple URLs, so I don&amp;#8217;t want &lt;code&gt;/questionnaire/new&lt;/code&gt; for a new questionnaire, I just want something very simple like &lt;code&gt;/q&lt;/code&gt;.  And then I want a &lt;em&gt;thank-you&lt;/em&gt; page at the end of the questionnaire, with a message about the email confirmation that I&amp;#8217;ve sent to the participant.  Nothing here sounds RESTy, and I&amp;#8217;d encourage you to just depart from REST when this happens - don&amp;#8217;t feel locked in.&lt;/p&gt;

&lt;p&gt;So, the controller will be familiar, and I&amp;#8217;m not really interested in repeating here what I&amp;#8217;ve done there.  It will be very similar to other RESTful controllers, bar a few bits.  What I &lt;em&gt;*am&lt;/em&gt;* interested in demonstrating here is what to do in your routes.&lt;/p&gt;

&lt;p&gt;Routes, more than controllers, are where a lot of REST magic is rolled up into some very concise helpers.  So, when we move away from REST how do we make our routes nice and simple, concise, and DRY?&lt;/p&gt;

&lt;p&gt;Well, let me just spill the beans on what I have for my questionnaire:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;map.with_options :controller =&amp;gt; 'q' do |c|
  c.with_options :conditions =&amp;gt; { :method =&amp;gt; :get } do |cget|
    cget.q 'q'
    cget.q_thanks 'q/thanks', :action =&amp;gt; 'thanks'
  end
  c.with_options :conditions =&amp;gt; { :method =&amp;gt; :post } do |cpost|
    cpost.connect 'q', :action =&amp;gt; 'create'
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Isn&amp;#8217;t that &lt;code&gt;with_options&lt;/code&gt; a nice little tool.  So what are we doing here?&lt;/p&gt;

&lt;p&gt;Well, we want all our routes to be for our new &lt;code&gt;Q&lt;/code&gt; controller, so we open up a block with the &lt;code&gt;:controller =&amp;gt; 'q'&lt;/code&gt; options sending that to the &lt;code&gt;map&lt;/code&gt; receiver.  Seriously cool.&lt;/p&gt;

&lt;p&gt;So then within that enclosing block we have our GET and POST URLs separated.  So we have two GET URLs defined (both as named routes), one for the (implicit) &lt;code&gt;index&lt;/code&gt; action with the &lt;code&gt;q&lt;/code&gt; helper, and one for the &lt;code&gt;thanks&lt;/code&gt; action with the &lt;code&gt;q_thanks&lt;/code&gt; helper.  Then we have a single POST URLs defined for the creation which we have named &lt;code&gt;q_create&lt;/code&gt;.  So now, what does our form look like?&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;% form_for @questionnaire, :url =&amp;gt; q_path do |f| %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Very neat and tidy, we just use our &lt;code&gt;q&lt;/code&gt; helper and we know that forms will have POST action, which will mean it will be routed to our &lt;code&gt;create&lt;/code&gt; action.  Then in our &lt;code&gt;create&lt;/code&gt; action in our controller the successful response will be something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;flash[:success] = 'Questionnaire was successfully created.'
format.html { redirect_to( q_thanks_path ) }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which is good enough for me.&lt;/p&gt;</description>
      <category domain="http://flow.handle.it/past/tags/restful">restful</category>
      <category domain="http://flow.handle.it/past/tags/routes">routes</category>
    </item>
    <item>
      <title>Column sorting with good_sort</title>
      <link>http://flow.handle.it/past/2009/4/3/column_sorting_with_good_sort/</link>
      <pubDate>Fri, 03 Apr 2009 11:17:00 GMT</pubDate>
      <guid>http://flow.handle.it/past/2009/4/3/column_sorting_with_good_sort/</guid>
      <author>jk@handle.it (Jason King)</author>
      <description>&lt;p&gt;I spent a little time this week pulling sorting out of a project of mine as a gem.  I&amp;#8217;m really happy with where I got to with it.&lt;/p&gt;

&lt;p&gt;What this is is something that lets you &lt;strong&gt;very&lt;/strong&gt; easily add column sorting to your data views so that visitors can click on the column headings to re-present the data sorted by that heading.&lt;/p&gt;&lt;p&gt;There are two parts to this gem:&lt;/p&gt;

&lt;h2&gt;The Model&lt;/h2&gt;

&lt;p&gt;You get the declarative &lt;code&gt;sort_on&lt;/code&gt; method for your model so you can stipulate in your model which attributes are allowed to be sorted on.  This means that sorting is always a positive assertion, so (for example) you can choose to select only those attributes that map to columns in your DB that you have indexes for.&lt;/p&gt;

&lt;p&gt;If sorting is attempted for any other columns, then an exception is thrown.&lt;/p&gt;

&lt;p&gt;You also get the class method &lt;code&gt;sort_by&lt;/code&gt; which takes a parameter (string or symbol) that has to be one of the attributes declared in that model&amp;#8217;s &lt;code&gt;sort_on&lt;/code&gt; and returns a hash suitable for merging into parameters for an ActiveRecord &lt;code&gt;find&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;The View&lt;/h2&gt;

&lt;p&gt;You also get a helper for outputting the headers in the view called &lt;code&gt;sort_headers_for&lt;/code&gt; which makes it really easy to output all the gracefully degrading AJAX-enabled headers/links for sorting your list.&lt;/p&gt;

&lt;h2&gt;Let&amp;#8217;s Have a Look&lt;/h2&gt;

&lt;p&gt;I&amp;#8217;ve pretty much just chomped this out of the gem&amp;#8217;s README, but it&amp;#8217;s a decent example:&lt;/p&gt;

&lt;h3&gt;app/models/author.rb&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;sort_on :name, :updated_at
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;app/controllers/site_controller.rb&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;def index
  @authors = Author.all( Author.sort_by(params[:sort]) )

  if request.xhr?
    return render :partial =&amp;gt; 'authors'
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;app/views/site/index.html.erb&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;div id="authors"&amp;gt;
  &amp;lt;%= render :partial =&amp;gt; 'authors' %&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;app/views/site/_authors.html.erb&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;table&amp;gt;
  &amp;lt;thead&amp;gt;
    &amp;lt;tr&amp;gt;
      &amp;lt;%
        sort_headers_for :author, %w{name ranking phone updated_at} do |header|
          "Last Changed" if header == 'updated_at'
        end
      %&amp;gt;
    &amp;lt;/tr&amp;gt;
  &amp;lt;/thead&amp;gt;
  &amp;lt;tbody&amp;gt;
    &amp;lt;% @authors.each do |author| -%&amp;gt;
    &amp;lt;tr&amp;gt;
      &amp;lt;td&amp;gt;&amp;lt;%=h author.name %&amp;gt;&amp;lt;/td&amp;gt;
      &amp;lt;td&amp;gt;&amp;lt;%=h author.ranking %&amp;gt;&amp;lt;/td&amp;gt;
      &amp;lt;td&amp;gt;&amp;lt;%=h author.phone %&amp;gt;&amp;lt;/td&amp;gt;
      &amp;lt;td&amp;gt;&amp;lt;%=h author.updated_at %&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;/tr&amp;gt;
    &amp;lt;% end -%&amp;gt;
  &amp;lt;/tbody&amp;gt;
&amp;lt;/table&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now the &lt;code&gt;sort_headers_for&lt;/code&gt; method is using a lot of convention in there for the code that it&amp;#8217;s generating, but the good news is that virtually everything can be overridden if you want to do things differently.&lt;/p&gt;

&lt;p&gt;Hope you enjoy, &lt;a href="http://github.com/JasonKing/good_sort"&gt;you can get the gem here&lt;/a&gt; or just install with &lt;code&gt;sudo gem install JasonKing-good_sort&lt;/code&gt;&lt;/p&gt;</description>
      <category domain="http://flow.handle.it/past/tags/ajax">ajax</category>
      <category domain="http://flow.handle.it/past/tags/gracefullydegrading">gracefullydegrading</category>
      <category domain="http://flow.handle.it/past/tags/pagination">pagination</category>
      <category domain="http://flow.handle.it/past/tags/sorting">sorting</category>
      <category domain="http://flow.handle.it/past/tags/willpaginate">willpaginate</category>
    </item>
    <item>
      <title>A couple of things in the Rails console</title>
      <link>http://flow.handle.it/past/2009/3/31/a_couple_of_things_in/</link>
      <pubDate>Tue, 31 Mar 2009 05:59:00 GMT</pubDate>
      <guid>http://flow.handle.it/past/2009/3/31/a_couple_of_things_in/</guid>
      <author>jk@handle.it (Jason King)</author>
      <description>&lt;p&gt;So for anyone who doesn&amp;#8217;t know, the script/console in Rails runs up an irb process behind the scenes.  It also loads Rails into the context, and a few other bits - but mainly it&amp;#8217;s an irb session.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve just been getting a couple of &amp;#8220;Oh wow, I didn&amp;#8217;t know that.&amp;#8221; responses when I mention these things in &lt;code&gt;#rubyonrails&lt;/code&gt;, so I thought I&amp;#8217;d just post this here.&lt;/p&gt;

&lt;h2&gt;Thing 1: the underscore method&lt;/h2&gt;

&lt;p&gt;The return from every command that you enter into irb is available in the underscore method &lt;code&gt;_&lt;/code&gt;.  So, if you&amp;#8217;re like me, you often run a command and then think that you should have assigned it to some variable, or pretty-printed it or something.&lt;/p&gt;&lt;p&gt;The underscore method is perfect for this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; City.all
=&amp;gt; [#&amp;lt;City id: 218996838, name: "Chatswood", postcode: "2067", state_id: 944944227, created_at: "2009-03-30 01:56:22", updated_at: "2009-03-30 01:56:22"&amp;gt;, #&amp;lt;City id: 957448139, name: "Roseville", postcode: "2069", state_id: 944944227, created_at: "2009-03-30 01:56:22", updated_at: "2009-03-30 01:56:22"&amp;gt;, #&amp;lt;City id: 1015505586, name: "Willoughby", postcode: "2068", state_id: 944944227, created_at: "2009-03-30 01:56:22", updated_at: "2009-03-30 01:56:22"&amp;gt;]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Bugger me if I didn&amp;#8217;t just forget to assign that to something&amp;#8230;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; c = _
=&amp;gt; [#&amp;lt;City id: 218996838, name: "Chatswood", postcode: "2067", state_id: 944944227, created_at: "2009-03-30 01:56:22", updated_at: "2009-03-30 01:56:22"&amp;gt;, #&amp;lt;City id: 957448139, name: "Roseville", postcode: "2069", state_id: 944944227, created_at: "2009-03-30 01:56:22", updated_at: "2009-03-30 01:56:22"&amp;gt;, #&amp;lt;City id: 1015505586, name: "Willoughby", postcode: "2068", state_id: 944944227, created_at: "2009-03-30 01:56:22", updated_at: "2009-03-30 01:56:22"&amp;gt;]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Yay!&lt;/p&gt;

&lt;p&gt;The only thing to remember is that if you don&amp;#8217;t grab it immediately, then it will be gone next command - it is overwritten with every line.&lt;/p&gt;

&lt;h2&gt;Thing 2: the y method&lt;/h2&gt;

&lt;p&gt;This is actually just the &lt;code&gt;Kernel#y&lt;/code&gt; method, but it&amp;#8217;s particularly useful in &lt;code&gt;irb&lt;/code&gt; sessions when you want to print something out in an easy to read (and easy to grab if you want YAML) format.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; { :foo =&amp;gt; 'bar', :woo =&amp;gt; { :ooo =&amp;gt; 1 } }
=&amp;gt; {:foo=&amp;gt;"bar", :woo=&amp;gt;{:ooo=&amp;gt;1}}
&amp;gt;&amp;gt; y _
--- 
:foo: bar
:woo: 
  :ooo: 1
=&amp;gt; nil
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is especially good for outputting large collections of Rails models.&lt;/p&gt;

&lt;h2&gt;Thing 3: the pp library&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;pp&lt;/code&gt; or Pretty-Print lib is also great for printing out collections of data in a neat way.  Just require it into your &lt;code&gt;irb&lt;/code&gt; session and use it to great effect:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; require 'pp'
=&amp;gt; true
&amp;gt;&amp;gt; pp City.all
[#&amp;lt;City id: 218996838, name: "Chatswood", postcode: "2067", state_id: 944944227, created_at: "2009-03-30 01:56:22", updated_at: "2009-03-30 01:56:22"&amp;gt;,
 #&amp;lt;City id: 957448139, name: "Roseville", postcode: "2069", state_id: 944944227, created_at: "2009-03-30 01:56:22", updated_at: "2009-03-30 01:56:22"&amp;gt;,
 #&amp;lt;City id: 1015505586, name: "Willoughby", postcode: "2068", state_id: 944944227, created_at: "2009-03-30 01:56:22", updated_at: "2009-03-30 01:56:22"&amp;gt;]
=&amp;gt; nil
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Voila!  To make that even easier, see the next thing.&lt;/p&gt;

&lt;h2&gt;Thing 4: .irbrc&lt;/h2&gt;

&lt;p&gt;By default in *nix based operating systems the file &lt;code&gt;.irbrc&lt;/code&gt; in your &lt;code&gt;$HOME&lt;/code&gt; directory will be loaded by &lt;code&gt;irb&lt;/code&gt; when it starts up.  (On Windows you need to create your own irbrc anywhere you like and set the &lt;code&gt;IRBRC&lt;/code&gt; environment variable).&lt;/p&gt;

&lt;p&gt;You can put any Ruby commands you like in here, here&amp;#8217;s mine:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'rubygems'
require 'irb/completion'
require 'pp'
require 'yaml'

def gvim(x)
  IO.popen( 'gvim -', 'w') do |io|
    io.puts x.to_yaml
  end
end

def less(x)
  IO.popen( 'less -', 'w') do |io|
    io.puts x.to_yaml
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can see that it&amp;#8217;s simple to require in your choice of libs in there, and you can even define your own methods, which brings us to the last thing.&lt;/p&gt;

&lt;h2&gt;Thing 5: total customization&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;.irbrc&lt;/code&gt; is just Ruby, and as you&amp;#8217;ve seen above you can define your own methods.  I&amp;#8217;ve defined two to make it easy to pipe an object (as yaml) out to an external program (I&amp;#8217;ve got &lt;code&gt;gvim&lt;/code&gt; and &lt;code&gt;less&lt;/code&gt; setup) - but you can have anything you like.  This lets you customize your own &lt;code&gt;irb&lt;/code&gt; interface with whatever little helpers you want to make your work easier.&lt;/p&gt;

&lt;p&gt;Take a look &lt;a href="http://drnicwilliams.com/2006/10/12/my-irbrc-for-consoleirb/"&gt;here&lt;/a&gt; and &lt;a href="http://drnicwilliams.com/2008/01/01/find-objects-in-irb-directly-from-browser-urls/"&gt;here&lt;/a&gt; at some powerful examples of what can be done.&lt;/p&gt;

&lt;p&gt;Enjoy.&lt;/p&gt;</description>
      <category domain="http://flow.handle.it/past/tags/console">console</category>
      <category domain="http://flow.handle.it/past/tags/irb">irb</category>
    </item>
    <item>
      <title>Case insensitive SQLIte</title>
      <link>http://flow.handle.it/past/2009/3/26/case_insensitive_sqlite/</link>
      <pubDate>Thu, 26 Mar 2009 05:15:00 GMT</pubDate>
      <guid>http://flow.handle.it/past/2009/3/26/case_insensitive_sqlite/</guid>
      <author>jk@handle.it (Jason King)</author>
      <description>&lt;p&gt;One of the things that quickly tripped me up in using SQLite in Rails was that there was no way to make a column case insensitive.&lt;/p&gt;

&lt;p&gt;Most human textual comparisons are case insensitive, we think that &amp;#8220;dog&amp;#8221; and &amp;#8220;doG&amp;#8221; and &amp;#8220;DOG&amp;#8221; all denote the same thing.  If we have a uniqueness constraint on a column, then we want it to protect us from having three separate entries for those three strings.  Also, when we&amp;#8217;re searching for &amp;#8220;dOg&amp;#8221; we want it to match any one of the three strings.&lt;/p&gt;

&lt;p&gt;Every database has its own way of doing these sorts of things - SQLite uses one of the more sensible methods: it allows you to specify that any column you like should be case insensitive (and then any index on that column will automatically be case insensitive too).&lt;/p&gt;

&lt;p&gt;So, you can write:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;CREATE TABLE foo ( bar varchar(255) COLLATE NOCASE );
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And you&amp;#8217;ll get a case insensitive column &amp;#8216;bar&amp;#8217;.  This is so often what you want, more often than not, so I wrote &lt;a href="http://github.com/JasonKing/sqlite_nocase"&gt;a quick gem&lt;/a&gt; that does this by default for all your migrations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is a kludgy kludge!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What would be nice would be to add a new option to the migration methods so that any given column could be marked with something like: &lt;code&gt;:case =&amp;gt; false&lt;/code&gt;  Unfortunately, the Rails code for all that is not very DRY and stuffed with metaprogramming - so it&amp;#8217;s not easy to retrofit a gem to make that happen.  So my gem just makes it happen for &lt;strong&gt;every&lt;/strong&gt; string or text field.&lt;/p&gt;

&lt;p&gt;Mostly this will be what you want, but every so often case sensitivity is something that is desirable - so beware :)&lt;/p&gt;</description>
      <category domain="http://flow.handle.it/past/tags/casesensitivity">casesensitivity</category>
      <category domain="http://flow.handle.it/past/tags/collation">collation</category>
      <category domain="http://flow.handle.it/past/tags/sqlite">sqlite</category>
    </item>
    <item>
      <title>Dot Versions</title>
      <link>http://flow.handle.it/past/2009/3/18/dot_versions/</link>
      <pubDate>Wed, 18 Mar 2009 06:08:00 GMT</pubDate>
      <guid>http://flow.handle.it/past/2009/3/18/dot_versions/</guid>
      <author>jk@handle.it (Jason King)</author>
      <description>&lt;p&gt;Ok, so there are chunks of code I write again and again, and this is one of them:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Version 
  include Comparable
  def initialize(_v); @v = _v.split('.').map(&amp;amp;:to_i); end
  def &amp;lt;=&amp;gt;(_v); @v &amp;lt;=&amp;gt; _v.split('.').map(&amp;amp;:to_i); end
  def to_s; @v.join('.'); end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I was going to reformat it, so that the methods are all newlined properly, but actually - you should have to put up with looking at it like I look at it.&lt;/p&gt;

&lt;p&gt;So, what does this do?  Well, check this irb out:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;irb(main):001:0&amp;gt; '3.6.8' &amp;gt; '3.6.4'
=&amp;gt; true
irb(main):002:0&amp;gt; '3.6.8' &amp;gt; '3.6.10'
=&amp;gt; true
irb(main):003:0&amp;gt; # Ack!  Should be false
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We get a true because they&amp;#8217;re strings, so they&amp;#8217;re being compared alphabetically.  Rescue us wonderful Version class:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;irb(main):004:0*   class Version 
irb(main):005:1&amp;gt;     include Comparable
irb(main):006:1&amp;gt;     def initialize(_v); @v = _v.split('.').map(&amp;amp;:to_i); end
irb(main):007:1&amp;gt;     def &amp;lt;=&amp;gt;(_v); @v &amp;lt;=&amp;gt; _v.split('.').map(&amp;amp;:to_i); end
irb(main):008:1&amp;gt;     def to_s; @v.join('.'); end
irb(main):009:1&amp;gt;   end
=&amp;gt; nil
irb(main):010:0&amp;gt; v = Version.new('3.6.8')
=&amp;gt; #&amp;lt;Version:0x547e0 @v=[3, 6, 8]&amp;gt;
irb(main):011:0&amp;gt; v &amp;gt; '3.6.4'
=&amp;gt; true
irb(main):012:0&amp;gt; v &amp;gt; '3.6.10'
=&amp;gt; false
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Yay.  That&amp;#8217;s it, you can get it &lt;a href="http://gist.github.com/80921"&gt;here&lt;/a&gt;.&lt;/p&gt;</description>
      <category domain="http://flow.handle.it/past/tags/comparable">comparable</category>
      <category domain="http://flow.handle.it/past/tags/comparisons">comparisons</category>
      <category domain="http://flow.handle.it/past/tags/version">version</category>
    </item>
  </channel>
</rss>
