By Developers, For Developers

Historical errata for Programming Ruby

PDF PgPaper PgTypeDescriptionFixed onComments
xixxxiiiSUGGEST

Last line: ‘became’ should be ‘become’

2005-11-24
66SUGGEST

Clarified location of cvsup sup files

2005-11-24
1416SUGGEST

third para: ‘instances variables’ should be ‘instance variables’

2005-11-24
1517SUGGEST

Penultimate paragraph: “The the keys and values”. Duplicate word.

2005-11-24
2931SUGGEST

In the Java code, the constructor should be ‘new JavaSong’

2005-11-24
5862SUGGEST

Last sentence: ‘of’ should be ‘off’

2005-11-24
6165SUGGEST

In the first paragraph, the pattern has a spurious extra single quote

2005-11-24
6569SUGGEST

At the bottom of the page, ‘thread-global variables $~ and $1-$9’ should be ‘thread-local’

2005-11-24
6872SUGGEST

In the table at the top of the page, the character
class descriptions for s and S somewhat recursively use s in the
‘As…’ field. It would be clearer to show a space.

2005-11-24
8995SUGGEST

‘Used to compare the each’
should be ‘Used to compare each’

2005-11-24
94100SUGGEST

Last para: ‘previously’ should be ‘previous’

2005-11-24
104110SUGGEST

In footnote, ‘ancestor’ should be ‘descendant’

2005-11-24
116123SUGGEST

‘Abmiguous’ should be ‘Ambiguous’

2005-11-24
116123SUGGEST

First para: ‘Alternativly’ should be ‘Alternatively’

2005-11-24
116123SUGGEST

In the example, ‘id’ should be ‘object_id’

2005-11-24
120128SUGGEST

Second para: mode ‘rw’ should be ‘r+’

2005-11-24
121129SUGGEST

‘For example, w could create’ should be ‘we’

2005-11-24
128136SUGGEST

Second to last paragraph in the last sentence, ‘bug’ should be ‘bugs’

2005-11-24
139147SUGGEST

Duplicated word ‘thread’ in code comment

2005-11-24
140148SUGGEST

In the PDF version of the book, the Pig program can’t be found, and an error message appears where you’d expect to see the output

2005-11-24
147155SUGGEST

Last para: ‘We could do lot more’ should be ‘a lot more’

2005-11-24
152160SUGGEST

‘The directory is the prepended’ should be ‘then prepended’

2005-11-24
153161SUGGEST

Missing period at end of first para

2005-11-24
154162SUGGEST

In description of assert_equal, ‘obj’ should be ‘actual’

2005-11-24
176187SUGGEST

Fifth line under ‘Tab Completion’, change ‘It there…’ to ‘If there’

2005-11-24
185196SUGGEST

First para: ‘incompatibility’ should be ‘incompatible’

2005-11-24
191203SUGGEST

End of first para: ‘Change ’Documenting can turned’ to ‘Documenting can be turned’

2005-11-24
192204SUGGEST

