New Photo Blog

Posted by keith 9 months ago

Not really Ruby related, but I'd like to announce the existence of my new photography weblog. Taking photos is a passion for me and I'm excited to have a new outlet for that passion in the form of a weblog.

I look forward to posting images from shoots there as well as photography tips and whatever else it evolves into.

What Gedit Can and TextMate Can't

Posted by keith 9 months ago

I noticed over at the Mark Gandolfo blog, a post talking about Ruby on Rails in Gedit. In his piece, Gandolfo claims

I have to say, using textmate for nearly a month, I see things gedit can do that textmate can't!

acck Phh!

Now that's all well and good and I'm sure Gedit is a great tool, but I would love to know what Gedit can do that TextMate can't. Maybe I should ditch TextMate and switch to Gedit. Well... I'll wait to see what these super-dooper features are first.

If Mr Gandolfo were to be so obliging as to post a list of things Gedit can do that TextMate can't, I'd happily address each point with either an explanation/example of how to do it in TextMate, or say "Ok, you got me on that one."

What are Ruby Symbols

Posted by keith 9 months ago

One of the hardest things to explain about Ruby (especially to newcomers) is what symbols are. Many explanations of symbols that I see or hear often only cover a low-level/technical difference between symbols and strings. That is, that symbols use one memory location for each unique instance whereas strings use separate memory locations for each instance. Also that symbols are kept around in memory for the life of the program while strings get cleaned up when they are no longer used.

While these differences are accurate, they are just implementation details and not really what Ruby symbols are all about and those who quote only these differences by way of explanation of what Ruby symbols are, are missing the point.

What Ruby symbols are really about is beauty and semantics. Ruby symbols give the programmer the distinction between identity and information.

Consider this method call:

validates_presence_of :firstname, :lastname, :on => :create, :message => "can't be blank"

and if we single out

:message => "can't be blank"

:message is a symbol and "can't be blank" is a string. We could have easily written this statement like:

"message" => "can't be blank"

But the difference here is that :message is just a label for something, some concept, that a part of our program needs to work with. Whereas "can't be blank" is actual data or information. Another way to look at it is that we could mess with one of the two and the program would not care but if we mess with the other and the program does care.

If I change it to:

:my_message => "can't be blank"

The program no longer works as it did before. The method does not look for anything labeled :my_message. It is not a concept it knows about. The label :message is there only so the programmer and the method can talk about the same concept.

Now if I change it to:

:message => "can't be blank, sorry about that."


:message => "darf nicht leer sein"

The program still works as it did before, it just displays a different message. The "can't be blank, sorry about that." is clearly different to :message. It's not a label or an identity at all, it's information.

Many other languages don't have this distinction between information and identity, or at least not in such a nice, convenient way. As a result, strings are often used to perform the task of labeling.

$car = array ("weight"=>"1000", "unit_of_measure"=>"kg", "year"=>"2004", "price"=>"7000");

If the program knows about the concept of weight and unit_of_measure, using strings for those labels doesn't quite feel right.

car = {:weight => '1000', :unit_of_measure => 'kg', :year => '2004', :price => '7000'}

Now we have a separation between the concepts our program deals with and the associated data. And with syntax highlighting it reads so much nicer.

Take this example again

validates_presence_of :firstname, :lastname, :on => :create, :message => "can't be blank"

It reads so much nicer and is easier to see which bits, if changed, will affect the semantics of the program and which bits won't, but if we use strings for our labels, we lose that distinction.

validates_presence_of "firstname", "lastname", "on" => "create", "message" => "can't be blank"

An easy way to work out if you should use a symbol or a string is this: Does the program care about the thing I am typing, or does the user care about it?

  • if the program cares:

  • if the user cares:


Fisheye Navigation is Crap

Posted by keith 10 months ago

I saw this AJAX fisheye navigation demo back in 2006 and forgot clean about it as I thought it was crap.

Well I just happened upon it again and guess what, it's still crap.

