By Developers, For Developers

Historical errata for Metaprogramming Ruby 2

PDF PgPaper PgTypeDescriptionFixed onComments
204ERROR

“a ||= []” should be “a || (a = [])” instead of “a = (a || [])”.

ref. www.ruby-doc.org/core-2.1.1/doc/syntax/assignment_rdoc.html
> Note that these two operators behave more like a || a = 0 than a = a || 0.

2014-06-15Hello, Kado! :) \nYou're as fast as ever. I think that you gave me a heads-up about this problem in the 1st edition. I can't remember why I decided to leave the text as it is, but I'll look into it soon. Thank you! \n \nUpdate: fixed.
107OK

“At the top level of your program, the current class is Object, the class of main. (That’s why, if you define a method at the top level, that method becomes an instance method of Object).”

As far as I can see it is not an instance method of Object but a private method:

2.1.1 :001 > self
=> main
2.1.1 :002 > self.class
=> Object
2.1.1 :003 > def new_method;p ‘Hey there’; end
=> :new_method
2.1.1 :004 > Array.new.new_method
NoMethodError: private method `new_method’ called for []:Array
\tfrom (irb):4
\tfrom /Users/brunodp/.rvm/rubies/ruby-2.1.1/bin/irb:11:in `

’
2.1.1 :005 > Array.new.send(:new_method)
“Hey there”
=> “Hey there”
2.1.1 :006 >

2014-03-21Both are true: it's an instance method, and it is private. :) \n \n \nTry Object.private_instance_methods.grep(/new_method/). \n \nI think that originally I wrote "[...] if you define a method at the top level, that method becomes a *private* instance method of Object". However, the fact that the method is private is just a separate design choice in the language, and it's not relevant in this context. I thought that mentioning "private" could take the attention of the reader away from the important point: that the current class at the top level is Object. So I removed the mention of "private". I'll keep in mind that you find this particular point confusing. If it confuses more readers, I might consider adding a footnote, or something. \n \nBTW, Bruno, your report also made me notice something weird: while your code (correctly) breaks in irb because you're calling a private method, it seems to work just fine in Pry. I have no idea why Pry allows you to call private methods on another object in this case - maybe I'll look at that in the future.
14ERROR

If I run the example on this page, I get the error that Money.from_numeric is undefined - I have installed the current version (6.1.1) of the money gem.

2014-06-15Anand, see your other errata about the Money gem example.
12SUGGEST

The example uses Test::Unit. Test::Unit is currently replaced by MiniTest (I get an error stating the same when i try to run with the example code in Ruby 2.1) - perhaps use MiniTest instead?