Missing closing paren. ‘(sometimes called
description lists’

2005-11-24
192204SUGGEST

The RDoc does’t quite have the same punctuation as the typeset list above

2005-11-24
196208SUGGEST

In figure 16.5, comment to setup_optional_block, ‘parameter’ is misspelled

2005-11-24
205217SUGGEST

Second para: ‘you can to use the query command’ should be
‘you can use…’

2005-11-24
210-1222-3SUGGEST

The stub mechanism has changed. You now “require ‘rubygems’” and then require the library normally

2005-11-24
212224SUGGEST

The gem specification uses ‘tests/’ for the test directory. To be consistent with the text, this should be ‘test/’

2005-11-24
213225SUGGEST

There is no plural form of ‘autorequire’

2005-11-24
230243SUGGEST

First para, ‘<% a ’ should be ’<= a %>’. Inline code on previous page is correct

2005-11-24
234247SUGGEST

Bottom of page: ‘reuqests’ should be ‘requests’

2005-11-24
235248SUGGEST

WEBrick can do far more that server should be than serve

2005-11-24
255269SUGGEST

First para: shell22 should be shell32

2005-11-24
259273SUGGEST

Last para: pragrams -> programs

2005-11-24
260274SUGGEST

last para: ‘then user’ should be ‘then used’

2005-11-24
263277SUGGEST

Item (1) under Building Our Extension: the filename in the sentence should be ‘my_test.c’. The inline code is correct

2005-11-24
261279SUGGEST

Last para: ‘may well included’ should be ‘may well include’

2005-11-24
267281SUGGEST

Missing semicolon after ‘char *p’ in code example

2005-11-24
268282SUGGEST

Third sentence in box: ‘prt field of an STRING’ should be ‘a STRING’

2005-11-24
268282SUGGEST

#end should be #endif

2005-11-24
268282SUGGEST

First sentence of main text: ‘alter with the data’ should be ‘alter the data’

2005-11-24
273287SUGGEST

First sentence of Allocation Functions: ‘other that’ should be ‘other than’

2005-11-24
274288SUGGEST

Last sentence of third para: ‘set up be’ should be ‘set up by’

2005-11-24
274288SUGGEST

Para before Cloning Objects: the word ‘either’ should be removed in ‘bypass either the constructor’

2005-11-24
279294SUGGEST

First sentence of Ruby Type System: ‘on an object’ should be ‘of an object’. Third sentence of same paragraph is missing a terminating period.

2005-11-24
281295SUGGEST

last para: ‘it you’re writing’ should be ‘if’

2005-11-24
282296SUGGEST

In item (2), ‘an supporting’ should be ‘any supporting’

2005-11-24
295309SUGGEST

rb_create_new_instance is now rb_class_new_instance

2005-11-24
296310SUGGEST

In text for rb_ensure, ‘rargs’ should be ‘eargs’

2005-11-24
298312SUGGEST

rb_cvar_set now takes a fourth parameter, ‘warn’. It does not appear to be used

2005-11-24
310325SUGGEST

Under [characters], the list of special characters is missing +. Should copy list from page 71

2005-11-24
312327SUGGEST

Doubled word ‘the’ in third paragraph

2005-11-24
313328SUGGEST

third paragraph under Names, third line: ‘lowercase letters’ should be ‘lowercase letter’

2005-11-24
322337SUGGEST

Doubled word ‘the’ in description of DATA (’the’s must have been on special offer that day).

2005-11-24
321338SUGGEST

In item describing Literal, ‘There are’ should be ‘These are’

2005-11-24
322339SUGGEST

The table lists a spurious operator, ~=

2005-11-24
325340SUGGEST

Fifth bullet: ‘more rvalues that lvalues’ should be ‘than’

2005-11-24
325340SUGGEST

Seventh bullet: ‘and the it is assigned’ should be ‘then it’

2005-11-24
342357SUGGEST

last para: ‘that operate in the context of the caller’ should be ‘the context in which they were defined’

2005-11-24
356372SUGGEST

‘desciptor’ should be ‘descriptor’

2005-11-24
371388SUGGEST

‘If a class definition is executes’ should be ‘executed’

2005-11-24
392411SUGGEST

In the table (and corresponding index entry, ‘undefineded’ should be ‘undefined’

2005-11-24
393413SUGGEST

Under Source Code: ‘You can look these’ should be ‘look at these’

2005-11-24
399418SUGGEST

Fifth para: ‘On 1GHz Powerbook’ should be ‘On my 1GHz PowerBook’ (two typos within three words :)

2005-11-24
419440SUGGEST

under uniq: duplicate values are detected using eql? and hash, not just eql?

2005-11-24
462483SUGGEST

‘appears to a’ should be ‘appears to be a’

2005-11-24
475496SUGGEST

under index: change ‘entries has’ should be ‘entries have’

2005-11-24
484505SUGGEST

IO.popen only accepts an array of strings under Ruby 1.9

2005-11-24
491512SUGGEST

Under read: change ‘in to it’ should be ‘into it’

2005-11-24
495516SUGGEST

Spurious ‘returns’ in summary of backquote method

2005-11-24
514535SUGGEST

Last word of paragraph starting ‘Ruby 1.8 includes…’ should be ‘marshal_dump,’ not ‘marshal_load.’

2005-11-24
550571SUGGEST

synopsis for instance_variable_set() says instance_variable_get()

2005-11-24
579600SUGGEST

Under new: The parameter name in the prototype doesn’t match the text. The first line of the description should be ’Constructs a new regular expression from string or regexp.

2005-11-24
579600SUGGEST

Under new: the last constant should be Regexp::MULTILINE

2005-11-24
579600SUGGEST

The statement that Regexp.escape(str) =~ str is true logically, and used to be true in practice. However Ruby now insists that the receiver of =~ is a Regexp, and so this will not work

2005-11-24
581602SUGGEST

Under match: ‘returns or nil’ should be ‘or returns nil’

2005-11-24
590611SUGGEST

under crypt, 2nd line: change ‘extend’ to ‘extent’

2005-11-24
629650SUGGEST

TrueClass#^: after ‘returns true if obj is nil’ add ‘or false’

2005-11-24
633654SUGGEST

penultimate para: “respond within hours” should be “response”

2005-11-24
637658SUGGEST

Under bigdecimal/newton: spelling of BigDecimal

2005-11-24
647668SUGGEST

MD2 should be MD5 in the first para

2005-11-24
669690SUGGEST

In the Logger code, the format string %H:%H:%S should be %H:%M:%S if we want to see minutes in the output that follows

2005-11-24
684705SUGGEST

Duplicate ‘the’ in ‘passed on the the NKF library’

2005-11-24
703724SUGGEST

second para: ‘most operating system’ should be ‘systems’

2005-11-24
711732SUGGEST

‘escapes’ should be ‘escaped’

2005-11-24
724745SUGGEST

‘RFC 2882’ in the text should be 2822 (the code below
is correct)

2005-11-24
734755SUGGEST

In header bar, DDL should be DLL

2005-11-24
738759SUGGEST

The zlib library doesn’t read zip files without
additional work. The description should say ‘The Zlib module contains
several classes for compressing and decompressing streams, and for
working with gzip files.’

2005-11-24
--SUGGEST

Some PDF hyperlinks in Acrobat’s sidebar point to an
earlier section. In addition, some page numbers in the index (in
particular those that would be shown in a bold typeface in the paper
book) and not hyperlinked.

2005-11-24
--DEFER

Index keywords ‘then’, ‘elsif’, ‘when’, and ‘in’, and
concept ‘backreferences’

2005-11-24
--DEFER

Perhaps build out bibliography with other Ruby books, such as “Learn Ruby in 21 Days”, “Ruby in a Nutshell”, “Code Generation in Action”

2005-11-24
--DEFER

Index Unicode

2005-11-24
--DEFER

Index immediate values

2005-11-24
45DEFER

Under ‘Source Code From This Book’, we end the paragraph with ‘make the code compile’. Perhaps ‘run’ might be a better word

2005-11-24
1416DEFER

third para: Should point out that variable names can end ?, !, and =

2005-11-24
4447DEFER

We say that “hash does not support multiple keys with the same value.” That’s ambiguous: it would be clearer to say “multiple entries where the keys have the same value.”

2005-11-24
5660DEFER

The transition into ?a-style constants is too
abrupt

2005-11-24
6468DEFER

Add a reference to figure on pg 342 to the description of ranges as conditions

2005-11-24
8288DEFER

Could explain ‘alias’ by adding a comment in the code example

2005-11-24
95101DEFER

second para: ‘The elements in a range’ might be better worded as ‘The start and end of a range’

2005-11-24
98104DEFER

Last example: should probably say that the value given to ‘break’ will be the value of the loop

2005-11-24
134142DEFER

The ‘super’ call in the constructor is superfluous

2005-11-24
147155DEFER

The test ‘assert_nothing_raised() { Roman.new(499) }’ is OK, but it meant to show the limit case, 4999

2005-11-24
173183DEFER

The book has ‘require “rbconfig.rb”’—the “.rb” is perfectly correct, but omitting it is idiomatic

2005-11-24
267281DEFER

Penultimate paragraph, change ‘If you want to ensure that a value pointer’ to ‘VALUE pointer’

2005-11-24
276290DEFER

Index dfree

2005-11-24
277292DEFER

Spurious (though benign) semicolon at end of last statement in cd_unit

2005-11-24
312327DEFER

Should point out that /a(?>.*b).*a/ is not equivalent to /a.*b.*a/

2005-11-24
317332DEFER

Penultimate para: Technically modules can have instance variables too

2005-11-24
325340DEFER

The list should probably be numbered for the (1) at the end of the second bullet to make sense

2005-11-24
330345DEFER

The code examples starting ‘match =’ have one or two spaces extra indentation

2005-11-24
335350DEFER

Under operator methods, should probably show (expr1.operator()) as equivalent to first two examples

2005-11-24
449470DEFER

Under File.link: the name of the file in the example, testfile.lnk, mayt be confusing to Windows users, where the extension .lnk is significant.

2005-11-24
516537DEFER

Add a reference to the list on 334 to the description of MatchData

2005-11-24
579600DEFER

First para: When it says ‘Later versions of Ruby use a different engine,’ it would be clear to say ‘Versions 1.9 and later use…’

2005-11-24
601622DEFER

String#to_sym should indicate it’s a synonym for #intern

2005-11-24
737758DEFER

Could change example to use YAML.load_file(“tree.yaml”) rather than YAML.load(File.open(“tree.YAML”))

2005-11-24
740763DEFER

The socket appendix could mention broadcast
capabilities and the “” string. Might also mention possible
problem with connecting if reverse lookups don’t work in your
environment, and the workaround using the
BasicSocket.do_not_reverse_lookup attribute

2005-11-24
762789DEFER

Add index reference to pg 341 to both != and !~

2005-11-24
805-DEFER

Hyperlinks are not linked to the web. (This might not
be possible to fix, as they are not full URIs—Dave)

2005-11-24
134142ERROR

The code print out shows c.count as being 20000, while the text says that it shouldn’t be. The script itself seems fine as running it yields values other than 20000.

(Dave says: yeah… they changed the thread scheduler, so both threads now run to completion. I’ve upped the count)

2006-01-16
120128OK

Might not be typo.
3rd para (starting with But….), 2nd sentence: The method File.open also opens a file. -> isn’t it ‘also closes a file’?

(Dave says: no. I agree the wording is a tad ugly, but here we’re sayibng that open opens a file, just like new does)

2006-01-16
241255ERROR

The code sample for the Ruby/Tk “Hello World” program is incorrect. The ‘pack’ method does not take a block, so the ‘padx’, ‘pady’, and ‘side’ options are never set. Change the ‘pack’ call from block form to hash form, like so:

pack(‘padx’=>15, ‘pady’=>15, ‘side’=>‘left’)

For more detail, see my post regarding this, and the responses, in Ruby-Talk:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/168308

2006-01-16
353369TYPO

“If fact, Dave had an interesting experience …” s.b. “In fact, Dave …”

2006-01-16
8557OK

Near the top of the page, you propose a solution for reading strings from a file as integers: “To fix this, use the Integer method to convert the string to an integer.” It would be helpful to write that Integer() is a method in module Kernel. As presented, it looks like a method w/o a module/class.

(Dave says: true, but that’s the same for puts and all the other top-level methods)

2006-01-05
1517OK

The example on using %w has braces afterwards, but I think they should be normal brackets/parentheses.

  1. this is the same:
    a = %w{ ant bee cat dog elk }

should be …

  1. this is the same:
    a = %w( ant bee cat dog elk )

Being very new to Ruby, it confused me - so I tried both (page 48 in the pdf has normal brackets) and the brace version throws a syntax errors.

HTH :)

(Dave says: I believe the example in book is correct)

2006-01-16
6268OK

There appears to be a problem with the listed code. The code fails to define “song_file” in the first code block. This works better:

File.open(“songdata”) do |song_file|
songs = SongList.new
song_file.each do |line|
file, length, name, title = line.chomp.split(/\\s*\\|\\s*/)
name.squeeze!(" ")
mins, secs = length.scan(/\\d+/)
songs.append(Song.new(title, name, mins.to_i*60+secs.to_i))
end

puts songs.lookup(“Fats”)
puts songs.lookup(“ain’t”)
puts songs.lookup(“RED”)
puts songs.lookup(“WoRlD”)
end

(Dave says: the book often elides common or obvious code, as in this case)

2006-01-16
4649OK

I was writing a negative test case for the example using the with_title method that uses a for loop. I kept getting errors when I searched for a non-existent song in the list. It appears that there was a minor oversight and that the loop:

for i in 0..@songs.length

Should be:

for i in 0..@songs.length - 1

(Dave says: ah, but the book has three dots, not two. The three dot form excludes the end of the range)

2006-01-16
180191ERROR

This bit:

def ri(*names)
system(%{ri #{names.map {|name| name.to_s}.join(" ")}})
end

should have “ri.bat” instead of “ri” to work under Windows.

2006-01-16
174DEFER

Not sure where this piece of info would fit best, so I put in the page number for the IRB chapter.

Windows users with locales (or specifically keyboard layouts, I suppose) like Swedish and German can’t input e.g. angular brackets, curly braces or dollar signs to irb.

The solution is a bit hard to find but is posted here: http://rubyforge.org/tracker/index.php?func=detail&aid=865&group_id=167&atid=715

One creates an .inputrc file in the home directory (typically c:\\documents and settings\\) containing

“\\M-[”: “[”
“\\M-]”: “]”
“\\M-{”: “{”
“\\M-}”: “}”
“\\M-\\\\”: “\\\\”
“\\M-|”: “|”
“\\M-": "
“\\M-“: ”
“\\M-$”: “$”

and then sets HOME to HOMEPATH by e.g. adding

set HOME=HOMEPATH

to your ruby/bin/irb.bat. One remaining problem is that inputing tilde requires AltGr + ~ and then SPACE, and then going back and removing a double pipe character…

7984TYPO

In the middle of the page, between the two code samples, there is a typo in the paragraph of text starting with “This works, but it’s…”. The second sentence reads “If would be nice if” but should read “It would be nice if”.

2006-01-16
619640ERROR

ThreadGroup.enclose doesn’t just prevent threads from being removed from the group, it also prevents them from being added. I can’t see any difference between the behavior of the enclose and freeze methods.

For some reason the freeze method doesn’t appear in the ri for Ruby 1.8.4.

mark@ociweb.com

(Dave says: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/78124 However, the description is still wrong.)

2006-01-17
110TYPO

In the footnote on this page, the last part of the second sentence reads “…is the same as or an descendent of…”. Here, “an” should be “a”.

2006-05-03
115OK

in the sample of ‘Instance Variables in Mixins’
has the sample :

module Observable
def observers
@observer_list || = []
end
def add_observer(obj)
observers << obj
end
def notify_observers
observers.each {|o| o.update}
end
end

The variable observer has ‘unbound’
can be a syntax error ?
the define correct is :

module Observable
def observers
observer_list || = [] end def add_observer(obj) observer_list << obj
end
def notify_observers
@observer_list.each {|o| o.update}
end
end

i hope this is a correct definition

Ciao
Ugo

(Dave says: actually, I think it’s fine. The ‘observers’ line is a method call)

2006-01-27
145TYPO

In the code sample at the bottom of the page, the second comment (above the second Thread.new block) reads “Customer request thread thread” but should read “Customer request thread”.

2006-05-03
125TYPO

last paragraph: it needn’t be restarted for new version
-> it needn’t be restarted for a new version
or
it needn’t be restarted for new versions

2006-05-03
683TYPO

first para:
the library also include SyncEnumerator
->
the library also includes SyncEnumerator

2006-05-03
226TYPO

first para: “extra_rdoc_file attribute” should be “extra_rdoc_files attribute”

2006-05-03
239TYPO

last para, first sentence: “allow you separate” -> “allow you to separate”

2006-05-03
142OK

"c.count -> 20000

Perhaps surprisingly, the count doesn’t equal 20,000."

From the output it appears to equal 20,000. Was the output in the example supposed to have a value other than 20000?

This is actually a change in the thread scheduler, so the live code in older versions of the book no longer causes threads to interfere. Later printings upped the count to 200,000 and the counts do indeed differ.

2006-05-03
327ERROR

In the example for (?>re), the given pattern is not anchored so the explanation can be a bit confusing. In particular, str=“aba” + (“b” * 5000)
str =~ /a.*b.*a/ → 0 #matches at start
but
str =~ /a(?>.*b).*a/ → nil #2nd “a” consumed by nested re
The right result in exponential time is better than the wrong result quickly. ;-)
The pattern should be anchored or reworked. (Perhaps /^a.*b.*a$/)

2006-05-03
39ERROR

I actually have the third printing, date 2004-12-7 but it’s not in the pull down. Chapter 3 has a section on access control mentioning an Accounts class which presumably uses the Account class below containing a protected balance instance/method. The Accounts class seems to use this balance method in the debit and credit methods, but since it’s a different class it shouldn’t be able to access the protected member right? A more consistent example would make the concepts clearer.

2006-05-03
67OK

There’s a reference to a method dial in an example, however the dial method is not defined in the example:

digits = 0..9
(more lines of code here …)
digits.each {|digit| dial(digit)}

(Dave says: it’s just an example… :)

2006-05-03
45OK

In the last section of code, should not the second line read:

a[2, 2] = ‘cat’ —> [1, 3, “cat”, “cat”, 9]

instead of:

a[2, 2] = ‘cat’ —> [1, 3, “cat”, 9]

The next line of code assumes the error is not there.

(Dave says: the assignmen replaces the two items with the single argument, ‘cat’)

2006-05-03
116123ERROR

The example for “Instance Variables in Mixins” produces a warning in the output.

Just above the heading “Resolving Ambiguous Method Names”, I see c1.state -> “cat”\
-:7: warning: Object#id will be deprecated; use Object#object_id

2006-05-03
140148ERROR

In “Spawning New Processes”, the example output indicates a failure to locate /usr/local/bin/pig. It looks like:

produces:
-:4: command not found: /usr/local/bin/pig
nil

2006-05-03
161140ERROR

Your code example and description consistent, but the output as shown is incorrect.

Book says (note incorrect B-A-B-A pattern):

produces:
B: 1
A: 1
B: 2
A: 2
B: 3
A: 3
B: 4
A: 4
B: 5
A: 5

But the correct “doesn’t let it get more than two higher” output is:

book/src $ ruby ex0319.rb
A: 1
A: 2
B: 1
B: 2
B: 3
B: 4
A: 3
A: 4
A: 5
B: 5

Chuck

(Dave says: ouch—for some reason, the threads work differently when run in our nested interpreter, used to geneate the book.)

2006-05-03
v-xvi,790-831DEFER

Please add bookmarks for the Tables of Contents, Tables, and Figures, the Index, and the reference tables at the back.

249TYPO

Middle of 3rd paragraph - “the number of times interested is compounded” should be “interest” instead of “interested”

2006-05-03
213TYPO

the sample program at page 213 delivers wrong output
because the format tags for month and minute are
interchanged.

This format string “%Y%M%d %H:%m”
delivers the wrong output: 2006-07-19 11:04

the sample program at page 213 delivers wrong output
because the format tags for month and minute are
interchanged.

This format string “%Y%M%d %H:%m”
delivers the wrong output: 2006-07-19 11:04

the sample program at page 213 delivers wrong output
because the format tags for month and minute are
interchanged.

This format string “%Y%M%d %H:%m”
delivers the wrong output: 2006-07-19 11:04

This format string “%Y%m%d %H:%M”
delivers the correct output: 2006-04-19 11:07

2006-05-03
26+TYPO

The name of the Bela Fleck tune is “Bicyclops”, not “Bicylops”. Yes, I know this has nothing to do with Ruby, and that it is, in fact, completely unimportant. But I’m a big Bela fan, and this typo appears over and over during the course of the book, and I just can’t take it anymore! :)

(Dave says: grr… and I’m a fan too. Sorry about that)

2006-05-03
826TYPO

Sequence “\\s” is given As [\\s\\t\\r\
\\f], hence defining \\s with itself in the character class. I believe the class should look As [ \\t\\r\
\\f] with the space character appearing in lieu of \\s. Similarly for \\S.

(Dave says: fixed in recent printings)

2006-05-03
580601ERROR

Regexp#===:
Case Equality - Synonym for Regexp#=~ used in case statements.

But it is not exactly the same. Example:

irb(main):001:0> /./ =~ :a
TypeError: cannot convert Symbol into String
from (irb):1
irb(main):002:0> /./ === :a
=> false

2006-09-20
606OK

str2 is constructed from str1, and the next two lines reports that they would have the same object id. This is wrong, they are separate objects and therefore have separate ids.

str1.object_id -> 946790
str2.object_id -> 946790

(Dave sys: actually, this is a Ruby optimization: it uses copy on write for the new string)

2006-09-20
105OK

hello!

the line reads
retry if gets =~ /^y/i

Is there any reason why the variable i appears on this line? The program seems to run correctly with or without the i.

thank you!

(Dave says: the ‘i’ means "case insensitive pattern match)

2006-05-18
421442TYPO

Under the description of the ‘quo’ method, the sample code actually uses ‘div’ on the third line.

2006-09-20
516TYPO

The sentence

The methods Regexp#match and Regexp#last_match also return a MatchData object

should be

The methods Regexp#match and Regexp.last_match also return a
MatchData object

since match is an instance method and last_match is a class method.

2006-09-20
523544TYPO

Under to_proc instance method, the sentence

See the Thing example at the start of this section.

should be

See the example at the start of this section.

The example is relevent but there is not mention of Thing.

2006-09-20
622643SUGGEST

Under the local instance method, it would be helpful if the following sentence (copied from the gm instance method) was added.

Will also accept ten arguments in the order output by Time#to_a.

2006-09-20
529DEFER

Description of the sleep method is incorrect for Ruby 1.8.4. Calling sleep with an argument of ‘zero’ as documented causes sleep to sleep for 0 seconds, not forever. As documented in ri, calling sleep with no arguments causes it to sleep forever.

(Dave says: this book describes 1.8.2. I’ll fix it in the next edition)

67OK

I’m working in windows xp, sorry ;-) with Ruby-1.8.4-17

In the code:

digits = 0..9
puts digits.include?(5)
puts digits.min
puts digits.max
puts digits.reject { |i| i < 5 }
digits.each {|digit| dial(digit) }

The last line show me an error:
chapter5.rb:151: undefined method `dial’ for main:Object (NoMethodError)
from chapter5.rb:151

(Dave says: it’s just an example of calling a method… dial() is not defined by this code)

2006-06-16
8793TYPO

Missing space between “and” and the “-=” that follows it.

2006-09-20
96102TYPO

A reference on this page reads “pages 120-120”.

2006-09-20
239252ERROR

When calling the doGoogleSearch the code example is passing nil for restrict, lr,ie, and oe. This results in a deserialization error when the method is called. Switching these to empty string (’’) fixed the error.

2006-09-20
546567TYPO

Object#send claims to be a synonym for send, but they have different signatures. is this a mistake?

page 567 send has <,args>+

page 574 send has <,args>*

(Dave says: well spotted! * is correct)

2006-09-20
239253TYPO

In the google example, when I use the syntax puts first.URL I get this error:
undefined method `URL’ for # (NoMethodError)
when using the syntax puts first[“URL”] I get the expected results. I’m clueless why and I’m very new to Ruby. Also on page 253, the first.url in the second example seems to fail as Google uses URL as the name of the field and SOAP seems to be case sensitive.
My results from from ruby 1.8.4 (2005-12-24) [i686-linux]
on Red Hat Enterprise 4 workstation.

(Dave says: the method is now called uRL (for some reason))

2006-09-20
158OK

Not actually a bug per se, but annoyance with irb. The .inputrc fix doesn’t work with my Windows XP SP2 / Finnish Locale. I assume that the problem might be same as with Danish Locale, though I don’t really know what causes the issue.

I have tried $HOME and $HOMEPATH variables, with multiple .inputrc files, but no avail.

However removing —readline option from C:\\ruby\\bin\\irb.bat fixed the issue.

[irb-fixed.bat]
“c:\\ruby\\bin\\ruby.exe” “c:\\ruby\\bin\\irb” -r irb/completion %1 %2 %3 %4 %5 %6 %7 %8 %9

(Dave says: this is probably a question for the Ruby list)

2006-09-20
529550SUGGEST

The examples for Module#instance_methods do not show the results:

A.instance_methods => [“method1”]
B.instance_methods(false) => [“method2”]
C.instance_methods(false) => [“method3”]
C.instance_methods(true).length => 42

2006-09-20
105DEFER

Newer versions of ruby (1.8.4) seem to have a problem with the break in the ‘retry’ example (the example still works though):

def do_until(cond)
break if cond
yield
retry
end

i = 0

do_until(i > 10) do
print i, " "
i += 1
end

produces:

/tmp/foo.rb:4:in `do_until’: unexpected break (LocalJumpError)
from /tmp/foo.rb:11
0 1 2 3 4 5 6 7 8 9 10

With ruby 1.8.2, there’s no warning.

(Dave says: the book covers 1.8.2. I’ll update this on the next edition)

235248TYPO

Second paragraph: for sentence “WEBrick can do far more …” the next word should read “than” not “that”.

2006-09-20
249OK

Third paragraph: for sentence “Initially, it offers …” the phrase “… times interested is compounded …” should be “… times interest in compounded …”.

(dave says: I think ‘is’ is correct)

2006-09-20
239252ERROR

The example for WSDL results in a message that create_driver is depricated (due to use of createDriver method). Use create_rpc_driver instead.

2006-09-20
376OK

The last Roman class example for coercion (xi + 4990) does not result in 5001 as shown. To get this answer, shouldn’t it be 4990 + xi such that xi is “coerced” to an Integer?

(Dave says: it works as shown: 5001 is not a Roman number)

2006-09-20
132OK

The code example on page 132 of the .pdf book will not run as documented. I’ve used both irb and tried it as an input file and both exhibit the same error(s):

bash-/sdownie$ ruby chaser.rb
chaser.rb:9: parse error, unexpected tIDENTIFIER, expecting kDO_COND or ‘:’ or ‘\
’ or ‘;’
while @count other.count > 1
^
chaser.rb:16: parse error, unexpected kEND, expecting $

(Dave says: you seem to be missing a minus sign)

2006-09-20
63OK

To achieve the desired output in the VU class, inspect should be replaced with to_s. Otherwise, it would return a normal object definition when to_a is called.

(Dave says: works here as is)

2006-09-20
540519ERROR

It is written that
method asin “returns 0..\\pi”. whereas it should returns -\\pi/2..\\pi/2 as
sin([0,\\pi]) = [0,1] and not [–1,1].

2006-09-20
164172TYPO

On page 164 of the latest version, in the line:
count = words.scan(PATT = /^……..\
/).size
the “PATT = ” is superflous and a little distracting.

2006-09-20
744767TYPO

There is a minor mistake on page 772, in the section for ‘gethostname’ under
class ‘Socket’. It is a class method, but the heading for it says:

gethostname sock.gethostname -> string

instead of

gethostname Socket.gethostname -> string

2006-09-20
772TYPO

Could the section on Socket.gethostname include a:

require ‘socket’

line in the example? I know it’s a subjective judgement call as to which examples should show the ‘require’ statement, but Socket.gethostname is something that people will want to call even though they may have no experience or interest in writing code for doing socket I/O. It took me about 15 minutes of searching through the whole PDF to realize why my call to Socket.gethostname wasn’t working.

As an alternate suggestion, you could include a short statement at the start of Appendix A (page 768 in my PDF) just saying that the “require ‘socket’ ” is needed for all of the socket-related classes. That is the first place I looked to see if there was some ‘require’ or an ‘include’ that I needed for Socket.gethostname, but there wasn’t any mention of it there or in the descriptions for the BasicSocket or Socket classes.

2006-09-20
458DEFER

It would be helpful if some of the places that describe a return value which is a numeric ‘gid’ or ‘uid’ value would also mention that the “Etc” library module can be used (at least on unix systems) to convert that to the correct userid or groupname character-string.

(places such as the File::Stat.gid method on page 458, the File::Stat.uid method on page 461, the description for the Process module on page 562, the Process::GID module on page 568, the Process::Sys module on page 573, and the Process::UID module on page 575. I don’t know that they all need to mention it, but it would be nice if at least some of them did)

Either that, or at least do something so the “Etc” library module will show up in the index around some gid or uid-related topics. Part of the problem is with “Etc” itself, as a name. Once the programmer has a numeric gid, it might not be intuitively-obvious that they should to search the PDF for the word “Etc” to get the appropriate character string for that numeric value. A unix sys-admin might make that connection, but I’m a unix sys-admin myself, and I thought of “NIS”, “LDAP”, and “Netinfo” (MacOS 10) without thinking of “Etc”. There is no real requirement that any of this information will be in the /etc directory.

154DEFER

Suggestion for next edition

Please consider changing Fig. 12.2 into something that can be searched in Apple’s Preview. As it is, I get no hits if I search for assert_resond_to, assert_same, and some other Test::Unit assertions.

340ERROR

I believe there is a rule missing in the “Parallel Assignment” section. The last sentence on p. 91 states, “If an assignment has just one lvalue and multiple rvalues, the rvalues are converted to an array and assigned to the lvalue.” This seems to contradict (or at least) modify rule 5 on p. 340.

342ERROR

I think some clarification of “Ranges in Boolean Expressions” is in order :) The last sentence in the first paragraph doesn’t agree with the last two sentences in the second paragraph. Also, in the first example, I would expect the slot for 18 to be nil since expr2 evaluates to true which should cause a transition to unset according to the text.

69ERROR

in ruby 1.8.5 =~ does not automatically convert a string on the right side to a regular expression.

xxOK

Footnote 1 is truncated

(Dave says: it continues on the next page…)

2006-12-31
374391OK

In the text it says that the method ``once’’ will be defined as a class method of ExampleDate, but the code sample defines it as an instance method. The line in the example defining ``once’’ should read:

def ExampleDate.once(*ids) # :nodoc:

Calling the method ``once’’ after the definition in the book/PDF results in the following error:

ex0646.rb:38: undefined method `once’ for \\
ExampleDate:Class (NoMethodError)

Changing it to a class method allows the program to run as expected.

Note: I borrowed a friend’s version of the PDF to ensure the error still existed.

The first edition of the books seems to correctly define the method:

http://www.rubycentral.com/book/classes.html

(Dave says: see the bottom of the same page)

2006-12-31
119OK

On the 6th line of text (NOT counting the indented lines of code) it seems that “who_am_i? instance method” should read “who_am_i? module method”.

(Dave says: nope—it’s an instance method. It can’t be called on the module directly)

2006-12-31
120TYPO

The 6th line from the bottom of the page reads, “class supports things such as map, include?, and find_all?”. The name of the third method should be “find_all”, not “find_all?”.

521542ERROR

The Math.sqrt function does not raise an “ArgError” (or an ArgumentError, if that’s what you meant) if ‘numeric’ is less than 0. On both Linux and Windows it raises Errno::EDOM.

-Dan

173TYPO

Table 13.1 - second section (the one about disp):
disp[lay] expr - Display value of nnn every time debugger gets control.
should probably be:
disp[lay] expr - Display value of expr every time debugger gets control.

191TYPO

The output of the sample invocation `ri “String.each”’ is missing the braces in the syntax synopsis. This can look confusing to first-timers (that I was when I first read this section).

398TYPO

Under the $SAFE table, second sentence should read: “…or if it is run under mod_ruby…”, the “is” is missing.

499ERROR

Both to_a and to_s show the following statement:

h = { “c” => 300, “a” => 100, “d” => 400, “c” => 300 }

I believe one of the “c” => 300 key value pairs is redundant. It’s not technically an error, but somewhat nonsensical.

762SUGGEST

The bookmarks section of the PDF no longer contains a link to the Index. What happened to it? Can you put it back? The last thing I see is “Part V, Appendixes”. Adobe Reader 7.08, Windows XP.

790SUGGEST

It would be nice if there was an index entry for ? that referenced pp. 319-320 where using ? to obtain the integer value of an ASCII character is described.

I went to the index after viewing the sample on p. 550 that used that technique and didn’t find anything in the index.

309ERROR

The documented signature of rb_apply is incorrect - in fact it has no argc argument.

6 & 7OK

2 seperate problems
——————————
in the example on page 6, when I type in “^D” I get:

machinename$ ruby
puts “Hello, world!”
^D
-:2: parse error, unexpected ‘^’, expecting $

(Dave says: ^D is “control-D” a single character)


in the 2nd irb example on page 7 (the one using the Fibonacci program which is ex0208.rb in the source tga) , the load command works, but when I try to “Fibonacci.upto(20)” I get:

irb(main):001:0> load “/RubyEx/ex0208.rb”
=> true
irb(main):002:0> Fibonacci.upto(20)
NameError: uninitialized constant Fibonacci
from (irb):2


(Dave says: that’s not the program to run. It’s just an example to illustrate irb)

2006-12-31
162OK

Figure 12.2.2 Test::Unit assertions

assert_instance_of(klass…)
assert_kind_of(klass…)
Expects obj to be a kind/instance of klass

Unless this is suddenly in German “klass” should be “class”

(Dave says: nope— ‘klass’ is a variable, because “class” is a reserved word. It’s an ugly Ruby convention)

2006-12-31
7OK

Last code example at the bottom of the page.
Replace
ri enable
With
ri GC::enable

(Dave says: it works fine here with just ri enable, as there’s no ambiguity with the method name in a standard Ruby install)

2006-12-31
608TYPO

Perhaps it’s just a one-time printing error, but at the top of the page, the small “1.8” sidenote is printed right over the word “Match”, instead of in the left margin.

376ERROR

In the ex0629.rb and ex0629.rb program listings this line should read:

if Fixnum === other && (other + @value) <= MAX_ROMAN

Otherwise, an miss-by-one (less) condition occurs not allowing the result of the +(other) method to include MAX_ROMAN.

Thanks for your great book!

P.S. couldn’t find the book version in my printed copy — sorry.

732ERROR

The first example of a weakref doesn’t cause an exception. The text suggests that this is being demonstrated, but even the “produces” output shown has no exception. It seems that strings aren’t being garbage collected at this time. Substituting Object.new for “fol de rol” in the 2nd line produces the expected exception after the gc runs.

251SUGGEST

The Google SOAP API seems no longer available for new users. Google says:

As of December 5, 2006, we are no longer issuing new API keys for the SOAP Search API. Developers with existing SOAP Search API keys will not be affected.

Depending on your application, the AJAX Search API may be a better choice for you instead. It tends to be better suited for search-based web applications and supports additional features like Video, News, Maps, and Blog search results.

For developers who are already using the SOAP Search API, we’ve kept the documentation live on this site.

Thanks for the great book!

114TYPO

“sum, when applied to strings it” should be “sum; when applied to strings, it”

193TYPO

“Both the following are” should be “Both of the following are”. It might also be nice to close the sentence with a colon.

237TYPO

“reformated” should be “reformatted”

336TYPO

“When used as an rvalue, element reference” should be “When used as an rvalue, an element reference”

344TYPO

“LocalJumpError or ThreadError depending on” should be “LocalJumpError or ThreadError, depending on”

2TYPO

“Linux distributions, and Mac” should be “Linux distributions and Mac”

xxTYPO

“and in particular covers” should be “and, in particular, covers”

8TYPO

“In particular you might” should be “In particular, you might”

22TYPO

"you

14SUGGEST

In the second paragraph, the wording isn’t really strong enough. Ruby enforces these conventions. “should all start” should be “must all start”, etc.

10TYPO

"In Ruby, you

10TYPO

“for example, the name of the song” should be “for example, the name of a song”

10TYPO

“These instance methods in turn have” should be “These instance methods, in turn, have”

12TYPO

“The following lines are both equivalent.” should be “The following lines are equivalent.”

12TYPO

"In this case it

28TYPO

“in the real world objects often” should be “in the real world, objects often”

28TYPO

"We

29TYPO

“In Ruby you do that” should be “In Ruby, you do that”

41TYPO

“the end position, and the three-period” should be “the end position; the three-period”

196TYPO

“return nil, otherwise return” should be “return nil; otherwise, return” (twice) Similarly, “use it, otherwise accumulate” should be “use it; otherwise, accumulate”

392ERROR

In the table under “Runtime Callbacks”, “Module#extend_object” should be “Module#extended”.

104SUGGEST

The fact that empty rescue rescues StandardErrors should be more emphasized - a separate paragraph or a side box or at least bold font. It seems that many people overlook this pretty important sentence.

7ERROR

TO load a file in irb, you reference “code/rdoc/fib_example.rb” . This file and the directory structure does not exist in the example code..

70TYPO

The last sentence in the second paragraph under the section Anchors, in parentheses.

in the book:
… string ends with a \
, it which case …

I think it is intended to be:
… string ends with a \
, in which case …

By the way, thank you so much for the great book!! I am learning a lot from this.

66SUGGEST

“Similarly, the patterns \\b and \\B match word boundaries and nonword boundaries, respectively” would be clearer as “Similarly, the patterns \\b and \\B match word boundaries and word non-boundaries,
respectively”

69ERROR

In the code for function show_regexp, the statements
“#{$`}<<#{$&}>>#${$’}” and “no match” should be preceded by
“puts”, otherwise no output is produced.

105TYPO

The do-it-yourself until loop throws a LocalJumpError from the break statement. It can be changed to a return statement.

109SUGGEST

When the raise statement (with no parameters) is called, the exception is rethrown. Can we say a few words about the type of the error? I believe it is RuntimeError.

119SUGGEST

Need to update the code given in the website (not in the book): it still uses id instead of object_id.

224OK

I hope we can be a little bit more consistent about the directory name test. On page 224, a test/ directory is created. But on page 232, we have tests/. I notice that the same situation can be found in the real gems directory: BlueCloth-1.0.0 uses tests, whereas rake-0.7.2 uses test/. By the way, which is the correct one, and does it make a difference for RubyGems?

(Dave says: test is probably the more usual)

2007-08-10
224SUGGEST

Since I was checking the gems directory, I found that all the doc/ directories in gems/ are all named with the singular form, not the plural form docs/. The book uses the plural form. Again is there a standard?

671TYPO

$ARGV should be ARGV.

46TYPO

Third line before last: “suggests a dequeue”, I believe “deque” is intended.

547SUGGEST

Under ‘clone’, I think it would be helpful to mention that cloned objects retain singleton methods while duped objects do not. For example,

class Snark
def beware
“Snarks are dangerous”
end
end

boojum = Snark.new

def boojum.beware
“Boojums are even more dangerous”
end

boojum.beware # => “Boojums are even more dangerous”
boojum.dup.beware # => “Snarks are dangerous”
boojum.clone.beware # => “Boojums are even more dangerous”

And maybe a cross-reference from ‘dup’?

358TYPO

last line: “is no longer valid”

360TYPO

Fourth line under the header “Raising Exceptions”:
“raise thing [, string [stack trace]]” should be
“raise thing [, string [, stack trace]]”

381TYPO

In Figure 24.2, shouldn’t be there an arrow linking klass of Class Object to the box of Class Object’?

673SUGGEST

The second paragraph says: “ERB breaks its input text into checks of regular text and program fragments.” Perhaps “chunks” makes more sense then “checks”.

74SUGGEST

The second last paragraph says “Whoever created it entered all the artists’ names in lowercase.”, and then goes on to explain how to make them mixed case. But the part of the file that we’ve been shown on page 63 doesn’t show the artist names in lowercase.

48ERROR

In the code for the ‘find’ method of class Array, the word ‘size’ should be ‘@size’, I believe, since size is presumably an instance variable of the Array class.

619TYPO

The documentation for str.squeeze shows it returns

-> squeezed_tring

I assume this should be

-> squeezed_string

287OK

First line on this page:

However, code fragment do not a program make =>

maybe you meant “do not make a program”

(Dave says: I like it as it is, but thanks)

2007-08-10
143ERROR

Table 11.1 purports to demonstrate a race condition this will occur when either thread runs before the previously active thread has a chance to "store val back into count" resulting in a lost update to count. The table erroneously shows suspensions after the update to count has occurred which will not affect count.

146SUGGEST

It’s not clear what the condition variable is in the code example.

75TYPO

ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32]

context ‘The obvious thing is to write str.gsum(/\\\\/, ’\\\\\\\\’)

This actually DOES work. The eight ‘\\’ are not needed.

456TYPO

the description of Enumerable#inject. the text: "The first form let’s you supply an initial value for memo. The second form uses the first element of the collection as the initial value (and skips that element while iterating).

the reverse is true from the examples printed. i.e. the second form supplies the initial value…

26SUGGEST

Please change:
song.inspect
to
puts song.inspect

It is probably obvious to an experienced person, but not the person that is reading your book.

Thanks

395TYPO

The page link in “See Kernel.require on page 507 for an example.” actually leads to page 495 — the first page for Kernel.

120TYPO

The code near the top of the page is missing the line:
attr_reader :duration

759ERROR

The Zlib module does not support zip-format compressed files. To read those one has to use the rubyzip gem.

609ERROR

You state in the documentation for the []= method ‘the Regexp and String forms will silently ignore the assignment [if the value is out of range].’ But they both raise an IndexError if there’s no match.

Furthermore theres no ‘~’ method for Strings.

(Either in 1.8.2 or 1.8.5)

769ERROR

The code listing for unpack_sockaddr_un on page 769 in the Second Edition is incorrect. It is a copy of the unpack_sockadd_in code listing. The explanation is OK.

31ERROR

This errata is in the section titled “Objects and Attributes”. On the top of p. 31, the book says:

“In this example, we named the accessor methods name, artist, and duration. The corresponding instance variables, name, artist, and @duration,
will be created automatically.”

After asking about that statement on the ruby-forum, it seems to be the general consensus that the statement is false. Here is an example, which I think proves the statement is false:

class Song
attr_reader :name, :artist, :duration
end

song = Song.new
puts song.name
puts song.artist
puts song.duration

vars = song.instance_variables
puts “Here are the instance vars: —->#{vars}<——”

—output:—
nil
nil
nil
Here are the instance vars: —-><——

66ERROR

In the example at the the top of p. 66, the variable song_file is undefined. It looks like the first line of the example should be something like:

song_file = File.open(“songdata.txt”)

31TYPO

Here is an example that led me to an erroneous conclusion about whether attr_reader creates the instance variables:

class Song
attr_reader :name, :artist, :duration
end

song = Song.new
puts song.name
puts song.fake

—output:—
nil
r3test.rb:7: undefined method `fake’ for # (NoMethodError)

Since there is clearly a difference between the output for the instance variable name and the instance variable fake, I thought attr_reader must have created the instance variable name (as well as artist and duration). I thought attr_reader created name and by default set its value to nil. Likewise, I thought that since attr_reader had not created the instance variable @fake, trying to read its value produced the error.

However, it was explained to me that song.name is a method call to the method: name(), which attr_reader created, and name() is defined to return the instance name. Since name doesn’t exist, name() returns nil. Likewise, song.fake is a method call to fake(). Since attr_reader did not create a method called fake(), song.fake produced a NoMethodError.

67SUGGEST

In the example on the bottom of page 67, there is this line:

include Comparable

The include statement was not covered earlier in the book, and there is no explanation of what it does after the example.

Suggestion: explain it or don’t use it.

292ERROR

Running the test ruby script for the my_test extension fails on OSX with:

1) Error:
test_test(TestTest):
NameError: uninitialized constant TestTest::MyTest
method test_test in my_test.rb at line 7

Seems it cannot find the MyTest class even though the extension loaded with require ‘my_test’

327ERROR

/a.*b.*a/ of course doesn’t take exponential time but quadratic time.

96ERROR

On p. 96, there is an example that starts with this line:

words[key] ||= [ ]

and the text says:

“The first line is equivalent to words[key] = words[key] || [ ].”

That seems obvious—unfortunately it’s not true. Here is an example:

h = Hash.new(5)

h[“a”] ||= 10
p h #{}

h[“a”] = h[“a”] || 10
p h #{“a”=>5}

Apparently in Ruby, the statement:

x ||= y

is equivalent to:

x = y unless x

Here is an example:

h = Hash.new(5)

h[“a”] ||= 10
p h #{}

h[“a”] = 10 unless h[“a”]
p h #{}

119SUGGEST

On p. 118-119 is this passage:

If this made you think of class methods, your next thought may well be “what happens if I define instance methods within a module?” Good question. A module can’t have instances, because a module isn’t a class[Ok, no module instance methods]. However, you can include a module in a class definition. When this happens, all the module’s instance methods are suddenly available as methods in the class as well. [Whoa! A module’s instance methods?]

I propose this change:

If this made you think of class methods, your next thought may well be “what happens if I define instance methods within a module?” Good question. You can define instance methods in a module, but they are not like instance methods in a class. Since a module is not a class, you cannot create instances of a module and use them to call the module’s instance methods.

However, you can include a module within a class definition. When this happens, all the modules instance methods are suddenly available as methods in the class as well.

131SUGGEST

129: Reading and Writing Files — The are no descriptions or examples showing how to write to a file in this section. So I find the title of the section baffling.

In addition, the intro to the chapter says:

“In this chapter, we’ll be concentrating on class IO and its most commonly used subclass File.”

“IO” stands for Input/Output. Yet, there isn’t a single example in the whole chapter showing how to write to a File, i.e. the Output half of Input/Output.

The acknowledgments at the beginning of the book tout the excellent work done by swarms of volunteer reviewers. Here’s a suggestion, next time give your book to someone who has never heard of Ruby before. Then give their comments 100 times the weight of anyone else’s.

In case anyone might ever need to write to a file using Ruby, here are some examples:

File.open(“aaa.txt”, “w”) do |file|
file.print(“hello\
”, “world\
”, “goodbye\
”)
end
#‘w’: erases existing file or creates new file

File.open(“bbb.txt”, “w”) do |file|
file.puts(“hello”, “world”, “goodbye”)
end
#puts automatically adds a new line to
#each argument.

File.open(“bbb.txt”, “a”) do |file| #‘a’ for append
count = file.write(“hi\
mars\
out\
”)
puts “The number of bytes written to the file was: #{count}.”
end
#‘a’: appends to the end of the file, i.e. does not
#erase file.

130ERROR

At the top of page the following code appears:

count = 0
threads = []
10.times do |i|
threads[i] = Thread.new do
sleep(rand(0.1))
Thread.current[“mycount”] = count
count += 1
end
end
threads.each {|t| t.join; print t[“mycount”], “, ” }
puts “count = #{count}”

Since rand(0.1) is the same as rand, “rand(0.1)” should be replaced with either “rand” or “0.1 * rand”, whichever was actually intended. This error was detected by someone other than me and posted on ruby-talk ML — I just thought I should post it here because nobody else has.

149OK

On the bottom of p. 149 is this text and example:
"For instance, we may want to kick off a long-running external sort.

exec(‘sort testfile> output.txt’) if fork.nil?
#The sort is now running in the child process
#carry on processing in the main program
#then wait for the sort to finish
Process.wait

The call to Kernel.fork returns a process ID in the parent, and nil in the child, so the child process will perform the Kernel.exec call and run sort."

How many lines of code got chopped off the top of that example? The call to Kernel.fork? Where is that?

Also, where does the if statement modifier: if fork.nil? come from. The list of classes/modules starting on p. 427, doesn’t reveal a class/module named ‘fork’, so fork.nil? isn’t a class/module method call, which means that fork must be a variable in the code that refers to some object. What object? A variable named ‘fork’ doesn’t appear anywhere in the code.

(Dave says: that statement modifier is the call to kernel.fork—you’ve answered your own question :)

2008-07-09
495ERROR

In the library reference, in the Kernel module section, it says that Kernel module instance methods are listed in the Object class page, and instead in thid Kernel module page are listed only Kernel module methods as for example the method “puts” among others…. The fact is that “puts” (and other moethods listed here) isn’t a module method, it is a private module instance method.

156ERROR

156, example at top of page: The output shows the test failing, but there is no description of what was entered to get the test to fail. I tried specifying an empty data file on the command line, a file with two words in it, and a file that doesn’t exist. Still the test succeeded. Then I omitted specifying a data file name on the command line, and instead I entered ^D for end-of-file when the program was running. Still the test succeeded.

Finally, I specified a file on the command line, and then I inserted the statement:

ARGF.read

before the line:

assert_not_nil(ARGF.read, “Read next…”)

and that caused the test to fail. I also tried that modified code without specifying a file on the command line and entering ^D when the program was running, but the test succeeded, which I don’t understand.

I asked about this on the ruby-forum, and no one knew how to make the test fail.

153SUGGEST

Unit Testing, chap 12: This omitted fact caused me hours of frustration and testing until I discovered how things work. Suppose you have a simple program that prompts the user for some information like this:

my_prog.rb
—————
def get_name(msg)
print msg
gets
end
def get_scores(msg)
print msg
gets
end

name = get_name(“Name: ”)
scores = get_scores(“scores: ”)

#do something with
#user info…

Then having just read about unit testing in pickaxe2, you decide to create a unit test for your program to test the get_scores method, and this is what you come up with:

my_test.rb
————-
require “test/unit”
require “my_prog.rb”

class TestFuncs < Test::Unit::TestCase
def test_get_scores
input = get_scores(“scores: ”)
assert_instance_of(Array, input)
end
end

However, if you run that unit test, the method get_name will execute—even though the unit test does not attempt to execute the get_name method.

Apparently, when you run a unit test on a program, any code in the program that is not inside a class definition or a top level method definition will execute before the unit test executes.

One solution is to just comment out any code that is outside of any class or method definitions. Another solution is to surround any code that is not in a class or a method definition with the block:

if FILE == $0
..
..
end

So the program would look like this:

my_prog.rb
—————
def get_name(msg)
print msg
gets
end
def get_scores(msg)
print msg
gets
end

if FILE == $0
name = get_name(“Name: ”)
scores = get_scores(“scores: ”)
end

FILE is the name of the file containing the FILE statement, which in this case is my_prog.rb And $0 is the name of the file you entered on the command line to execute with ruby, i.e.:

ruby my_test.rb

The net effect is that when you run the program directly, e.g.

ruby my_prog.rb

the code in the if block will execute. However, if the file is require’ed into another program, and that other program is executed, e.g.

ruby my_test.rb

the code in the if block won’t execute. Suggestion: please mention something about this in the next edition.

160SUGGEST

160, “Where to put Tests”, middle of the page: The text says, “A better solution is to run the tests from the directory containing the library being tested.” On the previous page is a diagram of the directory structure:

roman/ (note: there is a missing slash after roman)
——-lib/
————roman.rb
——-test/
————test_roman.rb

I think a literal reading of that quoted sentence means that you should run your tests from the roman directory. However, it turns out that the book is using the term “library” to refer to roman.rb—not the lib directory. That couldn’t be anymore confusing.

To clear things up: one way to run the test program from the command line is to first cd to the lib directory. Then use the command:

/lib% ruby ../test/test_roman.rb

The current directory is always included by default in the search path used by require and include. test.roman.rb has a require statement that says:

require roman.rb

One place ruby will look for roman.rb is in the current directory, and since the current directory is /lib, ruby will be able to find roman.rb.

The whole purpose of this whole section is a little tricky to understand. If I’ve got it right: when program A is required into program B, the path of a require statement in program A will be relative to program B’s directory. If program A has a require statement like this:

require “fileX”

then fileX is in the directory containing A. If program B then require’s program A into program B, and program B is in another directory, then ruby will search B’s directory for fileX. Since fileX is not in B’s directory, that will cause an error.

352ERROR

352, Aliases: At the top of the page, the first two lines say:

“When a method is aliased, the new name refers to a copy of the original method’s body. If the method is subsequently redefined, the aliased name will still invoke the original implementation.”

If that were true, then aliasing a name wouldn’t do anything: the new name would be a copy of the original method’s body and the aliased name would “still invoke the original implementation.” As a result, you would have two names that invoke identical methods.

The second line should read: “If the method is subsequently redefined, the new name will invoke the original implementation.” For proof, see the example under the text.

216ERROR

216, Installing Ruby Gems: the two commands at the top of the page read:

% cd rubygems-0.7.0
% ruby install.rb

However, according to the rubygems README file, which after I unpacked the files was in the directory

rubygems-0.9.4/

(0.9.4 is the current version number), the command to install rubygems is:

ruby setup.rb

Since there there was no file called install.rb in the directory rubygems-0.9.4/ and there was a file called setup.rb in the rubygems-0.9.4/ directory, I went with the command in README:

$ ruby setup.rb

However, I got an error mid way through the install:



mkdir -p /usr/bin/
install gem /usr/bin/
setup.rb:633:in `initialize’: Permission denied - /usr/bin/gem (Errno::EACCES)
from setup.rb:633:in `open’
from setup.rb:633:in `install’
from setup.rb:1377:in `install_files’
from setup.rb:1376:in `each’
from setup.rb:1376:in `install_files’
from setup.rb:1346:in `install_dir_bin’
from setup.rb:1532:in `send
from setup.rb:1532:in `traverse’
… 6 levels…
from setup.rb:1000:in `exec_install’
from setup.rb:814:in `invoke’
from setup.rb:773:in `invoke’
from setup.rb:1578

So, I reran the command like this:

$ sudo ruby setup.rb
password:

and everything installed fine.

217ERROR

217, The command at the top of the page is:

% gem install -r rake

But, when entered that command, first I got this:

$ gem install -r rake
Bulk updating Gem source index for:
ERROR: While executing gem … (Gem::GemNotFoundException)
Could not find rake (> 0) in any repository

So I tried the command again, and I got:

$ gem install -r rake
Bulk updating Gem source index for:
ERROR: While executing gem … (Errno::EACCES)
Permission denied - /usr/lib/ruby/gems/1.8/cache/rake-0.7.3.gem

The command I needed to use was:

$ sudo gem install -r rake
Password:
Bulk updating Gem source index for:
Successfully installed rake-0.7.3
Installing ri documentation for rake-0.7.3…
Installing RDoc documentation for rake-0.7.3…

336SUGGEST

I’m currently using your “Programming Ruby” as a reference while learning Ruby and especially Rails. I’m highly enjoying the book.

I did encounter one pain point, though: Symbols.

The concept of ruby symbols is used practically everywhere in RoR, so I very soon started looking through my Ruby books for some kind of explanation for the : that seemed to pop up everywhere. The explanation given on p336 in the 2nd edition (9th printing, if this makes a difference), did not leave me much less confused. I hope you’ll consider elaborating the section a bit. Googling for “Ruby symbols” gave me the impression that I’m not the first programmer moving into Ruby to have struggled with the concept, but did lead me to some articles that cleared it up a bit more.

Hope you can use the above suggestion in some future revision of the book.

0TYPO

Dears Dave and Andy

Follows some considerations about your extensible and complex book “Programming Ruby: The Pragmatic Programmer’s Guide”.

1) The chapter you call “Built-in Classes and Methods”, that refer built-in classes and modules, perhaps must be called “Built-in Classes and Modules”.

2) At the same chapter, section Classes, sub-section Array, and method “<=>”, I had difficult to understand some aspects of the comparison. The difficulty refer to the priority of the conflict between lexicographic and array length; when we have a array anterior (<) but with more length (>). Here I transcript the text of the book that, with minor modifications, help you to understand my difficulty:

"<=> arr <=> anOtherArray -> –1, 0, +1

Comparison—-Returns an integer –1, 0, or +1 if this array is less than, equal to, or greater than anOtherArray. Each object in each array is compared (using <=>). If any value isn’t equal, then that inequality is the return value.
If all the values found are equal, then the return is based on a comparison of the array lengths. In case of conflict between the aspects lexicographical and length, has priority the lexicographical one. Thus, two arrays are ``equal’’ according to Array#<=> if and only if they have the same length and the value of each element is equal to the value of the corresponding element in the other array.
If the arrays are different, the first one being lexicographically anterior (<) but with its array length more than the other (>), the comparison returns less.

[ “a”, “a”, “c” ] <=> [ “a”, “b”, “c” ] » –1
[ 1, 2, 3, 4, 5, 6 ] <=> [ 1, 2 ] » 1
[“a”, “a”, “c”, “d”] <=> [“a”, “b”, “c”] » –1
[“a”, “a”, “c”, “d”] <=> [“a”, “b”, “c”] » –1

"

The last example was tested with Ruby.

222ERROR

222: The text says:

"As of RubyGems 0.8.0, requiring rubygems.rb will install an overloaded version fo Ruby’s require method. Having loaded the RubyGems framework, you could say:

require ‘bluecloth’ "

Ok, so according to the text there are two prerequisites to using that require statement:

1) Installation of RubyGems 0.8.0 or higher

2) Requiring rubygems.rb, i.e. the statement:

require ‘rubygems’

So, if you have RubyGems 0.8.0 installed, then you have to write:

require ‘rubygems’
require ‘bluecloth’

How does that free your program from RubyGems-specific code?

After the explanation of the first example on the page, the rest of the section should be deleted since it is completely non-sensical.

718TYPO

In the 3rd sentence, “wrapper than profiles” should be “wrapper that profiles”.

613ERROR

gsub() documentation on p.613: Above the description is the syntax:

str.gsub(pattern, replacement) —string
str.gsub( pattern ){|match| block} —-> string

In the description is this passage:

“…the sequences \\1, \\2, and so on may be used to interpolate successive groups in the match.”

I wonder who can make any sense of that statement. ‘match’ is the block syntax’s parameter, which the description is not even referring to, so mentioning ‘match’ is confusing.

The sentence should say something like:

“…the sequences \\1, \\2, and so on may be used in replacement to refer to the actual matches to parenthesized groups.”

Or, simply:

"…the sequences \\1, \\2, etc. may be used in replacement.

(The sequences 1\\, \\2, etc. are described on p. 75 for any trying to figure out what they mean.)

Also, it’s worth highlighting that double quotes surrounding the replacement string prevent the sequences \\1, \\2, etc. from working. Instead, you have to use single quotes around the replacement string to get the sequences \\1, \\2, etc. to work. Since I’m told it that is a very common error, it should be in the docs that you need to use SINGLE QUOTES.

393ERROR

Regarding:

“At the top-level, we’re executing code in the context of some
predefined object. When we define methods, we’re actually creating
(private) instance methods for the class Object.”

The implication is that the second sentence somehow follows from the
first. But it doesn’t. In the context of the first sentence, the
behavior in the second sentence is magical.

516ERROR

“The Kernel module is included by class Object, so its methods are
available in every Ruby object.” Here, “methods” should read “instance
methods”. It is not clear why Kernel class methods can be called
without a receiver. It may be magical.

735ERROR

In the library reference for WIN32OLE, the first example (Open Internet Explorer…) omits the necessary “require ‘win32ole’” line.

163ERROR

The first time I tried to use the debugger was in 186 and I am seeing something different than in v2 of the book on page 163. Or perhaps I am doing something wrong.

In the book it appears that when you run with the debugger option, such as this

ruby.exe -r debug t.rbyou end up with the debugger looking at the source file (e.g., t.rb).

However, when I run it I end up in some Ruby module:

ruby.exe -r debug t.rb
C:/ruby/lib/ruby/site_ruby/1.8/ubygems.rb:10:require ‘rubygems’
(rdb:1) l
[5, 14] in C:/ruby/lib/ruby/site_ruby/1.8/ubygems.rb 5 # All rights reserved. 6 # See LICENSE.txt for permissions. 7 # 8 9
=> 10 require ‘rubygems’

The work-around seems pretty simple: set a breakpoint in your own file and type C, as below.

I thought you might want to know, in order to update the book.

(rdb:1) b t.rb:3
Set breakpoint 1 at t.rb:3
(rdb:1) c
Breakpoint 1, toplevel at t.rb:3

324ERROR

Table 22.4 does not list the assignment operator ^=

298ERROR

—with-name-lib=directory
Reads: “Add directory/lib to the link command”
Should read: “Add directory to the link command”

Similar error applies to
—with-name-include=directory

192TYPO

Third line of first paragraph in section “Interactive Configuration”:
… to change your prompt back to DEFAULT, you …
should be
… to change your prompt to SIMPLE, you …

Or change the code snippet below.

202TYPO

In the first line of the rdoc comment after the first paragraph, replace “though” with “through”.

257TYPO

Last paragraph: “Accessing mycheck.value will return …” should be “Accessing checked.value will return …”.

328TYPO

3rd paragraph of section “Names”, 1st and 2nd line: replace “a though z” and “A though Z” with “a through z” and “A through Z”.

373TYPO

Section “to_ary -> Array”, first line: “… convert an object …”

373ERROR

Section “to_hash -> Hash”, first line: “(The only known use is the second parameter to Hash#replace.)” should be “(The only known use is the parameter to Hash#replace.)”, since Hash#replace has no second parameter.

468TYPO

fnmatch, second line: “Because fnmatch in implemented…” should be “Because fnmatch is implemented…”.

485TYPO

divmod: remove one “on”.

487ERROR

Class constants, in the comment of MAX_EXP and MIN_EXP: replace “FLT_RADIX” with “RADIX”.

499TYPO

to_hash: “See page 373.” (not 372)

546ERROR

Instance methods, “<, <=, >, >=”, 3rd line: “… all operators return false.” should be “… all operators return nil.”

551ERROR

Module#module_eval: the first sample call is “mod.class_eval(…)” instead of “mod.module_eval(…)”.

622ERROR

String#to_sym: the sample call is “str.to_s” instead of “str.to_sym”.

640TYPO

ThreadGroup, first paragraph, second line: “… will remove it from the its current group.” should be “… will remove it from its current group.”

689TYPO

Library jcode, second paragraph, second line: “\\343\\210\\202” should be “\\342\\210\\202”.

695TYPO

Library Monitor, second paragraph, second line: “and as a extension” -> “and as an extension”.

712TYPO

—no-switch: “Defines a option…” -> “Defines an option…”.

713SUGGEST

Library ParseDate, second line: if the time zone is included in the returned array, it’s not just “an array of Fixnum values”, but “an array of Fixnum and String values”.

725TYPO

Library REXML, in the demo.xml: “Bignums store arbitraty-sized integers.” should be “Bignums store arbitrary-sized integers.”

726TYPO

18th line of the sample code: “# and write it out with a XML declaration at the front” should be “# and write it out with an XML declaration at the front”.

768ERROR

Socket#pack_sockaddr_un: there’s a typo in the sample call (Socket.pack_sockaddr_in instead of Socket.pack_sockaddr_un).

769ERROR

Socket#unpack_sockaddr_in: wrong sample call (Socket.pack_sockaddr_in instead of Socket.unpack_sockaddr_in).

769ERROR

Socket#unpack_sockaddr_un: wrong sample call (Socket.pack_sockaddr_in instead of Socket.unpack_sockaddr_un).

675ERROR

Near the bottom of the page:
users.join(“, ”) should be users=users.join(“, ”)
groups.join(“, ”) should be groups=groups.join(“, ”)

My book’s copyright page says “Eleventh Printing, October 2007”
“Version: 2007-9-13”

863SUGGEST

This may have been mentioned before, but the TOC no longer contains a link to the index in the PDF version. It would be great if it could have a link, not just to the start of the index, but to each letter in the index. This would make it much faster to skip to the portion of the book that contains what you’re looking for. For an example, see the TOC in the Agile Web Development with Rails book.

463TYPO

Under Exception#success? :

“Returns true is the exit status if nil or zero.”
should read
“Returns true if the exit status is nil or zero.”

146SUGGEST

Chapter 11, “Threads and Processes”, contains a section “Condition Variables”. The book gives a code example that uses a condition variable. However, other than a vague two-sentence description in the book (“A condition variable is a controlled way of communicating an event [or a condition] between two threads. One thread can wait on the condition, and the other can signal it.”), condition variables are not described in the main part of the book, in the reference part of the book, or even in the ri documentation. The closest one can get is by executing ri commands on some of the unexplained commands in the code sample (“ri new_cond”, “ri signal”). “ri new_cond” only obtains a “FIXME” notice, while “ri signal” tells you that you could look at a number of “signal” commands, including “ConditionVariable#signal” and “MonitorMixin::ConditionVariable#signal”. These produce fairly cryptic descriptions as well, though they do at least tell you that ConditionVariable is a genuine class (a fact that should be mentioned in the book).

If a subject is important enough to be discussed in the main part of the book, then it should be documented thoroughly where it is brought up, as well as in the reference part of the book and in the ri documentation. Otherwise, it derails the reader, who should be allowed to focus on the subject matter.

Note that the posted errata contain the following note, which is in accord with my perception: ”#29349: It’s not clear what the condition variable is in the code example.—bob”

168SUGGEST

In the example illustrating “Watch out for precedence issues…”, the complexity of the code (which contains several branches that are not executed) obscures the point being made. It probably also makes sense to execute the “puts” statements right after setting the corresponding variables.

Something like this might be better:

def one(arg)
“block given to ‘one’ returns #{yield}”
end

def two(arg)
“block given to ‘two’ returns #{yield}”
end

  1. Version with braces
    result1 = one two {
    “three”
    }

puts “With braces, result = #{result1}”

  1. Version with do/end
    result2 = one two do
    “three”
    end

puts “With do/end, result = #{result2}”

167SUGGEST

The book gives the following guideline:

“Within a class definition, Ruby will parse setter= as an assignment to a local variable, not as a method call. User the form self.setter= to indicate the method call.”

There are two confusing things about this. The first is that “setter” is a placeholder, not an actual word. Perhaps it should be written in italics.

The second is that a simpler, more intuitive, and more common approach is not mentioned: using “@” rather than “self.” on the left-hand side to indicate that an instance variable is being referred to. This approach should be mentioned in the text and also in the code:

class Incorrect
attr_accessor :one, :two, :three
def initialize
one = 1 # incorrect - sets local variable
self.two = 2 # correct - sets instance variable
@three = 3 # also correct - sets instance variable
end
end

235SUGGEST

Two examples of a CGI script are given, where the only difference is that the second inserts a header. But this is obscured by the fact that this difference is listed as a parenthetical remark, and is not followed by a colon linking it to the following script. To avoid confusion, this paragraph:

“Put this script in a CGI directory, mark it as executable, and you’ll be able to access it via your browser. (If your Web server doesn’t automatically add headers, you’ll need to add the response header yourself.)”

should be rewritten as follows:

“Put this script in a CGI directory, mark it as executable, and you’ll be able to access it via your browser. If your Web server doesn’t automatically add headers, you’ll need to add the response header yourself as follows:”

357SUGGEST

The code sample on page 357 could be improved in two ways: (1) The sample could demonstrate more aspects of the description at the top of the page. For instance, there should be “yield” statements that pass parameters as well as “yield” statements that don’t. (2) The sample could include more printed output to clarify what is going on. Currently, there is no output for any of the statements within the “Holder” class.

375SUGGEST

The final lines of the code sample may be poorly chosen as a means to illustrate the points made in the following paragraph.

The end of the code sample, followed by the final paragraph, runs as follows:

:::

iv = Roman.new(4)
xi = Roman.new(11)

3 * iv —> 12
1.1 * xi —> 12.1

Of course, class Roman as implemented doesn’t know how to do addition itself: you couldn’t have written “xi + 3” in the previous example, as Roman doesn’t have a “plus” method. And that’s probably as it should be. But let’s go wild and implement addition for Roman numbers.

:::

But that paragraph confuses the issue by bringing up addition whereas the code sample used multiplication. The important point that the paragraph is probably intended to make is that the order is important.

Here are a rewritten code sample and paragraph that make the point more effectively:

:::

iv = Roman.new(4)
xi = Roman.new(11)

3 * iv —> 12
1.1 * xi —> 12.1
3 + iv —> 7
1.1 + xi —> 12.1

iv * 3 —> error
xi * 1.1 —> error
iv + 3 —> error
xi + 1.1 —> error

Of course, class Roman as implemented doesn’t know how to do multiplication or addition itself: you couldn’t have written “xi + 3” in the previous example, as Roman doesn’t have a “plus” method. And that’s probably as it should be. But let’s go wild and implement addition for Roman numbers.

:::

454TYPO

In the description of the “all?” method, there should be a comma after “that is” in the parenthetical expression “(that is all? will return true…)”. Otherwise, the opening reads as “that is all?”, which is confusing. The fact that the code font is so close to the normal text font doesn’t help.

99ERROR

In the custom until loop, “break if cond” will cause an error: “unexpected break (LocalJumpError)”, probably because “def do_until” is a method and not a loop. Instead use “return if cond”.

81TYPO

(Version of the book: 2007-09-13, P11.0)
Page 81, in the fifth line from the bottom, “they must be methods…” should be “there must be methods…”

17TYPO

“The the keys and values in a hash can be…” it seems that second word “the” is a typo.

49ERROR

`while line = gets’ does not return false, but instead nil. The assertion stated could cause confusion for new readers.

N/ATYPO

I tried to find the errata for the first edition of this book but I was unsuccessful. The free edition hosted at ruby-doc.org reads in section “Containers, Blocks and Iterators” that:

“Parameters to a block may be existing local variables; if so, the new value of the variable will be retained after the block completes. This may lead to unexpected behavior, but there is also a performance gain to be had by using variables that already exist.”

The meaning here is inherently unclear and raises the question: do you mean the parameter definitions or the parameter passed via yield? It sounds like it means passing a local variable to a block via ‘yield’ will have the variable passed by reference, and thus that variable would be different if the called block assigned it’s parameter. Ex:

def foo()
x = 2
yield x
print x

foo { |z| z = 3 }

Of course 2 is printed. I realize that you mean this:

def foo()
yield 1
end

x = 0
foo { |x| y = 3 }

print x # prints 1 not 0

60TYPO

first para:
‘is generated using and ….’
=> ‘is generated using …’ (I think!)

84SUGGEST

Font size is too small

122TYPO

First code example:

observer_list ||= [] => observer_list = []

(I think!)

122TYPO

paragraph 4:
‘uses our Observer module’
=> ‘uses our Observable module’

361TYPO

Page 361
Your syntax diagram for parameters is missing a comma prefixing both *array and &block parameters.
Invoking a Method

