By Developers, For Developers

Historical errata for Metaprogramming Ruby

PDF PgPaper PgTypeDescriptionFixed onComments
13TYPO

> Then I went asked the class for a list of its instance methods

Extra “went” or missing “and” before asked.

2009-07-16Fixed. Thanks.
25ERROR

The ISBN format is actually less obvious than the book implies. I’ll have to change the example (reported by Jeremy Sydick).

2009-07-26
100ERROR

The description of instance_eval() is confusing. Clarify that it just changes self. (reported by Ola Bini).

2009-07-26
28ERROR

If Numeric.money() is defined as Money.new(self*100), then 10000.to_money() should be $10,000.00, not $100.00 as stated.

2009-07-16I should have specified that the number you pass to Money.new() (and the number it stores internally) is actually the number of US *cents*, not dollars. I changed the example to make that behavior more obvious. \n
53ERROR

The Quiz Solution says:
You can ask Ruby itself for the ancestors chain of Book:
b = Book.new
b.print_to_screen

shouldn’t the last line be ‘b.class.ancestors’ or
‘Book.ancestors’?

2009-07-16Whoops. Fixed!
34SUGGEST

Throughout the PDF I come across:

Class’

as the possessive of Class. The s at the end of a Class is not a plural s so the correct possessive is:

Class’s

There’s a growing tendency to apply the “s-apostrophe” rule to all words ending in s and not just those with a plural s, but it jars. The best rule of thumb is to ask yourself, “What would I say out loud?” I’ve never heard anyone say “Class’” as the possessive of “Class” - it’s always “Class’s” - hence that’s the best spelling to use.

There’s quite a good article about this on Wikipedia if you want more information. Don’t be afraid of s-apostrophe-s.

2009-07-21The copy editor might decide to change this before the final printing. Until then, I agree with your suggestion, and so does Jill (the editor). I changed possessives everywhere to use s-apostrophe-s. Thank you.
52OK

Code snippets being interrupted by the inset boxes is (mildly) annoying.

2009-07-18I marked this as "not a problem" (even if it is, especially if you want to copy/paste code from the PDF), because typesetting is an expensive operation, and it will be done once and for all when the book is out of beta. During the beta period the book is always changing, so we just take whatever layout comes from the automatic build. Thank you for your patience. :)
1OK

Pictures are missing from the epub version.

2009-07-18It works with Adobe Digital Editions reader on my Mac. The Stanza desktop reader seems to make a bit of a mess of it, though. I marked it as "not a problem" for now. Can you please provide more info? System, reader, which pictures are missing (if not all of them), and so on.
13TYPO

“Then I went asked the class for a list of its instance methods.”

I think there should be an ‘and’ between ‘went’ and ‘asked’ or delete the ‘went’.

Proposal:
“Then I asked the class for a list of its instance methods.”

2009-07-18Fixed.
83TYPO

‘Egiptology’ should be ‘Egyptology’.

2009-07-18Fixed.
0OK

I think that is a good idea to add the cool technique of methods that return dynamic class instances, like Camping does in routing, working with examples like:

class MyClass < Other ‘something’
end

Only a few people know about it, and I realize that this will be good if it’s exposed on this book

2009-07-18It's already in - on page 187 ("The Camping Example"). I even used the same example you suggested. ;) \nThis idiom doesn't seem to be common enough to deserve its own name, so I considered it a special case of Mimic Method. The sidebar "Delegates", on page 75, contains another example that is both a Mimic Method and a Kernel Method. I changed the text for the next beta to stress the first rather than the second.
0ERROR

re: missing pictures in epub version. reader is stanza 1.9 on iphone OS 3. None of the pictures shows, at least until end of chapter 4 (starting chap 5 soon…great book so far btw)

2009-08-04Fixed (with a workaround to a bug in the latest Stanza)
66ERROR

The description in the “Privacy Matters” blurb about Ruby 1.9’s behaviour of private methods is incorrect. Object#send() was not modified to disallow message passing to private methods in 1.9— furthermore, there is no method #send!() defined in Ruby 1.9.1.

2009-07-19The sidebar wasn't updated to 1.9.1. As far as errata go, this one was a biggie - thanks! \n(By now, you could write an entire paragraph about the history of send() in Ruby: __send()__, funcall(), send!(), __send!__(), the new public_send(), ...).
71TYPO

“rows_with(:country)()” appears to have an extraneous pair of parentheses at the end (probably should be just “rows_with(:country)”).

2009-07-18Fixed.
76ERROR

In the definition of method_missing, shouldn’t there be a “return” before “super”?

2009-07-19The super throws an error, so there is no need for a "return". That line does look strange, though, and you might consider it bad form. I think the lack of "return" is an acceptable shortcut, and it makes the intention of the code more explicit. However, I changed the text to explain the missing "return".
83TYPO

“ornitology” should be “ornithology”

2009-07-19Fixed. This thing with "-ology" words is getting embarrassing. :)
32TYPO

You write:

" You can think of instance variables
and their values as keys and values in a hash."

I think you meant to say the name of the variable would be used as the key.

2009-07-19Right, badly phrased sentence. Now it's: "You can think of the names and values of instance variables as keys and values in a hash."
174TYPO

“How can a mixin like CacheMixin bend the rules and define class method on the class that includes it?”

should be

“How can a mixin like CacheMixin bend the rules and define class methods on the class that includes it?”

2009-07-20Fixed.
189TYPO

a =|| []

should be

a ||= []

2009-07-20Ouch. Fixed.
62SUGGEST

The sidebar about symbols doesn’t mention that Ruby recognizes symbols faster than strings. While this is not essential I think it’s valid enough to mention in a symbols vs. strings argument.

2009-07-20I added this sentence: "Also, some operation (like comparisons) are faster on symbols than they are on strings."
136TYPO

class’ should be class’s

2009-07-21Fixed (see above).
173SUGGEST

The name ‘base’ in the code example is misleading to me - I’d expect ‘base’ to refer to the superclass String, not the subclass MyString.

2009-07-22For historical reasons, that argument is usually called "base" - but I agree it's misleading. I changed it to "subclass".
99TYPO

Last sentence under “Scope Wrap-Up”. “This a Flat Scope (99), the basic closure-related spell.”
Should this be “This is a Flat Scope…”?

2009-07-24Fixed. Thanks.
24TYPO

“Delving into the the Object Model, at the very heart of Ruby, …” - I think there is an extra “the”.

2009-07-24How strange that this one got unnoticed until now... Fixed.
124TYPO

test_class should be time_class

2009-07-24Fixed - thanks.
170TYPO

Top of the page:
Appears to be no space between “and” and “eval()free" looks like ”andeval()-free", but copy & paste shows a space there…

PS. Loving this book - exactly what I’ve needed to really ‘grok’ Ruby - thanks!

2009-07-24This one appears to be a problem with the build process. I removed the italicized "and" to make it look right. \nThank you for your comment. :)
77TYPO

Just under the paragraph:
“Now Computer#respond_to?( ) knows about Ghost Methods:
cmp.respond_to?(:mouse) # => true”
there is a “require ‘unit_test’ ” line that don’t really belong here, I think.

2009-07-26Fixed. Thanks.
92SUGGEST

The use of the first x variable (in my_method) is not really clear, as it’s not used at all. I understand that the goal is just to tell that the block will use the x defined outside of the method, and not inside, but I don’t really find it convincing. Maybe it would be better to use the “method” x inside the yield, like “yield(x)” ? Or maybe using back the result of the yield? Or maybe, doing a diagram showing the execution inside the method, and thus really showing clearly that the x used is the one defined outside? Just a suggestion, of course.

2009-08-09I didn't want to make the example more complex. Instead, I changed the values of the variables to stress the "which x is accessed?" point, and then explicitly specified that the x in the method is not used at all.
94SUGGEST

I don’t find the example of local variable name overwriting by block variable very convincing. A note or a diagram should maybe be made to indicate that naming the block argument ‘x’ is like passing the local variable x as the arg to the block, and then calling “yield(2)” just put 2 in x, thus the result with the local variable. I understand the example, but don’t find it crystal clear. Just a suggestion of course.

2009-08-09Clarified, I hope.
95TYPO

Sorry about that, but again, I don’t find your example crystal clear. It’s really easy to understand it wrong. Maybe it would be better for this whole paragraph to use kind of “scope” diagram, indicating what’s the scope (which variables are defined, what are their values, where were they defined, etc.), for pertinent lines of code. A bit like the “hierachy” object and classes diagrams that you used in Chapter one or that Dave Thomas used in its Ruby Metaprogramming screencasts (insert free ads here). Just simple square boxes diagrams will do, and I think it will greatly help to understand all this. Just a suggestion of course.

2009-08-12I simplified the example and reviewed it in the following discussion of Scope Gates. I think it's much better now (thanks for the suggestion). If you still find it lacking, please be free to open another erratum.
110SUGGEST

