John Topley’s Weblog

My Vim Vocabulary

At the end of March I started to learn the Vim text editor and four months into my journey I thought it would be a useful experience for me to document the commands I have committed to memory so far. Please note that this isn’t particularly intended as an introduction to Vim or a tutorial, but if that’s what you’re looking for then there are many fine ones out there as well as some good screencasts. I’m writing this so that I have a record of what I know at this point. Think of it as a crib sheet. Also, I apologise in advance if I don’t always use the official Vim terminology, or if some of my descriptions are sloppy, but I know what I mean!

My primary editor since switching to the Mac has always been TextMate and on Windows at work I used ConTEXT, but I hadn’t particularly taken much advantage of some of the more powerful features of either editor. I decided to give Vim a go for several reasons. The main reason is that I’ve been aware of the Pragmatic Programmers’ advice to “Use a Single Editor Well” for some time now and Vim certainly fits the requirement of being “configurable, extensible and programmable”. From what I’ve seen it’s pretty much infinitely powerful, albeit with a near-infinite possible set of commands. I know that I’m just getting close enough to the surface in order to scratch it, but already I feel productive using Vim.

A screenshot of MacVim

Another reason for picking it up is that I’m not sure who or what originated it, but there’s also been a resurgence of interest in Vim within the Ruby/Rails community recently, with many people giving Vim a try. A third reason is that Vim is ubiquitous. If there’s a platform that supports editing text files then chances are that Vim has been ported to it. Finally, I had a new person join my team at work who’s been using Vim for years and who was able to give me a flavour of what it can do and I liked what I saw.

Getting Around

Vim is designed to be efficient for a touch typist to use, so the general idea is to avoid using the mouse and the cursor keys. Instead, the basic four directional movement commands are on the home row, right underneath your right hand. There are probably historical reasons for this as well because Vim is an extension of vi and when vi debuted on UNIX thirty four years ago terminal keyboards didn’t even have cursor keys. So h, j, k and l move left, down, up and right respectively. Many commands in Vim can be preceded with a number representing repetition, so 10h moves the cursor ten characters to the left etc. w moves forward a word and b moves back a word. gg takes you to the top of the file and G takes you to the bottom. Pressing 0 goes to the first character of the line and ^ goes to the first non-blank character. $ goes to the end of a line. Ctrl + f goes forward one screen and Ctrl + b goes back one screen.

m<register> sets a (book)mark at the specified cursor position into the specified register, for example ma. You can return to it using `<register>. Typing :<line number> will go directly to that line. /<pattern> will search forwards for the specified text and ?<pattern> will search backwards. When performing a search, pressing n goes to the next match and N goes to the previous. Note that these are effectively reversed if searching backwards because the direction of the search is reversed. You can turn off the highlighting of the pattern matches using :nohls and turn it back on again using :set hls. Finally, % will match an opposite brace or bracket etc.

Text Surgery

As you’d expect, Vim excels at manipulating text. i inserts text before the cursor and I inserts it before the first non-blank character in the line. a and A do the same for appending text. r replaces the character underneath the cursor with the one you type and R enters replace mode, which is like having overwrite mode turned on in other editors. x deletes the character under the cursor and dd deletes the current line whilst also yanking it to the clipboard. D deletes from the cursor position to the end of the line and C does the same thing but enters insert mode afterwards so you can start typing straightaway. dw deletes the current word and cw changes the current word with the one you type. ~ toggles the case of the selected character(s). ci" will overwrite the text within the next pair of double quotes. Ctrl + n will attempt to keyword complete the current word, moving forwards through the completion list. Ctrl + p will do the same, but moving backwards through the list. u is undo and Ctrl + r is redo.

v enables visual character selection and V enables visual line selection. y will yank a selection to the clipboard and Y will yank the current line. p pastes below and P pastes above. Similarly, o opens up a new line below and O opens up a new line above. :<range> co . will copy the lines in the specified range below the current line and :<range> mo . will move them. For example, :25,30 co . will copy lines 25 to 30 to below the current line and :25,30 mo 50 would move lines 25 to 30 to below line 50. > will indent a selection and < will outdent it. :25,30s/foo/bar/gc will replace all occurrences of foo with bar within lines 25 to 30 and prompt for confirmation of each replacement. :%s/foo/bar/g will do the same for the entire file without prompting for confirmation.

Buffers, Windows and Tabs

Vim holds text you are editing in numbered buffers, which may or may not be visible within a window. :ls will list all buffers and :bd will delete the current buffer. Switch between buffers using :bn to go to the next one in the list, :bp to go to the previous one or use <n> Ctrl + ^ to go directly to buffer n. sp will split a window horizontally and vs will split it vertically. Pressing Ctrl + w w will toggle between all open windows. Alternatively, use Ctrl + w followed by one of the motion commands. For example, Ctrl + w h will move to the window to the left of the currently active one. :only will make the current window the only one on the screen.

:tabnew will open a new tab with an empty window, or :tabe <filename> will open a new tab ready for editing the specified file. :tabclose will close the current tab. :tabn switches to the next tab and :tabp switches to the previous one, or use gt to cycle through them.

The Rest

Typing . will repeat the last change. :e $MYVIMRC will edit your vimrc settings file. Entering q<register> will record typed characters into the specified register, for example qb. Press q to stop recording. Then play the macro back using @<register>. ga will display the decimal, hex and octal values for the character under the cursor. Toggle the display of hidden characters and line numbers using :set list, :set number, set nolist and set nonumber respectively. Change the current syntax highlighting colour scheme with :colorscheme <scheme>. For example, :colorscheme slate.

Conclusion

There are other commands that I use in Vim but I still have to look up how to use them. The ones I’ve listed above are the ones that are becoming second nature to me after four months of using Vim almost every working day. I’m pretty pleased with my progress so far and I try to learn something new in Vim every day.

Announcing Manifesto

I’ve just released my first ever RubyGem. It’s a simple gem named Manifesto that dynamically generates an HTML 5 cache manifest for offline application caching. I got the idea whilst developing my Truth Tables Sinatra micro web application. It returns a list of files within the specified directory and sub-directories. By default it also includes a computed hash of the files' contents, so that if a file is changed a different hash is produced, causing the cache to be automatically invalidated.

Installation

To install the gem, use:

[sudo] gem install manifesto

Usage

# Basic usage, list all non-hidden files in ./public and include
# a computed hash of their contents
Manifesto.cache

# Specify a directory
Manifesto.cache :directory => './mobile'

# Specify a directory and don't compute the hash
Manifesto.cache :directory => './mobile', :compute_hash => false

Sample Output

CACHE MANIFEST
# Generated by manifesto (http://github.com/johntopley/manifesto)
# Hash: 7013a3b8292ceeeb6336849bee1d1365
/apple-touch-icon.png
/apple-touch-startup.png
/index.html
/mobile/mobile.css
/mobile/mobile.js

Sinatra Example

require 'manifesto.rb'

get '/manifest' do
  # Must be served with this MIME type
  headers 'Content-Type' => 'text/cache-manifest' 
  Manifesto.cache
end

Ruby on Rails Example

# Create a Rails 2.x route for the manifest
map.manifest '/manifest', :controller => 'manifest', :action => 'show'

# ...or a Rails 3.x route
match '/manifest' => 'manifest#show'

# Create a controller action
def show
  headers['Content-Type'] = 'text/cache-manifest'
  render :text => Manifesto.cache, :layout => false
end

Enjoy!

Software Craftsmanship And Apprenticeship Patterns

One of the aspects of the world of software development that I find interesting is that as a group we seem to be constantly searching for the perfect metaphor or analogy to explain to non-software developers what it is we actually do. Some have said that writing software is like building a house, but others disagree and claim that it’s a more organic process akin to something like gardening. Some people like to think of themselves as software engineers, with all the rigour and discipline such a title implies. Whereas others regard themselves as artists, creating software by tastefully melding many creative disciplines.

I can’t really think of any other profession that is so self-absorbed with trying to define itself, but it is understandable because software development is still a young profession. It’s hard to think of anything else that is quite so abstract in terms of the daily materials we work with. Sure, we bash away at our keyboards, but ultimately we are manipulating fleeting pulses of electricity within the microscopic circuits of a CPU.

So it was with this background of uncertainly and introspection that I recently became aware of the Software Craftsmanship movement. At first the connotations the term brought to my mind weren’t especially positive. I thought of a carpentry shop or a blacksmiths. Skilled and detailed work undoubtedly, but far removed from what I do. A world of woodworking planes and chisels, not compilers and text editors. So I decided that I’d better look beneath the surface of the name and find it what the movement is really about. This is what the Manifesto for Software Craftsmanship has to say:

As aspiring Software Craftsmen we are raising the bar of professional software development by practicing it and helping others learn the craft. Through this work we have come to value:

  • Not only working software, but also well-crafted software
  • Not only responding to change, but also steadily adding value
  • Not only individuals and interactions, but also a community of professionals
  • Not only customer collaboration, but also productive partnerships
That is, in pursuit of the items on the left we have found the items on the right to be indispensable.

The Software Craftsmanship movement came out of the ideas expressed in The Pragmatic Programmer book by Andy Hunt and Dave Thomas and more explicitly in Software Craftsmanship by Pete McBreen. I have read the first of those books but haven’t yet read the second. The movement is founded on the idea that software development is still largely a craft industry because most applications are specialized. In other words, no-one has yet found a way to mass produce software development. It can occur on a large scale, as it does at Microsoft, Google, Apple and Oracle et al, but there isn’t an easily transferrable and repeatable process, because there are simply too many variables within each project. This makes sense.

A picture of the cover of the Apprenticeship Patterns book

The notion of craftsmanship also implies that programmers go through stages in their career that are akin to the European medieval guild traditions. This means starting as an apprentice working closely with journeymen and masters and learning from them, before progressing to becoming a journeyman who is someone who moves between teams, projects and masters, spreading ideas as he or she goes. Finally, achieving mastership means having the ability to enhance the skill of others significantly, ideally until they surpass your own. This is done by training and by creating tools to make the work easier.

An important point is that becoming a master doesn’t mean reaching the end of the software craftsmanship journey because there is no end as such—you should always be learning and acquiring new skills. A master is a superset of a journeyman and an apprentice, just as a journeyman is a superset of an apprentice.

The craft model recognises that you can’t pick up a skill just by being told about it. You have to practice the skill under realistic conditions and under the watchful eye of an experienced practitioner. In software craftsmanship this is frequently accomplished by pair programming. Intrigued and in agreement with these ideas, last weekend I read Apprenticeship Patterns – Guidance for the Aspiring Software Craftsman by Obtiva’s Dave Hoover and Google’s Adewale Oshineye.

The first thing I liked about this book is that at about 130 pages it’s an easy read. Although I read it all the way through, it’s actually intended to be dipped in and out of, because as the name implies, it’s a catalogue of patterns. It’s common for readers of patterns books such as the original Gang of Four Design Patterns book or Refactoring to realise that the book they’re holding simply gives a name to things that they were already doing anyway, and so it was for me with Apprenticeship Patterns.

For example, the Read Constantly and Study the Classics patterns encourage you to consume as much of the written word as possible, particularly by immersing yourself in the classics of the field. The Breakable Toys pattern is about building things for yourself in order to create opportunities for yourself to learn by building complete software projects on your own. The software that this blog uses is one of my breakable toys, as are UUID Waster and Truth Tables. This blog is also where I implement the Record What You Learn and Share What You Learn patterns. You may be thinking that some of these patterns sound kind of obvious and not really a big deal and that’s true to an extent, but I did find that this book contains some real insight into how to progress as a software developer by thinking more about certain situations and by practising deliberate behaviours.

The White Belt is a pattern for when “you a struggling to learn new things and it seems somehow harder than it was before to acquire new skills.” This resonated with me because I’ve been feeling like that lately whilst learning how to write my first Ruby gem and how to test it correcting using the RSpec Behaviour-Driven Development framework. The pattern talks about being prepared to sacrifice some short term productivity in whatever it is you’re trying to learn, so that you can leap forward. You have to unlearn what you know to acquire deeper and idiomatic knowledge of that new thing you’re trying to master.

The Be The Worst pattern encourages you to surround yourself with developers who are better then you are so that you have room to grow. As guitarist Pat Metheny said to some young musicians: “Be the worst guy in every band you’re in.” This pattern is all about starting at the bottom and working your way up and then repeating the process by finding a stronger team when you do become as skilled as your peers.

The patterns in the book are broken down into a context, a problem, the solution and concrete action you can take. Some of the patterns also include risks of applying the pattern to your career. For example, by being the worst you may drag the rest of your team down or even get fired!

I enjoyed reading Apprenticeship Patterns and found that it helped me to get some things I have been struggling with in my mind into perspective. Being primarily immersed in the Ruby on Rails world it can sometimes feel difficult to keep your head above water, because the pace of change is so fast and there always seems to be some supposedly wonderful new fad to learn. The book explains that if you aspire to become a software craftsman then you need to plan for the long term, for “if you’re still going to be working in 20 years' time, then you can do anything.”

It also made me realise that there’s only so far you can go programming in isolation. Doing so is great and it does give me pleasure, but you need to work closely with someone who is more experienced to get to the next level—as long as you both approach it with the right attitude and leave your egos at the door. I think this realisation is actually the logical conclusion of the value I’ve got out of watching screencasts such as Railscasts and PeepCode, where effectively you’re working along with a non-interactive mentor. Pair programming with a real person is the end game along that path.

To return to the issue of struggling to define the nature of software development raised at the start—did I come away from reading Apprenticeship Patterns with any clearer an idea of how to categorise what we do? Yes I did, actually. To quote the book: “software development is a craft precisely because we don’t understand it well enough to make it a codified discipline like science or engineering.” If you’re a developer and you find yourself agreeing with that statement, then I’d recommend reading Apprenticeship Patterns as you start walking the long road to becoming a software craftsman.

Micro Web Applications For Fun And Learning

As I mentioned previously, I’ve been having a lot of fun lately writing micro web applications using the Sinatra framework. I’ve found myself thinking of a simple idea for an application, developing it fairly quickly using Sinatra and some technologies or techniques that are new to me and then getting it out there running for free on Heroku. I’ve developed two other applications this way since blogging about my bespoke URL shortener jtblog.me: UUID Waster and Truth Tables.

UUID Waster

I think I first came across the idea of the 128-bit Universally Unique Identifier (UUID) shortly after Windows 95 came out. As the World Wide Web was still in its infancy you had to learn about hacking Windows from magazines printed on actual paper and sold in a physical shop. A bizarre idea, I know.

Reading one of those magazines I learned that you could use the Registry Editor—at your own risk, they were at great pains to point out—to tweak Windows in all sorts of interesting and officially undocumented ways. For example, you could rename the Recycle Bin to anything of your choosing, an option that wasn’t exposed by the Windows shell at the time.

I noticed that the Windows registry was crammed full of strange long hexadecimal strings, which I eventually learned were what Microsoft calls Globally Unique Identifiers or GUIDs. Even later I learned that these were being used as COM class IDs and that they were generated programmatically without any fear of being the same as an existing identifier. Still a bit fascinated by this idea all these years later, I thought it would be amusing to create a web application that frivolously wasted UUIDs at the rate of one a second. Thus, UUID Waster was born. It’s not an original idea, but I went ahead with it anyway.

A screenshot of UUID Waster

As a side effect of creating UUID Waster I also took the opportunity to use jQuery’s AJAX support, which was a first for me because previously I’ve used Prototype. I also used a different database and ORM tool from the MySQL/ActiveRecord combination used in my Rails applications. UUID Waster uses a SQLite 3 database when running locally in development and in production it uses PostgreSQL, which is part of the standard Heroku stack. I chose Data Mapper as the ORM layer. So that’s a pointless application that as a side effect gave me exposure to three new things.

Truth Tables

I can never remember the Boolean logic truth tables for the slightly more exotic operations such as XOR (Exclusive Or) and it always seems to take me longer than I’d like to look them up. With this in mind I decided to create a simple application that would act as a reference. Then I bought the Meet jQTouch PeepCode screencast, got very excited by what I saw and realised that I could also effectively turn it into an iPhone app.

I created the web version first and used it as an opportunity to dip my toe into the world of HTML5 and CSS3 (the rounded corners are done using CSS3). I also used Haml and Sass on the server to generate the markup and stylesheet respectively.

A screenshot of the Truth Tables web application

Next, I moved on to creating the iPhone-specific version using the jQTouch framework. To be honest, this was pretty hard work because although it was easy to get the basic bones of the application up and running in no time using jQTouch, I wanted an installation screen and I wanted things to still work without an Internet connection, because after all this is simply an app that’s displaying read-only reference information.

The desire for an installation screen was simply because asking the user to add the application to their home screen makes it essentially indistinguishable from a native iPhone application written in Objective C. You can provide a custom application icon, a startup screen and you don’t have to worry about Mobile Safari displaying its toolbar at the top.

A screenshot of Truth Tables running on the iPhone simulator

Both of these noble objectives were surprisingly difficult to achieve. An installation screen is quite hard to do because jQTouch wants to take over everything it comes into contact with and I didn’t want my installation screen within its grasp, as I wanted to style it myself. I chose to have the elements comprising the installation screen and the application proper dynamically shown or hidden within a single HTML file so that a single URL could be used. The reason for this is that otherwise the app gets the URL of the installation screen when it’s added to the home screen, which causes further complications down the line.

Eventually I hit upon the trick of using JavaScript to dynamically change the ID attribute of the main container div element which enables jQTouch to control the application when it’s running standalone but to leave it alone otherwise. This works well.

if (window.navigator.standalone) {
  $("#installation").hide();
  var $container = $("#container");
  $container.attr("id", "jqt");
  $container.show();
  // Initialize jQTouch (not shown)...
} else {
  $("#installation").show();
}

HTML5 offline application caching is how you make one of these web-apps-masquerading-as-a-native-app work without an Internet connection. It sounds simple in theory: you create a cache manifest file that lists the other assets needed for things to work offline. On the iPhone what actually happens is that the assets are downloaded in the background and stored in a BLOB column within a SQLite 3 database on the phone.

So much for the theory. The reality is that the slightest error in the cache manifest file will cause the whole thing to stop working and you probably won’t have a clue why because it’s extremely hard to debug. During development I was testing Truth Tables on my Mac by using the iPhone simulator which comes with the iPhone SDK. At one point I was following the instructions in the excellent Building iPhone Apps with HTML, CSS, and JavaScript book to inspect the simulator’s application cache database by using the sqlite3 command-line interface. It was a nice idea but there weren’t any rows for my application in there at all! Needless to say, I got it working eventually but more by trial and error than by judgement. I think the final result is worth it.

  • The source code for both UUID Waster and Truth Tables is available on GitHub.

The Scottish Ruby Conference 2010

On Sunday I returned from two days in Edinburgh for the inaugural Scottish Ruby Conference. The event has broadened its focus and rebranded from its previous Rails remit when it was Scotland on Rails. The venue this year was the splendid Royal College of Physicians, an imposing building with an ornate interior.

Day One

This year’s opening keynote was from Jim Weirich who spent about fifteen minutes talking about one of his favourite subjects which is particle physics, drawing parallels between wave particle duality and the duality of code and data amongst other things. Jim also delved into the first chapter of MIT’s Structure and Interpretation of Computer Programs book, providing Ruby equivalents of the book’s Scheme code samples. It was a very thought-provoking opener and made me want to check out the SICP book even more.

Joseph Wilk reprised his appearance at last year’s conference, this time talking about rocket-fuelled Cucumbers i.e. how to get your acceptance tests to run faster. As ever there are no silver bullets, but Joseph showed us how to execute subsets of tests and how to distribute the load across multiple Amazon EC2 instances in order to reduce the build time from over an hour to closer to the magic ten minute mark.

Brian Marick’s talk was entitled I Think I Finally Understand Mocks and billed as how not to miss the point of mock objects. Unfortunately I must have missed the point of the talk because it didn’t teach me anything new about mocks. However, I did learn quite a bit about cows in a veterinary school, and the use of audience members to represent objects was fun and entertaining.

Rails core team member Carl Lerche was up next and gave a presentation on the new relational algebra support in ActiveRecord 3, dubbed ActiveRelation or simply Arel. Carl gave a brief overview of the new finder syntax before giving us a fairly interesting preview of some of the enhancements planned for ActiveRecord 3.1. A nice buffet lunch followed and I had the pleasure of meeting the founder and some of the mentors and developers from Eden Development, a consultancy that I have long admired with a focus on software craftsmanship and producing high quality work.

Alexander Lang talked about CouchDB and when you might choose to use a document database in preference to a relational database. A lot of this session seemed familiar to me from his presentation at Scotland on Rails 2009, although he did have an innovative and slick continuous slide deck.

After lunch I went into the magnificent library to show support for my friend Martin Evans, who was giving a presentation about using Ruby in conjunction with the Arduino range of microcontroller boards. Martin hadn’t spoken in public before, but you couldn’t tell because he gave a presentation that was interesting even to someone like me who doesn’t really know much about electronics. The highlights had to be the video of the Arduino-powered drink mixer and Martin’s live demonstration of his obstacle avoiding—sometimes obstacle seeking!—robot named Roo-Bee. It was a lot of fun.

The final session I attended on the first day was given by John Leach, who talked about some lesser-known features in UNIX that are sometimes needlessly re-implemented by Rubyists. This was a good talk that included subjects such as how to impose memory and file IO limits on a process.

Day Two

The final day of the conference opened with a great keynote from Google’s new employee Tim Bray, talking about his love of Ruby and the places where Ruby isn’t that it ought to be. Tim urged the Ruby community to improve Ruby’s support for concurrency, to get Ruby into the enterprise and onto mobile devices. Tim had the best quote of the conference for me, stating that if your web application doesn’t work well on a mobile device then it doesn’t work well.

I sat at the back for the Vim for the Modern Rubyist presentation which unfortunately meant that I couldn’t hear a lot of what was being said. The presenters had my sympathy because with something like Vim it’s difficult to know what level to pitch the talk at given an audience of unknown ability. Aimee from Eden Development pointed out to me that pair programming is a great way to pick up Vim tips.

Renzo Borgatti made the brave move of doing a lot of live coding in his talk on MacRuby. As someone who used to enjoy writing Windows programs using Borland Delphi, I was hoping for a flavour of what it’s like to create native Mac OS X applications using MacRuby. Unfortunately I didn’t get that as a lot of this talk seemed to be spent debugging and I got bored. Sorry Renzo!

The Exceptional guys spoke about the ten most common errors in Rails applications based on analysis of data from their exception logging service. An amusing nugget was that they actually have three .NET applications using their service, which account for twenty percent of the total errors! They gave a useful run through of what the most common errors are and how to fix them. Unfortunately one of their speakers was noticeably more nervous than the other and they kept switching, which was somewhat distracting.

After another fine buffet lunch it was time to listen to GitHub’s Scott Chacon talk about some of the lower-level commands available in Git. I found this session pretty hard going, not because it wasn’t any good but because I was feeling sleepy after the combination of food and going outside for some fresh air! Scott is an authority on Git and gave a good example of how it can be put to uses beyond version control. For example, he demonstrated synchronizing configuration files across a set of servers based on a master copy held in a Git repository.

You’re Doing It Wrong by Tammer Saleh was a great session about common Rails anti-patterns. Tammer talked about his experiences of being brought in to companies as a consultant to fix their badly broken Rails applications and the strategies he employs to do so. For example, he logs all possible refactorings in an issue tracker so that he doesn’t get distracted from the immediate job at hand and so the client has some visibility on what they’re paying for. There seemed to be a real focus this year on bad Ruby code, but this was the best presentation on the subject that I attended at the conference.

As happened last year, the event closed with Jim Weirich and Joe O'Brien performing a role play, this time about how to get a typically conservative company to adopt Ruby and to understand the productivity benefits it brings. The actual role play wasn’t as funny as last year’s code review and Jim admitted later that it was slightly under-rehearsed. However, there was a great Q & A session afterwards with plenty of practical advice such as selling your boss benefits rather than features when trying to introduce Ruby, or anything new for that matter. The term “Architect Slayer” was also used in the context of someone who is able to introduce Ruby into an organisation past the sort of technical architects who thought that Enterprise JavaBeans were a good idea. You perhaps know the type.

An added benefit of the conference this year was that there were fifteen minute gaps between each session, giving much needed time to talk or grab some refreshment. Talking of which, it would be remiss of me not to mention the party held the night after the conference finished; what’s not to like about a room full of Rubyists, traditional Scottish dancing and a sword-fight in an amazing venue? Yet again this was a very well run and enjoyable event. Taken as a whole I think I got more out of the talks I attended last year, but that may have simply been because I made better choices. I certainly feel that I got more out of meeting and talking to new people this year, which more than made up for any slight disappointment I felt in some of the sessions.

Create A Sitemap For Your Rails Application

The Sitemap protocol was introduced by Google in 2005, but is now supported by all of the major search engines. Unrelated to a traditional website sitemap navigation page, it defines an XML schema for listing the URLs within a site, including metadata such as when a URL as last updated, therefore allowing search engines to crawl the site more intelligently.

Using the Sitemap protocol does not guarantee that web pages are included in search engines, but provides hints for web crawlers to do a better job of crawling your site. It’s easy to add support for a dynamically generated Sitemap to a Rails application. This post documents how I went about it for this site, whereby blog posts are stored in instances of a Post model. Obviously you’ll likely need to adapt some of these instructions for your own application.

The first step is to set up a dedicated route and controller for the sitemap. Add the following route towards the bottom of config/routes.rb:

map.sitemap '/sitemap.xml', :controller => 'sitemap'

This routes all requests for /sitemap.xml to a controller dedicated to serving the sitemap. Next, create app/controllers/sitemap_controller.rb:

class SitemapController < ApplicationController
  layout nil
  
  def index
    headers['Content-Type'] = 'application/xml'
    latest = Post.last
    if stale?(:etag => latest, :last_modified => latest.updated_at.utc)
      respond_to do |format|
        format.xml { @posts = Post.sitemap.published }
      end
    end
  end
end

The index action gets the latest Post model instance and then checks the HTTP request for staleness using ActionController’s stale? method, which does so by checking the HTTP ETag and Last-Modified headers. This ensures that the Sitemap is only served to the client if it contains fresh content, otherwise an HTTP 304 Not Modified status is returned. The @posts instance variable is set to the result of executing the chained sitemap and published named scopes within the Post model. This is how those named scopes are defined in app/models/post.rb:

class Post < ActiveRecord::Base
  named_scope :published, :conditions => { :published => true }
  named_scope :sitemap, :select => 'slug, created_at, updated_at',
              :limit => 49999 # +1 for About page to make 50,000
end

The sitemap named scope only selects the slug, created_at and updated_at columns because they’re all that’s required within the generated XML. I also limit it to 49,999 results because as you’ll see shortly the view template includes a hard-coded reference to my site’s static About page. The Sitemap protocol specifies that each Sitemap file contain no much than 50,000 URLs, hence the limit. I’ll worry about how to handle more than 50,000 posts in the extremely unlikely event that I write that many!

The final piece of the puzzle is the view template. Although originally using Builder for view generation, I switched to using Haml (HTML Abstraction Markup Language) because it’s simpler and faster. Haml is based on the idea of removing all duplication from markup and of using meaningful indentation to describe structure. This is what the app/views/sitemap/index.xml.haml file looks like:

- base_url = "http://#{request.host_with_port}"
!!! XML
%urlset{:xmlns => "http://www.sitemaps.org/schemas/sitemap/0.9"}
  - for post in @posts
    %url
      %loc #{base_url}#{post.permalink}
      %lastmod=post.last_modified
      %changefreq monthly
      %priority 0.5
  
  -# About page
  %url
    %loc #{base_url}/about
    %lastmod 2009-08-28
    %changefreq monthly
    %priority 0.5

This small quantity of Haml generates a Sitemap XML file that looks like the extract below. Job done!

<?xml version='1.0' encoding='utf-8' ?>
<urlset xmlns='http://www.sitemaps.org/schemas/sitemap/0.9'>  
  <url>
    <loc>http://johntopley.com/2010/02/02/the-apple-ipad</loc>
    <lastmod>2010-02-02</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.5</priority>
  </url>
  <url>
    <loc>http://johntopley.com/2010/01/14/the-best-of-twitter-2009</loc>
    <lastmod>2010-01-22</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.5</priority>
  </url>
  ...
  <url>
    <loc>http://johntopley.com/about</loc>
    <lastmod>2009-08-28</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.5</priority>
  </url>

The Apple iPad

A picture of the Apple iPad

I've been following the Web’s reaction to last week’s Apple iPad unveiling with great interest. It’s clear that this was no iPhone announcement, meeting with near universal acclaim. From watching the video of the event the applause seemed subdued in parts and any talk of game-changing was not unanimous. The long-awaited Apple tablet didn’t live up to the hype, but given the level the bar was at exactly because of that iPhone keynote a mere three years ago, it probably never could.

Before I weigh in with my own thoughts on the iPad, I recommend that you read the opinions of these four pundits if you haven’t already, because I won’t be going over ground that they've already covered superbly. They are Stephens Fry and Frank, John Gruber and Alex Paine.

A Special Event

Apple did was what Apple always do at these special events. They sent out an invitation and then talked with a singular focus about the product that the event was introducing. There were no distractions such as announcing iPhone OS 4.0 or new revisions of the MacBook Air, or anything else that would obscure the main message. I don’t know why some people worked themselves into a frenzy expecting otherwise.

That Name

I really thought it was going to be named Canvas, given that the event invitation showed a canvas. The only problem was that I just couldn’t see how the i prefix was going to fit in with that, because iCanvas just doesn’t work.

I still haven’t got used to the name iPad. Aside from the often mentioned feminine sanitary product connotations, it sounds too similar to iPod, or even iPAQ (remember those?) In fact, Jobs even mistakenly called the iPad an iPod at one point in the keynote. In common with Apple, I cannot think of a better iSomething name though.

First Impressions

Unsurprisingly the iPad hardware itself is up to Apple’s usual slick standards and follows the recent trends such as a longer life sealed-in battery and what’s probably unibody construction, although I've haven’t seen official confirmation of that. External controls and apertures are typically minimal, although it’s easy to envisage that a future revision will at least add a forward-facing camera with companion iChat and Photo Booth applications.

The iPad looks like it’s portable within the bounds of the home. I can imagine having one powered on lying around the house, ready to be picked up for instant Internet access or entertainment. It’s a much more convenient way to get online than going upstairs to turn the Mac or PC on and having to wait for it to boot up and log in. Google’s forthcoming ChromeOS is designed to address the same problem, with Google aiming for a switch-on to online time of as little as six seconds.

If I had an iPad then I think I'd take it on holiday to relieve boredom during the flight, but I probably wouldn’t take it on my commute to work every day. An iPhone is sufficiently compact and capable for that.

Watching the promo video I was struck by how much the iPad really does look like a device from the future. It wouldn’t look out of place on the bridge of the starship Enterprise or the USS Discovery on its way to Jupiter. When the iPad is docked with a hardware keyboard it reminds me of the trail blazing Xerox Alto from 1973, because both have the rigorously logical yet seldom imitated portrait display orientation:

A comparison of the Xerox Alto and the Apple iPad with keyboard dock accessory

When I first saw the iPad home screen I thought it looked strangely sparse and kind of goofy. The icons are really spread out in a similar fashion to how they are if you dial up the desktop icon grid spacing on Mac OS X. I've come to realise that this is simply because I'm so used to the iPhone with its densely packed together icons. The iPad Dock down at the bottom of the screen looks like it could easily accommodate eight icons instead of four—I don’t know if that’s possible. I also don’t know if it enforces the grid layout or if you can go free form and drag icons to where you like. I suspect the grid is enforced.

A Simpler Model Of Computing

One of the most striking (apparent) omissions of the iPad is that it doesn’t support multiple user accounts. At first I thought this was a potential deal-breaker for my future ownership of the device. Then with a little help from some of the pundits linked to earlier I realised that the iPad is really all about a simpler model of computing. This is a device that attempts to distill the tasks that most people use their computers for to a bare essence, with all other distractions removed.

The lack of multiple user accounts and multitasking of App Store applications are not technical limitations, for OS X is easily powerful enough to do both and obviously does so in its Mac OS X variant. These are very deliberate design constraints put in place for the iPad.

Supporting multiple users implies a way of identifying those users and securing their personal data. Using biometrics is probably too expensive, so that means having to use passwords, which introduces complexity around setting, remembering, entering and resetting them and also around terminology—does the phrase Log In really have a place in the modern world?

Multitasking of App Store applications might come to the iPad and the iPhone eventually, probably with advances in battery technology. In case you haven’t noticed by now, Apple like to take their time to get features right, the prime example being the delay in bringing Copy and Paste to the iPhone. Multitasking isn’t a now or never proposition because it can easily be added in a future operating system update.

Your Only Computer?

One obvious question about the iPad that needs addressing is whether it’s intended to be a primary or a secondary computing device. It feels to me like Apple are hedging their bets a little on this one.

The iPad is being pitched as the best way to surf the Web, use email, view photos etc. If you just want a computing appliance for straightforward Web access and content consumption then why would you need another, general-purpose computer? Yet the keynote mentioned USB syncing and backup to a Mac or a PC. Also, as far as I'm aware the iPad is like the iPhone in so much as it is unable to download and install its own operating system updates i.e. you have to do that in concert with a connected desktop or laptop computer.

Undoubtedly if you are a consumer who already has a Mac or a PC then Apple will be perfectly happy to sell you an iPad as well, but it’s when it strays into companion device territory that the case for its existence becomes weaker and you wonder if it might be a luxury too far.

I'm also not clear on what the business usage angle is for the iPad. Apple clearly don’t see it as a consumer-only gadget because part of the introduction was dedicated to a reimagining of the iWork suite and rather impressive it was too. However, how do you hook up your iPad to a projector to share your whizzy Keynote presentation with your colleagues and how do you print stuff? It looks like Wi-Fi printing is the only option.

Having said all that, I can see the iPad being a success in certain vertical markets. It’s not hard to imagine a sales force going out and wowing customers by being equipped with iPads that showcase product videos and that run internally-developed sales and data collection software.

Will It Sell?

I think as bets go it’s a fairly safe one, so I do actually think that the iPad is going to be the first commercially successful computer with a tablet form factor. The price is very competitive and Apple kit generally seems to be perceived as desirable amongst the populace at large and is still flying off the shelves. Come March it’s going to be hard to get your hands on a demo iPad in an Apple store.

The iPad has been accused of simply being a bigger iPhone, but I can think of worse ways in which it could have turned out. An adapted laptop running Windows 7, for example. It seems obvious to me in retrospect that the iPad’s technology was going to be an evolution rather than a revolution. Apple were never going to throw away their substantial investment in the technology behind the iPhone revolution. From multi-touch, to the App Store, they were going to build on those successful foundations. That’s a two-way process too, because if Apple are able to put the iPad’s new A4 system-on-a-chip or future derivative into the iPhone then the other mobile phone manufacturers will fall even further behind because none of them are capable of designing or manufacturing their own custom silicon. Creating CPUs for mobile devices is now a core competency at Apple.

In spite of its limitations I think the iPad will succeed, because there are still whole swathes of people who don’t yet have computers or Internet access, including most of my relatives. I would have no hesitation in recommending an iPad to them as an easy way to get online and join the digitally literate. I would make that recommendation with a big smile because I would know that for a change I wouldn’t have to serve as unpaid front-line technical support for a new toy that’s more complicated and capable than its owners need it to be.

The Best Of Twitter 2009

With 2009 receeding to a distant dot in the rear-view mirror of life, I wanted to take a moment to record my favourite tweets of the past year. I think it’s particularly important to preserve them for posterity, as I read somewhere that Twitter don’t store tweets indefinitely. I guess those 140 characters or less soon add up. It would be criminal for these perfectly formed vignette-lets to be lost to future generations, particularly as three of them are from my own fair keyboard.

Without further ceremony, here are the winners in reverse chronological order:

On Technology

Anything Goes

With Humour

I’ve been aware of the Pragmatic Programmers’ advice to “Use a Single Editor Well” for some time now.



Sign In