As you mouse over the navigation items, the items increase in size in proportion to how close the mouse cursor is to them. This means the position of each nav item changes. The idea of navigation items as moving targets is bad.

Using with_scope the Right Way

Posted by keith 10 months ago

Most examples of with_scope I've seen floating around the web seemed to be to be going about it the wrong way.

Stuff like this wedged in with some other code:

Article.with_scope(:find => {:conditions => "published = 1"]}) do
  Article.find(:all) # or some other find operations.

To me that's a bit arse-about and even a little messy to stick in the middle of some other code.

A much nicer way is to use the with_scope method to help craft one's own specialised find methods. With the following example, the above code could be replaced with a much nicer looking call to Article.find_published(:all):

class Article < ActiveRecord::Base

  def self.find_published(*args)
    with_scope(:find => {:conditions => "published = 1"}) do


Some other examples of use:

@published = Article.find_published(:all)
@published_today = Article.find_published(:all, :conditions => ["published_at >= :today", {:today =}])

To me, that is a much neater way to use with_scope. I also find these type of find methods help remove business logic from controllers and put it back into models where it belongs. The definition of a published article is a matter for a model class rather than a controller.

iPhone Released

Posted by keith about 1 year ago
Vote for this article on Digg It!

Finally Apple have announced the much rumoured iPhone. What a cool device. They have redefined cell phones, and in my opinion hand-held devices in general. I don't remember any new gadget announcement bringing me to say the word "fuck" as many times as the introduction of the iPhone did.

A while back I wrote about multi-functional devices and polymorphic UIs. I had some pretty lofty ideas and hopes for an iPod / iPhone multi-functional gadget and I have to say I was blown away with the iPhone.

I think Apple has nailed it.

For me one of the neatest things about the device is that it runs OS X - or maybe some kind of cut down version. Presumably I will be able to ssh into my iPhone and do some ruby scripting. I'm sure someone will write an app that can be used to control other devices in the home - salling clicker style.

Most popular story on digg by far.

The news of the iPhone has turned out to be wildly popular. AAPL shares rose by some 8% and iPhone was pretty much the only news in Steve's keynote.

On this story is the most popular story in the last 365 days and it's barely 13 hours old.

The stock market was also impressed

Take a look at the graph of AAPL against PALM and RIMM (makers of blackberry) as at close of trading on the 9th January 2007 (thanks to daringfireball for that link)

picture taken from

Finding Descendants of a Class

Posted by keith about 1 year ago

Ruby offers a method for finding all the ancestors of a class (ancestors funnily enough) but, as far as I know, no easy way to get at all the descendants of a class.

I thought it had to be possible, this *is* Ruby after all! But in thinking about it a little more, I figured it could well be a tricky thing to do and probably require some hook in the Ruby language for it all to be even possible.

Luckily I found this beauty: ObjectSpace. With ObjectSpace you can eacherate over every object in the Ruby object space. What else?

So it tuns out that finding all the descendants of a particular class is not such a big deal after all. Just eacherate over ObjectSpace and do a little recursion:

class Object

  def self.show_descendants(klass = nil, indent_level = 1)
    unless klass
      klass = self
      puts ' - ' * (indent_level) + klass.to_s
    ObjectSpace.each_object do |obj|
      if obj.class == Class and obj.superclass == klass
        puts ' - ' * (indent_level + 1) + obj.to_s
        show_descendants(obj, indent_level + 1)

  def show_descendants(klass, indent_level = 1)
    klass.show_descendants(nil, indent_level)


# you can pass the class as an argument

# or you can send the method to the class

This code could be modified a little to return a list of descendants, each containing their own list of descendants rather than putsing it all to the screen.

Remote Editing with TextMate

Posted by keith about 1 year ago

TextMate does not have a save over sftp function, and I'm not sure Allan has any plans to add it in. Sometimes it's useful to edit files remotely. I often run my development server on another (faster) machine and do the actual editing on my trusty old (now slightly slow) PowerBook.


