The past few years have seen the English-language Ruby book market explode. Before the phenomenal success of Rails it was perfectly possible to own every available title (and not use much storage space), but now that would be quite a challenge and lead to considerable redundancy. Having worked my way through quite a few Rails books of late, reading Practical Ruby Projects—a Ruby book that doesn’t even mention web frameworks—was both a pleasant diversion and a highly illuminating experience.
Like the last volume I reviewed, this book is unabashedly aimed at experienced programmers. There’s a brief paragraph on “getting set up”, but no detailed guide to obtaining the tools. Instead we dive right in to a sequence of projects that includes: making music (dipping into calling C code from ruby), animation, simulation, building a strategy game (and adding a RubyCocoa frontend), genetic algorithms, and even implementing lisp and parsers. Once again the “apress roadmap,” a diagram intended to show how the skillsets in their different volumes build on one another, is misleading pitching this between “Beginning Ruby” and other volumes I’ve reviewed like Practical Ruby for System Administration and Pro Active Record. Don’t believe it. Though there’s little overlap in the material, this is a more advanced volume than either of those and readers should be prepared.
The pace of the book is measured and Topher Cyll does a good job of gradually building up the projects a step at a time. Along the way a variety of practices are demonstrated with many methods stubbed out for demonstration purposes before being filled in when they are needed, and considerable time spent on decoupling code. That latter piece is particularly in evidence in the chapters on building a turn-based strategy game and then developing a RubyCocoa front-end. Despite careful design early on further refactoring is needed to make it easy to apply the front-end and that process is carefully worked through.
Most of the book makes some use of existing libraries. The initial lisp chapter uses the sexp library and the subsequent section on writing a parse relies on rparsec. For the most part, however, use of the libraries is kept to a minimum, allowing for fairly self-contained code. Unit testing is largely ignored until the last chapter, where the need for tests when constructing a grammar/parser is explained and a test-first development model is encouraged. That works well to demonstrate the power of tests for complex (and often brittle) code.
This is not a book designed for public transport reading. Working through chapters on the bus I frequently found myself wanting to reach for my laptop to get a better grasp of how a piece of code worked. While the explanation is generally very good, with material of this complexity there is nothing like running the code and tweaking it to make sure you’ve understood exactly what each transformation does. It’s a book to take your time over, so be prepared!
A few editorial errors have crept in, suggesting a re-organisation of the contents late in the day. In particular an early reference to s-expressions seemed to presume that the lisp and/or parsing chapters were featured early. That’s not a big deal and will hopefully be corrected in later printings; the author does encourage skipping around within the book, but there is value in working through it roughly in order, and not just for the two “paired” chapters that explicitly build on one another.
Perhaps the most striking thing about this book is the reminder that even for those of us whose primary programming activity is web development, studying other areas can be extremely helpful. Not only is it helpful to see how other developers structure their code, but tools like genetic algorithms and parsers are likely to be very helpful where web applications require sophisticated processing and/or backend systems. And it never hurts to learn a little lisp. For the ruby developer who’s comfortable with the language and wants to stretch out a little, this book would be an excellent investment.