Test-Driven Language Study

I learned Perl and Python by reading a lot of other people’s code, and by writing lots of small programs (and a few bigger ones). When faced with a “how do I make the language do…” problem, I’d fumble through a growing collection of scripts looking for that one place where I’d solved a particular problem before. Having a big collection of prior solutions is handy, but searching is problematic. Some patterns aren’t amenable to grep.

I’ve been playing around with Ruby (and the Rails framework) for several months, and have decided that it’s time to have a serious go at the language, using the the “Pick Axe” book as a guide. The pile of experimental scripts was beginning to grow again, until Mike Clark provided the transforming idea: Capture knowledge about how a language works by writing unit tests. In this case, one really big file of unit tests.

The idea is stunning in its obvious simplicity.

After an evening of digging through my pile of Ruby experiments, collecting up the useful pieces into a set of unit tests, I have a file with just over 100 unit tests, divided into categories like “tests about strings”, “tests about numbers”, and so on. Another evening’s work should double that number. Now, much of what I learn about Ruby will be captured in one easily searchable place.

I did encounter one anomaly, which I’ve boiled down to a simple test case.

  require 'test/unit'
    
  class TestUnitTest < Test::Unit::TestCase
    def testAssert
      assert true
      assert not false      # syntax error
      assert(not false)     # syntax error
    end
  end

After scratching my head at this for a while, I took it to the #ruby-lang IRC channel, where the resident experts pondering it and announced that it’s a problem in the implementation of Ruby’s parser, and that the workaround is to write

      assert((not false))

I wouldn’t have guessed that. But now I’ve captured the problem and its workaround in a unit test.