The solution is fairly rudimentary and simple but it works:

  • create a TextMate project. Create a real TextMate project rather than temporary one as we will want to save some project variables.

  • setup your project variables.

    setup two project variables

    • $TM_REMOTE_SERVER. Set this to something like keith@servername:
    • $TM_REMOTE_SERVER_PORT. Set this to 22 unless you have your ssh access setup over some other port
  • create a snippet or better still, create a new bundle called something like "Remote Editing" and then a new snippet in that bundle. The snippet code:


    Have the snippet save the current file, output as a tooltip and set its key equivalent to APPLE-s. It should all look something like this:

One limitation of this system is that the directory structure on both local and remote machines needs to be the same. It would be possible to address this issue, but mirroring my directory structures for projects I want edit remotely has not been a big deal for me. Basically you setup a /User/UserName/projects dir on each machine and everything is ok.

You also need to have ssh public key authentication and an ssh-agent (like SSH Chain) running so that the scp happens without asking for a password.

Enumerable Constants for Active Record Models

Posted by keith over 2 years ago

A problem that had often bothered me in the past is this:

You're modelling a concept in a database like, say, property listings and a property has an attribute of "type". The possible values of "type" are not arbitrary. They are some fixed set of values like "rental", "for sale" and "auction", and the software needs to do stuff depending on the value of "type".

So this is like a :belongs_to where a property belongs to a suburb say. But there is an important difference. With a belongs_to :suburb the values for suburb are arbitrary. That is to say that the software doesn't care about the values, only that there is some value (which the user cares about, of course). But the program does care about the set of values available for the "type" attribute.

Setting up a has_many/belongs_to relationship always seemed overkill but it gave me a nice list of available attributes and I could enforce the relationship. The other problem was that the data in the table would mirror some set of constants in the code. If you changed one, you had to make sure you changed the other or things got out of whack. Not to mention problems of populating a new database and making sure all such "non-arbitrary" value set tables had the correct values (including correct ids to match the constants in code) in them.

Making the attribute "type" a string and stuffing values "rental", "for sale" and "auction" in it felt particularly bad.


I felt the correct way to do it was to use integer values in the field and represent these values as constants in the code (which is where the values have meaning).

But writing validation for these and coming up with a list of human readable descriptions (for drop-downs) was tedious. It felt like the values belonged in the database... but wait, no, the values have meaning in the code...

So I've written a Rails plugin to take away the tediousness of it all and make it a lot more DRY. With it I get

  • an easy way to define, in a nice DSL looking way, what the constants are
  • validation code generated dynamically
  • a nice way of getting the list of values and descriptions (useful for UI stuff)


Model definition:

class Property < ActiveRecord::Base
  enumerable_constant :type, :constants => [:rental, :for_sale, :auction]

Some view code:

<p><label for="property_type">Property Type</label><br/>
< %= collection_select(:property, :type, Property::Type.constants, :id, :title, {:prompt => 'Select a Property Type'})  % ><br />

Note the use of Property::Type.constants in place of where you would normally use a collection object like @suburbs

Some code that tests the value

property = Property.find :first
if property.type == Property::Type::FOR_SALE
  # do some stuff

Other things you can access

>> Property::Type.constants.first.title
=> "Rental"
>> Property::Type.constants.first.value
=> 1

Download the Enumerable Constants project

Rails Workshop - Sydney

Posted by keith over 2 years ago

Last weekend I attended a Rails Workshop in Sydney. The workshop was put together by wwworkshops and presented by Geoffrey Grosenbach of Top Funky Corp.

The workshop was great and I got a lot out of it. Geoffrey gave us a lot of material to wade thru and learn from including code (lots of code), screencasts and cheatsheets.

Geoff is a great presenter. Although Geoff knows a ridiculous amount of stuff, he always comes across as being very approachable willing to learn from those he's presenting to. I like his style.

It was also great to meet up with some talented people in the Sydney Rails community.

Convertible to csv format options

Posted by keith over 2 years ago

The latest version of convertible to csv can be told how to format particular fields when it returns data for the to_csv method. The default behaviour is to use the to_s method for each field. But sometimes you might want to display the data a little differently.

Use :format_options to specify a format method to be called when outputting a field. This is useful, for example, if you have a Time field and you want to format it differently to how Time.to_s displays a time.

Here's an example:

class Customer < ActiveRecord::Base
  acts_as_convertible_to_csv :header => true, 
                             :fields => %w(id firstname lastname email_address),
                             :format_options => {:lastname => :format_lastname, :firstname => :format_firstname}
  def format_firstname

  def format_lastname

As Customer.find(:all).to_csv is invoked, each time the fields "lastname" and "firstname" are output, instead of calling to_s on the fields, calls are made to the format_firstname and format_lastname methods respectively and your csv output will contain upcased firstname and reversed lastname.

Markdown on Rails

Posted by keith over 2 years ago

I have renamed the Markdown Template Handler project to Markdown on Rails. "Markdown Template Handler" was kinda dull and "Markdown on Rails" has a much better ring to it.

If you install the new renamed version you will need to change your config/environemt.rb file:

from this

require 'markdown_template'
ActionView::Base.register_template_handler('md', MarkdownTemplate)
ActionView::Base.register_template_handler('text', MarkdownTemplate)
MarkdownTemplate::map_headings_down_by 0


require 'markdown_on_rails'
ActionView::Base.register_template_handler('md', MarkdownOnRails)
ActionView::Base.register_template_handler('text', MarkdownOnRails)
MarkdownOnRails::map_headings_down_by 0

simple as that.

External diff with Subversion using BBEdit

Posted by keith over 2 years ago

BBEdit has a great Find Differences function. You get a list of description of differences that you can click on to see the two affected files. You can also do things like apply the difference to either the new or the old file.

Subversion's differences output is of course command-line only, but subversion does support using external diff tools.

Enter bbdiff from John Gruber.

bbdiff is a command line interface to BBEdit's Find Differences command.

Download bbdiff from John Gruber's site, and follow his install instructions (very easy, copy it to where you want it and chmod it to be executable)

You will need to setup subversion to actually use an external diff command. To do this we will need to write a quick interface between the svn diff command and the bbdiff command as the argument lists do not match.

The arguments we want from the svn diff command are $6 (old file) and $7 (new file).

The bbdiff usage states:

Usage: /usr/local/bin/bbdiff [-b -i -s] oldfile newfile
-b keep BBEdit in the background
-i case insensitive comparison
-s ignore leading and trailing whitespace on lines

So we see that we need to pass in params $6 and $7 from the svn diff command in the order that they appear. Write a script that calls bbdiff with those params. Mine is called svndiff2bbdiff:

/usr/local/bin/bbdiff $6 $7

Make sure you chmod your svndiff2bbdiff file to be executable (chmod +x svndiff2bbdiff).

In your ~/.subversion/config file, search for the [helpers] section and create a line like:

diff-cmd = /usr/local/bin/svndiff2bbdiff

assuming your svndiff2bbdiff is in /usr/local/bin/

Test it out: svn diff -r PREV <file_name>.

Convertible to Csv

Posted by keith over 2 years ago

Convertible to csv now has a project page.

I've also added some unit tests.

Convertible to csv allows you to specify that an ActiveRecord model should respond to a to_csv message. You can also specify if a header row of field names should be used and which fields (and their order) should be used in the csv output.

Apple iPod / iPhone multi-functional device

Posted by keith over 2 years ago
Vote for this article on Digg It!

With the upcoming Apple media event on Tuesday 12th September it is widely expected that Apple will introduce an iTunes Movie store, some iPod updates of some kind and the new iMacs (already released at the time of writing). Some pundits are tipping an iPhone.

I'm hoping for an iPod / iPhone multi-functional device.

All the handheld electronic devices I can think of that are wildly successful concentrate on one task and do that task very well. Devices that try to do too many tasks (read: more than one) often do a mediocre job of each task and thus don't turn out to be successful - relatively speaking.

This could be about to change.

For a multi-functional device to be successful, among other things, it would need to do an excellent job of each task it performs and have a UI that accommodates each of its tasks equally well without compromising the usability of any other task.

Unless the two tasks are very closely related in terms of UI requirements, this implies a kind of UI that can morph to fit the requirements of each task.

As UI components such as touch sensitive input devices and small display devices improve, "polymorphic UIs" are much more doable.

Apple Insider thinks that an Apple cell phone is real and ready for production:

"We believe this smart phone has been in development for over 12 months and has overcome substantial challenges including design, interference, battery life and other technical glitches."

The smart phone they speak of is not a multi-functional iPod / iPhone device, just a phone, albeit having an iPod-like form factor:

"The design will be an iPod nano-like candy bar form factor..."

When I think about what I would like Apple to produce in terms of an iPhone, I always think of an iPod nano with which I can make and receive phone calls. ie a multi-functional device. I carry an iPod around so I can listen to music and I carry a phone so I can make phone calls. If some of the UI functions overlap and the difference can be accommodated by a morphing UI, then why not package the two together?

This MacNN article talks about how Apple has filed a "Multi-functional hand-held device patent application"

The article reveals a

"multi-functional hand-held device capable of configuring user inputs based on how the device is to be used."

If the article is reliable, Apple is clearly thinking about multi-functional devices.

And many analysts certainly think Apple is working on a cell phone.

If two groups of analysts got together, one group behind the multi-functional device idea and the other behind the iPhone idea, would they end the meeting with the idea of an iPod / iPhone multi-functional device?

Let's hope it is an iPod / iPhone multi-functional device.

Of course if on Tuesday Apple brings out a multi-functional device that is both an iPod music player and an iPod video player, I'll be both disappointed and looking silly.

Markdown template handler for rails

Posted by keith over 2 years ago
Vote for this article on Digg It!

Writing is all about content. Style and presentation is a separate concern. When I am writing, be it for the web or some documentation or whatever, I like to write pure text. Style and presentation comes later.

Markdown allows me to do that very effectively. I get to concentrate purely on the content of what I am writing and the semantics of the content (this is a heading, this is a list, this should be emphasised...)

For me, this desire to write plain text extends to writing content for web sites. Of course, html has it place but if I am writing a content page for a client's web site, I would much rather just write the content and not have the html markup of that content get in my way.

I solved this by writing a rails markdown template handler so I could write web site content in my rails apps in markdown.

