scottl writes "Metaprogramming Ruby is the first book to give an in-depth and readable explanation of how dynamic programming works in Ruby. It is both readable and accurate and will be a valuable resource to intermediate and probably advanced Ruby programmers for some time to come." Keep reading for the rest of scottl's review.Metaprogramming Ruby is not a book for programmers new to Ruby, but would make an excellent follow on book to either Programming Ruby by Dave Thomas, Chad Fowler, and Andy Hunt or The Ruby Way by Hal Fulton. Both of the above books have chapters on or at least mention metaprogramming, but this is the first full length exposition of it. The book itself is broken into two sections and four appendices. In the first section, you (the reader) is paired with a more experienced programmer for a week, a chapter for each day, and as the week progresses you cover different topics in metaprogramming after being given tasks by your boss. The second section has two chapters on the design and implementation of ActiveRecord from Rails as well as a chapter on safe metaprogramming. Finally, there are three very useful appendices and a bibliography. One other note is that the book has the concept of "spells". Each concept as it is discussed in the book will have a spell associated with it. There will be a note in the sidebar with the name of the spell and the third appendix has the spells listed in alphabetical order, a short example of the spell, and a page number linking back to the extended discussion of the spell.
The first chapters are an informal introduction to metaprogramming where the reader, just starting a new job, is paired with Bill, an experienced developer, for a week. Each day is a chapter and each chapter covers a specific topic. The topics, as might be expected, increase in complexity as the week goes on. This more informal style actually works quite well. I had expected to be a bit irritated with the "schtick", but it turns out that Perrotta does not use it to excess. The topics covered here are Monday: The Object Model, Tuesday: Methods, Wednesday: Blocks, Thursday: Class Definitions, and Friday: Code That Writes Code.
Chapter 1 on Monday starts out with you meeting Bill, your experienced pair programmer, on a Monday morning and then goes straight into the Ruby object model. It discusses reopening classes to add additional methods including predefined Ruby classes such as String. It follows up with Monkey Patching (opening an existing class and redefining an existing method) and the pitfalls therein.
In Chapter 2, methods are examined. Perrotta goes over a problem with duplicated code and how to reduce this code by generating and calling code dynamically. He then moves to showing the same example using method_missing(), followed by adding a change to respond_to? to make sure the methods show up.
Wednesday's topic in Chapter 3 covers blocks, lambdas, and procs all of which are really just "callable objects". The chapter starts with a review of blocks. This is followed by a discussion of scopes and how to carry variables through scopes using blocks as closures. Perratto shows how to use instance_eval() to receive blocks and then use them to manipulate scopes. Next, converting blocks into "callable objects", lambdas and Procs, and then calling them later is covered. Finally, there's a short introduction to domain specific languages (DSL) using the the techniques from this chapter.
Chapter 4 or Thursday covers class definitions. A discussion of self and the current class open the chapter. There's also a section on singleton methods and eigenclasses. There are class instance variables, variables that belong to the class and not to a particular object. Examples of class macros, such as attr_reader, attr_writer, and attr_accessor, and how to write them are shown. Finally he covers around aliases where method names can be renamed and then redefined but the original is still available.
The final day of the week, Friday, Chapter 5, goes deep into Ruby metaprogramming with code that writes code. In this chapter, Perrotta shows how to implement an "attr_checked" attribute in a few different ways starting with a kernel method using eval and moving on to passing the validation attributes in a block. Then this gets moved to a class macro (from Chapter 4), and finally moving on to using a module with hooks. This last is a pattern that's seen in many Ruby projects including Rails and two I'm familiar with, Sequel and Ramaze.
The second section, Metaprogramming in Rails, consists of two chapters on ActiveRecord and a final chapter on metaprogramming safely. In the first two chapters, Perrotta takes a tour through
ActiveRecord, the Rails object relational mapper (ORM) and shows how ActiveRecord uses the tips and techniques from the previous chapters. The final chapter on safe metaprogramming discusses how to test metaprogramming and working around and with to make sure that monkey patching doesn't cause problems.
Finally, there are three appendices. The first shows common Ruby idioms that are seen pretty much in all Ruby code. They provide a good review, but I'm not sure how useful they really are for the audience that this book is aimed at. The second appendix is one DSLs. This is also a nice to have, but there's probably not enough to let you program a DSL if you don't have additional help from somewhere. The final appendix really is almost worth the price of the book. It contains a list of metaprogramming "spells". Each of the spells contains a short programming example as well as the page number with the longer explanation. This is incredibly useful when looking at code from any of the major frameworks (some mentioned above) and you don't understand a piece of it. Just by scanning through the spells you can often find a simple version of what you're looking at and then read a longer explanation.
All in all, this is one of the better, more readable programming books that I've read in a long while. Perrotta keeps it to around 250 pages including the appendices and it's packed full of useful information. As I noted above, this book is highly recommended as a second Ruby book. The presentation of metaprogramming is both enjoyable and useful and the book itself is well written.
You can purchase Metaprogramming Ruby from amazon.com. Slashdot welcomes readers' book reviews -- to see your own review here, read the book review guidelines, then visit the submission page.