Errata

The Ruby Programming Language

Errata for The Ruby Programming Language

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released.

The following errata were submitted by our customers and have not yet been approved or disproved by the author or editor. They solely represent the opinion of the customer.

Color Key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted by Date submitted
all
all

The book seems never to mention the RUBYLIB environment variable (except once in the 10.5 Security chapter, but it doesn't explain what it is, there or elsewhere). This is a crucial piece of information and should not be omitted. Modification of RUBYLIB is a very important technique.

Anonymous  Apr 11, 2009 
PDF Page x
Section: Conventions Used in This Book

In Apple Preview (Version 6.0.1 (765.5), under Mac OS X 10.8.3), the font for Constant Width, Constant Width Bold, and Constant Width Italic is not correct. (Some other non-fixed-width font is substituted.) This problem exists for all code examples throughout the entire book. The font does appear correctly in Adobe Acrobat.

My copy of the PDF has
Creation Date: Jan 25, 2010 8:56 AM
Modification Date: Feb 14, 2013 7:12 AM

David Hull  May 04, 2013 
ePub Page 0000
Example 4-4

= album.getTracks.mapToInt( ...

Will not compile. .stream() is missing.

Must be: = album.getTracks.stream().mapToInt( ...

Kevin De Man  Mar 25, 2014 
Printed Page all
pervasive

The pervasive phrase "from other languages" is misleading at best; what is familiar depends on what languages you know. In particular, || is concatenation in some languages, not short circuit or. Phrases like "C-like languages" are more accurate. Some examples from other languages include

|| Concatenation of strings
||| Concatenation of lists
| Logical or
& Logical and
& Concatenation of strings
^ Logical and
^ Exponentiation
ª Exclusive or
ª Unary logical not
++ Union of csets
** Intersection of csets
:= Assignment
= Equal
== Strictly equal
<< Strictly less than
>> Strictly greater than

Shmuel (Seymour J.) Metz  Jan 18, 2018 
Printed Page 1,2,3
.nitems {|x| x > 2} # => 1: # of elts matching block (Ruby 1.9)

And replace them with these:

[1,2,nil].nitems # => 2: number of non-nil elements (Ruby 1.8 only)
[1,2,nil].count(nil) # => 1: # of nils (Enumerable method in Ruby 1.9)

Anonymous   
Printed Page 1,2,3
.count {|x| x > 2} # => 1: # of elts matching block (1.9)

Anonymous   
Printed Page 3
first code line

The comment to the first code line on page 3 says:

"true is a the singleton instance of TrueClass"

Should this be either "true is a singleton instance..." or "true is the singleton instance..."?

Sanders Kleinfeld  Dec 23, 2008 
PDF, ePub Page 3
1.1.2 Blocks and Iterators, second code example

The code is
a[3] = a[2] - 1
but should be
a[3] = a[2] + 1
to produce the output "4321"

David Hull  May 04, 2013 
5.1.2
near end of section

In section 5.1.2, the third column of the three examples showing how to express an if structure:

(
line1
line2
) end if expression

...the word "end" is a mistake and should be deleted.

Anonymous  Apr 07, 2009 
Printed Page 6
first paragraph

In the last line of the first paragraph on page 6, should "singletonmethods" be "singleton methods"?

Sanders Kleinfeld  Dec 24, 2008 
PDF Page 8
Sample code at the top

generation = case birthyear
when 1946..1963: "Baby Boomer"
when 1964..1976: "Generation X"
when 1978..2000: "Generation Y"
else nil
end

Comment:
According to the footnote on page 123, a colon (:) should not be used to terminate a when clause.

The when clauses don't cover year 1977.

Anonymous  Oct 09, 2011 
PDF Page 8
code example

It says:
# Determine US generation name based on birth year
# Case expression tests ranges with ===
generation = case birthyear
when 1946..1963: "Baby Boomer"
when 1964..1976: "Generation X"
when 1978..2000: "Generation Y"
else nil
end

but the '===' operator is not used I guess it should say:

# Determine US generation name based on birth year
# Case expression tests ranges with ===
generation = case birthyear
when 1946..1963 === "Baby Boomer"
when 1964..1976 === "Generation X"
when 1978..2000 === "Generation Y"
else nil
end

Anonymous  Feb 14, 2013 
PDF Page 14
Second group of examples

"enviroment" should read "environment".

Leo Wong  Mar 03, 2009 
Printed, PDF Page 15
Line 10

Complete coverage of RubyGems, the gem program, and the rubygems module are beyond the scope of this book.

Comment:
"are" -> "is"

Anonymous  Jan 31, 2012 
Printed, PDF Page 15
Second line from the bottom

a detailed overview of the core Ruby API

Comment:
An overview is not detailed by definition.

Anonymous  Apr 02, 2012 
Printed, PDF Page 16
Line 10

literals, variable references, method invocations, and assignments

Comment:
The word "method" is italicized. It's not necessary to do so.

Anonymous  Apr 03, 2012 
Printed Page 20
Top

(Found in the 12/08 edition; haven't examined other editions.)
The line "@grid = @grid.dup" in the dup method defined in the Sudoku solver's Puzzle class doesn't assign to the new Puzzle object a new duplicate of the @grid array. Instead, the original Puzzle object is assigned a new duplicate @grid, and the original @grid has been moved to the new Puzzle object. Although this may not cause a problem in the context of the Suduko solver, the technique seems misleading and potentially risky.

Here's test code that demonstrates the problem:

class Puz
def initialize(grid)
@grid = grid
end
def dup
copy = super
@grid = @grid.dup
copy
end
def grid_objid
@grid.object_id
end
end
#----------------------
pz = Puz.new("xyzzy")
puts "pz grid object id is: #{pz.grid_objid}"
pz2 = pz.dup
puts "pz grid object id is now: #{pz.grid_objid}"
puts "pz2 grid object id is: #{pz2.grid_objid}"

Steve Eppley  Mar 08, 2009 
Printed Page 26
2.1.1

The line:
x = "#This is a string" # And this is a comment

...should correctly read:
x = "#This is a string" # And this is not a comment

Anonymous   
Printed Page 26
2.1.1

The line:
y = /#This is a regular expression/ # Here's another comment

...should correctly read:
y = /#This is a regular expression/ # And this is also not a comment

Anonymous   
Printed, PDF Page 26
2.1.1

#
# This class represents a Complex number
# Despite its name, it is not complex at all.
#

Comment:
Since the second sentence ends with a period (.), end the first sentence with a period, too, like

#
# This class represents a Complex number.
# Despite its name, it is not complex at all.
#

Anonymous  Apr 08, 2012 
Printed Page 27
First code in section "Test Helpers"

from:
require File.dirname(__FILE__) + '/test_helpers'

to:
require_relative 'test_helpers'

Jan Friedrich  Jul 20, 2009 
28
First paragraph after 2.1.1 .1 Embedded documents

It is mentioned that:
Any text that appears after =begin "or" =end is part of the comment...

I think that the ONLY text that is ignored is the one after =begin, right?

Thanks.

Abder-Rahman  Jul 04, 2010 
Printed, PDF Page 30
2.1.5 Keywords

__LINE__
__ENCODING__
__FILE__

Comment:
Reorder alphabetically to
__ENCODING__
__FILE__
__LINE__

Anonymous  Feb 03, 2012 
Other Digital Version 34
comments on third code block

The text accompanying the example seems say that it is useful to consider control structure expressions such as if then...end as statements, even though they are expressions.

But the comments next to the code implies that the constituent expressions print x and x = x + 1 should be considered separate statements.

Shouldn't it be the whole control structure that is considered a statement? Or is it that these control expressions *contain* statements?

Thanks for any clarification,
Brian

Brian Jordan  Feb 01, 2011 
Printed Page 38
middle

There should be a note that ASCII-8 is not ASCII and a statement as to what code page is used for code points 127-255 when converting.

The reference to BOM is questionable. While it is true that some Microsoft applications incorrectly insert the UCS character U+FEFF "ZERO WIDTH NO-BREAK SPACE" when the encoding is not UTF-16, the concept of a byte-order mark is meaningless in UTF-8. Inserting U+FEFF at the beginning of a file actually breaks some software.

Shmuel (Seymour J.) Metz  Jan 18, 2018 
Printed Page 43
middle

Pages 43 and 323 do not explain how the components of a complex number are treated. Are they Integer, Float, Rational or polymorphic?

Shmuel (Seymour J.) Metz  Jan 18, 2018 
Printed Page 46
middle

The text should mention that, although Ruby does not support it, there is an IEEE standard for decimal floating point and that some hardware, .e.g., current IBM mainframes, support it.

Shmuel (Seymour J.) Metz  Jan 18, 2018 
Printed Page 50-51
second to last paragraph of pg. 50, throughout pg. 51

The "Q" in the sequence "%Q" is printed as a strange glyph that looks like a 0 with a squiggly, diagonal underscore. This glyph is not immediately recognizable as Q unless you already know it should be Q.

The misprint appears in both the original book (pg. 50-51) and the Japanese translation (pg. 53). The online version at Google Books has it correct as Q.

Matt Falkenhagen  Jan 20, 2010 
Printed Page 52
2nd paragraph

The following sentence...

After these lines have been read, the three string literals are concatenated into one.

...should also indicate that the the string concatenation is joined by newlines...

After these lines have been read, the three string literals are concatenated into one, joined by newlines (
).

Anonymous   
Printed Page 53
End of 3.2.1.6

The code example...

listing = Kernel.`(listcmd)

...is missing a closing `, but in either case (with or without a closing `) results in errors:

>> listcmd = 'ls'
=> "ls"
>> listing = Kernel.`(listcmd)
`# had to enter closing ` to proceed
SyntaxError: compile error
(irb):46: unterminated string meets end of file
from (irb):46
from :0
>> listing = Kernel.`(listcmd)`
SyntaxError: compile error
(irb):47: syntax error, unexpected tXSTRING_BEG, expecting $end
from (irb):47
from :0

Anonymous   
PDF Page 55
12th line from the bottom

a = 0;

It's better to remove the unnecessary semicolon (;).

Anonymous  Sep 30, 2011 
PDF Page 55
4th paragraph, last line of example code

alphabet << 256 # Error in Ruby 1.8: codes must be >=0 and < 256

should read

alphabet << 256 # Error in Ruby 1.8: codes must be >=0 and < 255

Anonymous  Aug 14, 2012 
Printed Page 56
bottom

Footnote marked with asterisk should appear on previous page, page 55.

Todd Shandelman  Nov 19, 2009 
PDF Page 56
Sample code (2 places)

s = 'hello'; # Ruby 1.8

s = 'hello'; # Ruby 1.9

It's better to remove unnecessary semicolons (;).

Anonymous  Sep 30, 2011 
Printed Page 57
3rd line

s[s.length] = ?! succeeds in Ruby 1.9. The book states it is an error.

irb(main):001:0> s = 'hello'
=> "hello"
irb(main):002:0> s[s.length] = ?!
=> "!"
irb(main):003:0> s
=> "hello!"
irb(main):004:0>

$ ruby --version
ruby 1.9.1 (2008-12-16 revision 20770) [i686-linux]

James Ravn  Dec 15, 2008 
Printed Page 57
3rd line

s[s.length] = ?! # this is NOT an error in Ruby 1.9+

Thanos Tsouanas  Feb 10, 2014 
PDF Page 58
12th line from the top

s["l"] = "L"; # Replace first occurrence of "l" with "L"

It's better to remove the unnecessary semicolon (;).

Anonymous  Sep 30, 2011 
PDF Page 58
3.2.5 Sample code

s.each_char {|x| print "#{x} " } # Prints "? 1 0 0 0". Ruby 1.9

The comment should be

# Prints "? 1 0 0 0 ". Ruby 1.9

(Add a space after the third 0.)

Anonymous  Sep 30, 2011 
Printed, PDF Page 58
Line 11 and 12

s = "hello"
while(s["l"])
s["l"] = "L";
end

Comment:
Change the code as shown below to honor Ruby's conventions:

s = "hello"
while s["l"]
s["l"] = "L"
end

2nd line - remove parentheses *
3rd line - remove ;

* Apply this change to the while statements on the following pages as well:
134, 135, 148, 149, 151, 189, 190 (2 instances), 191, 386

Anonymous  Mar 17, 2012 
PDF Page 59
Sample code (3 places)

s.bytesize.times {|i| print s.getbyte(i), " "} # Prints "50 195 151 50 61 52"

Change the comment to

# Prints "50 195 151 50 61 52 "

(Add a space after 52)

---

s.length.times { |i| print s[i], " "} # Prints "2 ? 2 = 4"

Change the comment to

# Prints "2 ? 2 = 4 "

(Add a space after 4)

---

s.setbyte(5, s.getbyte(5)+1); # s is now "2?2=5"

It's better to remove the unnecessary semicolon (;).

Anonymous  Oct 01, 2011 
Printed Page 61
code example, bottom of page

Comment saying

# Transcode to Latin-15

should be

# Transcode to Latin-9

because that is the latin-X equivalent of ISO-8859-15.

See http://en.wikipedia.org/wiki/ISO/IEC_8859-15

Anonymous  Feb 13, 2014 
PDF Page 64
7th line from the bottom

Ruby includes a special-case syntax for expressing array literals whose elements are short strings without spaces:

Comment:
Remove "short". The syntax doesn't limit strings to be short.

Anonymous  Oct 02, 2011 
Printed Page 66
5th paragraph, not counting code insets

Paragraph states "Note that these operators are not transitive: a|b is not the same as b|a, for example."

You're confusing "transitive" with "commutative." "Transitive" refers to relations like "<", and states, e.g. that (a < b && b < c) => (a < c).

Andy Lowry  Jun 15, 2009 
Printed Page 66
"Note that..." paragraph

It is mentioned that | is not "transitive", while in fact the author(s) explain that it is not *commutative*.

Thanos Tsouanas  Feb 10, 2014 
Printed Page 66
middle

"transitive" should be "commutative". An operation O is commutative if for every a and b, a O b = b O a; a *relation* R is transitive if whenever a R b and b R c then a R c.

Shmuel (Seymour J.) Metz  Jan 18, 2018 
Printed Page 68
bottom

Footnote at bottom of page 68 should appear on previous page, page 67.

=====================================================================

Note: My version of the book says:
Printing History: Jan. 2008: First edition.

Todd Shandelman  Nov 19, 2009 
PDF Page 68
2nd line in 3.5 Ranges

between the start and end value.

Comment:
Should "value" be changed to "values"?

Anonymous  Oct 02, 2011 
PDF Page 69
last line to 8th line of page 70

begin...end
begin <= x <= end
begin <= x < end
begin, begin.succ, begin.succ.succ

Comment:

According to "Conventions Used in This Book" on page x, the constant width font is used for program listings, as well as within paragraphs to refer to program elements such as variable or function names, datatypes, environment variables, statements, and keywords.

The above lines are written in the constant width font but can't be valid program elements because "begin" and "end" are keywords and <= and < can't be chained as "a <= b < c".

Anonymous  Oct 02, 2011 
PDF Page 70
10th line

only if it is a value returned by one of the succ invocations.

Comment:

Change to

only if it is a start value or a value returned by one of the succ invocations.

Anonymous  Oct 02, 2011 
PDF Page 73
first paragraph of 3.8.2, Object Lifetime

On page 29 the author said "Class and module names must begin with initial capital letters." So I assume that "myObject = myClass.new" is a mistake. Also, there's a discrepancy in the name of the class between that code snippet and the following sentence, where the name of the class is given as "Class."

Bob Kline  Apr 10, 2012 
Printed Page 73
8th paragraph

At the start of the 8th paragraph, the following sentence appears:

"Ruby objects never need to be explicitly deallocated, as they do in languages like C and C++"

While it is correct that in C++ objects need to be explicitly deallocated, this is not the case in C because C is not an object-oriented language. The sentence should say something like the following instead:

"Ruby objects never need to be explicitly deallocated as they do in C++"

Jason Gero  Jun 09, 2015 
PDF Page 75
3rd line

we would also like to know if the object is an instance of any subclass of that class.

Comment:
Change subclass -> superclass

Anonymous  Oct 03, 2011 
PDF Page 75
13th line

The Class class defines the === operator

Comment:
The Class class doesn't define the === operator but inherits it.

Anonymous  Oct 03, 2011 
PDF Page 76
1st line in 3.8.5.1

The equal? method is defined by Object

Comment:
For accuracy, make a reference to "BasicObject in Ruby 1.9" on page 235.

Anonymous  Oct 04, 2011 
PDF Page 77
4th line in 3.8.5.3

1.eql?(1.0) # false: but they are never eql!

Comment:
Chnage eql! in the comment to eql?

Anonymous  Oct 04, 2011 
Printed Page 78
First block of example code

The following example:

:s === "s" # true in Ruby 1.9

states that using Ruby's version 1.9 it should return true. I'm using Ruby version 1.9.2 on a Mac and the same example returns false.

I would like to know if there has been some change about it or if I'm doing something wrong.

Thanks in advance.

Greetings,

Ramon Maria

Ramon Maria  Sep 07, 2011 
PDF Page 78
3rd line

And Class defines === to test whether an object is an instance of that class.

Comment:
According to the Ruby 1.9 documentation, Class doesn't define === but it inherits ===.

Anonymous  Oct 04, 2011 
PDF Page 78
Portugal

Section 3.8.5.4 - The === operator

In the last example of the section, where it reads

:s === "s" # true in Ruby 1.9

It's not actually true, I tested it on ruby 1.9.2 and ruby 1.9.3 and :s === "s" is false.
Not sure if I'm actually missing something here, would appreciate some clarification.

Jo?o Soares  Mar 08, 2012 
Printed, PDF Page 82
3.8.7.5

Suppose you want to test whether the variable x is nil or not. In some languages, you must explicitly write a comparison expression that evaluates to true or false:

if x != nil # Expression "x != nil" returns true or false to the if
puts x # Print x if it is defined
end

This code works in Ruby, but it is more common simply to take advantage of the fact that all values other than nil and false behave like true:

if x # If x is non-nil
puts x # Then print it
end

Comment:
It sounds you're saying you can rewrite the first code snippet to the second but these code snippets behave differently when x == false.

Anonymous  Mar 09, 2012 
Printed Page 82
middle

There should be an note that the conversion rules given for arithmetic conversion prevent normally commutative operations from being commutative on mixed types, e.g., 1 + 1.1 does not give the same result as 1.1 + 1.

Shmuel (Seymour J.) Metz  Jan 18, 2018 
PDF Page 84
Sample code

s[0] = "ni" # TypeError: can't modify frozen string

Comment:
Ruby 1.9 returns RuntimeError, not TypeError.

Anonymous  Oct 04, 2011 
Printed Page 87
middle

"If a . or :: appears in an expression" should be "If a period not part of a numeric constant or a :: not part of a quoted string appears in an expression"

Shmuel (Seymour J.) Metz  Jan 18, 2018 
Printed Page 94
bottom

the following sentence is incorrect:
"Then o.m can be used as an lvalue in an assignment expression."

An lvalue is an address of something, so that the compiler or
interpreter can store the value from the right side there. But in the
example "o.m" does not have an address, as it is a method invocation.
The complete term "o.m = v" is no assignment at all. This is even noted
in the first sentence of this section: "Assignment to an attribute or
array element is actually Ruby shorthand for method invocation."

Anonymous  Jan 06, 2012 
Printed Page 94
middle

Pages 94-97 should note that the existence of m and m= methods does not guaranty that m is a simple attribute. For instance, an array-like object might have a length= method with the side effect of extending or truncating the array.

Shmuel (Seymour J.) Metz  Jan 18, 2018 
Printed Page 97
middle

I know the || operator from other languages, and it's concatenation. Only in languages derived from C is || short circuit or. The text should not make assumptions about what languages the reader knows.

Shmuel (Seymour J.) Metz  Jan 18, 2018 
PDF Page 99
Paragraph right before 4.5.5.6

Finally, recall that earlier we described two simple cases of parallel assignment in which there is a single lvalue or a single rvalue.

Comment:
Change "a single rvalue" to "a single array rvalue" because this explanation applies to a case like
x, y, z = [1, 2, 3]
but not to a case like
x, y, z = 1

Anonymous  Oct 05, 2011 
PDF Page 100
2nd line

In order for it to work, b must be a splattable object such as an array or enumerator.

Comment:
It is inaccurate to say that b must be a splattable object in order for
x,(y,z) = a, b
to work. If a=1 and b=2, the result is x=1, y=2, z=nil and the assignment still "works." Tested with Ruby 1.9.2 on Windows.

Anonymous  Oct 05, 2011 
PDF Page 100
4.5.5.7

The return value of a parallel assignment expression is the array of rvalues (after being augmented by any splat operators).

Comment:
Ruby 1.9.2 on Windows doesn't give the stated result:
>> x, y = 1, 2
=> [1, 2]
>> x, y = 1
=> 1
The return value of the first assignment is an array but that of the second assignment is not an array [1].

Anonymous  Oct 05, 2011 
PDF Page 108
Middle of the page

1 || 2 && nil # => 1
The && is performed first,

Comment:
It is misleading to say that the && is "performed" because 2 && nil is not evaluated because of short-circuiting.

Anonymous  Oct 09, 2011 
PDF Page 109
Sample code above 4.6.9

x || y && nil # && is performed first => x
x or y and nil # evaluated left-to-right => nil

Comment:
The return values shown in the comments are not necessarily correct.

First expression "x || y && nil"
If x = false and y = true, for example, the expression returns nil, which is not x (false). See also my comment for page 108 about "performed."

Second expression "x or y and nil".
If x = false and y = false, the expression returns false, not nil.

Anonymous  Oct 09, 2011 
Printed Page 113
2nd paragraph

Section 4.6.11 - Assignment Operators

"Finally, note that although assignment operators cannot be defined as methods, "

huh? Sure you can.

http://ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html

This kind of dead simple operator overloading is one of the best things about Ruby.

The worse thing is the horrid state of its free documentation, but I digress.

Michael Soulier  Jun 05, 2010 
Printed Page 114
Section 4.6.13, 3rd paragraph, 1st sentence.

typo: "operfators" should be "operators"

Roger Smith  Dec 18, 2008 
PDF Page 114
Sample code right before 4.6.13

Page 114
defined? a && defined? b # Evaluated as: defined?((a && defined? b))

Comment:
Is it necessary to use two pairs of parentheses as shown in the comment?

Anonymous  Oct 09, 2011 
Printed Page 115
. and ::

Perhaps deleting "These are not operators because the righthand side is not a value but and identifier" would be simpler than addressing [1.size, (1+1).size, 'hey'.size].sort.reverse or explaining "abc"::reverse, etc.

Is it so wrong to think of . as a very high precedence, non-overridable operator within expressions?

Anonymous  Jan 12, 2011 
Printed Page 115
;, ,, and =>

You may want to add "<= also has a role in rescue clauses."

Anonymous  Jan 12, 2011 
Printed Page 115
*, &, and <

Change header to: *, &, <, and <<

And add to the description:

<< is used for eigenclass access and singleton method definitions.

Anonymous  Jan 12, 2011 
PDF Page 122
Code after the second paragraph

(
line1
line2
) end if expression

Comment:

Remove "end" as

(
line1
line2
) if expression

Anonymous  Dec 20, 2011 
Printed Page 122
middle

The text refers to a begin (lower case) statement but there is no begin in the index. The text should refer to the section on exceptions and there should be an index entry.

Shmuel (Seymour J.) Metz  Jan 18, 2018 
Printed, PDF Page 124
9th line from the bottom

when 2 then "two" # Then keyword instead of newline

Comment:
In the comment, change "Then" to "then".

Anonymous  Oct 20, 2011 
Printed, PDF Page 124
4th line from the bottom

the values obtained by evaluating the when expression.

Comment:
Change "expression" to "expressions".

Anonymous  Oct 20, 2011 
Printed, PDF Page 125
17th line

The Class class defines ===

Comment:
=== is defined by Module, not by Class.

Anonymous  Oct 20, 2011 
Printed, PDF Page 125
21st line

In Ruby 1.9,Symbol

Comment:
Add a space between the comma (,) and "S".

Anonymous  Oct 20, 2011 
Printed, PDF Page 125
Sample code at the bottom

<code>
# Compute 2006 U.S. income tax using case and Range objects
tax = case income
when 0..7550
income * 0.1
when 7550..30650
755 + (income-7550)*0.15
when 30650..74200
4220 + (income-30655)*0.25
when 74200..154800
15107.5 + (income-74201)*0.28
when 154800..336550
37675.5 + (income-154800)*0.33
else
97653 + (income-336550)*0.35
end
</code>

Comment:
Check the numbers. For example,

4220 + (income-30655)*0.25
30655 should be 30650

15107.5 + (income-74201)*0.28
74201 should be 74200

Anonymous  Oct 20, 2011 
Printed, PDF Page 126
Code at the top

while line=gets.chomp do # Loop, asking the user for input each time
case line
when /^\s*#/ # If input looks like a comment...
next # skip to the next line.
when /^quit$/i # If input is "quit" (case insensitive)...
break # exit the loop.
else # Otherwise...
puts line.reverse # reverse the user's input and print it.
end
end

Comment:
The line
next # skip to the next line.
is indented by 4 spaces from the previous line. It should be indented by 2 spaces.

Anonymous  Apr 29, 2012 
Printed Page 127
Section 5.2.1, 2nd paragraph (not counting code blocks), 2nd sentence

"...between the do and the end keyword."
'keyword' is in constant width bold font. 'keyword' should be in the normal prose font.

Roger Smith  Dec 18, 2008 
Printed, PDF Page 127
5.2.1 code

while x >= 0 do
...
end # The loop ends here

until x > 10 do
...
end # Loop ends here

Comment:
The first comment includes "The" but the second doesn't. Is there any reason for the difference?

Anonymous  Apr 04, 2012 
Printed, PDF Page 132
Line 3

In general, n.upto(m) runs its block m-n+1 times.

Comment:
Need to explain what happens if m < n.

Anonymous  Mar 21, 2012 
Printed, PDF Page 132
Lines 1 and 9

Line 1: 4.upto(6) {|x| print x} # => prints "456"
Line 9: 3.times {|x| print x } # => prints "012"

Comment:
On Line1, there is no space between x and }.
On Line 9, there is a space between x and }.
There are numerous style inconsistencies of this kind in this book.

Anonymous  Mar 23, 2012 
Printed Page 134
middle

It is in fact not clear from the examples and text why the yield method is called what it is; it looks like yield only calls a procedure parameter. The reasons for calling it yield does not become clear until the book introduces external iterators, which behave like coroutines. A forward reference to external iterators would be appropriate here, or else something like "the reason for the nomenclature will become clear in section 5.3.5.".

Shmuel (Seymour J.) Metz  Jan 18, 2018 
Printed, PDF Page 136
Lines 12-13

So, to pass an array enumerator to a method rather than the array itself, you can simply call the each method:

Comment:
This should read:

So, to pass a string enumerator to a method rather than the string itself, you can simply call the each_char method:

Anonymous  May 10, 2012 
Printed, PDF Page 140
7th line in 5.3.6

a.each {|x| puts "#{x},#{a.shift}" } # prints "1,1\n3,2\n5,3"

Comment:
Add \n after 5,3 so the code looks

a.each {|x| puts "#{x},#{a.shift}" } # prints "1,1\n3,2\n5,3\n"

Anonymous  Mar 23, 2012 
Printed, PDF Page 140
9th line from the bottom

5.4 Blocks

Comment:
Since 2.2.1 (page 35) says "There are two kinds of blocks in Ruby programs.", add a footnote to explain "blocks" here refer to formal blocks.

Anonymous  Apr 08, 2012 
Printed, PDF Page 141
13th line from the bottom

they are otherwise much like method parameters (see ?5.4.5 for details):

Comment:
?5.4.4 is a better sub-section to refer to because it begins with "We?ve said previously that the parameters to a block are much like the parameters to a method."

Anonymous  Apr 08, 2012 
Printed Page 143
3rd paragraph

In the code example the following:
1.upto(4) do |x;y| # x and y are local to block

should read:
1.upto(4) do |x;y| # y is local to block

Anonymous  Sep 04, 2010 
Printed, PDF Page 145
6th line in 5.4.5

five do |head, *body, tail| # Extra values go into body array
print head, body, tail # Prints "1[2,3,4]5"
end

Comment:
With Ruby 1.9.2, "1[2, 3, 4]5" is printed (There is a space after 2, and 3,).

Anonymous  Mar 25, 2012 
Printed, PDF Page 147
Figure 5-2

Figure 5-2.

Comments:
|y| should be inside the "block" box.

Also for ease of understanding,
Arrow 1 should start at "iterator" of z = x.iterator,
Arrow 2 should point to the top part of the "block" box.

Anonymous  Mar 25, 2012 
Printed Page 148
United States

The eval in both examples should use double quotes instead of parenthesis: puts eval "line"

Otherwise it generates an error: in `eval': undefined local variable or method `test' for main:Object (NameError)

This might work fine in 1.8, but in 1.9.3...it failed.

Great book BTW.


Chris Yeun  Feb 05, 2015 
Printed, PDF Page 149
Figure 5-3

Figure 5-3.

Comments:
|y| should be inside the "block" box.

Also for ease of understanding,
Arrow 1 should start at "iterator" of z = x.iterator,
Arrow 2 should point to the top part of the "block" box.

Anonymous  Mar 25, 2012 
Printed, PDF Page 150
Figure 5-4

Figure 5-4.

Comments:
|y| should be inside the "block" box.

Also for ease of understanding,
Arrow 1 should start at "iterator" of z = x.iterator,
Arrow 2 should point to the top part of the "block" box.

Anonymous  Mar 25, 2012 
Printed, PDF Page 150
7th line from the bottom

the value of those expressions.

Comment:
value -> values

Anonymous  May 16, 2012 
Printed, PDF Page 153
Sample Code

Sample code for throw and catch

Comment:
Right before this sample code, you write "it is best to consider throw and catch as a general-purpose (if perhaps infrequently used) control structure rather than an exception mechanism" but this sample code demonstrates handling an unexpected circumstance - the value of an element of a matrix is missing - for which the exception mechanism with raise and rescue is probably more suited.

Anonymous  Apr 13, 2012 
Printed, PDF Page 153
Second paragraph

But throw and catch are much more general than a labeled break. For one, it can be used with any kind of statement and is not restricted to loops.

Comment
it can be used -> they can be used
and is not restricted -> and are not restricted

Anonymous  May 18, 2012 
Printed, PDF Page 154
10th line

The return value of catch can help you distinguish normal completion of the block from abnormal completion with throw,

Comment:
Since throw and catch are a general-purpose control structure, throw doesn't necessarily mean "abnormal" completion.

Anonymous  Apr 13, 2012 
PDF Page 157
Bullet point 4, 2nd paragraph

The relevant paragraph is

"raise accepts a string as its optional second argument. If a string is specified, it is passed to the exception method of the first argument. This string is intended for use as the exception message."

The first sentence is, I believe, misleading. raise accepts any object, which may be subsequently inspected. I've found this behaviour extremely useful.

An irb session, tested on both Ruby 1.8 MRI and 1.9 MRI, illustrates.

irb(main):001:0> class Foo; attr_accessor :bar; end
=> nil
irb(main):002:0> f = Foo.new
=> #<Foo:0x3b4ea8>
irb(main):003:0> f.bar = 10
=> 10
irb(main):004:0> begin; raise RuntimeError, f; rescue => e; puts e.message.bar; end
10
=> nil

Regards
Paul

Paul Carey  Jan 08, 2009 
Printed, PDF Page 157
Various places

Comment:
factorial(0) should not raise an exception, since 0! = 1 by convention in mathematics. Change the code and text as follows:

Page 157

def factorial(n) # Define a factorial method with argument n
raise "bad argument" if n < 0 # Raise an exception for bad n
return 1 if n == 0 # factorial(0) is 1
n * factorial(n-1) # Compute other factorials recursively
end


raise RuntimeError, "bad argument" if n < 0
raise RuntimeError.new("bad argument") if n < 0
raise RuntimeError.exception("bad argument") if n < 0


raise ArgumentError if n < 0

raise ArgumentError, "Expected argument >= 0. Got #{n}" if n < 0


Page 158

if n < 0
raise ArgumentError, "Expected argument >= 0. Got #{n}", caller
end


Ruby compares the argument n to the integer 0 with the < operator.

Anonymous  Mar 28, 2012 
Printed, PDF Page 159
Third paragraph from the bottom

Recall that the factorial method we defined earlier can raise ArgumentError or TypeError. Here?s how we would write a rescue clause to handle exceptions of either of these types and assign the exception object to the variable error:

rescue ArgumentError, TypeError => error

Comment:
As explained on page 158, the factorial method can raise NoMethodError as well. So the paragraph should be updated to:

Recall that the factorial method we defined earlier can raise ArgumentError, TypeError, or NoMethodError. Here?s how we would write a rescue clause to handle exceptions of any of these types and assign the exception object to the variable error:

rescue ArgumentError, TypeError, NoMethodError => error

Anonymous  May 05, 2012 
Printed, PDF Page 159
Last paragraph and code at the top of page 160.

Comment:
The paragraph and the code that follows should be updated to cover NoMethodError as well. The code should look:

begin
x = factorial(1)
rescue ArgumentError => ex
puts "Try again with a value >= 1"
rescue TypeError, NoMethodError => ex
puts "Try again with an integer"
end

Anonymous  May 05, 2012 
Printed, PDF Page 164
5.6.6

# it throws an exception, or if it executes a return statement.

Comment:
Change "throws" to "raises" as
# it raises an exception, or if it executes a return statement.

Anonymous  Mar 31, 2012 
Printed, PDF Page 164
4th line

If a begin statement does not propagate an exception, then the value of the statement is the value of the last expression evaluated in the begin, rescue, or else clauses.

Comment:
Is it possible that a begin statement does not propagate an exception but an expression is still evaluated in the rescue clause?

Anonymous  May 06, 2012 
Printed, PDF Page 165
First line in 5.7

BEGIN and ENDare reserved words...

Comment:
Add a space between "END" and "are" as
BEGIN and END are reserved words...

Anonymous  Mar 31, 2012 
Printed, PDF Page 165
Code at the bottom

BEGIN {
puts "if"; # This will be printed
a = 4; # This variable only defined here
}

Comment:
Remove unnecessary semicolons as

BEGIN {
puts "if" # This will be printed
a = 4 # This variable only defined here
}

Anonymous  Mar 31, 2012 
Printed, PDF Page 165
Code at the bottom

if (false)

Comment:
Remove unnecessary parentheses as

if false

Anonymous  Mar 31, 2012 
Printed, PDF Page 166
Code in the middle

a = 4;
if (true)
END { # This END is executed
puts "if"; # This code is registered
puts a # The variable is visible; prints "4"
}
else

Comment:
Remove unnecessary parentheses and semicolons as

a = 4
if true
END { # This END is executed
puts "if" # This code is registered
puts a # The variable is visible; prints "4"
}
else

Anonymous  Mar 31, 2012 
Printed, PDF Page 168
First sentence in 5.8.2.1

Fibers and their callers can exchange data through the arguments and return values of resume and yield.

Comment:
yield -> Fiber.yield

Anonymous  May 26, 2012 
Printed, PDF Page 171
Sample code

f = g = nil

f = Fiber.new {|x| # 1:
...
}

g = Fiber.new {|x| # 8:
...
}

Comment:
It is not necessary to initialize f with nil. To follow the common convention (page 141), use do/end, instead of curly braces, to delimit the blocks. The result should look:

g = nil

f = Fiber.new do |x| # 1:
...
end

g = Fiber.new do |x| # 8:
...
end

Anonymous  Apr 03, 2012 
Printed, PDF Page 171
10th line in 5.8.2.3

the caller uses resume and the fiber uses yield.

Comment:
yield -> Fiber.yield

Anonymous  May 26, 2012 
Printed, PDF Page 172
8th line in 5.8.3

JRuby, the Java-based implementation

Comment:
The word "JRuby" is used without a qualification at line 8 on the previous page. So the explanation "the Java-based implementation" should be attached to "JRuby" on the previous page. Or remove it because JRuby explained on page 12.

Anonymous  May 26, 2012 
PDF Page 176
8th line from the bottom

methods names

Comment:
methods names -> method names

Anonymous  Oct 30, 2011 
Printed Page 177
Bottom of page

factorial(0) = 1 by convention, including elsewhere in the book. So to be consistent, and true to the spirit of the example, change error condition from n < 1 to n < 0.

Anonymous  Dec 18, 2010 
PDF Page 177
8th line from the bottom

In the factorial method, that last expression will either be 1 or n*factorial(n-1).

Comment:
In the factorial method, the last (and only) expression is the "if" statement. 1 or n*factorial(n-1) is a sub-expression "if" evaluates.

Anonymous  Oct 30, 2011 
Printed, PDF Page 177
5th line

that cover method names, method parentheses, and method arguments in more detail.

Comment:
method arguments -> method parameters

Note the 8th line from the bottom on the previos page (p.176) reads:

covering methods names, method parentheses, and method parameters.

Anonymous  Jun 05, 2012 
Printed, PDF Page 182
3rd line from the bottom

these arguments may be omitted form method invocations.

Comment:
Change "form" to "from".

Anonymous  Oct 22, 2011 
PDF Page 182
line 1

the same method thats also_known_as does.

Comment:
thats -> that

Anonymous  Apr 18, 2013 
Printed, PDF Page 184
Lines 6-8

The following code, using the sum method defined above, prints 4, but issues a warning in Ruby 1.8:
puts sum 2, 2

Comment:
Tried this with Ruby 1.8.7 but didn't see a warning.

Anonymous  May 26, 2012 
Printed, PDF Page 185
First bullet point in 6.4

How to declare an argument that has a default value, so that the argument can be omitted when the method is invoked

Comment:
an argument that has a default value
-> a parameter that has a default value

Anonymous  May 27, 2012 
Printed, PDF Page 188
8th line from the bottom

Arguments n, m, and c are passed as keys in a hash,

Comment:
It is more accurate to say "Arguments n, m, and c are passed as values associated with keys in a hash," or simply,
"Arguments n, m, and c are passed as hash values,"

Anonymous  Oct 31, 2011 
Printed, PDF Page 198
Second sample program from the bottom

def test
puts "entering method"
p = lambda { puts "entering lambda"; return }
p.call # Invoking the lambda does not make the method return
puts "exiting method" # This line *is* executed now
end
test

Comment:
For the name of the variable that refers to the lambda, it's better to use "l" like in the next sample program.

Anonymous  Jun 02, 2012 
PDF Page 200
6.5.5.4

p.call(1) # x,y=1: nil used for missing rvalue: Prints 1nil

Comment:
Ruby 1.9.3 prints just "1", not "1nil".

Anonymous  Apr 30, 2013 
Printed Page 208
2nd code in section 6.8.3

from:
module Functional
.... omission....
# Example:
# product = lambda {|x,y| x*y}
# doubler = lambda >> 2 <== here

to:
module Functional
.... omission....
# Example:
# product = lambda {|x,y| x*y}
# doubler = product >> 2 <== here

Anonymous   
Printed Page 208
2nd line

double = lambda {|x| product(2,x) }

should be

double = lambda {|x| product[2,x] }

Christian Campbell  Jul 03, 2009 
Printed Page 211
top of page

The call to self.instance_eval is not needed here. The following code works just fine with Ruby 2.1:

class Module
def []=(symbol, f)
define_method(symbol, f)
end
end


Enumerable[:average] = lambda do
puts "average"
end

[1].average

Anonymous  Aug 17, 2015 
PDF Page 218
4th paragraph

The typo is in the word "method" in:

... so you can invoke these "method" inside any class definition...

As I think it should be "methods"

Thanks.

Anonymous  Aug 13, 2011 
Printed Page 221
Bottom code sample

The code in the book is:

# Define [] method to allow a Point to look like an array or
# a hash with keys :x and :y
def [](index)
case index
when 0, -2: @x # Index 0 (or -2) is the X coordinate
when 1, -1: @y # Index 1 (or -1) is the Y coordinate
when :x, "x": @x # Hash keys as symbol or string for X
when :y, "y": @y # Hash keys as symbol or string for Y
else nil # Arrays and hashes just return nil on bad indexes
end
end

Using a colon instead of "then" doesn't work any more in Ruby 1.9.
The code should be:

# Define [] method to allow a Point to look like an array or
# a hash with keys :x and :y
def [](index)
case index
when 0, -2 then @x # Index 0 (or -2) is the X coordinate
when 1, -1 then @y # Index 1 (or -1) is the Y coordinate
when :x, "x" then @x # Hash keys as symbol or string for X
when :y, "y" then @y # Hash keys as symbol or string for Y
else nil # Arrays and hashes just return nil on bad indexes
end
end

Jeremiah LaRocco  Apr 18, 2010 
Printed Page 221
The last 4 lines of the page

In the class method "def []index", the 4 lines following "case" keyword:
when 0, -2: @x
when 1, -1: @y
when :x, "x": @x
when :y, "y": @y

In each when clauses, the colons should be replaced by semicolons. The correct code is :
when 0, -2; @x
when 1, -1; @y
when :x, "x"; @x
when :y, "y"; @y

Fan Chou  Apr 23, 2012 
Printed Page 232
general

And the PDF. Also p. 237.

I think it might be worth mentioning that a method on a superclass can call *private* subclass methods if the object is an instance of the subclass (since the superclass method is inherited).

E.g.,

class Super
def full_name
"#{first} #{last}"
end
end

class Sub < Super
attr_reader :first, :last
def initialize(first, last)
@first, @last = first, last
end
private :first, :last
end

s = Sub.new("John", "Norman")
puts s.full_name

In other words, "private" is all about self, and not allowing a receiver. I think the language about access from subclasses is a bit misleading.

John Norman  Oct 09, 2009 
Printed Page 238
Code

Redundant semicolon. (Also on page 239.)

Anonymous   
Printed Page 238
2nd paragraph of 7.3.3

super doesn't just look at superclasses for chaining. It can also chain to methods inherited from modules. And a singleton method defined on an object can use super to chain to an instance method defined by the class of the object.

David Flanagan
 
May 13, 2009 
Printed Page 240
3rd paragraph from bottom

In "is it actually something different" transpose "it" and "is".

Anonymous   
Printed, PDF Page 250
9th line in 7.5.2

To mix a module into a class, use include.

Comment:
This "include" should have an entry in the Index section of the book.

Anonymous  Mar 25, 2012 
PDF Page 251
4th line of 7.5.3

Change:

include 'Math' # The Math namespace can be included

To:

include Math # The Math namespace can be included

(This was already reported for 'printed' and 'other digital', so why is this error still present in the PDF?)

TPReal  Sep 01, 2009 
Printed Page 251
Last paragraph of section 7.5.2

The parentheses that reads "(And if the receiver object is a Class instance, then the methods of the receiver become class methods of that class.)" should read "(And if the receiver object is a Class instance, then the methods of the specified module or modules become class methods of that class.)".

Jonas Collberg  Jan 23, 2010 
PDF Page 255
first line of 7.6.2

The first four words of the section 7.6.2 are: 'load and require execute' (where 'load' and 'require' are ruby function names, in monospace font). Those four words are not separated by spaces.

TPReal  Sep 01, 2009 
Printed Page 261
2nd Paragraph

The paragraph says:

"Class objects are special: they have superclasses. The eigenclasses of
class objects are also special: they have superclasses, too. The
eigenclass of an ordinary object stands alone and has no superclass."

Both the eigenclass of a class object and the eigenclass of an ordinary object have a superclass. If not then sending a message to an ordinary object would end up invoking method_missing.

I think that the paragraph should read:

"Class objects are special: they can have subclasses. The eigenclasses of
class objects are also special: they can have subclasses, too. The
eigenclass of an ordinary object can have neither a subclass, nor any other instance except that single ordinary object. If an ordinary object with an eigenclass is duplicated with the Object#dup method, the duplicate will not acquire any of it's singleton methods. If it is cloned with the Object#clone method, the result will get an eigenclass which is a duplicate of the original objects eigenclass, so that each eigenclass has but a single instance."

The following ruby code (which behaves identically on Ruby 1.8.6, 1.8.7 and 1.9.1) illustrates the above:

module Kernel
def eigenclass
class << self;self;end
end
end

class TestClass

def bar
:bar
end

def self.foo
:foo
end
end

t = TestClass.new
def t.gorp
:gorp
end

p t_eigenclass = t.eigenclass # => #<Class:#<TestClass:0x232d0>>
p t_eigenclass.superclass # => #<Class:TestClass>

p t.bar # => :bar
p t.gorp # => :gorp

p t_dup = t.dup
p t_clone = t.clone
p t_clone.respond_to?(:gorp) # => true
p t_clone.eigenclass == t_eigenclass # => false
p t_dup.respond_to?(:gorp) # => false

p t.class.foo # => :foo
p t.eigenclass.foo # => :foo

Rick DeNatale  May 07, 2009 
Printed Page 261
2nd paragraph

The sentence: "The eigenclass of an ordinary object stands alone and has no superclass" is not correct. The description of method lookup in this section is correct, but the details about superclasses of eigenclasses strays into messy implementation-dependent behavior.

See http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/336490 for some discussion.

David Flanagan
 
May 13, 2009 
Printed Page 271
paragraph after exemple code in section 8.3.1

The book says "eval can alter the value of instance variables that already exist. But any new instance variables it defines are local to the invocation of eval and cease to exist when it returns."

This should say local variables instead of instance variables in both cases.

Eval can alter INSTANCE variables, whether they exist or not. If an instance variable is set by eval, it will be created in the receiver of eval, just as it would be if this were done by executing a method on an object for which this is the first assignment to the instance variable.

irb(main):001:0> eval("self")
=> main
irb(main):002:0> self
=> main
irb(main):003:0> eval("@x = 1")
=> 1
irb(main):004:0> @x
=> 1

Rick DeNatale  Feb 24, 2009 
PDF Page 277
2nd paragraph of 8.5

Change this:

Recall that class methods are inherited, so that the an inherited method will be ...

To this (remove the word 'an'):

Recall that class methods are inherited, so that the inherited method will be ...

TPReal  Sep 01, 2009 
PDF Page 278
4th paragraph

In the part about the method_added hook, it is said:

(...) there is no way to tell whether the named method was added to the class that defines method_added or whether it was added to a subclass of this class.

Next, a workaround solution for this problem is given. But in fact no workaround is needed - the class to which the new method was added is stored in self when inside the hook method. A simple code to demonstrate it:

class A;def A.method_added(m);p [self,m];end;end
class B<A;end
class A;def q;end;end # prints [A, :q]
class B;def w;end;end # prints [B, :w]

TPReal  Sep 01, 2009 
PDF Page 278
4th paragraph

... so there is no way to tell whether the named method was added to the class that defines method_added or whether it was added to a subclass of that class.

One can solve the problem changing the code in this way:

def String.method_added(name)
puts "New instance method #{name} added to #{self} "
end

Giovanna.lavado  Jan 05, 2012 
279
8.6 paragraph

STDERR.puts "#{__FILE__}:#{__LINE__): invalid data"

the last round bracket should be substituted with a curly bracket, like this:

STDERR.puts "#{__FILE__}:#{__LINE__}: invalid data"

Giovanna Lavado  Jan 05, 2012 
Printed Page 282
Canada

On the line which reads

1.upto(5) { |i| after i { puts i } }

A "undefined method `i'" error is occurring. It should be either

1.upto(5) { |i| after(i) { puts i } }

or

1.upto(5) { |i| after i do puts i end }

to avoid the second nested block binding to the `i' instead of `after'

Jon  Jan 03, 2013 
Printed Page 282
code samples

Ih the first code sample the following code

1.upto(5) {|i| after i {puts i} }

should be

1.upto(5) {|i| after(i) {puts i} }

or

1.upto(5) {|i| after i do puts i end }

otherwise it would raise the following exception

NoMethodError: undefined method `i'

because of the high precedence of the curly brackets which binds to the i.
As well in the comments of the second code sample:

after 1 { puts "done"}
every 60 { redraw_clock }

are SyntaxError because the { binds to the numbers and should be either

after(1) { puts "done"}
every(60) { redraw_clock }

or

after 1 do puts "done" end
every 60 do redraw_clock end

Maurizio  Aug 17, 2014 
PDF Page 288
first line of 8.10.1

Missing space. Change this:

Example 8-6defines ...

To this:

Example 8-6 defines ...

TPReal  Sep 01, 2009 
Printed Page 296
8.12.1

Change "Here's an example of how the XML can be used"
to "Here's an example of how the DSL can be used"

Henry Collingridge  Mar 23, 2011 
PDF Page 304
first line of 9.1

Missing space. Change this:

Chapter 3explained ...

To this:

Chapter 3 explained ...

TPReal  Sep 01, 2009 
PDF Page 305
near middle of the page

Change this line:

s.start_with? "hell" # => true. Note singular "start" not "starts"

To this:

s.start_with? "hell" # => true. Note "start" not "starts"


(Already marked as corrected in 'printed' and 'other digital' versions, but still present in PDF.)

TPReal  Sep 01, 2009 
Printed Page 307
3rd paragraph, first code section

Shows:
"a".upto("e") {|c| print c } # Prints "abcde. upto iterator based on succ.

Should show:
... # Prints "abcde"

Anonymous   
Printed Page 321
Second code section

Says:
0.odd? # => false

Should also say:
0.odd? # => false (Ruby 1.9)

Anonymous   
Printed Page 321
various

spaces missing between words

p. 321: "Numericand"
p. 321: "Integervalues"

Anonymous  Dec 04, 2009 
Printed Page 322
First sentence

Says:
The Float class defines a methods ...

Remove the word "a".

Anonymous   
Printed Page 323
middle

Pages 323-324 should mention that e.g., exponentiation, logarithm, square root, are multivalued, and should explain which values the complex functions in Ruby return. As an example, Ln(e) is not only 1, but also, e.g., 1 - 2 pi i, 1 + 2 pi i. In particular, CMath.sqrt(-1) returns only one of the two square roots.

Shmuel (Seymour J.) Metz  Jan 18, 2018 
PDF Page 329
first full paragraph on this page

Missing space. Change this:

each_sliceand each_cons ...

To this:

each_slice and each_cons ...

TPReal  Sep 01, 2009 
Printed Page 335
in the middle

The nitems method of Array has been removed in Ruby 1.9.

Delete the following two lines:

[1,2,nil].nitems # => 2: number of non-nil elements

Anonymous   
PDF Page 359
3rd line of 1st code sample

The encoding name is written as Encoding::UTF-8 and should be Encoding::UTF_8 (underscore and not dash).

TPReal  Sep 01, 2009 
PDF Page 361
4th line from the top

In this sentence: 'If you specify the empty string "" as the line terminator, ...', the empty quote is in the normal text font, and it should be in the monospace font, as it is a piece of Ruby code.

TPReal  Sep 01, 2009 
Printed Page 364
3rd paragraph

Output record separator is $ not $/

Anonymous   
Printed Page 367
last paragraph in 9.8.1, first sentence

Change:
This client code for use...

To:
This client code is for use...

Anonymous   
Printed Page 384
3rd paragraph

Section 9.9.7.1 claims "The way to avoid this kind of deadlock is to always lock resources in the same order. If the second thread locked m before locking n, then deadlock would not occur."

This is false as tested by the code:
require 'thread'

m,n = Mutex.new, Mutex.new

t = Thread.new {
m.lock
puts "Thread t locked Mutex m"
sleep 1
puts "Thread t waiting to lock Mutex n"
n.lock
}

s = Thread.new {
m.lock
puts "Thread s locked Mutex n"
sleep 1
puts "Thread s waiting to lock Mutex m"
n.lock
}

t.join
s.join

This returns:

Thread t locked Mutex m
Thread t waiting to lock Mutex n
deadlock 0x10019c638: sleep:- - rubytest.rb:14
deadlock 0x1001b8360: sleep:J(0x10019c638) (main) - rubytest.rb:22
rubytest.rb:22:in `join': Thread(0x1001b8360): deadlock (fatal)
from rubytest.rb:22

Leo Sternlicht  Nov 16, 2009 
Printed Page 390
Last bullet before 10.1

Change:
... SQL injection and similar attacks on with ...
To:
... SQL injection and similar attacks with ...

Anonymous   
Other Digital Version 2572-90
Kindle location: 2572-90, "The == operator"

TEXT WITH ERROR ---------

The == operator is the most common way to test for equality. In the Object class, it is simply a synonym for equal?, and it tests whether two object references are identical. Most classes redefine this operator to allow distinct instances to be tested for equality: a = "Ruby" # One String object b = "Ruby" # A different String object with the same content a.equal?(b) # false: a and b do not refer to the same object a == b # true: but these two distinct objects have equal values

---------

These two blocks of text seem to be at odds with each other. One says that == is a synonym for equal? but the other clearly shows that the two operators return different values when applied to the same two objects

Peter Nixey  Mar 06, 2011