These two images show a rails view (this site's about page) as html and markdown. In the markdown version, the content is free of the clutter of html tags.

The code is released under the MIT licence and can be found at the markdown_template_handler project home

Markdown Syntax Reference

Posted by keith over 2 years ago
Vote for this article on Digg It!

I have posted a markdown syntax reference. It's mostly for my own benefit but if others can get some use out of it, then great.

I use markdown a lot (read all the time) - this post, this whole site is written in markdown. In my work I often introduce markdown to other programmers and I find myself repeatedly producing pretty much the same sample document to demonstrate the syntax.

Here is the reference

No Database? Sometimes it feels right.

Posted by keith over 2 years ago

In No Database, Tim Bray talks about why he doesn't want to use a database for storing comments in a blog system.

Tim says:

...there is a psychology out there in our profession,which says: if you have data that you want to store and retrieve, that means you need a database. But sometimes you don’t. And sometimes you come out ahead on one or both of the less-work and runs-fast metrics by not having one.

I agree with Tim here. I'm not saying no databases, ever! I use databases almost all the time, but there are times when not using a database feels like the right way to do it. It's all a matter of the requirements and what you are modeling.

This blog runs on a system that uses subversion to store it's data. To edit posts I don't need to use a web interface or some client talking to a database. I just edit files.

This gives me the freedom to edit my posts in my favourite text editor from anywhere I like. I just need a working copy of my blog repository. And of course with subversion I can edit offline.

As Tim does, I like the semantics of the Unix filesystem and for writing blog articles, it just feels totally right for me.

Public Key Authentication with SSH

Posted by keith over 2 years ago

Here's how to setup public key authentication over ssh.

  1. Generate the keys

    First create a directory on your local machine ~.ssh/ if it is not already there.

    ssh-keygen -t dsa
    ssh-keygen -t rsa

    ssh-keygen will ask for the filename to save to. Just press ENTER to use the default values. It will then ask for a passphrase. A blank passphrase can be entered but this is obviously less secure and the same result can be achieved by using an ssh-agent.

    Private and public keys will then be generated. The public keys have a .pub extension.

    Your private keys should be kept private so you should make sure they are only readable by you (chmod 0600).

  2. Copy the Keys

    Now you should copy the public keys to each machine you will want to connect to. The contents of the public key needs to be appended to ~.ssh/authorized_keys on the remote machine. You could upload them using scp then login to the remote machine and append the contents but these commands can do all of that from your local machine:

    cat .ssh/ | ssh username@newmachine "cat >> .ssh/authorized_keys"
    cat .ssh/ | ssh username@newmachine "cat >> .ssh/authorized_keys"
  3. Configure the SSH daemon

    You need to make sure the SSH daemon (sshd) is configured to allow the use of public keys.

    cd /private/etc/
    sudo vi sshd_config

    Make sure the sshd_config file contains these options:

    PubkeyAuthentication yes
    AuthorizedKeysFile .ssh/authorized_keys
  4. Test it out:

    ssh username@host

    You will now be asked for you passphrase (not your password for the remote machine).

    To avoid having to type in the passphrase, setup an ssh-agent which will effectively do that for you each time you connect to a remote machine that knows about public keys. If you're on a Mac, SSHChain is an excellent utility.


Posted by keith over 2 years ago
Vote for this article on Digg It!

update: convertible to csv now has a project page

A little ruby magic in the form of meta-programming allows you to define your models as being able to output data in csv format. The definition is a DSL style acts_as_convertible_to_csv with :header and :fields as valid specifications.

Here's how you would use it.

In your model declaration:

class Customer < ActiveRecord::Base
  acts_as_convertible_to_csv :header => true, 
                             :fields => %w(id firstname lastname email_address)

The first row will contain fields names if you specify :header => true. You can specify which fields and the order in which they appear by using :fields. If you omit :fields, the field list will default to those returned by the human_readable method.

Getting the csv data from a collection of records:


You can pass a block:

Customer.find(:all).to_csv do |line|
  # write the line to a file or something

You can also convert individual records to csv:


The code

class ActiveRecord::Base

  def self.acts_as_convertible_to_csv(*args)

    @@use_header_fields = false

    args.each do |param|
      if param.is_a? Hash
        if param.include? :header and param[:header]
          @@use_header_fields = true

        if param.include? :fields and param[:fields] and param[:fields].is_a? Array
          class_eval <<-CEEND
            def self.csv_header
              %w(#{param[:fields].join(' ')})
          class_eval <<-CEEND
            def self.csv_header
              field_names =
              self.content_columns.each do |column|
                field_names <<

    class_eval <<-CEEND
      def self.use_header_fields

      def to_csv
        line = ""
        self.class.csv_header.each do |field_name|
          line = line + "," + self.send(field_name).to_s
        # remove first ', '
        line.gsub! /^,/, ''


# Allow a collection class to repond to to_csv
class Array

  def to_csv(&block)
    data =
    # check to see if the objects in the array are capable of to_csv    
    if self[0] and self[0].class.method_defined?(:to_csv)
      if self[0].class.use_header_fields
        data << self[0].class.csv_header.join(',')
        yield self[0].class.csv_header.join(',') if block_given?
      each do |object|
        data << object.to_csv
        yield object.to_csv if block_given?