For some time now I’ve been meaning to learn another programming language. The last one I learned was Python and that was so long ago that I’ve mostly forgotten it. Then I spent nearly 3 years working at Rare doing mostly C#, and some C++ (and maybe some Powershell if fate was feeling particularly cruel that day). That job was really fun but it didn’t have much need to use a many different languages, and most of my learning time was taken up getting better at testing, refactoring, and teaching (which I think are pretty good skills to have).

So, it was time to pick a new language and learn it properly, and by properly I mean ‘I can casually create a reasonable sized project in it’, but which one? There’s a load to choose from but looking at the languages I already know well, there’s an obvious gap in the shape of a decent cross-platform scripting language. I know a bit of Perl but that’s effectively a write-only language which doesn’t really suit my ethos of making good, easy-to-understand code.

It would also be cool if the language could be used for modern web stuff, the last web project I did was in C# which somewhat limits what type of server you can run it on (I assume you can use mono, but that sounds like pain), and the project before that was PHP and the less said about that the better (though maybe the new version has improved things?).

Essentially I narrowed my choice down to two languages, Javascript and Ruby. Out of the two, Ruby has the better tools (by some large margin), plus Octopress (the software that powers this site) is Ruby.

I’d messed around in Ruby a bit, mostly poking Octopress to do what I want, but I wanted a more structured approach to leaning so I checked out the resources on the official Ruby site.

Initially I rolled my eyes at the Ruby Koans, I really hate this whole faux-mysticism some people wrap around coding (I’m looking at you Perl Monks) but when I read more it seemed that the actual contents were exactly what I was looking for.

The Koans are a collection of files, each one dedicated to a different part of the Ruby language (so there’s one for methods, another for classes, another for arrays, etc.) and inside the files is a load of (currently failing) unit tests. Each test demonstrates a particular behaviour, for example, in the file describing arrays, there’s the following test

1
2
3
4
5
6
7
def test_slicing_with_ranges
  array = [:peanut, :butter, :and, :jelly]

  assert_equal ___, array[0..2]
  assert_equal ___, array[0...2]
  assert_equal ___, array[2..-1]
end

The testing framework the Koans use recognises the underscores as representing a value that the user has to fill in, so the test will fail with something like “Expected “FILL ME IN” to equal [:peanut, :butter, :and]”

(Side-note: The fact that ‘..’ and ‘…’ are different operations is a bit horrid)

As you progress through each file fixing the unit tests, you learn more and more about a given feature, and because you’re actually using it, I found that the knowledge sticks more than times when I’ve just read about a thing.

In addition to this, there’s a couple of times where you’re given a larger task to complete, like writing a function or an entire class, and again in these there’s a load of tests that are failing, but this time, the tests represent the specification of the code you need to write. These parts were my favourite, it allowed me to use some of the code I’ve just learned in a non-trivial context, which again, really helped cement the knowledge.

In total, there’s at-least 280 checks that are failing, spread over about 32 different files (depending on the installation of Ruby it detects). I managed to complete the lot in a single evening (though it took a few hours) and I plan to move on to the ‘extra credit’ task that is suggested at the end.

For me, I don’t think there could be a better way to lean a new language, I learn best by writing the language, and having the structure of the file-per-subject and test-per-behaviour made it easier to follow that writing something larger that requires many trips to the docs, and finally, I really enjoy the TDD style of working.

So if you’re already a coder and are interested in learning some Ruby, I’d definitely recommend it.