small medium large xlarge

Errata for Metaprogramming Ruby


The latest version of the book is P4.0, released almost 3 years ago. If you've bought a PDF of the book and would like to upgrade it to this version (for free), visit your home page.

By default this page displays the errata for the latest version of the book. If you have a previous version, select it here:

If you've found a new error, please submit it.

  • Typo
  • Tech. error
  • Suggestion
  • Maybe next edition
  • Not a problem
  • Reported in: P4.0 (16-Dec-13)
PDF page: 75

The order of expected output for Frank and Bob is reversed from what it should be based on the order of the output statements.--Peter Alfvin

Paolo Perrotta says: Thank you. Fixed.
  • Reported in: P4.0 (18-Dec-13)
Paper page: 116
"This fact explains why you can call MyClass#b() and MyClass#b=()" Shouldn't it by MyClass.b() and MyClass.b=() (with .'s instead of #"s) since b w...more...
Paolo Perrotta says: Indeed. Fixed. Thanks,

Stuff To Be Considered in the Next Edition

  • Reported in: P2.0 (17-Sep-10)
PDF page: 1
From Kado: a comment about "private" on the book: there is one exception: it's "setter" method. "setter" always need "self" as literal. def set...more...
Paolo Perrotta says: Kado, as weirdly interesting this corner case is, I decided to leave it out of the 2nd edition. It would make the sidebar too large, and force me to upgrade the sidebar to a regular section in the book - and I don't see any good place in the main text that can contain this information. This one and other interesting but not essential corner cases will probably be good for a blog post. Thanks!
  • Reported in: P3.0 (15-Aug-12)
PDF page: 1
Mention (from the BasicObject documentation): "BasicObject does not include Kernel (for methods like puts) and BasicObject is outside of the namespac...more...
Paolo Perrotta says: Will mention this stuff in the discussion on Clean Room
  • Reported in: P2.0 (14-Jan-11)
Paper page: 1

One reader complained that the ToC is useless. Any ways to make it more informative?--Paolo Perrotta

  • Reported in: P3.0 (26-Nov-11)
PDF page: 1
(from @jonclaus) The methods/dynamic_definition.rb code example in Chapter 5 didn't convey define_method's power or a reason to use it over the def bu...more...
  • Reported in: P2.0 (10-May-11)
PDF page: 1
Rewrite the Methods chapter to talk about the trade-offs of Ghost Methods vs. Dynamic Methods. Show the two main Ghost Method spells (the "difficult" ...more...
  • Reported in: P4.0 (11-Sep-13)
Paper page: 39
In foot note #3, it says "There is also an Object#define_method() that defines a Singleton Method(101)." There is no Object#define_method() method,...more...
Paolo Perrotta says: Well spotted! I removed that footnote in the 2nd edition altogether.
  • Reported in: P1.0 (21-Jul-10)
Paper page: 41

It might be useful to discuss the way that Dynamic Dispatch relates to Second-order predicates in mathematical logic.--Rich Morin

Paolo Perrotta says: (UPDATE: I decided to skip this.) I considered this for the second edition. However, athough the discussion would be interesting, I don't want to add to this already long chapter. Same reason why I didn't really discuss all the interesting stuff about functional programming in the Blocks chapter. Thanks for the suggestion anyway, Rich.
  • Reported in: P1.0 (24-Feb-11)
Paper page: 47
"Note that define_method() is executed inside the definition of Computer..." As the author noted, that should be: "Note that define_component() ...more...
Paolo Perrotta says: Hey, 7stud. I finally got down to 2nd edition suggestions. ;) I toyed with your ideas for a while. In the end, I kept the original code, mainly for a few reasons. You guessed one: I don't want to go into details about how define_method() is private, being forced to use Computer.send() or worse self.class.send() in define_component(), and so on. I also think that a few beginners might be confused by the interplay of initializing the object and defining methods on the class. Thanks for the suggestion anyway - food for thought.
  • Reported in: P4.0 (13-Dec-12)
PDF page: 48
In the last paragraph, last sentence, you have an extra "-" between "get" and "ListUser()" in the Flickr#tags_getListUser() method reference.--Kim Shr...more...
Paolo Perrotta says: Fixed. Thanks.
  • Reported in: P4.0 (11-Sep-13)
Paper page: 55
In paragraph 2.5, at the bottom of the page, it says "The drastic Module#undef_method() removes all methods, including the inherited ones." I found...more...
Paolo Perrotta says: Sorry, sloppy English. :) I rephrased to "removes *any* method". This should make it clear.
  • Reported in: B1.5 (31-Dec-09)
PDF page: 56
Hi Paola, I am learning a lot from the book! Great content! A suggestion for the "The Top Level" sidebar: I would extend this a bit to mention irb sub...more...
Paolo Perrotta says: Thanks for the suggestion, Greg. I considered this for the second edition, but I decided that it would end up adding more text to an already long section.
  • Reported in: P3.0 (15-Nov-12)
Paper page: 65
When the ^__ methods get added to the regex in more_blank.rb, the regex gets a little looser in other respects. The resultant regex does match respon...more...
Paolo Perrotta says: I hanged on this suggestion, but today I realized that I don't need that regexp anymore: in the 2nd edition, I changed the code to just use BasicObject as a blank slate. This makes everything smoother. Thank you for forcing me to think about a hard-to-spot problem, anyway!
  • Reported in: P4.0 (01-May-13)
PDF page: 73
In the method_missing definition, args[0] is being passed in the @data_source.send call. However, the various methods being called actually need the ...more...
Paolo Perrotta says: You're right - I changed the code to use @id everywhere. Thanks!
  • Reported in: P4.0 (22-Jan-13)
PDF page: 89
in the redflag.rb: Dir.glob('*events.rb').each do |file| load file each_event do |name, event| the line above should be: each_event do...more...
Paolo Perrotta says: Those are the arguments to the block, not define_method. The block gets passed on and is ultimately called here, with two arguments: events.each_pair do |name, event| name, event end So it must be a block that takes two arguments.
  • Reported in: P3.0 (04-Nov-12)
PDF page: 90
the switch from "info = @data_source.send("get_#{name}_info", @id)" to "info = @data_source.send("get_#{name}_info", args[0])" in chapter Methods is a...more...
Paolo Perrotta says: I ended up going with Kado's suggestion.
  • Reported in: P2.0 (18-Dec-11)
Paper page: 96
At the beginning of section 3.7, the boss writes a `test_events.rb` file that includes two events, both of which get triggered. The example would be m...more...
Paolo Perrotta says: Done. :) Thanks, Katrina!
  • Reported in: P1.0 (04-May-10)
Paper page: 98
The '' solution does not seem to clear the setups and events variables for each new events file, whereas the previous solution on page 97 d...more...
Paolo Perrotta says: I simplified the example to use one single events file. Using multiple files wasn't adding any value to the DSL explaination anyway, and just causing subtle problems such as the one you reported.
  • Reported in: P2.0 (18-Dec-11)
Paper page: 98
"[setups and events are] evaluated in the context of an `Object` that acts as a _Clean Room_". It would be very helpful if the example on page 96 f...more...
Paolo Perrotta says: "Fixed" (I didn't add a test suite, which would make the chapter far too long - but I did specify that the Clean Room is optional). Thanks!
  • Reported in: B1.5 (10-Dec-09)
PDF page: 120
The test cases for the redflag example are too simple to preclude a number of more simplistic solutions to the problem. In particular there's nothing...more...
Paolo Perrotta says: You're right. I made it clear in the 2nd edition that a Clean Room is not required. I might even add a test for it.
  • Reported in: B1.5 (08-Jan-10)
PDF page: 123
I like your example answer ( blocks/monitor_framework/redflag.rb ) but I see some issues ... I'm sorry if I'm wrong in my assumptions. - The event ...more...
Paolo Perrotta says: I fixed the first point, and clarified the second for the 2nd edition of the book. Thanks.
  • Reported in: P1.0 (20-Oct-10)
Paper page: 126
In the GUT, rule 6 needs a little hint that the class of a class object will be class Class at the top of the eigenclass chain. Seeing figure 4.6 mad...more...
Paolo Perrotta says: This would be best fixed by adding Class in figure 4.5. Re-doing a picture is a pretty big change, outside the scope of a reprint - so it'll have to wait until a second edition. Thank you for telling me.
  • Reported in: P1.0 (21-Jul-10)
Paper page: 135
A third problem with the Around Alias is that it pollutes the name space and might clash with an existing or future name. Why not present the alter...more...
Paolo Perrotta says: Good point, Rich. This will come useful in the second edition.
  • Reported in: P4.0 (16-Dec-12)
PDF page: 147
In the paragraph right after the code fragment for mere_cache/merb_ext/controller.rb, second sentence, there is a "-" between "Class" and "Methods" th...more...
Paolo Perrotta says: Fixed. Thanks.
  • Reported in: P3.0 (07-Nov-11)
Paper page: 148
From pwim on Twitter: "4.5 Quiz: Module Trouble seems to fall outside of The Great Unified Theory. Is including modules not part of the object model?"...more...
  • Reported in: P1.0 (15-May-10)
Paper page: 149
The author suggests that you can't support methods that accept blocks, such as Array#find, with dynamic dispatch, and thus you'll need to resort to ev...more...
Paolo Perrotta says: Thank you for your comments Tim. :) About the item you reported, I wasn't clear enough in the book. This example assumes that somebody is putting the method name, arguments and (eventually) the block on a web page. If you don't care about blocks, then your user can just insert the name of a method and the values of arguments - but if you want to also allow your user to input a block, then you can only capture the content of the block as a string. If you do that, then you have to use eval() to pass that string on to the Array method. A tad confusing in hindsight. I'll probably find a clearer way to express it in a next edition of the book.
  • Reported in: P2.0 (09-Oct-12)
Paper page: 152
In the proc{ ... }.call, the $SAFE works differently from normal global variable. I wrote a simple test like this: $ABC = 'abc' puts $ABC ...more...
  • Reported in: B1.5 (05-Jan-10)
PDF page: 175
The text says, "It [erb] ... also creates a Clean Room (109) to execute the code in a separate scope." P. 109 shows how to create a clean room by cal...more...
Paolo Perrotta says: Thanks, Wayne. You're right that the definition of Clean Room uses an object, and the ERB example is confusing in this respect. The idea is that the Proc object is acting as a clean room (you don't need to use instance_eval in this case, because you can pass the block to the Proc when you create it. I changed the text to: "It [...] also uses a Proc as a Clean Room [etc]", to make it clearer.
  • Reported in: B1.5 (05-Jun-10)
PDF page: 184
Similar to comment #41674, I'm confused about all this extra machinery. I don't see why module/mixin authors must go through such ridiculous contortio...more...
Paolo Perrotta says: The reason is that this is actually a common pattern in the wild - in particular, Rails usues it a lot. I'm not very enthusiastic about all of this complication either, and apparently neither are the Rails authors, because they changed it in Rails 3. However, the book heavily uses Rails 2 as an example in the second part, so it has to explain what's going on. I'll consider removing this description in a second edition of the book. [Update: I'm working on the second edition, and removing this spell is on the to-do list]
  • Reported in: P3.0 (29-Nov-12)
PDF page: 243
`a ||= []` is not equivalent to `a || (a = [])` `a || (a = [])` will throw a "undefined local variable or method 'a'" The correct equivalent is `a...more...
Paolo Perrotta says: Not only did I get this wrong, but the following snippet is wrong as well as a result. I fixed the snippet you refer to, and I replaced the following one with: if defined?(a) && a a = a else a = [] end Surprising that nobody had noticed this problem yet. Thank you very much for pointing this out.
  • Reported in: P1.0 (20-Apr-10)
PDF page: 243
Nill Guards do not work well with booleans. a = false # a gets initialized .... a ||= true # initialization gets overwritten Effectively, it...more...
Paolo Perrotta says: I added a short section about this. Thank you, Martijn.