First and Rest in Ruby

A common pattern when doing functional-style programming is to split a list into first and rest components, otherwise known as head and tail (or car and cdr in Lisp). first is the first item in the list, or nil if the list is empty. rest is a zero or more-length list containing the remaining elements in the original list.

For instance, here’s a recursive reimplementation of Ruby’s Array#join method which splits the joined list into first and rest:

In this example we used list.first to get the first element, and list[1..-1] to get the rest. But is this a robust way to split an array into head and tail components? Let’s see:

Hmmm. We said that rest should always be a list with zero or most elements; but when given an empty list to start with, this technique gives us nil as the tail of the list. It’s also a bit ugly. Let’s see if we can do better.

Now we’re using the splat operator to break the source list into it’s parts. The code is much more concise, but the results are very wrong. In this version rest is never a list!

However, a slight refinement and we have exactly what we want:

Here we’ve added a splat operator to the left side of the variable assignment as well, telling Ruby to collect all remaining values into an Array assigned to the rest variable. This version works exactly as we intended, and is still concise. I first saw this technique used in the DataMapper codebase, and it’s the most elegant way I’ve come across to break a Ruby Enumerable object into first and rest components.