’
By Developers, For Developers
| PDF Pg | Paper Pg | Type | Description | Fixed on | Comments |
|---|---|---|---|---|---|
| 13 | TYPO | > Then I went asked the class for a list of its instance methods Extra “went” or missing “and” before asked. | 2009-07-16 | Fixed. Thanks. | |
| 25 | ERROR | 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 | ||
| 100 | ERROR | The description of instance_eval() is confusing. Clarify that it just changes self. (reported by Ola Bini). | 2009-07-26 | ||
| 28 | ERROR | 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-16 | I 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 | |
| 53 | ERROR | The Quiz Solution says: shouldn’t the last line be ‘b.class.ancestors’ or | 2009-07-16 | Whoops. Fixed! | |
| 34 | SUGGEST | 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-21 | The 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. | |
| 52 | OK | Code snippets being interrupted by the inset boxes is (mildly) annoying. | 2009-07-18 | I 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. :) | |
| 1 | OK | Pictures are missing from the epub version. | 2009-07-18 | It 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. | |
| 13 | TYPO | “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: | 2009-07-18 | Fixed. | |
| 83 | TYPO | ‘Egiptology’ should be ‘Egyptology’. | 2009-07-18 | Fixed. | |
| 0 | OK | 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’ Only a few people know about it, and I realize that this will be good if it’s exposed on this book | 2009-07-18 | It'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. | |
| 0 | ERROR | 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-04 | Fixed (with a workaround to a bug in the latest Stanza) | |
| 66 | ERROR | 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-19 | The 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(), ...). | |
| 71 | TYPO | “rows_with(:country)()” appears to have an extraneous pair of parentheses at the end (probably should be just “rows_with(:country)”). | 2009-07-18 | Fixed. | |
| 76 | ERROR | In the definition of method_missing, shouldn’t there be a “return” before “super”? | 2009-07-19 | The 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". | |
| 83 | TYPO | “ornitology” should be “ornithology” | 2009-07-19 | Fixed. This thing with "-ology" words is getting embarrassing. :) | |
| 32 | TYPO | You write: " You can think of instance variables I think you meant to say the name of the variable would be used as the key. | 2009-07-19 | Right, badly phrased sentence. Now it's: "You can think of the names and values of instance variables as keys and values in a hash." | |
| 174 | TYPO | “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-20 | Fixed. | |
| 189 | TYPO | a =|| [] should be a ||= [] | 2009-07-20 | Ouch. Fixed. | |
| 62 | SUGGEST | 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-20 | I added this sentence: "Also, some operation (like comparisons) are faster on symbols than they are on strings." | |
| 136 | TYPO | class’ should be class’s | 2009-07-21 | Fixed (see above). | |
| 173 | SUGGEST | 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-22 | For historical reasons, that argument is usually called "base" - but I agree it's misleading. I changed it to "subclass". | |
| 99 | TYPO | Last sentence under “Scope Wrap-Up”. “This a Flat Scope (99), the basic closure-related spell.” | 2009-07-24 | Fixed. Thanks. | |
| 24 | TYPO | “Delving into the the Object Model, at the very heart of Ruby, …” - I think there is an extra “the”. | 2009-07-24 | How strange that this one got unnoticed until now... Fixed. | |
| 124 | TYPO |
| 2009-07-24 | Fixed - thanks. | |
| 170 | TYPO | Top of the page: PS. Loving this book - exactly what I’ve needed to really ‘grok’ Ruby - thanks! | 2009-07-24 | This 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. :) | |
| 77 | TYPO | Just under the paragraph: | 2009-07-26 | Fixed. Thanks. | |
| 92 | SUGGEST | 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-09 | I 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. | |
| 94 | SUGGEST | 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-09 | Clarified, I hope. | |
| 95 | TYPO | 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-12 | I 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. | |
| 110 | SUGGEST | 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-09 | Good suggestion. I'll try it out. | |
| 123 | SUGGEST | Concerning the last example of “Class Variables”, I think it should be noted why it is the case (overwriting @ 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-10 | I explained the example, and I chickened out of explaining all the other problems related to class variables. | |
| 124 | ERROR | 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-10 | Thank 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. | |
| 120 | ERROR | “While instance_eval( ) only changes self, class_eval( ) changes both self and | 2009-08-12 | Fixed. That resulted in a footnote and a couple of new sidebars. Thanks. | |
| 127 | TYPO | In the second example: “def s.title? ” I think this “s” came from nowhere, and is never again used. | 2009-08-09 | Fixed. Thanks. | |
| 140 | SUGGEST | 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). - make the link with figures 1.4 and 1.5 | 2009-08-09 | I 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. | |
| 142 | SUGGEST | 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-12 | Fixed. I managed to do that in a single figure by changing the example. | |
| 143 | OK | A figure for each example code (Class Extension and Object Extension) would be very much welcome I think. Just a suggestion. | 2009-08-12 | I'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. | |
| 144 | DEFER | 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. | 2009-12-07 | I 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. | |
| 156 | SUGGEST | 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-09 | There 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. | |
| 159 | SUGGEST | Code colouring is wrong in the nested irb example. | 2009-08-13 | Still 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. | |
| 165 | SUGGEST | Suggest you use instead of tags in your eRB HTML. | 2009-07-30 | Done. Thanks. | |
| 186 | SUGGEST | 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-31 | I 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. | |
| 186 | TYPO | “the MVC component that contains domain objects and logics.” I would use the singular ‘logic’. | 2009-07-31 | Fixed. | |
| 186 | TYPO | “ActiveRecord::Base is the most important class in ActiveRecord. Not only - shouldn’t this be “…not only DOES it…”? | 2009-07-31 | Ouch. Fixed. | |
| 188 | SUGGEST | some_duck = Duck.find(:first) 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-31 | Whoops - fixed. | |
| 195 | TYPO | “No Java coder in her right mind …” - I think the unisex adjective ‘their’ would be a little more appropriate here? | 2009-08-09 | I reverted back to the original "his or her" instead. Thanks. | |
| 193 | ERROR | 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 | ||
| 16 | TYPO | Footnote 2 contains an extraneous closing parenthesis. | 2009-08-04 | Fixed. Thanks. | |
| 28 | TYPO | 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-09 | I 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. | |
| 70 | TYPO | Footnote nr. 6 at page 70 The sidebar say about “send” and “public_send”. I think the footnote could be erased. | 2009-08-09 | I left the footnote, but it just points to the sidebar and nothing else. Thanks. | |
| 42 | TYPO | module Text
Text is a module in ActionMailer (format.rb), not in Bookworm, where’s a class. | 2009-08-12 | Fixed. | |
| 35 | TYPO | I think from the following the second ‘instance’ can be erased. So: An object’s instance variables live in the object itself, will become: An object’s instance variables live in the object itself, :-) | 2009-08-13 | Fixed. | |
| 33 | TYPO | 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-21 | Fixed ("[...] to minimize your chances of tripping over a Monkeypatching bug.") | |
| 120 | SUGGEST | 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-21 | It works in 1.8.7, but I added a footnote for people using older versions. Thanks. | |
| 95 | TYPO | Last para. : […] where the block pick up its bindings. This is a magnificent and readable book and I love getting | 2009-08-26 | Fixed - and thank you so much! :) | |
| 96 | TYPO | […]" a computer scientists would say " < sing. scientist ? | 2009-08-26 | Fixed. | |
| 115 | TYPO | 3rd para. “… basically, whenever one of many different things happen.” <- ? one .. “happens.” [nitty, I know] | 2009-08-27 | Not nitty at all... Fixed. | |
| 49 | TYPO | In the second paragraph: | 2009-08-31 | It was *my* English, not yours... ;) \nFixed - thank you. | |
| 103 | OK | “— that’s what the define_methods() method is for.” <- sing. ‘define_method()’ ? | 2009-09-10 | ||
| 103 | OK | Paolo .. my mistake .. define_methods() is not a typo. You can erase my noise if you wish. Thanks for a great book! | 2009-09-10 | Thank you, John! Keep the noise coming - I like to get errata. ;) | |
| 119 | OK | Obi-Wan would say it more like this: | 2009-09-11 | Steve, that's Yoda-speak, not Obi-Wan-speak! Such a blunder would get you thrown out of any righteous geek's home. ;D \n | |
| 109 | SUGGEST | When I run this code, Ruby 1.9.1 returns an array, not the puts result in the first highline example. | 2009-09-18 | See #40717 | |
| 243 | ERROR | When running the Code Processor example, I get his error using Ruby 1.9.1: TypeError: can’t convert String into Integer ’ | 2009-09-15 | Fixed. Thanks, Steve. | |
| 109 | TYPO | 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-18 | Thanks 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". | |
| 126 | TYPO | “If all you want is change self,” This might be better: “If all you want is to change self,” | 2009-09-12 | Fixed. | |
| 157 | TYPO | 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-18 | See #40752. | |
| 218 | TYPO | “wether” should be “whether” | 2009-09-12 | Fixed. | |
| 219 | TYPO | “After reading though this book,” | 2009-09-12 | Fixed. | |
| 239 | TYPO | 3rd paragraph in it says: " It’s easier to adapt “that” should be “than” | 2009-09-15 | Fixed. | |
| 243 | SUGGEST | Steve’s report #40716 might be about a technical error : the | 2009-09-15 | Thanks, John. | |
| 147 | SUGGEST | 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-18 | Ouch, 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. | |
| 157 | SUGGEST | Re: Steve’s report #40719 .. I suspect that the test-unit | 2009-09-18 | I added a footnote for this. Thanks, Steve and John! | |
| 102 | TYPO | On the last line but 4: I guess this should be: | 2009-09-19 | Fixed. Thanks. | |
| 150 | TYPO | First line: Bill decides it’s time time for a story: Duplicated words ‘time’. | 2009-09-22 | Fixed. Thanks | |
| 69 | TYPO | 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-27 | Fixed. Thanks. | |
| 149 | SUGGEST | 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). 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-10 | Touché! 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. | |
| 146 | TYPO | “Bill tries to sums it all up” | 2009-10-06 | Fixed - thanks. | |
| 73 | SUGGEST | Description for the table example: 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 class MyTest < Test def does_nothing puts MyTest.new.does_nothing # => does nothing from Test | 2009-10-06 | You wouldn't believe it, but I'd already fixed this right after the beta release. :) | |
| 15 | OK | Out of curiosity, does Bob’s middle names include DROP TABLE Students? | 2009-10-10 | Is 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) | |
| 24 | ERROR | 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-10 | Yet another reason to miss _why. I see that TryRuby has a new home now. I updated the link. Thanks, Andrew. | |
| 26 | TYPO | Are you sure you mean last-generation monitor, or do you mean latest-generation monitor? | 2009-10-10 | Ehm, I hope this isn't going to be the last generation. Fixed. | |
| 15 | OK | 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-10 | I 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. | |
| 152 | ERROR | In the following code: module MyModule obj = Object.new class MyClass 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-15 | Fixed. Thanks. | |
| 162 | TYPO | At the risk of being extremely pedantic, the “ctcw” in “ctcw/simple_eval.rb” (and elsewhere in the chapter) should be “ctwc”. | 2009-10-26 | Hey, we're programmers - we're supposed to be pedantic! :) \nFixed - thanks. | |
| 173 | OK | Is “klass” a more common variable name than “clazz”? | 2009-10-26 | I'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. | |
| 168 | ERROR | 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-26 | Thanks. Fixed. | |
| 96 | SUGGEST | 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-29 | Fixed. Thanks. | |
| 95 | SUGGEST | 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-02 | I notified the typesetter about this. Thanks. | |
| 253 | OK | 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-02 | Paul, 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. :) | |
| 152 | TYPO | Incorrect usage of the term fluke. “Bookworm itself should log this fluke and proceed.” | 2009-11-02 | Replaced with "problem". Thanks. | |
| 160 | OK | In footnote 2, the sentence is cut off: (collected and …? | 2009-11-01 | Hello, Paul. Please see your related item about page 165. | |
| 165 | OK | Ok, can now see the problem, footnotes are flowing between pages. Footnote 6 has very odd justification/word spacing. | 2009-11-01 | This 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. | |
| 180 | OK | Last line on page extends beyond body text into the right margin:…), or method_undefined( ):12 | 2009-11-02 | Typesetting issue - will be fixed after beta. Thanks. | |
| 49 | SUGGEST | any chance of mentioning Object vs BasicObject (1.8 vs 1.9) in figure 1.7? | 2009-11-17 | Fixed. | |
| 229 | TYPO | 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-04 | Fixed. Thanks. | |
| 243 | ERROR | I am not sure of Ruby 1.8 but: “…and it has to be the last argument in 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-17 | I'd missed this change in Ruby 1.9. Thank you. | |
| 33 | ERROR | Monday: The Object Model >> Open Classes >> The Money example | 2009-12-07 | Fixed. Thanks! | |
| 71 | OK | “You open an irb session and smoke-test the new Computer.” | 2009-12-07 | You 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. | |
| 111 | TYPO | The two sentences seem inconsistent: | 2009-12-07 | Actually, 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. | |
| 117 | DEFER | 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-07 | This 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). | |
| 41 | OK | 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). | 2009-11-23 | (See report for page 39) | |
| 39 | OK | “So, a class is just a souped-up module with three additional methods—new(), allocate(), and superclass().” | 2009-11-23 | (See below) | |
| 39 | OK | Please withdraw earlier erratum report, on this page and later reference to it. | 2009-11-23 | OK, thanks! | |
| 130 | SUGGEST | “To prove that all his theory | 2009-12-07 | By "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. | |
| 152 | OK | “The superclass of #BasicObject is … Class. This fact explains why you can call MyClass#b() and MyClass#b=().” | 2009-12-01 | See below. | |
| 152 | DEFER | 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-07 | Thanks, Thomas. I'll consider it. | |
| 181 | SUGGEST | 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-07 | I added: "Bill replaces the two test cases that checked for nil or false attributes with a single new test case" Thanks. | |
| 181 | ERROR | 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’ | 2009-12-07 | Good idea. Thanks. | |
| 184 | SUGGEST | “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: module CheckedAttributes def attr_checked(attribute, &validation) end # module CheckedAttributes class Person class TestCheckedAttribute < Test::Unit::TestCase def setup def test_accepts_valid_values def test_refuses_invalid_values
end # class TestCheckedAttribute | 2009-12-07 | I 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. | |
| 120 | DEFER | 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:
def event(name, &block) def setup(&block) Dir.glob(‘*events.rb’).each do |file| 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-20 | 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. | |
| 120 | ERROR | 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-18 | I removed the reference to the events order. Thanks. | |
| 221 | OK | Highlighting of code in example for find_by_description! is slightly off / misleading. At the end, we have: where there is a mix of blue and green text as it appears the ‘#’ are mistakenly taken as comment starters, | 2010-01-02 | There 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). | |
| 56 | DEFER | 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” | 2013-04-16 | 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. | |
| 55 | TYPO | 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-02 | Changed to "testing_self". I must confess that the crude meaning was actually intentional, but OK, I have a childish sense of humor. ;) | |
| 31 | SUGGEST | 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-02 | Changed the title to "Inside Class Definitions". Thanks! | |
| 170 | ERROR | In the sidebar on “Here Documents,” the result is shown as puts this is a “multi-line” string 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 | 2010-01-05 | That was the intention, but the book's build system munched up the indentation. I indented the two lines differently to show the difference. Thanks. | |
| 175 | DEFER | 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-03 | 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. | |
| 120 | TYPO | The sentence “The DSL stills checks events in the order…” has a typo. The word “stills” should be “still” | 2010-01-08 | I'd removed that sentence in a previous edit, because it was technically inaccurate - so I guess it's fixed. :) | |
| 123 | DEFER | 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 ). | 2013-09-22 | I fixed the first point, and clarified the second for the 2nd edition of the book. Thanks. | |
| 169 | OK | 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-06 | Thanks, 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. | |
| 21 | TYPO | On line 4, “you’re ready to dive in this book.” should be “you’re ready to dive into this book.” | 2010-05-06 | Thanks, James. | |
| 44 | OK | the line: “Module, so a class is also a module.” | 2010-05-06 | I 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. | |
| 72 | ERROR | line: “of Kernel that every object inherits.” | 2010-05-06 | Actually, 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. | |
| C3p30 | OK | I think ‘class Txt < Fatty::Format’ should be ‘class Txt < Fatty::Formatter’ | 2010-05-06 | Maybe wrong report from another book? | |
| 250 | TYPO | “which prides itself” succinct is spelled incorrectly | 2010-05-06 | Fixed. Thanks. | |
| 190 | ERROR | 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-06 | Fixed. Thanks. | |
| 243 | DEFER | Nill Guards do not work well with booleans. | 2013-07-08 | I added a short section about this. Thank you, Martijn. | |
| 35 | TYPO | … 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-06 | The 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. | |
| 52 | TYPO | 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-07 | Thank 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. | |
| 251 | OK | [1, 2, 5].inject(0, &:+) # => 8 can even be written as [1, 2, 5].inject(&:+) # => 8 | 2010-05-06 | Very 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. | |
| 154 | OK | Quit many (small) code examples extend over two pages. | 2010-05-06 | Martijn, 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. | |
| 155 | TYPO | In if load_error.message =~ /#{Regexp.escape path}\\z/ and everything to the right of the # is accidently marked as comment… | 2010-05-06 | This is a known limitation of the Prags' current Ruby formatter. It's annoying (especially when "eval" is involved), but unavoidable at this stage. | |
| 130 | TYPO | because @time_class( ) is always nil. | 2010-05-06 | ||
| 130 | TYPO | because | 2010-05-06 | Thanks, Kado. | |
| 172 | TYPO | “eRB” should be “ERB”. | 2010-05-06 | ||
| 207 | TYPO | AcriveRecord::Base() | 2010-05-06 | Fixed this and two other instances of the same typo. :) | |
| 211 | OK | Thus is the description=() | 2010-05-06 | I actually meant "thus". :) The full sentence: "Thus is the description=() method born". | |
| 98 | DEFER | 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-20 | 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. | |
| 53 | TYPO | “my_method() is called on obj()” | 2010-05-15 | ||
| 25 | TYPO | tryruby.sophrinix.com. has moved to tryruby.org | 2010-05-15 | ||
| 149 | DEFER | 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 = explore_array(:find,[]) do |x| 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-03 | 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. | |
| 114 | TYPO | “The Stubby Lambda” may be “The Stabby Lambda” ? | 2010-05-17 | ||
| 154 | TYPO | “Integer() class” should be “Integer class” | 2011-04-15 | ||
| 184 | TYPO | 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. | |
| 203 | TYPO | “ActiveRecord::Validation” should be “ActiveRecord::Validations” | 2011-04-15 | ||
| 213 | TYPO | “ActiveRecord::Base#respond_to?” should be “ActiveRecord::Base#respond_to?()” according to your convention. | 2011-04-15 | ||
| 58 | TYPO | Bill points out the previous code implicitly calls ancestors() method, but the code says “ancestors # => [Book, Document, Printable, Object, Kernel, BasicObject] ” explicitly. | 2011-04-15 | This 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. ;) | |
| 185 | ERROR | “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-15 | I 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! | |
| 243 | OK | “In this example, the value to the right happens…” should be “In this example, the value to the left happens” ??? | 2011-04-15 | I 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. | |
| 56 | OK | In The Top Level sidebar, "because it ‘s the object", space between t and ’. | 2011-04-15 | Unfortunately, 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. | |
| 195 | TYPO | 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 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-15 | I 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! | |
| 184 | DEFER | 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-24 | 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] | |
| 197 | TYPO | “opening database connections—-It’s also the base class” s/It’s/it’s/ | 2011-04-15 | ||
| 206 | TYPO | “But wait—-There is more” s/There/there/ | 2011-04-15 | ||
| 211 | TYPO | “I’ll go over it with you one piece at the time.” s/at the time/at a time/ | 2011-04-15 | ||
| 131 | TYPO | Class#new() -> Class.new() | 2011-04-15 | This one was difficult to spot. :) Thanks! | |
| 1 | ERROR | 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 | ||
| 1 | TYPO | “stubby lambda” vs. “stabby lambda” | 2011-04-14 | ||
| 1 | OK | 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-17 | The 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. | |
| 111 | TYPO | “Hello, Bill!” should be “Hello, Bill” | 2011-04-15 | ||
| 120 | TYPO | “Your main code loads the files that end with event.rb.” | 2011-04-15 | ||
| 1 | OK | Constant lookup rules in Ruby 1.9 have changed. Check. | 2011-04-17 | This 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. | |
| 96 | TYPO | C# names (like conn.readStuff() and dispose()) should begin with an uppercase character by convention. | 2011-04-14 | ||
| 41 | DEFER | 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 | |
| 65 | ERROR | 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-15 | Very true. Fixed. | |
| 135 | DEFER | 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-25 | Good point, Rich. This will come useful in the second edition. | |
| 243 | ERROR | a ||= [] | 2011-04-15 | This 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. | |
| 1 | DEFER | From Kado: a comment about “private” on the book: there is one exception: it’s “setter” method. def setter=(val) def getter self.setter=(123) # => 123 | 2013-07-08 | 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! | |
| 1 | TYPO | Note that define_method( ) is executed inside the definition of Computer, […] It should be define_component(). | 2011-04-15 | I actually rewrote the entire paragraph - I found it confusing. | |
| 76 | ERROR | “gem install flickr” at footprint. But flickr gem does not maintenace. | 2011-04-15 | You'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. | |
| 130 | SUGGEST | 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-15 | Fixed. :) | |
| 126 | DEFER | 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-25 | 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. | |
| 44 | SUGGEST | 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-15 | Some people CallThisCamelCase, others CallItPascalCase. Some other people even CallItUpperCamelCase. I agree that Pascal case is more correct, and thisIsWhatCamelCaseShouldStrictlyLookLike. I changed it. Thanks! | |
| 0 | ERROR | 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-17 | Thanks, Kado. Surprising that this one stood unnoticed so far. | |
| 1 | DEFER | One reader complained that the ToC is useless. Any ways to make it more informative? | 2013-06-06 | ||
| 102 | TYPO | “If you could call a method instead of using the class, ”. It should be “[…] using the class keyword, ”. | 2011-04-15 | ||
| 108 | OK | In the Loan class revisited example the class method Loan.time_class seems wrong. def self.time_class While actually is def self.time_class so the @time_class class instance variable in never really assigned. | 2011-04-15 | This 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. | |
| 47 | DEFER | “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-09 | Hey, 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. | |
| 47 | SUGGEST | 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-17 | I changed all define_method() examples in the chapter to "do..end" for consistency. | |
| 108 | OK | 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 The text explains that in production code, the variable 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-15 | Agreed. The original code is how I meant the example to work. Thank you for the confirmation. | |
| 164 | ERROR | 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 x 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 Person.x #class method —output:— 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-15 | You're absolutely right - I'd already resolved to remove that broken example, and your erratum convinced me that this was the best option. | |
| 13 | SUGGEST | 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 to not_inherited = false 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-17 | You 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. | |
| 1 | DEFER | 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 | ||
| 90 | ERROR | info = => info = | 2012-11-04 | Kado, 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 | |
| 158 | TYPO | broken_math.rb sample code is missing the following line. require ‘test/unit’ | 2012-08-21 | Actually, 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. | |
| 94 | ERROR | require ‘using’ fails | 2012-08-21 | You'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. | |
| 203 | ERROR | module.rb sample does not work. ’ | 2012-11-04 | Yasuo, 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 | |
| 131 | ERROR | The book says that you can use Class#new to define a new class. This is not correct, you use Class.new. | 2012-08-21 | Fixed. Thanks. | |
| 146 | OK | class D < C; end absent in the code snippet. | 2012-08-21 | Thanks, 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). | |
| 148 | DEFER | 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 | ||
| 1 | DEFER | (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 | ||
| 224 | TYPO | “They also call model objects to execute business logics,” “logics” should be “logic” | 2012-08-21 | Fixed. Thank you. | |
| 234 | TYPO | Footnote is not numbered and not referenced on the page. | 2012-11-02 | This 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 | |
| 98 | TYPO | “Your main code loads the files that end with `event.rb`”. This should be “(…) that end with `events.rb`” (plural events). | 2012-08-21 | Thanks, Katrina. | |
| 96 | DEFER | 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 | 2013-09-20 | Done. :) Thanks, Katrina! | |
| 98 | DEFER | “[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! | |
| 1 | DEFER | Mention (from the BasicObject documentation): | 2013-07-08 | Will mention this stuff in the discussion on Clean Room | |
| 152 | DEFER | In the proc{ … }.call, the $SAFE works differently from normal global variable. I wrote a simple test like this: $ABC = ‘abc’ 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, | 2013-10-03 | ||
| 71 | ERROR | 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-04 | Fixed! Thank you. | |
| 82 | ERROR | 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-04 | Thanks, 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, | |
| 72 | ERROR | “Kernel#method_missing() responded by raising a NoMethodError” in 1.9, #method_missing was moved to BasicObject should read: thank you | 2012-11-04 | Fixed (in multiple places). Thanks! | |
| 90 | DEFER | the switch from “info = | 2013-07-09 | I ended up going with Kado's suggestion. | |
| 65 | DEFER | 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 | 2013-07-09 | 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! | |
| 243 | DEFER | `a ||= []` is not equivalent to `a || (a = [])` The correct equivalent is `a = (a || [])` | 2013-05-10 | 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: \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. | |
| 48 | DEFER | In the last paragraph, last sentence, you have an extra “-” between “get” and “ListUser()” in the Flickr#tags_getListUser() method reference. | 2013-05-10 | Fixed. Thanks. | |
| 147 | DEFER | 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-10 | Fixed. Thanks. | |
| 89 | DEFER | in the redflag.rb: Dir.glob(‘*events.rb’).each do |file| the line above should be: since the define_method :each_event above specifies only 1 block paramater. | 2013-05-10 | Those 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. | |
| 73 | DEFER | In the method_missing definition, args[0] is being passed in the | 2013-07-09 | You're right - I changed the code to use @id everywhere. Thanks! | |
| 39 | DEFER | 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-20 | Well spotted! I removed that footnote in the 2nd edition altogether. | |
| 55 | DEFER | 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-20 | Sorry, sloppy English. :) I rephrased to "removes *any* method". This should make it clear. | |
| 75 | ERROR | 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-20 | Thank you. Fixed. | |
| 116 | TYPO | “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-20 | Indeed. Fixed. Thanks, |