2014-06-10Actually, both test-unit and minitest have been removed from the standard Ruby distribution (https://bugs.ruby-lang.org/issues/9711). It's strange that it doesn't work on 2.1 for you... It seems to work for me. From 2.2 onwards (the current ruby-head) I need to "gem install test-unit" to run the tests. \n \nThanks for the tip, Anand... I added a few lines to the Introduction explaining that you need to install test-unit.
14ERROR

to_money is deprecated in the gem money v6.1 - see money-rails/issues/150 on github. I get error “undefined method `to_money’ for 100:Fixnum (NoMethodError)” when I run the sample on this page.

2014-06-15Things like this happen frequently: as soon as you print the code of an open source library, that code changes. In this case, the problem is more visible, because the core interface of the Money gem changed. Instead of adding notes and disclaimer to every example, I'll add two lines in the Introduction explaining that the examples are useful for the tricks they show, but they might not match the current version of the gem. Thank you for making me aware of this, Anand.
121TYPO

“I want to open this object, and I don’t particularly care it’s a class,”

Missing an ‘if’ => Should be “…if it’s a…”

2014-06-28...and fixed! Thank you, Jon.
20TYPO

The paragraph says:
“While talking about superclasses, you can ask ourselves one more question. What is the superclass of Class?”

I think it should say WE can ask ourselves.

2014-06-28Fixed...
21TYPO

A variable can references a class just like any other object:

I think it should be REFERENCE instead of referenceS

2014-06-28...fixed...
44ERROR

The code from example money_example.rb is deprecated, the money gem has bin split into money and monetize - method from_numeric must be used from Monetize module. Here is my fix (also removed second require ‘money’): GIST: a9f2bd6492ce857c3f80

Best Regards
Bart

2015-03-04This is great info, Bart. Thank you - I'll update the book for the next batch of printings.
193TYPO

The sentence: “if the validation fails, and otherwise falls back to the original save_with_validation!.”
I think should be: “if the validation fails, and otherwise falls back to the original save_withOUT_validation!.”

2015-02-28Right! Fixed.
192TYPO

The last paragraph says: “Validation#save_with_validation
returns false if the validation fails, or if the caller explicitly disables validation.
Otherwise, it just calls the original save_without_validation.”

But based on the validation code:

“if perform_validation && valid? || !perform_validation”

I think the method:
“save_with_validation(perform_validation = true)”

will still call the original save_without_validation method if the caller explicitly disables validation since the call:

save_with_validation(false) will make !perform_validation
evaluate as TRUE (unless I am misunderstanding the sentence “he caller explicitly disables validation”)

2015-02-28You're right! I replaced "or if the caller" with "unless the caller".
30OK

I have a question about method lookup.
You have said “one step to the right, then up”, I think it is not exactly.
If the object is a instance of Class, when i call a class method it will find in itself and its superclasses, and then goto its class.
e.g.:
class A
def self.method_a
p ‘method_a in A’
end
end

class B < A
end

class Class
def method_a
p ‘method_a in Class’
end
end

B.method_a #=> “method_a in A”

So, i think it should be “Goes up, the one step to the right”.

2014-09-23Marcus, class methods look like a special case - but they actually work the same way, even if that's not easy to see. In your example, Ruby goes one step to the right into B's class (which is Class), and then up. You'll find a detailed explaination in chapter Class Definitions.
12OK

It says to install `test-unit` for ruby 2.2 or later. Isn’t that version (2.2) a typo? We are on 2.1.

2014-09-23It's just a very new book, so I peeked in the ruby-head branch put in information that should become valid soon - as soon as Ruby 2.2 is out. :)
55OK

For the refinement gotchas,

using MyClassRefinement
MyClass.new.my_method

returns “original my_method()” for me instead of the “refined my_method()”

Refinement does not seem to work for me. I am using ruby 2.1.1

2015-03-04I just tried the example with 2.1.1, and it works for me. I'll mark this as "not a problem" for now, but feel free to open a new one if the test fails on you on the original file. To run the test, run "ruby code/object_model/refinements_gotcha.rb".
210TYPO

On 3rd paragraph:

“(We discussed additional arguments to method_eval, such as FILE and LINE, in The irb Example, on page 144.)”

method_eval should be module_eval

2015-02-28Fixed. Thanks you.
95SUGGEST

class_eval is used in an example, but it’s only introduced later (on page 107).

2015-03-04
1OK

The text should be updated for JRuby 9000 (“supporting Ruby 2.2, except for Refinements and a few other things”).

2015-03-04This was my own errata. Then I decided that the current text already makes adequate references to non-MRI interpreters, by warning the reader that some examples might not work. So I stopped running JRuby-specific tests.
1ERROR

From Kado: “blocks/using.rb” on ch04 doesn’t work because Ruby 2.x has “using” method for Refinements.

2015-03-05
1ERROR

ch03: There are “accounting” department and “purchasing” department are intermingled in the same context.

2015-02-28
1ERROR

Introduction : “Until Ruby 2.1, test-unit was a standard library. From Ruby 2.2 onward, you need to install it as a gem” isn’t correct. 2.1 doesn’t have it (actually it is mini-test) and 2.2 has real test-unit.

2015-03-05
1ERROR

From Kado: “blocks/flat_scope_3.rb” on ch04 has a unwanted assertion method. It seems a test code for your self. And it needs two ‘puts’ in front of the strings.

2015-02-28
191TYPO

In the sentence “The only the first two methods include the new feature.” there is an extra “The”.
“The only the first two methods include the new feature.” => “Only the first two methods include the new feature.”

2015-02-28Fixed. Thanks.
1ERROR

“Try defining a method inside another method with def, and you’ll see that the new method is defined on the class of self.” Not 100% accurate - in case self belongs to a subclass, the method is defined in the class of the wrapper method.

2015-02-28
1TYPO

From Kado: Ch05: “Kernel#callers” => “Kernel#caller”.

2015-03-04
194TYPO

In sentence “and extended defines an @_dependenciesClass Instance Variable (109) on the includer” , should includer be extender?

2015-03-07Indeed it should. :) Thanks,
1OK

“+ Here’s how you create a Money object from a number:”

It has still “Money” string.

2016-05-15this is actually correct - Monetize still returns Money objects
1ERROR

Ch04 about Padrino: “written with the RSpec test gem”

It is not RSpec but minitest.
ref. github.com/padrino/padrino-framework/blob/0.11.3/padrino-core/test/mini_shoulda.rb

2016-05-15
1TYPO

From Kado:
ch09 The Validations Modules
Both ActiveModel::Validation and ActiveRecord::Validation misses validation[s].

2016-05-15
1ERROR

On Stack Overflow: questions/29980160/metaprogramming-ruby-2-example-from-the-book-isnt-working-when-i-try-it-troubl

2016-05-15
1ERROR

[09/06/15 15:21:19] KADO Masanori: ch02: monetise gem doesn’t work on Ruby 2.2.2.
see https: teamtreehouse.com/forum/using-the-gem-money-it-will-not-allow-me-to-use-puts-price
[09/06/15 15:21:54] KADO Masanori: It needs to insert " I18n.enforce_available_locales = false" after ‘require “monetise”’
[09/06/15 15:41:33] KADO Masanori: It also needs “require ”forwardable“” before “require ”monetize“”
——
[14/06/15 16:37:34] KADO Masanori: monetize:
All versions don’t work, even github master … but it might be fixed in the future version. So It seems better to use a footnote if you don’t want to change the sample code (I also like current simple code).
[14/06/15 16:41:05] KADO Masanori: Like this (of course in Japanese) : If you encountered ``uninitialized constant Monetize::Collection::Forwardable (NameError)``, insert ``require “forwardable”`` into the top of the code. If you encountered ``enforce_available_locales!’: :en is not a valid locale (I18n::InvalidLocale)``, insert ``I18n.enforce_available_locales = false`` after ``require “monetize”``.

2016-05-15
1ERROR

appendix01: changed sample code at the point of ‘*’.

class MyClass

  • private :my_attribute=
    end

obj.set_attribute 11 # No error!

  • obj.my_attribute # => 11
2016-05-15
146TYPO

> “revert()” to explore_array, the method will evaluate the string “[’a’, ’b’, ’c’].revert()”. It’s time to try out this utility:

revert() should be reverse()

2016-05-15
1ERROR

Kado rightly observers that “the & operator” is a misnomer. It’s not technically an operator.

Some people call it “the & modifier”, but I’m not sure how common this is in English. Check it, and decide whether to add a one-sentence note to the book, or even change the name altogether.

2016-05-15
51TYPO

The last two lines in the “methods/dynamic_definition.rb” code sample are tests, and they shouldn’t appear in the text.

2016-05-15
193TYPO

The writer is describing the “save_with_validation!” and mistakenly reuse the name again when what he meant was “save_without_validation!”.
This is how it appears in the document -> “The actual validation happens in the valid? method. Validation#save_with_validation returns false if the validation fails, or if the caller explicitly disables validation. Otherwise, it just calls the original save_without_validation. Validation#save_with_validation! raises an exception if the validation fails, and otherwise falls back to the original save_with_validation!.”

2020-04-02Thanks, Bolatan! I'll submit this for the next printings, if we get any more.
¨82TYPO

In the Safari Books Online edition (no page numbers available), Chapter 3, Quiz: Bug Hunt, the sample output is:
5…​
 6…
​  10…
​  Bob got a 3​
 7…​
 4…
​  3…
​  Frank got a 10
(swap Bob’s and Frank’s lines). In the paragraph preceding the last listing in the same section, should be “Bill’s team”, not Frank’s.

2020-04-02I cannot believe nobody spotted this so far. Thank you! If we have another printing, I will fix it.
49OK

The Pry example is not behaving as advertised. Pry instances do not have a quiet= method, nor do they have a refresh method. Is there a specific version of Pry you are using for these examples?

2020-04-02Hey, Peter! I used Pry version 0.9.12.2, which is the version that you will find in the book's source code, under the 'gems' directory. (Ruby libraries typically change fast, so I expect that some examples became obsolete soon after the book came out. To make it easier for readers to make their own experiments, I packaged the versions of gems that I used in the book with the rest of the examples.)
35ERROR

The example regarding private method calls no longer works on ruby 2.7. Looks like it’s caused by Ruby issue number 16783 (which I would link to, but this form doesn’t accept links)

Thank you, Szymon. Yes, I'm aware that the behaviour of private methods changed slightly in Ruby 2.7. That's one of the few corner cases where information in the book became stale. However, it's not worth for us going through indexing/typesetting again to fix those rare inaccuracies. \nIf anything, we should wait for Ruby 3, and then consider a third edition. I'll leave this erratum here in case we ever decide for that. Thank you for reporting this!

Categories: