Then I remembered a project my friend had mentioned to me earlier. This project was Ruby Koans. Koans is a collection of unit tests where most of the code is written, but the expected values in all the asserts are left blank.
The first few are dead simple, and it seemed really silly to be doing things like:
def test_fill_in_values assert_equal __, 1 + 1 end
When first starting I wondered how it could be useful to have tests that simple. But then I ran into this one:
def test_nil_is_an_object assert_equal __, nil.is_a?(Object), "Unlike NULL in other languages" end
Still dead simple. But as someone who's used to C++ and Java the correct answer was surprising.
Some of the tests are really simple like that, geared to show you some of the basic syntax and concepts of Ruby, like array access and flow control. But later on you get to more complex tests, including ones that have you write some classes to fit the tests.
Another nice thing about Koans is that the "__" that you have to replace in the tests does not cause compile errors. It's an actual object defined by the koans infrastructure that, when run, provides a value something like
"<FILL ME IN>". This lets you actually run the tests before you're filled in the code, and the test output will show you what the proper answer is.
I ended up slowly working on Koans while waiting for builds at work, and I couldn't get enough. I was actually kind of depressed when I stopped getting test failures. I have a feeling that Koans is one of the primary reason I stayed motivated enough to keep poking at Ruby without having any real projects to use it on.
I've always found that I learn languages fastest by actually writing code in it, and that's exactly what Koans let me do. It really is one of the best learning tools for a programming language I've ever seen. Before now I never would have considered using unit tests to create a tool for learning a language, but now I'm hoping that something like this will exist for any language I end up needing to learn in the future.
Ruby koans is an incredibly awesome way to learn ruby. More languages should have things like that.