[ receiver. ] name [ parameters ] [ block ] [ receiver:: ] name [ parameters ] [ block ]

parameters ← ( [ param, … ] [ , hashlist ] [ *array ] [ &a_proc ] ) block ← { blockbody }

do blackbody end

Should be:
parameters ← ( [ param, … ] [ , hashlist ] [ ,*array ] [, &a_proc ] ) block ← { blockbody }

99ERROR

Ruby classes are instances of Class, which defines === to test…

=== is defined in Module not in Class.

127ERROR

bash-3.2# cat retry.rb
for i in 1..100
print “Now at #{i}. Restart? ”
retry if gets =~ /^y/i
end
bash-3.2# irb retry.rb
ruby-1.9.2-p290 :001 > for i in 1..100
ruby-1.9.2-p290 :002?> print “Now at #{i}. Restart? ”
ruby-1.9.2-p290 :003?> retry if gets =~ /^y/i
ruby-1.9.2-p290 :004?> end
SyntaxError: retry.rb:3: Invalid retry
/usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb/workspace.rb:100:in `sub!‘: can’t modify frozen string (RuntimeError)
\tfrom /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb/workspace.rb:100:in `filter_backtrace’
\tfrom /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb.rb:180:in `block (3 levels) in eval_input’
\tfrom /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb.rb:179:in `each’
\tfrom /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb.rb:179:in `block (2 levels) in eval_input’
\tfrom /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb.rb:273:in `signal_status’
\tfrom /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb.rb:156:in `block in eval_input’
\tfrom /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb/ruby-lex.rb:243:in `block (2 levels) in each_top_level_statement’
\tfrom /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `loop’
\tfrom /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `block in each_top_level_statement’
\tfrom /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in `catch’
\tfrom /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in `each_top_level_statement’
\tfrom /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb.rb:155:in `eval_input’
\tfrom /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb.rb:70:in `block in start’
\tfrom /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb.rb:69:in `catch’
\tfrom /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/irb.rb:69:in `start’
\tfrom /usr/local/rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `


bash-3.2#

327ERROR

The description of how the three-dot range works does not match what the code actually does. Further clarification is at least required. Expr2 in the example range is true for 15, so according to the text, the range should transition to unset, and return false. But in the code output (which matches what irb does), the range does not transition or return false for 15.

145ERROR

In the “Collecting Hash Arguments” section, the book said that:
>
> You can place key => value pairs in an argument list, as long as they follow any normal arguments and precede any splat and block arguments.

Actually, you can only omit the curly braces around the hash literal if it is the last argument to the method (or if the only argument that follows it is a block argument, prefixed with &).

Details:
When i play with this code snippet:

def hello(hash_var, *var)
p hash_var
p var
end
hello(:a => ‘a’, :b => ‘b’, 3, 5)

I got an error like this:

untitled:6: syntax error, unexpected ‘,’, expecting tASSOC
hello(:a => ‘a’, :b => ‘b’, 3, 5)
^

Best Regards.

118SUGGEST

connection.download_mp3(“jitterbug”) {|p| show_progress(p) }

The above line is a little confusing because the method show_progress is never mentioned in the explanation of callers, receivers, etc

Maybe something like this would be less distraction

connection.download_mp3(“jitterbug”) { puts :whatever }

121ERROR

“If the last argument to a method is preceded by an ampersand, Ruby assumes that it is a Proc object. It removes it from the parameter list, converts the Proc object into a block, and associates it with the method.”

This doesn’t sound right at all. Ruby takes the object appended to the & and runs to_proc on it.

procinator = Object.new

def procinator.to_proc
puts “called to_proc”
Proc.new {|x| x}
end

p (1..3).map(&procinator)

outputs:
called to_proc
[1, 2, 3]

327ERROR

“Any parameter may be a prefixed with an asterisk. If a starred parameter supports the to_a method, that method is called, and the resulting array is expanded inline to provide parameters to the method call. If a starred argument does not support to_a, it is simply passed through unaltered.”

The last sentence is not quite right. If the argument doesn’t support to_a, it is not passed through unaltered, but instead wrapped in a single element array

def my_method(*x)
x
end

p my_method( 1 ) #=> [1]

Categories: