Errata

Learning Ruby

Errata for Learning Ruby

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
Printed Page 10
Example 1-4. matz_tk.rb

I'm using Mac Snow Leopard and Ruby 1.8.7 [had to download this in order to update the default version of Ruby that comes with Leopard, my original OSX].

I have Tcl at the command line, see following:

>tclsh
% expr 2+2
4

However, when I go to IRB, it can not find 'tk', see next line:

>irb
>> require 'tk'
LoadError: no such file to load -- tk
from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:36:in `gem_original_require'
from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:36:in `require'
from (irb):1

I'm heading to Rails but would like to put up a few apps using tk...

Surprisingly, I ran into the same problem when working with Haskell...I finally gave up on loading tk and the web with it...

I'd appreciate any help in loading tk...otherwise, I'm going to have to use C# and Linq...

Thank you

Ps
I tried the Ruby Forum but so far no help there...bummer

patrick lynch  Apr 27, 2011 
Printed Page 39
Aliasing example

The calls to object_id do not do what the text implies. The call to object_id is made on the *return value* of methods "greet" and "baby", which is nil. Thus the fact that greet.object_id and baby.object_id both return 4 just means that the singleton nil instance has an object_id of 4; it does not in any way "verify" that the identifiers "greet" and "baby" refer to the same method.

Anonymous  Jun 26, 2011 
Printed Page 49
5th paragraph

Simple type in the following statement...The is repeated twice...

if not queue then print "The the queue is empty." end

It should be:

if not queue then print "The queue is empty." end




patrick lynch  Apr 26, 2011 
Printed Page 54
1st paragraph code snippet

This is a 'code snippet' but it contains a syntax error in the last statement.

The erroneous line is:
p => temp # => ["Quarter", "Arabian"]

The first => should not be there, that is:
p temp # => ["Quarter", "Arabian"]

patrick lynch  Apr 26, 2011 
Printed Page 73
talking about next and succ String methods

"It adds a character when it reaches a boundary, *or adds a digit or decimal place* when appropriate, as shown in these lines:"

next (and succ) do not add a decimal place. They keep as many decimal places as the number already had, incrementing the rightmost digit by 1 (e.g. '999.09'.next! =>
999.10, and '123.99'.next! =>
124.00, '123.04'.next! => 123.05)

Anonymous  May 12, 2011 
Printed Page 75
Last code snippet

In all of the phone.grep examples (starting on p75, and continuing to p76), the area code is
incorrectly enclosed in square brackets, rather than parentheses. That example should read:

phone.grep(/((ddd))?ddd-dddd/) # => ["(555)123-4567"]

The examples will produce the output shown, because the area code segment is made optional with "?".
The remainder of the expression matches the remainder of the phone number ("123-4567"), and so an array
consisting of the phone string is returned, as shown. But the text implies that the regular expressions
shown match the ENTIRE number, which is not true.

Anonymous   
Printed Page 75
.

<< Let?s figure out how to match a phone number in the form
(555)123-4567.Supposing
that the string phone contains a phone number like this, the following
pattern will
find it:
phone.grep(/*[\(\d\d\d\)]?*\d\d\d-\d\d\d\d/) # => ["(555)123-4567"]
The backslash precedes the parentheses (\(...\)) to let the regexp engine
know that
these are literal characters.Otherwise, the engine will see the parentheses
as enclosing
a subexpression.The three \ds in the parentheses represent three digits.The
hyphen (-) is just an unambiguous character, so you can use it in the
pattern as is. >>

Given regexp will match '(123-4567' as well. The subpattern in black is
equivalent to [\(\d\)],
as a matter of fact. Repeating \d inside square brackets has no
consequences. The right
regexp would be (\(\d\d\d\))? [or, if we could use {} at this point:
(\(\d{3}\))?], if I got the idea
right.

Anonymous  May 12, 2011 
Printed Page 80
Figure 5-1

The diagram has quite a few errors:
- Rational is a child of Object, not Integer
- Complex is a child of Numeric, not Integer
- Float is a child of Numeric, and missing from the diagram

Anonymous   
Printed Page 84
last line

||= should read |= .

Anonymous  Jan 22, 2012 
Printed Page 86
5th paragraph

In Ruby 1.8.7, the http://ruby-doc.org/core-1.8.7/ gives the following definition for 'nonzero?':

"Returns num if num is not zero, nil otherwise..."

The code snippet on this pages shows:

op=0
...
op.nonzero? # => false

Actually, this statement returns 'nil' -- which is what the definition above indicates...
Perhaps, this is new to 1.8.7.

patrick lynch  Apr 26, 2011 
Printed Page 91
Example 5-2. prime.rb

I like to type in the examples rather than copying them...
I made a typo while doing this for example 5-2. it was:

puts "The prime number is " + prime_number.to_s +"."

Note: I didn't put a space between ...to_s + and "." - see next line:

prime_number.to_s +"."

It produces the following error:

scratchpad.rb:8: syntax error, unexpected tUPLUS, expecting $end
puts "The prime number is " + prime_number.to_s +"."

I noticed this in a few other places...is it a Ruby syntax error...
If you delete the blank between '+' and prime_number it works just fine...

Just a thought...

patrick lynch  Apr 27, 2011 
Printed Page 97
8th paragraph

Two problems:
1. The array years was never created in the text
2. If array year, which was created as an array of integers, is used it gives an error.

The statement in the book:
print "The event is scheduled for " + months[3] + " " + years[8] + "."

If run in irb, after entering the arrays in the chapter, the following error message is displayed:
NameError: undefined local variable or method `years' for main:Object
from (irb):8

If years is changed to year and the command is run, the following occurs:
NameError: undefined local variable or method `years' for main:Object
from (irb):8

To correct, make the change shown in the next statement and rerun - see following:
>> print "The event is scheduled for " + months[3] + " " + year[8].to_s + "."
The event is scheduled for March 2008.

patrick lynch  Apr 27, 2011 
Printed Page 101
.


In page 101:

----------------------------------------------------------------------
bob = [ "full", 40, "yes" ]

[...]

What?s the difference between == and eql?. eql? checks to
see if the values are equal (as in ==), but also checks if the values are of
the same type.

bob == schlomo # => true
bob.eql?( "full, 40, yes" ) # => false, bob is not a string
----------------------------------------------------------------------

The example is wrong. bob == "full, 40, yes" also returns false. That's not how eql? and == are different at all. The difference is eql compares the type of /each/ member of the array (not of the
array itself, that's mandatory for both). A good example would be

bob == ["full, 40.0, "yes"] # => true
bob.eql? ["full, 40.0, "yes"] # => false, 40.0 is an instance of Float
class, 40 is a Fixnum

It'd be good to add, also, that == won't return true if we use "40" instead of 40 (at least in Ruby 1.9.2)

Anonymous  May 12, 2011 
Printed Page 102
2nd code example

months.insert(0, nil) does not replace "nil," insert() adds nil so the array looks like this:

[nil, "nil", "January", "February", "March", "April", "May", "June", "July", "August", "September",
"October", "November", "December"]

Anonymous   
Printed Page 102
2nd paragraph

The statement months.insert(0, nil), according to the example in the text should replace the string "nil" and replace it with the nil value.
What actually happens is that the string "nil" remains and become array index item 1 and nil is added as array index 0.

This is correct, that is, both values should be in the array - see following:
Inserts the given values before the element with the given index (which may be negative).

a = %w{ a b c d }
a.insert(2, 99) #=> ["a", "b", 99, "c", "d"]

I ran the code in irb, as shown in the book, and the result was [note: both nil, "nil" appear]:

>>months
=> ["nil", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
>> months.insert(0,nil)
=> [nil, "nil", "January", "February",...]

patrick lynch  Apr 27, 2011 
Printed Page 103
last paragraph

The author explains (p.104) the difference between 'each'
and 'map' as that 'each' returns a string and 'map' returns
an array. In fact they both return arrays ('each' returns the original array). The output on p.103 is not a string result,
it's the output of the "print" in the block. There is no
explanation (in this book) of why one block contains "print"
and the other doesn't.

My guess is that the author has lifted this example from
some other Ruby source (where the intent is to show that
the main distinction between 'each' and 'map' is that 'each'
is used for the block side-effect) and doesn't understand it.

Anonymous  Jan 22, 2012 
Printed Page 105
4th bullet point

"You will be able to assign nil to existing array elements,
thus deleting them" - assigning nil doesn't delete an array
element (in the sense that delete_at deletes it), it replaces
the element with nil, leaving the array indices unchanged.

Anonymous  Jan 22, 2012 
Printed Page 109
.

------------------------------------------------------------------------
zip = { 82442 => "Ten Sleep", 83025 => "Teton Village", 83127 => "Thayne",
82443 =>
"Thermopolis", 82084 => "Tie Siding", 82336 => "Tipton", 82240 =>
"Torrington", 83110
=> "Turnerville", 83112 => "Turnerville" }

[...]

Now *return a value for a given key* (one key only) with the index method:
zip.index "Thayne" # => 83127
----------------------------------------------------------------------

It actually does the opposite: it returns a key given a value. If value is present for more than one key, it returns just the first occurrence (Hash#index has been
deprecated in
favor of Hash#key as of Ruby 1.9).

Anonymous  May 12, 2011 
Printed Page 112
5th paragraph

In order for the following statement to work it is necessary to "Restoring the Rhode Island hash", otherwise a result different from that shown in the book will be produced -- see following:

>> rhode_island = {1=>"Bristol",2=>"Kent",3=>"Newport",4=>"Providence",5=>"Washington"}
=> {5=>"Washington", 1=>"Bristol", 2=>"Kent", 3=>"Newport", 4=>"Providence"}
>> rhode_island.delete_if{|key, value|key < 3 }
=> {5=>"Washington", 3=>"Newport", 4=>"Providence"}
>> rhode_island.delete_if{|key, value|value == "Kent" }
=> {5=>"Washington", 3=>"Newport", 4=>"Providence"}

now, if "Restoring the Rhode Island hash" is performed, the result shown in the book will be displayed - see following:

>> rhode_island = {1=>"Bristol",2=>"Kent",3=>"Newport",4=>"Providence",5=>"Washington"}
=> {5=>"Washington", 1=>"Bristol", 2=>"Kent", 3=>"Newport", 4=>"Providence"}
>> rhode_island.delete_if{|key, value|key < 3 }
=> {5=>"Washington", 3=>"Newport", 4=>"Providence"}
>> rhode_island = {1=>"Bristol",2=>"Kent",3=>"Newport",4=>"Providence",5=>"Washington"}
=> {5=>"Washington", 1=>"Bristol", 2=>"Kent", 3=>"Newport", 4=>"Providence"}
>> rhode_island.delete_if{|key, value|value == "Kent" }
=> {5=>"Washington", 1=>"Bristol", 3=>"Newport", 4=>"Providence"}


patrick lynch  Apr 28, 2011 
Printed Page 116
last two line on the page

I believe that...

dir.tell #=> "."
dir.read #=> 1

should be switched to...

dir.tell #=> 1
dir.read #=> "."

Anonymous   
PDF Page 118
Almost at the end of the page

It says:

You can apply any method to ARGV that you might apply to any other array.For example, try adding this command:

p ARGV # => ["sonnet_119.txt"]
or:
ARGV#[0] # => ["sonnet_119.txt"]

------------------

The second option actually outputs (in interactive mode) the same as ARGV on its own, because that hash (#) starts a comment. Moreover, if you remove that hash the output is not ["sonnet_119.txt"] but "sonnet_119.txt" (a string).

Diego Barreiro  May 12, 2011 
Printed Page 120
top of page

link = page_content.scan(/<a class=l.*?"(.*?)").flatten

I think the "class=l" is in the code example erroneously, it prevents the code from running properly. I
solved it by taking it out.

Anonymous   
Printed Page 135
Example 9-12

One of the ternaries in the dice roll method of the Dice module, r1 = r_1>0?r_1:1; r2 = r_2>0?r_2:6, is
incorrect in that in over one million rolls a 12 is never obtained. While such results are not impossible,
statistically they qre highly unlikely. Re-writing the statements as r1 = r_1>0?r_1:6; r2 = r_2>0?r_2:6,
that is setting both r1 and r2 to 6 in the negative case solves the problem. Data follows:

with r1 = r_1>0?r_1:6 1000000 rolls
Frequencies
Actual Expected
two = 27909 0.028 0.028
three = 55540 0.055 0.056
four = 83132 0.083 0.083
five = 111112 0.111 0.111
six = 139029 0.139 0.139
seven = 166741 0.168 0.167
eight = 139193 0.139 0.139
nine = 110788 0.111 0.111
ten = 83264 0.083 0.083
eleven = 55388 0.054 0.056
twelve = 27904 0.028 0.028

with r1 = r_1>0?r_1:1 1000000 rolls
Frequencies
Actual Expected
two = 55501 0.056 0.028
three = 83259 0.083 0.056
four = 111443 0.111 0.083
five = 139386 0.139 0.111
six = 166769 0.167 0.139
seven = 166207 0.166 0.167
eight = 110925 0.111 0.139
nine = 83170 0.083 0.111
ten = 55552 0.056 0.083
eleven = 27788 0.028 0.056
twelve = 0 0.000 0.028

Anonymous   
Printed Page 135
Example 19.2

the method roll does not generate dice rolls from 2 to 12. it has more than 1 error. Results of a run of
3000 executions are shown 2 is generated 167 times, 11 generated 93 times, 12 never generated. Test code
provided below results.

2
167
3
271
4
325
5
403
6
514
7
487
8
369
9
231
10
140
11
93

Run code below and see what happens when the three methods are plugged into the main routine and are
called:

#!C:RailsInstantRails ubyin uby.exe -w

# Written by: David S. Banham
# Version : 1.0

# Create Test-case Count
TEST_CASES = 3000

# Create a hash representing the possible dice outcomes and initialize counts to 0
$roll=Hash.new(0)

# Three dice algorithms

# simplified version of algorithm on page 135
def roll_dice_lp_simple
r_1 = rand(6)
r1 = r_1>0?r_1:1
r1
end

# algorithm on page 135
def roll_dice_lp
r_1 = rand(6); r_2 = rand(6)
r1 = r_1>0?r_1:1; r2 = r_2>0?r_2:6
total = r1+r2
# puts "you rolled #{total}"
total
end

# correct simple dice roll algorithm
def roll_dice
rand(max=6) + 1
end

# Main Program plug in any algorithm and look at its results for
# a large number of rolls of the dice

puts Time.now.to_f
for i in 1..TEST_CASES
dice_value = roll_dice_lp
# puts dice_value
$roll[dice_value] = $roll[dice_value] +1
end

puts Time.now.to_f

puts"


"
puts $roll.sort
puts "

The End"

# End of Main Program

Anonymous   
Printed Page 152
middle

"a hint that Ruby is managing resources efficiently"...

NOT TRUE. if you say a = b
a.object_id and b.object_id all the time... a and b point to the same object. hence same object id.

Anonymous   
Printed Page 156
middle of page

Program example asks to load from http://www.wyeast.net/images/sunrise.jpg

site does not exist

Anonymous   
Printed Page 190
last paragraph

After following successfully all previous instructions

./script/generate scaffold address address

gives:

17:29:07 -> ./script/generate scaffold address address
exists app/controllers/
exists app/helpers/
create app/views/address
exists app/views/layouts/
exists test/functional/
dependency model
exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/address.rb
create test/unit/address_test.rb
create test/fixtures/addresses.yml
error Before updating scaffolding from new DB schema, try creating a table for your model (Address)
17:29:20 ->

instead of what the book reports.

Anonymous   
190
final paragraph

Apparently Scaffolding has changed in 2.0 of Rails. The command as given in the text results in the error: wrong number of arguments (1 for 2)

After a bit of research, I determined that appending ':string' to the second 'address' parameter permits the command to complete successfully.

Irwin Friedman  Feb 28, 2010 
Printed Page 191
1st paragraph and fig. 11-5

"Apparently Scaffolding has changed in 2.0 of Rails. The command as given in the text results in the error: wrong number of arguments (1 for 2)

After a bit of research, I determined that appending ':string' to the second 'address' parameter permits the command to complete successfully." Note: prepending the second 'address' parameter with ':title' will also allow the command to complete successfully.

When I enter the url in fig. 11-5 "http://0.0.0.0:3000/address" I get the following message in an HTML formatted page:


We're sorry, but something went wrong.

We've been notified about this issue and we'll take a look at it shortly.

I have no idea who "We" are, and it'd be nice to know how to find out when the problem will be fixed.

Peter Vanderhaden  Jun 12, 2010