The list of Callable Objects (Blocks, Procs, Lambda, Methods) may be better at the start of the section 3.5 (Callable objects). It would be easier to follow the list of descriptions of all callable objects. Also, it may be better to subdivise it into a main list (Blocks, Procs, Methods) and then a sublist for Procs (regular procs and lambda) and then finally describe all the way to create a Proc (Proc.new, lambda(), proc(), &block, ->(x) {}, to_proc()). Once all those information are given, like a outline, it will be easier to follow the rest of the chapter, which is a list of description of all those objects. Just a suggestion of course.

2009-08-09Good suggestion. I'll try it out.
123SUGGEST

Concerning the last example of “Class Variables”, I think it should be noted why it is the case (overwriting @v). In particular, this would explain why there is overwriting when the class var is defined in the top level, but NOT in a containing class: class MyClass1 v = 1 class MyClass2 v = 2 end @v # => 1
end

So in fact, the surprise overwriting happens only if @@v is defined in the top level, that is in Object (And Object being the superclass of everyclass…). Just a suggestion, of course.

2009-08-10I explained the example, and I chickened out of explaining all the other problems related to class variables.
124ERROR

I don’t think that your example of use of class_eval is pertinent. In fact, you’re not using the fact that class_eval is redefining the current class, you’re just using the fact that class_eval is redefining self, just like instance_eval. Indeed, one can change class_eval with instance_eval in the example and the example is working exactly the same. It’s not a problem to show an example where class_eval can do the same thing than instance_eval, but it’s a bit of a problem when you introduced class_eval as able to do different things than instance_eval. At least, you should mention that here, class_eval is not used for its current class changing capacity, but only for its self changing capacity, and that instance_eval can do exactly the same thing.

2009-08-10Thank you for this - in hindsight, the example was very confusing. I changed class_eval to instance_eval in the code. It's less in theme with the chapter, but it makes the code's intention clearer.
120ERROR

“While instance_eval( ) only changes self, class_eval( ) changes both self and
the current class.” This is not exactly true. instance_eval ALSO change the current class, just not the same way than class_eval(). Instance_eval change the current class not to be the receiver, but the eigenclass of the receiver. Even if the eigenclass is not yet defined at this point in the book, I think at least a footnote should be put to inform the reader about this. I think also that a sidebar, when talking about eigenclass, about instance_eval changing current class to the eigenclass of the receiver, would be a good thing, if only for completeness.

2009-08-12Fixed. That resulted in a footnote and a couple of new sidebars. Thanks.
127TYPO

In the second example: “def s.title? ” I think this “s” came from nowhere, and is never again used.
I think the singleton method “title?” should be defined AFTER paragraph is defined, and on it, so that it can be passed to index.

2009-08-09Fixed. Thanks.
140SUGGEST

In figure 4.5, I think the “go to right” link shouldn’t be called “Eigenclass” but “class”, as it’s the SAME link and same mechanism, be it a regular class or a eigenclass. Moreover, it’s more consistent with preceding figures (like figure 4.3).
Then, the “Class” class is missing from figure 4.5, which will:

- make the link with figures 1.4 and 1.5
- make the link with first solution described next page (putting class attributes in Class class).

2009-08-09I addressed the first problem by changing the picture. I tried to address the second problem as well, but I think that my explanation only made things more confusing (do eigenclasses have eigenclasses? and so on), so I left it as it is.
142SUGGEST

I think that two figures would be very much helpful to explain the class attribute example. One would be with attr defined “classically” (class MyClass; attr_accessor :my_attribute; end), the other one would be with attr defined at the class level, in the eigenclass. For each case, the figure will describe the place of the methods and the call path (go to right, then up). It will be good to see the difference between the two (in fact, just a switch on the right). Just a suggestion.

2009-08-12Fixed. I managed to do that in a single figure by changing the example.
143OK

A figure for each example code (Class Extension and Object Extension) would be very much welcome I think. Just a suggestion.

2009-08-12I'm not sure about this. It seems like overkill. I'll skip it for now, but I'll be ready to get back to it if other readers ask for it.
144DEFER

To finish section 4.5, just before going to aliases, I think it could be good to have a full-page figure of a full complete object model, with an object, its eigen class, its eigenclass module (Object extension), then its class, a module, a superclass, a superclass module, and Object, and then, to the right, the classes eigenclasses, and then some modules over those eigenclasses (Class extension), and then Class, Module, and back to Object.
The idea is to get an object model as complete as possible, with every cases, and especially every cases seen until there in the whole book. Just a suggestion.

2009-12-07I don't want to make that chapter longer - it's long enough as it is. A catch-all example is a good idea, but I'd have to think how to present it, and how to integrate it into the narrative. I'll leave this suggestion around for a next edition of the book.
156SUGGEST

Code colouring of the eval string in the Capistrano map.each block is wrong: some of the eval string appears green as if its a comment.

2009-08-09There is no obvious way to fix this with the current tools (one option might be to disable syntax coloring on this example, but I don't like the idea). I hope to have it fixed during the final typesetting before the release. Thanks for the report.
159SUGGEST

Code colouring is wrong in the nested irb example.

2009-08-13Still broken. It's a problem (more of a feature, actually) of the book build tools. We'll try to fix this just before going to print.
165SUGGEST

Suggest you use instead of tags in your eRB HTML.

2009-07-30Done. Thanks.
186SUGGEST

Last paragraph second sentence reads better as “It not only contains class methods that do important stuff like opening database connections—it’s also the base class of all mapped classes like Duck:”

2009-07-31I changed to sentence to: "Not only does it carry class methods that do important stuff like opening database connections-It's also the base class of all mapped classes, such as Duck:". Maybe it's just me, but "contains" feels somewhat ambiguous, because the class methods are not really contained by the class-they're in the eigenclass. "Carry" is more abstract, so I like it more. Also, "like" seems to imply that Duck is similar to the mapped classes, but actually it it *is* a mapped class. This kind of precision feels nitpicky to some people, authors included-but the Prags do recommend it.
186TYPO

“the MVC component that contains domain objects and logics.”

I would use the singular ‘logic’.

2009-07-31Fixed.
186TYPO

“ActiveRecord::Base is the most important class in ActiveRecord. Not only
it carries class methods that do…”

- shouldn’t this be “…not only DOES it…”?

2009-07-31Ouch. Fixed.
188SUGGEST

some_duck = Duck.find(:first)
my_duck.id # => 1
some_duck.name # => “Donald”
some_duck.delete

Why is this my_duck.id and not some_duck.id? Aren’t you trying to show how the data is called back from the db?

2009-07-31Whoops - fixed.
195TYPO

“No Java coder in her right mind …”

- I think the unisex adjective ‘their’ would be a little more appropriate here?

2009-08-09I reverted back to the original "his or her" instead. Thanks.
193ERROR

The code from alias_method_chain was edited improperly to make it fit on the page, resulting in an error in the lines that assign with_method and without_method

2009-08-05
16TYPO

Footnote 2 contains an extraneous closing parenthesis.

2009-08-04Fixed. Thanks.
28TYPO

In the callout box “Where Should You Put Your Methods?”, the reference to page 29 for Open Class should be 26 (as the first reference in that box already is). Also, the reference for Singleton Method is page 128; it should be 127 (but the link correctly goes to page 127).

2009-08-09I tried to make this more clear in the Introduction: "The number in parentheses is the page where the spell receives a name." We'll consider pointing to the paragraph where the spell is introduced instead, but I'm not sure that would work better.
70TYPO

Footnote nr. 6 at page 70
“See the sidebar on page 65. The sidebar also explains why in Ruby 1.9, you have to use send!( ) instead of send( ).”

The sidebar say about “send” and “public_send”. I think the footnote could be erased.

2009-08-09I left the footnote, but it just points to the sidebar and nothing else. Thanks.
42TYPO

module Text

  1. …
    That’s where the problem lies: Since Text is already the name of a module
    in Bookworm, Ruby complains that it can’t also be the name of a
    class at the same time.

Text is a module in ActionMailer (format.rb), not in Bookworm, where’s a class.

2009-08-12Fixed.
35TYPO

I think from the following the second ‘instance’ can be erased. So:

An object’s instance variables live in the object itself,
and an object’s instance methods live in the object’s class.

will become:

An object’s instance variables live in the object itself,
and an object’s methods live in the object’s class.

:-)

2009-08-13Fixed.
33TYPO

In the “Is Monkeypatching Evil?” sidebar the final sentence reads “Finally, you can apply techniques such as that described in the (as yet) unwritten sb.rakeAndMonkeypatching to minimize your chances of catching a Monkeypatching bug”

I suspect you meant either “to maximize your changes of catching a Monkeypatching bug,” or “to minimize your changes of causing a Monkeypatching bug.”

2009-08-21Fixed ("[...] to minimize your chances of tripping over a Monkeypatching bug.")
120SUGGEST

The redflag.rb script (An Even Better DSL) doesn’t work in ruby 1.8 (I don’t think passing ‘&block’ style args to a block is supported). Should this compatibility issue be flagged?

2009-08-21It works in 1.8.7, but I added a footnote for people using older versions. Thanks.
95TYPO

Last para. : […] where the block pick up its bindings.
< should be “picks” ?

This is a magnificent and readable book and I love getting
fully immersed into each subject! P.S. PLEASE KEEP the
lovely hand-crafted line drawings!

2009-08-26Fixed - and thank you so much! :)
96TYPO

[…]" a computer scientists would say " < sing. scientist ?

2009-08-26Fixed.
115TYPO

3rd para. “… basically, whenever one of many different things happen.” <- ? one .. “happens.” [nitty, I know]

2009-08-27Not nitty at all... Fixed.
49TYPO

In the second paragraph:
As he draws Figure 1.7, Bills also explains …
Since I’m not so good at English, I do not understand why “Bill” is plural in this context. I think “Bill” does not need to be plural. Sorry, if I’m wrong.

2009-08-31It was *my* English, not yours... ;) \nFixed - thank you.
103OK

“— that’s what the define_methods() method is for.” <- sing. ‘define_method()’ ?

2009-09-10
103OK

Paolo .. my mistake .. define_methods() is not a typo. You can erase my noise if you wish. Thanks for a great book!

2009-09-10Thank you, John! Keep the noise coming - I like to get errata. ;)
119OK

Obi-Wan would say it more like this:
“Global variables in disguise, those top–level instance variables are like. Get rid of them, why don’t you?”

2009-09-11Steve, that's Yoda-speak, not Obi-Wan-speak! Such a blunder would get you thrown out of any righteous geek's home. ;D \n
109SUGGEST

When I run this code, Ruby 1.9.1 returns an array, not the puts result in the first highline example.
Return value:
[“puts \\”You’re friends with \\#{friends.inspect}\\“Tom”, “Jane”, “Ricky”]

2009-09-18See #40717
243ERROR

When running the Code Processor example, I get his error using Ruby 1.9.1:

TypeError: can’t convert String into Integer
from (irb):44:in `read’
from (irb):44
from /usr/local/bin/irb:12:in `

’

2009-09-15Fixed. Thanks, Steve.
109TYPO

I found the problem. The “puts” line has to be executed after the “Friends?” prompt. When I cut and paste all 3 lines, the puts line doesn’t execute as expected. Perhaps moving the puts line to be after the “Friends?” prompt might work better, if users are cutting and pasting example code.

BTW, this is one great book. Your examples all are very consise and directed to a particular point, without a lot of embellishment. And sorry for my Yoda/Obi Wan mixup. “A brain fart, it must have been.”

2009-09-18Thanks for the compliments, Steve. :) \nThe problem in this case is that the program has to be executed as a whole, not copy-pasted into irb. If you copy-paste it, then the "puts" line becomes an input to the "ask" line. \nI don't want to say this explicitly, becomes it might end up confusing the example. Instead, I changed the wording slightly to suggest the right way to use the program: "Here’s a Ruby program that lets you input a comma–separated list of friends".
126TYPO

“If all you want is change self,”

This might be better:

“If all you want is to change self,”

2009-09-12Fixed.
157TYPO

Ruby 1.9.1 - I get this same error in both irb and "ruby -e broken_math.rb’

/usr/lib/ruby/gems/…/gems/test-unit-2.0.3/lib/test/unit/autorunner.rb:274:in `block in keyword_display’: undefined method `[]’ for nil:NilClass (NoMethodError)

The Around Alias works fine for the FixNum class, but the test code blows up. Am I missing something?

2009-09-18See #40752.
218TYPO

“wether” should be “whether”

2009-09-12Fixed.
219TYPO

“After reading though this book,”
change to:
“After reading through this book,”

2009-09-12Fixed.
239TYPO

3rd paragraph in it says: " It’s easier to adapt
Ruby to your own needs that it is to adapt Java"

“that” should be “than”

2009-09-15Fixed.
243SUGGEST

Steve’s report #40716 might be about a technical error : the
File.readlines method works as advertised here. My tiny 2c.

2009-09-15Thanks, John.
147SUGGEST

Rule 6 at the bottom of the page is slightly incomplete. “The superclass of the eigenclass of a class is the eigenclass of the class’s superclass” does not apply to #BasicObject, since BasicObject does not have a superclass. In fact, the superclass of #BasicObject is Class (which makes sense, because the object is, after all, an instance of Class).

While adding this detail makes rule 6 complete, it may also make it hopelessly confusing.

2009-09-18Ouch, Ken. You're right on both counts - this is an exception to the rule, and it does make the rule even more confusing (I'd also have to specify that the same happens with Object in Ruby pre-1.9). I tried adding a footnote, but in the end I found it broke the flow of the rules - rule 6 is already complex enough as it is. After some consideration, I think that I'll just skip this particular exception and leave the text as it is, on the assumption that a reader who wants to find out what happens with the root class will immediately get an answer from irb.
157SUGGEST

Re: Steve’s report #40719 .. I suspect that the test-unit
gem may be the trouble. If I use the ‘test/unit’ that ships
with Ruby 1.9.1 (on linux) I have success for the broken_math.rb test.

2009-09-18I added a footnote for this. Thanks, Steve and John!
102TYPO

On the last line but 4:
For short, you can this spell a Flat Scope.

I guess this should be:
For short, you call this spell a Flat Scope.

2009-09-19Fixed. Thanks.
150TYPO

First line:

Bill decides it’s time time for a story:

Duplicated words ‘time’.

2009-09-22Fixed. Thanks
69TYPO

How? By getting get rid of all the define_component( ) methods.

should read:

How? By getting rid of all the define_component( ) methods.

2009-09-27Fixed. Thanks.
149SUGGEST

I think that the diagram 4.6 on page 149, although technically correct, miss the point to be made. It’s true that the class of #MyClass is a Class, but that’s not what’s important, because methods in the class of the eigenclass can only be called if you call directly the eigenclass (only ONE step to the right at a time).
What’s important here is that the SUPERCLASS of the eigenclass #MyClass is Class! Then, it means that if you call a class method on MyClass, then it will search FIRST in the eigenclass (one step to the right) THEN in the Class (one step up). And then, this explains WHY the preceding code (using the b var) was working before, but why it was a bad code (as b is then defined for all classes).

I think that this whole point is also missed in the diagram 4.5, page 146. The footnote talk about being a completist and adding Kernel and BasicObject. But I thik that what’s really missing is the Class and Module classes, on the top of #Object, on the top right. This way, it would be coherent and explaining both diagram 4.2 (page 139) and diagrams done in the first chapter (1.2 page 37, 1.4 page 44 and 1.5 page 45).

I think it’s important NOT to forget the ‘standard’ place of Class with eigenclass, that is as the “class” of any class object, even if the class object has eigenclass. Also, this would show that the eigenclass of the superclass of a class object are put on top of the class object own eigenclass, but still always UNDER the Class object. Without this, there’s a link missing between model in the first chapter (the class hierarchy of a class object is Class -> Module), and the model in the fifth chapter (the class hierarchy of a class object is a hierarchy of its own and its superclass eigenclass).

Not sure that what I wrote is crystal clear, I hope that you will still understand what I mean :)

2009-10-10Touché! This one wins my personal prize for best erratum this month. :) \nI drew a new diagram to replace 4.6, I changed the text to remark the fact that Class sits above all eigenclasses (and that explains why defining an attribute on Class kinda works), and I also changed the text for diagram 4.2 to explain that it stops shy of going higher up the chain. I hope things are clearer now. I didn't get any more detailed than that, though - this is already an extremely long and complex chapter, and I don't want to make it even more of a struggle. As long as the readers have all the elements they need to understand corner cases, I'll be OK with it - and now that I addressed your remark, I think they do have those elements.
146TYPO

“Bill tries to sums it all up”
Should be:
“Bill tries to sum it all up”

2009-10-06Fixed - thanks.
73SUGGEST

Description for the table example:
(That’s why there is no return before super: Nothing is ever returned).

Even if super returns a value, that would be fine, because the last expression is used by ruby as the default value. I think that the description about the missing “return” is a bit confusing

Example:

class Test

def does_nothing
“does nothing from Test”
end
end

class MyTest < Test

def does_nothing
var = “text from Mytest”
super
end
end

puts MyTest.new.does_nothing # => does nothing from Test

2009-10-06You wouldn't believe it, but I'd already fixed this right after the beta release. :)
15OK

Out of curiosity, does Bob’s middle names include DROP TABLE Students?

2009-10-10Is that a polite way to say that you got rubbed the wrong way by Bob's little lectures? :) \n(Please reply by opening another issue)
24ERROR

You may want to change the link for online ruby to a newer site - the old web site seems to be one of the casualties from _why’s disappearance.

2009-10-10Yet another reason to miss _why. I see that TryRuby has a new home now. I updated the link. Thanks, Andrew.
26TYPO

Are you sure you mean last-generation monitor, or do you mean latest-generation monitor?

2009-10-10Ehm, I hope this isn't going to be the last generation. Fixed.
15OK

I’m referring to the XKCD comic “Exploits of a Mom”, which featured Robert’); DROP TABLE Students;— . (The code on page 15 is SQL injection-unsafe, isn’t it?) I just found the coincidence in first names (Robert vs Bob) interesting. Also, thanks for the prompt replies to errata!

2009-10-10I read XKCD on a random basis, and I missed that one. Thanks for the laugh! \nI talk about SQL injection in the "Code that writes code" chapter. I think it's OK to keep this code injection-prone - it's supposed to be a beginner's faux pas anyway.
152ERROR

In the following code:

module MyModule
def my_method; ‘hello’ ; end
end

obj = Object.new
obj.extend MyModule
obj.my_method # => “my_method”

class MyClass
extend MyModule
end

MyClass.my_method # => “my_method”

The two invocations of my_method should probably resolve to “hello” as opposed to “my_method” unless I’ve misunderstood the example badly.

2009-10-15Fixed. Thanks.
162TYPO

At the risk of being extremely pedantic, the “ctcw” in “ctcw/simple_eval.rb” (and elsewhere in the chapter) should be “ctwc”.

2009-10-26Hey, we're programmers - we're supposed to be pedantic! :) \nFixed - thanks.
173OK

Is “klass” a more common variable name than “clazz”?

2009-10-26I've seen both used. You're right that "klass" is probably more common, but I prefer to stick with "clazz" just because it's the convention used in the Rails source.
168ERROR

In the second paragraph, the one that follows the loop code, it says that “The infinite loop on the last line collects strings from the standard output…”. That should be “…from the standard input…”.

2009-10-26Thanks. Fixed.
96SUGGEST

In the description of closures, the use of the variable name x in both the method and the local scope along with:

Still, the code in the block sees the x that was around when the block was defined, not the method’s x, that is not used at all.

could be understood to mean that the local variable is taking precedence over the one in the method, when in fact, the x in the method is not available at all.

I suggest:

Still, the code in the block sees the x that was around when the block was defined, not the method’s x, which is not available at all to the block.

Or perhaps another example that shows the error you would get if you tried to refer to a variable in the method, within the block.

2009-10-29Fixed. Thanks.
95SUGGEST

I think the code splitting across the page in this example is particularly troublesome as it tends to obscure the fact that variable x is defined in two different scopes (the split being immediately after the assignment to x), and programmers with no fp experience may not notice the subtlety of the example.

2009-11-02I notified the typesetter about this. Thanks.
253OK

I tend to disagree with the difference between programming, metaprogramming and DSL. As an old Lisp hack, we almost always “build the language we need to solve the problem at hand”. Put another way, we create a simple, clean syntax that expresses the problem. In some cases this syntax may be more verbose than the host language. There is nothing unusual or special about doing this, except that not many people do it today, few languages support this style of coding.

Ruby supports much of what Lisp can do and therefore metaprogramming and DSLs are really nothing more than using Ruby (or Lisp) properly. I expect (hope) that in a few years the term DSL dies; because not using core language features, where it is necessary, is considered poor style, just as not abstracting interfaces in OO is today.

2009-11-02Paul, I actually share your opinions. Matter of fact, though, most coders don't think of coding as an activity that's akin to inventing languages - Instead, they think of the language they're using as something static, out of their control and entirely separated from their programs. That's why this coarse distinction between "regular programming", "metaprogramming" and "Internal DSLs" is useful IMHO: it helps communicate to people who don't look at programming "the LISP way". At the end of Part 2, I attempted to blur the line between "regular programming" and "metaprogramming". Like you, I hope that all these byzantine distinctions will gradually fade away over time, but I'm not holding my breath. :)
152TYPO

Incorrect usage of the term fluke. “Bookworm itself should log this fluke and proceed.”

2009-11-02Replaced with "problem". Thanks.
160OK

In footnote 2, the sentence is cut off: (collected and …?

2009-11-01Hello, Paul. Please see your related item about page 165.
165OK

Ok, can now see the problem, footnotes are flowing between pages. Footnote 6 has very odd justification/word spacing.

2009-11-01This is a typesetting issue. Since typesetting is the very last thing that gets done before the book goes to the printers, I think that this will be fixed, so I marked this as "not a problem". Thanks.
180OK

Last line on page extends beyond body text into the right margin:…), or method_undefined( ):12

2009-11-02Typesetting issue - will be fixed after beta. Thanks.
49SUGGEST

any chance of mentioning Object vs BasicObject (1.8 vs 1.9) in figure 1.7?

2009-11-17Fixed.
229TYPO

First paragraph:

“Now look at self_test_assigns( ).”

should be

“Now look at set_test_assigns( ).”

Then again in the second paragraph:

“Then self_test_assigns( ) iterates…”

should be

“Then set_test_assigns( ) iterates…”

2009-11-04Fixed. Thanks.
243ERROR

I am not sure of Ruby 1.8 but:

“…and it has to be the last argument in
the method (not considering the final “block” argument)."

is incorrect in Ruby 1.9. You can put the argument array wherever you want. You just may get an empty array as it will be filled last.

2009-11-17I'd missed this change in Ruby 1.9. Thank you.
33ERROR

Monday: The Object Model >> Open Classes >> The Money example
There’s a code that says that “standard_price = 10000.to_money()” is equal to 100.00 US Dollars but later in the same text, the method Numeric#to_money is defined as “Money.new(self*100)”. Wouldn’t 10000.to_money be 10000.00 US Dollars then?

2009-12-07Fixed. Thanks!
71OK

“You open an irb session and smoke-test the new Computer.”
It won’t run because we haven’t defined a file DS (or an in-memory string replacement for it). I suggest creating one making it downloadable by clicking on a link.

2009-12-07You can use the same downloadable mock-up of DS that was defined at the beginning of section "The Legacy System". I tried adding a footnote that references it, but then I removed because it actually confused things. \nIt's a bit of a catch-22: The source code in this chapter is a tad complicated, because there are so many versions of the same Computer class, tests, and so on. I assume that people who want to try out the code, will make sense of it just by looking at the folder that contains it. Explaining these details in print can be counter-productive.
111TYPO

The two sentences seem inconsistent:
" The real mean of the & is: “This is a Proc that I want to use as a blcok.” Just drop the &, and you’ll be left with a Proc:"
Would seem consistent to say “Just drop the &, and you’ll be left with a block.”(implicitly the block that the previous sentence says you wanted_.
Or change the first sentence to read: “This real meaning of & is ”This is a block that I want to use as a Proc. Do so; drop the & and you’ll be left with a Proc."

2009-12-07Actually, I really meant what I wrote, as in: "the_proc is a Proc. If I prefix it with an ampersand (&the_proc), it becomes a block. If I drop the ampersand again (the_proc), I'm left with a Proc again. I know that's confusing, but I found no clearer way to express it. I added an "again" at the end of the second sentence in hope to clarify it a bit more.
117DEFER

The section on callable objects needs to be expanded to motivate the distinctions the language makes between procs, lambdas, blocks and methods. Having Bill say " Good luck finding a use for this exotic stuff" doesn’t help. I suggest that the author have a deeper discussion with the language designer about the rationale for the differences, and construct realistic examples of where you might want to use each.

2009-12-07This is a far-ranging suggestion, so I moved it to the "To be considered" for the next edition. (BTW, I suspect that most differences between procs and lambdas have historical reasons).
41OK

In section 1.3 you learned that … a class is just a module with a couple of additional features ( a superclass and a new() method).
In ruby 1.9 at least, Module has a superclass: Object
puts “#{Module.superclass}” # Object

2009-11-23(See report for page 39)
39OK

“So, a class is just a souped-up module with three additional methods—new(), allocate(), and superclass().”
At least in Ruby 1.9 Module supports the method superclass(). The superclass of Module is Object.

2009-11-23(See below)
39OK

Please withdraw earlier erratum report, on this page and later reference to it.
‘Module.superclass’ returns Object, but only because the class of Module is Class, and Class defines the method ‘superclass()’ as your text says.

2009-11-23OK, thanks!
130SUGGEST

“To prove that all his theory
can come very useful, Bill shows you a trick called class instance
variables.” Text then goes off to describe class-level instance variables for next 3 pages. It is unclear what (if anything) these have to do with the class_eval() method Bill was describing.

2009-12-07By "all [t]his theory", I meant all the points above. I changed the sentence to "To prove that all this theory about the current class can come very useful, [...]". Thanks.
152OK

“The superclass of #BasicObject is … Class. This fact explains why you can call MyClass#b() and MyClass#b=().”
Two issues: There has been no mention of MyClass#b(); did you mean MyClass#c()?
Second: I may be slow but it was not clear to my why the fact that class Class was the superclass of #BasicObject made these method calls possible. Is it that class Class makes ALL calls possible? Perhaps a bit more detailed unraveling.

2009-12-01See below.
152DEFER

Sorry. Withdraw the previous errata report also. You did mean MyClass#b — that was the method that was defined on class Class in an overly powerful attempt to define getters and setters for a class-level attribute. It still might be interesting in rev 2.0 to talk a bit about the very top of the class hierarchy — the fact that both the superclass and the class of #BasicObject are Class.

2009-12-07Thanks, Thomas. I'll consider it.
181SUGGEST

You might want to note that in the test suite for step 3 you had to drop the test cases for nil and false that were present in the test suite for step 2. The ‘>=’ method used in the validation block is not defined on either nil:NilClass or false:FalseClass.

2009-12-07I added: "Bill replaces the two test cases that checked for nil or false attributes with a single new test case" Thanks.
181ERROR

In step 4(a) — when the method attr_checked is just defined on class Class — avoid name clash by using ‘value’ or ‘v’ in the block associated with attr_checked in Person rather than ‘val’
class Person
attr_checked: age do |value|
value >= 18
end
end

2009-12-07Good idea. Thanks.
184SUGGEST

“How can a mixin like CacheMixin bend the rules and define class methods on the class that includes it?” I got the how. But when I started reading this section I had an antecedent question: Why do this? Why not simply extend Person with a module that defines the method attr_checked? And when I had finished this section 5 pages later, I was left with the same question. You need to motivate this trickery. Pick and example where the straightforward thing won’t work, and explain why you’ve moved to fancier trickery. Simple solution:
require ‘test/unit’

module CheckedAttributes

def attr_checked(attribute, &validation)
define_method “#{attribute}=” do |val|
raise ‘Invalid attribute’ unless validation.call(val)
instance_variable_set(“#{attribute}", val) end define_method "#{attribute}" do instance_variable_get("#{attribute}”)
end
end

end # module CheckedAttributes

class Person
extend CheckedAttributes
attr_checked :age do |value|
value >= 18
end
end

class TestCheckedAttribute < Test::Unit::TestCase

def setup
@bob=Person.new
end

def test_accepts_valid_values
bob.age=20 assert_equal 20, bob.age
end

def test_refuses_invalid_values
assert_raises RuntimeError,‘Invalid attribute’ do
@bob.age=17
end
end

  1. def test_refuses_nil_values # Fails this test with error “undefined method ‘>=’ for nil:NilClass”
  2. assert_raises RuntimeError, ‘Invalid attribute’ do
  3. @bob.age=nil
  4. end
  5. end
  1. def test_refuses_false_values # Fails this test with error “undefined method ‘>=’ for false:FalseClass”
  2. assert_raises RuntimeError,‘Invalid attribute’ do
  3. @bob.age=false
  4. end
  5. end

end # class TestCheckedAttribute

2009-12-07I added a few sentences to the description of Class Extension Mixin (described later) to specify that with this trick, you can get new class methods *and* new instance methods by simply including a single module.
120DEFER

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 that requires the “clean room” approach, e.g.., nothing in those test cases fails if you just put everything at the top level scope:

events = Hash.new setups = []

def event(name, &block)
@events[name] = block
# puts “ALERT: #{name}” if yield
end

def setup(&block)
@setups << block
end

Dir.glob(‘*events.rb’).each do |file|
load file
events.each do |name, event| setups.each { |setup| setup.call }
if event.call
puts “ALERT: #{name}”
end
end
end

I realize that you’ve just discussed things like clean room and instance_eval, so the reader might be inclined to use them, but it would be nice if the tests pushed the reader in that direction.

2013-09-20You'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.
120ERROR

The spec for the Red Flag DSL is “The DSL stills checks events in the order they’re written”. Putting the events in a hash as is done in the given solutions doesn’t ensure that they’ll come out in the specified order if we use “each” like is done in the given solutions, correct?

2009-12-18I removed the reference to the events order. Thanks.
221OK

Highlighting of code in example for find_by_description! is slightly off / misleading. At the end, we have:
result || raise(RecordNotFound, “Couldn’t find #{name} with
#{attributes.to_a.collect {|pair|
”#{pair.first} = #{pair.second}" }.join(‘, ’ )}")

where there is a mix of blue and green text as it appears the ‘#’ are mistakenly taken as comment starters,

2010-01-02There are a few syntax highlighting problems throughout the book. Unfortunately, I have no way to fix them - syntax highlight is applied automatically by the book's build system. I hope that problems like this will be fixed in typesetting, but for now I can only mark it as "not a problem" (even if it is, although minor).
56DEFER

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 subsessions which allow you to change the value of self used by the interpreter. You might also mention that this is a convenient technique for exercising private methods:

irb(main):007:0> s = “abc”
=> “abc”
irb(main):008:0> s.private_methods
=> [“rand”, … ]
irb(main):009:0> s.rand
NoMethodError: private method `rand’ called for abc
\tfrom (irb):9
\tfrom :0
irb(main):010:0> irb s
irb#1(abc):001:0> rand
=> 0.181140548984387

2013-04-16Thanks 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.
55TYPO

You should probably choose a name other than “play_with_self” due to its crude meaning. How about “test_self” or simply “return_self”?

2010-01-02Changed to "testing_self". I must confess that the crude meaning was actually intentional, but OK, I have a childish sense of humor. ;)
31SUGGEST

I have a problem with the heading “Ruby Classes Are Special”. This is actually opposite of what you say in the following paragraph — that classes are NOT special in Ruby. Perhaps the intention was to note that Ruby classes are special from the perspective of other languages. But we already know that if for no reason other than that they’re open. How about “Ruby classes are not special” or “Ruby classes are first-class objects” or something like that.

2010-01-02Changed the title to "Inside Class Definitions". Thanks!
170ERROR

In the sidebar on “Here Documents,” the result is shown as

puts

this is a “multi-line” string
wishing you a great 2010

However, leading spaces in the string are preserved by a here-doc string in Ruby 1.8.7:

puts

this is a “multi-line” string
wishing you a great 2010

2010-01-05That was the intention, but the book's build system munched up the indentation. I indented the two lines differently to show the difference. Thanks.
175DEFER

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 calling instance_eval on an object; p. 122 uses that technique again. I don’t see that happening in the ERB snippet at the top of p. 175. Is this code using a different method of making a clean room? Is the instance of ERB the clean room?

2013-10-03Thanks, 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.
120TYPO

The sentence “The DSL stills checks events in the order…” has a typo. The word “stills” should be “still”

2010-01-08I'd removed that sentence in a previous edit, because it was technically inaccurate - so I guess it's fixed. :)
123DEFER

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 names could collide, silently. I know this is just a sample ( that you quickly replace but it was the first thing that popped into my head and distracted me from the following code for a while ).
- All of the setup blocks are iterated for each event in cleanroom objects, it really doesn’t just remove the “global” nature of the @variables in the setup blocks, it removes their shared nature between events.

2013-09-22I fixed the first point, and clarified the second for the 2nd edition of the book. Thanks.
169OK

A minor formatting issue (and possibly a matter of opinion): Footnote 6, “However, these days…”, looks odd with that much whitespace between the words.

2010-05-06Thanks, Wayne. This is a typesetting issue that I have no control over (and it changes for every medium that the book is compiled for), so I marked it as "not a problem" from my side.
21TYPO

On line 4,

“you’re ready to dive in this book.”

should be

“you’re ready to dive into this book.”

2010-05-06Thanks, James.
44OK

the line: “Module, so a class is also a module.”
I mean: Module is a superclass of Class and it is a class too;
Module is the name of a class not a module.

2010-05-06I fail to see the logic failure. :) Let's review: "(1) a class is an instance of Class; (2) a module is an instance of Module; (3) Class is a subclass of Module => a class is a module". By OOP standards, it seems to hold. (3) is implicit in this paragraph, but it should be self-evident.
72ERROR

line: “of Kernel that every object inherits.”
I mean: Kernel is a module and has no instance_methods;
method_missing resides as a private_instance_method in BasicObject.

2010-05-06Actually, modules do have instance_methods (and private_instance_methods) - just try Kernel.private_instance_methods. However, you're correct that method_missing has moved from a private_instance_method of Kernel to a private_instance_method of BasicObject in Ruby 1.9. I fixed this.
C3p30OK

I think ‘class Txt < Fatty::Format’ should be ‘class Txt < Fatty::Formatter’

2010-05-06Maybe wrong report from another book?
250TYPO

“which prides itself”

succinct is spelled incorrectly

2010-05-06Fixed. Thanks.
190ERROR

at the very bottom of the page, you have ”…generated_methods() returns true…” but I think you want the boolean version of the method ‘generated_methods?()’.

2010-05-06Fixed. Thanks.
243DEFER

Nill Guards do not work well with booleans.
a = false # a gets initialized
….
a ||= true # initialization gets overwritten
Effectively, it guards both against nil and false.
A pitfall that cost me quit some time, once….
Should be explained more clearly, I think.

2013-07-08I added a short section about this. Thank you, Martijn.
35TYPO

… if Bill hadn’t called obj.my_method( ), …

should be

… if Bill hadn’t called obj.my_method, …

He actually calls obj.my_method, not the result of calling obj.my_method.

2010-05-06The convention I use throughout the book is to identify a method by its name followed by parentheses. I agree with you that's a semantic clash between the method itself and the method call (unless the method has arguments), but this is the standard convention in Ruby texts.
52TYPO

Not Found

The requested URL /titles/ppmetr/code/gems/rubygems-update-1.3.3/lib/rubygems.rb was not found on this server.

There are other examples that can’t be downloaded either…

2010-05-07Thank you Martijn - this is a biggie. Actually, all examples in the gems folder were not meant to be downloaded - just referenced. This is a side effect of the build process. I'll look for ways to fix it.
251OK

[1, 2, 5].inject(0, &:+) # => 8

can even be written as

[1, 2, 5].inject(&:+) # => 8

2010-05-06Very neat! I'd leave the current more verbose form in the book, though, because using a default value for the first argument of inject() is orthogonal to the discussion of Symbol to Proc, and I want to focus on that spell rather than on writing the most compact code.
154OK

Quit many (small) code examples extend over two pages.
I think they’d be more readable if they’d been on just one page.

2010-05-06Martijn, as an author I have no control over it - it's a typesetting issue. Our typesetter is aware of the problem, but sometimes splitting a code example (even a small one) wins over leaving a lot of ugly blank space.
155TYPO

In

if load_error.message =~ /#{Regexp.escape path}\\z/ and

everything to the right of the # is accidently marked as comment…

2010-05-06This is a known limitation of the Prags' current Ruby formatter. It's annoying (especially when "eval" is involved), but unavoidable at this stage.
130TYPO

because @time_class( ) is always nil.
->
because time_class( ) is always nil.

2010-05-06
130TYPO

because time_class( ) is always nil. -> because time_class is always nil.

2010-05-06Thanks, Kado.
172TYPO

“eRB” should be “ERB”.
“ERB” is the official name.

2010-05-06
207TYPO

AcriveRecord::Base()
->
AcriveRecord::Base

2010-05-06Fixed this and two other instances of the same typo. :)
211OK

Thus is the description=()
->
This is the description=()

2010-05-06I actually meant "thus". :) The full sentence: "Thus is the description=() method born".
98DEFER

The ‘lambda.call’ solution does not seem to clear the setups and events variables for each new events file, whereas the previous solution on page 97 did.

2013-09-20I 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.
53TYPO

“my_method() is called on obj()”
should be
“my_method() is called on obj”

2010-05-15
25TYPO

tryruby.sophrinix.com. has moved to tryruby.org

2010-05-15
149DEFER

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 eval(). I don’t agree; I’ve only been reading up on Ruby for a month so maybe I’m missing something? Surely the ability to convert a block into a Proc by having a third argument to a method with a preceding ‘&’, and then from this Proc to the block required by find() etc with another, allows this?

def explore_array(method,*args,&block)
[‘a’,‘b’,‘c’].send(method,*args,&block)
end

a = explore_array(:find,[]) do |x|
x 'b' end p (a ‘b’ ? “Book wrong - you can” : “Book right - you can’t”) + " support blocks without eval" # => Book wrong - you can support blocks without eval

Fantastic book either way, it’s almost brought me to an understanding of eigenclases, I’ve got that good brain ache feeling :)

Cheers,

Tim Ruffles

2013-10-03Thank 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.
114TYPO

“The Stubby Lambda” may be “The Stabby Lambda” ?

2010-05-17
154TYPO

“Integer() class” should be “Integer class”

2011-04-15
184TYPO

I think “inclusor” is not a English word. Is it “includer” which includes module (so “include + r”) ???

2011-04-15"Includer" also sounds strange, but at least it's not as clearly made-up as "inclusor". I changed it. Thanks.
203TYPO

“ActiveRecord::Validation” should be “ActiveRecord::Validations”

2011-04-15
213TYPO

“ActiveRecord::Base#respond_to?” should be “ActiveRecord::Base#respond_to?()” according to your convention.

2011-04-15
58TYPO

Bill points out the previous code implicitly calls ancestors() method, but the code says “ancestors # => [Book, Document, Printable, Object, Kernel, BasicObject] ” explicitly.

2011-04-15This is not an error, but the sentence is potentially confusing - it meant to say: "Bill points out that the implicit receiver of ancestors() in the previous code is Book [...]". I changed it to say exactly that. ;)
185ERROR

“On the other hand, if you don’t need to define instance methods on the including class, …”

might be

“On the other hand, if you don’t need to define class methods on the including class, …”

2011-04-15I really meant "instance methods" there. However, the whole sentence (and the following code snippet) is actually misleading, because it results in adding the :x method *both* as a class method and an instance method when you include MyMixin. I ended up removing both the sentence and the code, and connecting this paragraph to the following one. Thanks Kado!
243OK

“In this example, the value to the right happens…” should be “In this example, the value to the left happens” ???

2011-04-15I really meant the R-value. The L-value becomes an empty array only after assignment, and then only if it had a non-false value in the first place.
56OK

In The Top Level sidebar, "because it ‘s the object", space between t and ’.

2011-04-15Unfortunately, I cannot fix this - it's just an artifact of pagesetting, and the original text is OK. Hopefully, it will fix itself in the next printing as the typesetting changes slightly.
195TYPO

In the epub version of the book, there are plenty of inconsistent - vs — vs —- vs actual em dashes. Some of my notes include the nearby words:

high, profile
method, related
donut, induced
stand, alone
kick, start

In some of them (donut-em-induced) a simple ‘-’ should have been used. In others, it’s just inconsistent: stand—alone vs kick-start.

But after a while I stopped keeping track of them, so an audit to find them all probably ought to be done.

2011-04-15I think all of these (and other minor typographic issues) have all been fixed during the last proofreading. We usually don't care about such minor issues until the book gets out of beta, because the text is changing too fast to justify looking at the details. Thanks for reporting anyway, and if you spot one of these in the final book, I'll be grateful if you report it!
184DEFER

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 contortions to make mixins. Ruby provides both include(foo) and extend(foo), and it seems silly to me that the whole point of all the included() hooks is just to turn around and call extend. The thing being extended is calling include! So why doesn’t the API author just say “please call ‘extend BlubberMixin’ to get access to Blubber”?

2013-01-24The 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]
197TYPO

“opening database connections—-It’s also the base class”

s/It’s/it’s/

2011-04-15
206TYPO

“But wait—-There is more”

s/There/there/

2011-04-15
211TYPO

“I’ll go over it with you one piece at the time.”

s/at the time/at a time/

2011-04-15
131TYPO

Class#new() -> Class.new()

2011-04-15This one was difficult to spot. :) Thanks!
1ERROR

Some of the limitations of arguments described in the book are made obsolete by Ruby 1.9 (for example, Array Arguments can be in the middle of other arguments)

2011-04-17
1TYPO

“stubby lambda” vs. “stabby lambda”

2011-04-14
1OK

In the book I say that lambdas are more tolerant than blocks when it comes to arity, but this has been tightened up in Ruby 1.9. Check.

2011-04-17The way I put it in the book is: lambdas are as strict as methods, except for some corner cases. This is still valid, because it doesn't go into the details, and it might well refer to corner cases in Ruby 1.8 only. I'll leave it untouched.
111TYPO

“Hello, Bill!” should be “Hello, Bill”

2011-04-15
120TYPO

“Your main code loads the files that end with event.rb.”
should be
“Your main code loads the files that end with events.rb.”

2011-04-15
1OK

Constant lookup rules in Ruby 1.9 have changed. Check.

2011-04-17This only impacts corner cases like constant references in *_eval() and the block passed to Class.new vs. a regular class definition. Nothing that is quoted in the book.
96TYPO

C# names (like conn.readStuff() and dispose()) should begin with an uppercase character by convention.

2011-04-14
41DEFER

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

2013-04-16(UPDATE: I decided to skip this.) \n \nI 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. \n
65ERROR

The string “respond_to?” is used in a regular expression (twice). Given that ‘?’ is an RE metacharacter, this is asking for a match to either “respond_t” or “respond_to”.

More generally, the RE will match any method name which includes “method_missing” or “respond_t”. It should be tightened up, so that it only matches the desired methods.

2011-04-15Very true. Fixed.
135DEFER

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 alternative formulation which captures a reference to the old method in a variable and uses that in the wrapped call?

2013-09-25Good point, Rich. This will come useful in the second edition.
243ERROR

a ||= []
is the same as
a || (a = [])
but
a = a || []

2011-04-15This is a bit of a pain to explain (David Black did it on http://dablog.rubypal.com/2008/3/25/a-short-circuit-edge-case). I had to change some text around this section to be more correct, and still avoid a lengthy discussion of all edge cases.
1DEFER

From Kado: a comment about “private” on the book:

there is one exception: it’s “setter” method.
“setter” always need “self” as literal.

def setter=(val)
 p val
end
private :Setter=

def getter
 p 123
end
private :getter

self.setter=(123) # => 123
self.getter       # => NoMethodError

2013-07-08Kado, 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!
1TYPO

Note that define_method( ) is executed inside the definition of Computer, […]

It should be define_component().

2011-04-15I actually rewrote the entire paragraph - I found it confusing.
76ERROR

“gem install flickr” at footprint. But flickr gem does not maintenace.
stackoverflow.com/questions/976211/flickr-gem-how-to-access-user-details
So this page flickr example does not work. I do not know what gem is alternative most major flickr wrapper.

2011-04-15You're right, sanemat. That's annoying. I "fixed" it by adding a warning in the footnote that the original gem doesn't work anymore, and pointing readers to a more recent fork of it at https://github.com/ctagg/flickr.
130SUGGEST

Not a big deal, but since Taboo is our family’s favorite game, thought I might correct one portion of the text in section 4.2: In Taboo you are not trying to have your teammate guess a “sentence,” but you have them try to guess a certain “Word” - the person has to get their teammates to guess the ‘word’ without saying any of the taboo words listed on the card.

2011-04-15Fixed. :)
126DEFER

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 made rule 6 clear. The placement of the object Class isn’t mentioned until figure 4.6, which is a page too late (in v1.0).

2013-09-25This 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.
44SUGGEST

Isn’t Pascal cased a better term here? Camel cased normally means mySpecialClass - with “humps” in the middle of the compound word. Pascal case is similar but starts with an initial capital letter.

2011-04-15Some people CallThisCamelCase, others CallItPascalCase. Some other people even CallItUpperCamelCase. I agree that Pascal case is more correct, and thisIsWhatCamelCaseShouldStrictlyLookLike. I changed it. Thanks!
0ERROR

Chap05:

> you can execute code in that scope by using the Binding object in conjunction with eval( ), instance_eval( ), or class_eval( ).

> You can evaluate code in the captured scope by passing the Binding as an additional argument to one of the eval*( ) methods:

Only eval method can accept binding (xxx_eval cannot).

2011-04-17Thanks, Kado. Surprising that this one stood unnoticed so far.
1DEFER

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

2013-06-06
102TYPO

“If you could call a method instead of using the class, ”. It should be “[…] using the class keyword, ”.

2011-04-15
108OK

In the Loan class revisited example the class method Loan.time_class seems wrong.
It should be

def self.time_class
@time_class ||= Time
end

While actually is

def self.time_class
@time_class || Time
end

so the @time_class class instance variable in never really assigned.

2011-04-15This is actually the expected behaviour, even if an experienced Ruby coder would probably expect a Lazy Instance Variable (with ||=) in place of a Nil Guard (simply ||). I wanted to keep the example as simple as possible, so it's OK (if not very elegant) to just never initialize @time_class unless it's been initialized at creation time, or from outside.
47DEFER

“Note that define_method() is executed inside the definition of Computer…”

As the author noted, that should be:

“Note that define_component() is executed inside the definition of Computer..”

…which refers to the last three lines of the class—the lines where define_component() is called—not the definition of define_component().

However, why is that class method approach even taken? Why not simplify the example and call define_component() from inside initialize()? Inside initialize() self is the object, and if you called define_component() inside initialize(), then define_component() could be defined as a regular instance method.

Regressing for a moment, what the text fails to mention is that Module#define_method() is a private method. As the text explained earlier, private methods cannot be called explicitly by an object—private methods have to be called without a “receiver”. And when a private method is called, the receiver becomes whatever self is at that moment.

Now, because the goal is to define regular instance methods inside the Computer class using define_method(), when we call define_method(), at that instant self must be Computer. If self isn’t Computer, then define_method() won’t create instance methods in the Computer class.

When is self equal to Computer? Inside a class method! When a class is used to call a method, inside the method self is the class. That is exactly analogous to when you call an instance method with an instance/object of the class—inside the method, self is the instance/object.

As a result, if you create a wrapper method around define_method() and you make the wrapper method a class method, then the receiver for define_method() will be Computer, and Computer will be populated with regular instance methods.

2013-07-09Hey, 7stud. I finally got down to 2nd edition suggestions. ;) \n \nI 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.
47SUGGEST

The syntax for define_method() looks different on this page. Why?

Note that the method that is being defined takes no arguments. define_method() itself takes an argument, the name of the method, but in this case the method being defined doesn’t require any arguments. Therefore, you can forgo the “do |my arg|” part of the syntax.

2011-04-17I changed all define_method() examples in the chapter to "do..end" for consistency.
108OK

This is in response to the previous comment which said there is a mistake in the line:

@time_class || Time

The comment says that || should be replaced by ||=. That is incorrect. The purpose of the method that contains that line is not to assign a value to time_class. Instead, the purpose of the method is to return the value of time_class if it exists, otherwise return the Time class.

The text explains that in production code, the variable time_class will always be nil because it is never set anywhere, and therefore the method will always return the Time class. It should be noted that time_class is not the same kind of variable as book and time, which are introduced in initialize(). time_class is introduced in a method where self = the Loan class, and book and time are introduced in a method where self = a Loan instance. As discussed on p. 106, time_class is a Class Instance Variable, which means you access it through the Loan class—not an instance of the Loan class.

The code on p.109 then creates a unit test that employs what the author calls a “Context Probe”. A Context Probe inserts some code into an object, and then evaluates the code in the context of the object. In this case, the object is the Loan class, and the evaluation of the code inside the Loan object is done with instance_eval(). The instance_eval() method sets the value of @time_class to FakeTime. As a result any subsequently calls to the method containing the line:

@time_class || Time

will now return the value of @time_class since it is no longer nil—as the author intended.

2011-04-15Agreed. The original code is how I meant the example to work. Thank you for the confirmation.
164ERROR

This error was also mentioned in comment #43465 with respect to pdf p. 185. However the correction offered in that comment is also incorrect.

The text claims:


On the other hand, if you don’t need to define instance methods on the including class, you can drop the inner module altogether and define all the methods in the mixin itself:

module MyMixin
def self.included(base)
base.extend(self)
end

def x
puts “x()” #I added puts because the text
#seems to run everything in irb
#which is NOT the way to run code

end
end
———

If you had been following the text up to that point, then that claim should be shocking, and in fact it is false:

class Person
include Mixin
end

Person.x #class method
Person.new.x #instance method

—output:—
x()
x()

If you understood the text up to that point, that is the result you would expect. I have no idea what the author was trying to demonstrate with that example, perhaps:

“On the other hand, if you drop the inner module altogether, and instead you define all the methods in the mixin itself, then you can simultaneously make the methods both class and instance methods.”

2011-04-15You're absolutely right - I'd already resolved to remove that broken example, and your erratum convinced me that this was the best option.
13SUGGEST

If you asked 100 programmers what they thought the following code did:

print Class.instance_methods(inherited)

…100 of them would say the line probably displays some inherited methods.

And if you asked those same programmers what the following code did:

print Class.instance_methods(not_inherited)

…all of them would say that the code probably displays some methods that aren’t inherited.

The point?? ‘inherited’ is a HORRIBLE CHOICE OF VARIABLE NAMES when the goal is to print the methods that ARE NOT inherited! The suggestion? Change this code:

inherited = false
Class.instance_methods(inherited)

to

not_inherited = false
Class.instance_methods(not_inherited)

Now the meaning of the second line of code is intuitive, which is the most important line of the two. The meaning of the first line of code is irrelevant.

2011-04-17You have a point here, but I don't think that changing "inherited" to "not_inherited" makes things that much less confusing. I ended up inlining the variable altogether (Class.instance_methods(false)), and just adding a comment (# The "false" argument here means: ignore inherited methods). \n \nI avoided this kind of comment everywhere in the book, and that's why I had "inherited". But in this case, it's actually better to break my own rule about comments - the alternatives are just too confusing. Thanks.
1DEFER

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” case of Dynamic Proxy and a new spell, maybe named Convenience Ghost, for cases when you use method_missing() for convenience reasons). End by picking Dynamic Methods in the main example over Ghost Methods.

2013-06-06
90ERROR

info = data_source.send("get_#{name}_info", args[0]) price = data_source.send(“get_#{name}_price”, args[0])

=>

info = data_source.send("get_#{name}_info", id)
price = data_source.send("get_#{name}_price", id)

2012-11-04Kado, I fixed this - although now it's a bit confusing that the *args argument is never used. I made a note to remove this potential source of confusion in the next edition. Thank you! \n
158TYPO

broken_math.rb sample code is missing the following line.

require ‘test/unit’

2012-08-21Actually, this was a slip-up on my part that survived three printings of the book - the test code wasn't even meant to be printed in the book. Thanks, Yasuo.
94ERROR

require ‘using’ fails
maybe require_relative ‘../blocks/using’ is needed to be used.

2012-08-21You're right. I replaced the "require 'using'" with a "require './using'" in the source code, and removed it from the text. It's not necessary for understanding the text, and people trying out the code will see it anyway. I avoided require_relative(), because it's not available in Ruby 1.8.
203ERROR

module.rb sample does not work.
—
$ rails -v
Rails 2.3.2
$ ruby -v
ruby 1.9.2p180 (2011-02-18) [i686-linux]
$ ruby modules.rb
/usr/local/lib/ruby/gems/1.9.1/gems/activerecord-2.3.2/lib/active_record/validations.rb:92:in `generate_message’: undefined method `self_and_descendants_from_active_record’ for MyClass:Class (NoMethodError)
from /usr/local/lib/ruby/gems/1.9.1/gems/activerecord-2.3.2/lib/active_record/validations.rb:48:in `add’
from /usr/local/lib/ruby/gems/1.9.1/gems/activerecord-2.3.2/lib/active_record/validations.rb:602:in `block in validates_length_of’
from /usr/local/lib/ruby/gems/1.9.1/gems/activerecord-2.3.2/lib/active_record/validations.rb:399:in `block (2 levels) in validates_each’
from /usr/local/lib/ruby/gems/1.9.1/gems/activerecord-2.3.2/lib/active_record/validations.rb:396:in `each’
from /usr/local/lib/ruby/gems/1.9.1/gems/activerecord-2.3.2/lib/active_record/validations.rb:396:in `block in validates_each’
from /usr/local/lib/ruby/gems/1.9.1/gems/activesupport-2.3.2/lib/active_support/callbacks.rb:182:in `call’
from /usr/local/lib/ruby/gems/1.9.1/gems/activesupport-2.3.2/lib/active_support/callbacks.rb:182:in `evaluate_method’
from /usr/local/lib/ruby/gems/1.9.1/gems/activesupport-2.3.2/lib/active_support/callbacks.rb:166:in `call’
from /usr/local/lib/ruby/gems/1.9.1/gems/activesupport-2.3.2/lib/active_support/callbacks.rb:90:in `block in run’
from /usr/local/lib/ruby/gems/1.9.1/gems/activesupport-2.3.2/lib/active_support/callbacks.rb:90:in `each’
from /usr/local/lib/ruby/gems/1.9.1/gems/activesupport-2.3.2/lib/active_support/callbacks.rb:90:in `run’
from /usr/local/lib/ruby/gems/1.9.1/gems/activesupport-2.3.2/lib/active_support/callbacks.rb:276:in `run_callbacks’
from /usr/local/lib/ruby/gems/1.9.1/gems/activerecord-2.3.2/lib/active_record/validations.rb:1029:in `valid?’
from modules.rb:27:in `

’
$
—

2012-11-04Yasuo, you're right - the example doesn't work under the latest rubies. Fixing this properly makes the entire example ugly, and probably not worth it - the latest Rails uses a completely different module inclusion mechanism anyway, so I'll have to rewrite the chapter for the next edition of the book. I just added a note to the text that the code only works properly on Ruby 1.8.x. I think that the example still makes the point it's meant to make: you can use a module in isolation. \nThanks! \n
131ERROR

The book says that you can use Class#new to define a new class. This is not correct, you use Class.new.

2012-08-21Fixed. Thanks.
146OK

class D < C; end

absent in the code snippet.

2012-08-21Thanks, Selman. In this case, the code snippet is meant as an addition to the "lab rat" program - so that line is not there, just as the definition of the eigenclass() method is not there. I could repeat the rest of the program, but in this case I think it's OK to just show the new code (in the text it clearly says that "Bill adds a class method" to the program).
148DEFER

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?”. Good point, the “theory” list needs to talk about module inclusion.

2013-09-25
1DEFER

(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 built-in.

2013-07-08
224TYPO

“They also call model objects to execute business logics,”

“logics” should be “logic”

2012-08-21Fixed. Thank you.
234TYPO

Footnote is not numbered and not referenced on the page.

2012-11-02This is actually just confusing layout - the footnote is actually the continuation of the footnote on the previous page. I'll ask the layout person to maybe break up the footnote in a different spot, to avoid this confusion in the next reprint. Thanks. \n
98TYPO

“Your main code loads the files that end with `event.rb`”.

This should be “(…) that end with `events.rb`” (plural events).

2012-08-21Thanks, Katrina.
96DEFER

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 more complete if it also had an event that did not get triggered, e.g.

event “Everything is OK!” do
sky_height > mountain_height
end

2013-09-20Done. :) Thanks, Katrina!
98DEFER

“[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 failed if you don’t use a Clean Room. In the current version, it works if you use `block.call` for both setups and events.

Blocks are somewhat mind-bending, so it would be extremely useful to have an extensive failing test suite to force the reader to understand the subtleties and implications.

2013-09-20"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!
1DEFER

Mention (from the BasicObject documentation):
“BasicObject does not include Kernel (for methods like puts) and BasicObject is outside of the namespace of the standard library so common classes will not be found without a using a full class path. … Access to classes and modules from the Ruby standard library can be obtained in a BasicObject subclass by referencing the desired constant from the root like ::File or ::Enumerator.”

2013-07-08Will mention this stuff in the discussion on Clean Room
152DEFER

In the proc{ … }.call, the $SAFE works differently from normal global variable. I wrote a simple test like this:

$ABC = ‘abc’
puts $ABC # abc
proc {
$ABC = ‘cde’
puts $ABC # cde
}.call
puts $ABC # cde

Why is $SAFE different? I hope you can talk about it in the book.

I would appreciate if you can tell me why.

My email is: yzhang.wa@gmail.com

Thanks,
Yi Zhang

2013-10-03
71ERROR

String#grep is mentioned when the author means Array#grep (or Enumerable#grep) in

“First, if you pass a block to String#grep(), the block is evaluated for each element that matches the regular expression…”

2012-11-04Fixed! Thank you.
82ERROR

I believe this to be a very simple problem. On page 82 it is stated that, "Bill had to use Dynamic Dispatch (41) to access the private method define_method() on Kernel.) This is, in fact, not completely true. (Luckily you teach all the concepts so well, I was able to diagnose this.)

The statement can be corrected by saying, “Bill had to use Dynamic Dispatch (41) to access the private class method define_method on Kernel.” Allow me to explain.

If “define_method” was simply a private instance method of Kernel, then you should be able to call it with an implicit self from anywhere that contains Kernel in it’s ancestor chain. But this is not the case. Since it is a private class method of Kernel, it must be called with an implicit self equal to Kernel.

I hope what I am saying makes sense, because this caused a great deal of trouble for me. At first, I thought I was misunderstanding what you had written previously, but it turns out that you were entirely correct just not completely correct per se.

Thanks for a great book, I really love it!

2012-11-04Thanks, Denzel! The misunderstanding here is that I don't usually specify that a method is a class method, because class methods are just regular methods that you can call on a class. So, when I say "method define_method() on Kernel", I mean Kernel.define_method(), not necessarily Kernel#define_method(). However I understand that might be confusing (and your explanation is right), so I changed "method" to "class method" as you suggested. Thank you,
72ERROR

“Kernel#method_missing() responded by raising a NoMethodError”

in 1.9, #method_missing was moved to BasicObject
this is mentioned a few paragraphs earlier in the book
i have also confirmed that it is indeed in BasicObject by looking at the docs

should read:
“BasicObject#method_missing() responded by raising a NoMethodError”

thank you

2012-11-04Fixed (in multiple places). Thanks!
90DEFER

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 bit confusing. Kado suggested changing everything to the id form, which I did - but as a result, the *args argument of method_missing() is never really used. I should find a way to make this less confusing in the next edition.

2013-07-09I ended up going with Kado's suggestion.
65DEFER

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 respond_to?, but only because it matches the respond_t part (since the ? isn’t escaped). Also, the anchors got stripped from the final two method names.

I would probably use something like /$/. Others might use /|^method_missing$|respond_to\\?$/ or /|$/. My preference is for the first alternative since I find it the most explicit. The .* makes it clear that I mean followed by anything, I have one and one $ at their respective ends of the regex and they are always used so I don’t have to waste cycles figuring out if I’m missing them somewhere or if they were omitted from one of the alternatives on purpose.

—Toby Ovod-Everett
toby@ovod-everett.org

2013-07-09I 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!
243DEFER

`a ||= []` is not equivalent to `a || (a = [])`
`a || (a = [])` will throw a “undefined local variable or method ‘a’”

The correct equivalent is `a = (a || [])`

2013-05-10Not 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: \n \nif defined?(a) && a \n a = a \nelse \n a = [] \nend \n \nSurprising that nobody had noticed this problem yet. Thank you very much for pointing this out.
48DEFER

In the last paragraph, last sentence, you have an extra “-” between “get” and “ListUser()” in the Flickr#tags_getListUser() method reference.

2013-05-10Fixed. Thanks.
147DEFER

In the paragraph right after the code fragment for mere_cache/merb_ext/controller.rb, second sentence, there is a “-” between “Class” and “Methods” that shouldn’t be there.

2013-05-10Fixed. Thanks.
89DEFER

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 |event|

since the define_method :each_event above specifies only 1 block paramater.

2013-05-10Those are the arguments to the block, not define_method. The block gets passed on and is ultimately called here, with two arguments: \n \nevents.each_pair do |name, event| \n block.call name, event \nend \n \nSo it must be a block that takes two arguments.
73DEFER

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 id (as seen in previous pages/revs). Is there something I’m missing here? This implementation seems to imply that one must call my_computer.cpu 42 in order to get the cpu info for computer 42. But, the example farther down the page does not show an id being passed in the my_computer.cpu call.

2013-07-09You're right - I changed the code to use @id everywhere. Thanks!
39DEFER

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, but for ruby 1.9.X and 2.0 there is an Object#define_singleton_method(), defines a Singleton Method, taking a name and either a Proc, Method object or a block.

Great book! Thanks for putting it together

2013-09-20Well spotted! I removed that footnote in the 2nd edition altogether.
55DEFER

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 it a bit confusing in a first read. Module#undef_method does remove all the occurrences of a given method in the inheritance chain, but it seems to say that removes “all methods”, creating some kind of blank slate.

Not a big deal if you keep reading or look at Ruby API documentation…

2013-09-20Sorry, sloppy English. :) I rephrased to "removes *any* method". This should make it clear.
75ERROR

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

2013-12-20Thank you. Fixed.
116TYPO

“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 would be called on MyClass itself, not on an instance of MyClass?

2013-12-20Indeed. Fixed. Thanks,

Categories: