Errata

Programming Perl

Errata for Programming Perl

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 8
(around line 15):

The comma at the end of the line

"Sat" => "Saturday",

should be deleted. It's not really wrong, but it looks bad.

Anonymous   
Printed Page 17
7

The line that reads:

$val ||= "2"; #Set $val to 2 if it isn't already set.

is misleading because it will also set $val to 2 if $val is already set to 0.
It should read:

$val ||= "2"; #Set $val to 2 if it isn't already set or set to 0.

Anonymous   
Printed Page 21
1st paragraph, line 2:

"awhile" should be "a while."

Anonymous   
Printed Page 22
1st paragraph:

"logic operator" should be "logical operator" (twice).

Anonymous   
Printed Page 37
3rd paragraph, line 1:

"nine constructs" should be "ten constructs."

Anonymous   
Printed Page 38
2nd para:

"Names that start with anything else ..." is not quite right as it stands,
because there are the special variables like $^T and $^O.

(Chapter 3):
In the list of functions by category at the start of chapter 3, the divisions
don't make sense.

"Fetching user and group information" has endhostent and endnetent, while
"Fetching network information" has gethostent, sethostent, getnetent, and
endnetent. I don't know exactly what these functions do, but the similarly
named ones are all described on the same page.

Anonymous   
Printed Page 43
First line of code under "'Here' Documents":

The comment mentions an earlier example, but there doesn't seem to be a
relevant earlier example.

Anonymous   
Printed Page 51
2nd paragraph, line -3:

"%HASH" should be "%hash".

Anonymous   
Printed Page 55
last paragraph

but you can't say <$foo> because that's an indirect
filehandle

Something seems to be missing here, maybe a * character? It occurs in a
discussion about filename globbing, and the text does not say what $foo
contains.

Elsewhere on the page, you _can_ say <$foo> (3rd paragraph).

Anonymous   
Printed Page 56
6'th paragraph

($file) = <blurch*>; # list context
should be
(@file) = <blurch*>; # list context

Anonymous   
Printed Page 60
paragraph -1, line3:

"if Engine" should be "if the Engine."

Anonymous   
Printed Page 61
paragraph 5, line 1:

"it either it matches or" should be "it either matches or it."

Anonymous   
Printed Page 62
table of assertions

Second to last entry in table is (?...), should be (?=...)

Anonymous   
Printed Page 64
paragraph 4, line5:

After "A  means a backspace in a character class" add ", not a word
boundary."

Anonymous   
Printed Page 66
paragraph 1, line 4:

"bracket match" should be "paranthesis match."

Anonymous   
Printed Page 66
There is one line I think is unclear. As an example, you have the

following:

/^(d+.?d*|.d+)$/; # match valid number

What this should really say is that this matches a valid *positive* number.
This will not match negative numbers. To match all postive and negative valid
numbers, you should say:

/^-?(d+.?d*|.d+)$/

Anonymous   
Printed Page 67
paragraph 1, line -1:

"There's an" should be "This is an."

Anonymous   
Printed Page 69
paragraph 3, line 2:

"(1) question" should be "(1) the question."

Anonymous   
Printed Page 71
code 2:

"match the both `is'" should be "match both `is'."

Anonymous   
Printed Page 71
code 2:

"paragrep mode again" should be "paragraph mode again."

Anonymous   
Printed Page 71
the example at the bottom of the page

The example for finding duplicate words will not work for single character
words.

For example:

"The example has a a mistake in it and won't catch this line."
"Nor this 1 1."

The offending fragment is line 8 of the example--it picks up only words of 2
or more characters:

(wS+) # find wordish chunk

Either of these work:

(wS*) # find wordish chunk
(S+) # find wordish chunk

(77, 90, and index (and elsewhere?):
There's no documentation for the range operator ... (as distinct from ..).
It's in the online documentation for Perl 5.005 and it's mentioned in
"Perl Cookbook" recipe 6.8.

Anonymous   
Printed Page 94
The last paragraph begins

"There is also a logical xor operator that has no exact counterpart in C or
perl, ...."

If "xor" is in the perl language, there _is_ an exact counterpart, isn't there?

Anonymous   
Printed Page 97
1st paragraph

Bh01.LOCK => BLOCK

Anonymous   
Printed Page 105
paragraph -4

In the paragraph beginning "You might think it odd," the word "foreach's"
should be changed to "for's".

Anonymous   
Printed Page 117
4th paragraph, third indented example

This example reads

($aref, $bref) = func(@c, @d);
print "@$aref has more than @$bref
";
...

However, if @c has the same number of elements as @d, then the text of the
print statement will be incorrect. Instead, it could read

print "@$aref has at least as many as @$bref
";

Anonymous   
Printed Page 120
Chapter 2: The Gory Details -- Subroutines (Prototypes)

There is a program listed:

1) sub try (&$) {
2) my($try,$catch) = @_;
3) eval { &$try };
4) if ($@) {
5) local $_ = $@;
6) &$catch;
7) }
8) }
9) sub catch (&) { @_ }
10)
11) try {
12) die "phooey";
13) } catch {
14) /phooey/ and print "unphooey
";
15) };

If you run this program, you'll receive an run-time error something like this:

=====
Undefined subroutine &main::1 called at ./test.pl line 8.
=====

This is because of the prototype on subroutine "try".

Line 1) The prototype (&$) forces the second parameter to be in scalar context.

Line 9) "catch" returns the array of its parameters, @_. That array is then
passed to try in scalar context. When an array is passed in scalar context, it
returns the number of elements on the array.

Line 2) So then the variable $catch in the subroutine "try" actually does not
contain a subroutine reference but a scalar "1".

Line 6) When &$catch is called, perl treats this as a symbolic reference to a
subroutine named 1. Since there is no subroutine in the main namespace named
1, perl dies with an error.

This can be fixed in a number of ways. (TMTOWTDI :) ) Two of the ways that
will keep from changing the main executable program are:

==========
*) Change Line 1:

Line 1) sub try (&@) {

+++) This will cause perl to pass the array returned by catch in list context.
Passing an array in list context will maintain all of the elements, so the
original subroutine reference is actually passed correctly to try.
==========

OR (really this should be an AND/OR, but I think OR is more appropriate here)

==========
*) Change Line 9:

Line 9) sub catch (&) { $_[0] }

+++ By returning a scalar, nothing is lost when the scalar returned by catch
is passed in scalar context to subroutine try. The function reference actually
gets passed and the program runs.
==========

Personally I like the former change better than the latter. If it were me, I
would make the first change and then make a special note saying that if that
second parameter were a scalar then the program would have a run-time error.
(And then point out why)

I feel that this is an important correction as it can confuse the reader who
is new to perl prototypes. (Because this error is a GREAT example of how the $
scalar prototype FORCES the second parameter into scalar context)

Anonymous   
Printed Page 136
$[ section

It mentions that $[ is a compiler directive, but it doesn't tell you the real
significance of this. What it really means is that if the compiler sees it,
while parsing the program, it will generate code differently, even if the
statement is in a subroutine that never gets called.

Sure, it's deprecated, but the official tool a2p uses it, and that's how I got
into trouble. I imported an awk script as a subrotine into my program by
running a2p on it and then creating a closure around it. The subroutine only
gets called under rare circumstances, and then only in a child created as a
pipe. (This saved me from having to deliver two files.) But after I did this,
things like ARGV[1] and substr didn't work any more in program code after the
new subroutine. It took quite a while to pin down, but the 'compiler
directive' statement in the book was the clue, and by setting $[ back to 0 at
the end of the subroutine, everything was hunky dory again.

I think there should be some discussion of this.

And $[ is mentioned a number of other times in the book; I think more of them
should be referred to in the index.

Anonymous   
Printed Page 137
for $^I it says

The current value of the inplace-edit extension. Use undef to disable
inplace editing. (Mnemonic: value of -i switch).

What this doesn't say explicitly is that if you _set_ $^I you _enable_ inplace
editing.

The text as written can be interpreted as meaning that you must use the -i
switch, at which point the value of $^I contains the value of the extension
named with the switch (e.g. -i.bak) and undefing $^I disables inplace editing
at that point. It would be helpful to include text to the effect that you
don't need to use -i _iff_ you set $^I instead.

Anonymous   
Printed Page 144-145
There are several functions listed in "Perl Functions by Category"

that are not described in "Perl Functions in Alphabetical Order":

- Flow of program control: continue
- Fetching user and group information: entgrent, endhotsnt, endnetent,
endpwent, setgrent, setpwent
- Fetching network information: endproent, endservent, sethostent,
setnetent, setprotoent, setservent

Anonymous   
Printed Page 161
code sample 3

eval "$$arrayname{$key} = 1";

This doesnt work! If $arrayname isnt a hash(which it shouldnt be), Perl
expands that to:

eval "$ = 1";

Which perl does not like at all. A bit of experimenting proves the correct
syntax to be:

eval "$$arrayname{$key} = 1";

Effectively keeping perl from expanding "arrayname" as a hash.

Anonymous   
Printed Page 165
Next to last line

In the sample fcntl call, &F_SETFL should be &F_SETFD.

Also, the preceding statement that "Perl always sets the close-on-exec flag
for file descriptors above 2" appears to be incorrect for version 5.004_04.
Using this bit of code:

pipe PARENT_READER, CHILD_WRITER;
fcntl CHILD_WRITER, &F_SETFD, 1;
($pid = fork) >= 0 or die "fork: $!";
if($pid == 0) {
close PARENT_READER;
exec @ARGV or do { print CHILD_WRITER " "; exit 1; }
}
close CHILD_WRITER;
(read PARENT_READER, $childError, 1 > 0) and exit 1;

The parent process blocks on the read if the fcntl call is removed (i.e.
CHILD_WRITER appears to remain open in the exec'ed process).

Anonymous   
Printed Page 181
middle of page "join"

in the first addition:

join
$_ =join':',($login,$passwd,etc);

second addition:

$_ =join':',$login,$passwd,etc;

The first one works; the latter does not.

Anonymous   
Printed Page 185
description of localtime()

"... and the year has had 1,900 subtracted from it."

The text is exactly right, but the wording had to leave me thinking: "Are they
saying that because we are in the 1900's and that value would be different
after the year 2000 or did they literally mean the fixed value 1,900?" Since
so many people are and will be concerned with year 2000 issues over next few
years, I thought maybe some extra wording might be helpful to users.

Anonymous   
Printed Page 186
m// is missing from the functions list.

Anonymous   
Printed Page 193
The code example is not -w clean.

Anonymous   
Printed Page 194
code sample 1

open(FOO, "|tr '[a-z]' '[A-Z]'");
open(FOO, "|-") or exec 'tr', '[a-z]', '[A-Z]';

open(FOO, "cat -n file |");
open(FOO, "-|") or exec 'cat', '-n', 'file';

does not match the code on the WebMaster CD-ROM. In particular the following,
"or" in line 2 and line 4 should be "||".

Anonymous   
Printed Page 200
printf description

The syntax description was "corrected", and though the change certainly makes
the syntax clearer, it now renders the description's comparison to
print/sprintf incorrect (where does the format go?).

Anonymous   
Printed Page 202
When discussing the "rand" function, the text reads "To get

an integral value..." I'm thinking that perhaps you all meant "integer"
instead of "integral"

This is confusing because in Matlab, the "int" function is for integral,
but for c, int is a data type for integer.

Anonymous   
Printed Page 230
5th paragraph

the code:

@args = ("command", "arg1", "arg2");
system(@args) == 0
or die "system @args failed: $?"

is not terminated with a semicolon.

Anonymous   
Printed Page 237
in the description of unpack

For example, the following computes the same number as the System V sum
program:

undef $/;
$checksum = unpack ("%32C*", <>) % 32767;

For the System V systems that I have access to, the modulus should be 65535.
This is also the same number as produced by the berkeley 'cksum -o 2'.

Anonymous   
Printed Page 251
halfway down on the right

"If you want the C notion..." should read "If you want the C notation..."

Anonymous   
Printed Page 268
first example line

foreach $i ( 0 .. $#{ $HoL{$family} ) {

should be

foreach $i ( 0 .. $#{ $HoL{$family} } ) {

Anonymous   
Printed Page 268
top code segment (this is the 7/99 printing)

I think the authors wanted to put

print "
";

at the end of the outer `for' loop, and not outside both loops. Indeed, with
the input file

a: b c
b: c d
c: d e
d:
e:

and with the code in the book, I get the output a: 0 = b 1 = cb: 0 = c 1 =
dc: 0 = d 1 = ed: e: which is probably not what the authors intended. Moving
'print "
"' to the place I am suggesting, I get

a: 0 = b 1 = c
b: 0 = c 1 = d
c: 0 = d 1 = e
d:
e:

which I think the authors wanted (though I'd prefer not to see spaces around
"="---which is what the authors do in later examples for HoH).

Anonymous   
Printed Page 275
I think I found an error in the code

# print the whole thing
foreach $family ( keys %TV ) {
print "the $family";
print " is on during @{ $TV{$family}{nights} }
";
print "its members are:
";
for $who ( @{ $TV{$family}{members} } ) {
print " $who->{name} ($who->{role}), age $who->{age}
";
}
- --> print "it turns out that $TV{$family}{lead} has ";
print scalar ( @{ $TV{$family}{kids} } ), " kids named ";
print join (", ", map { $_->{name} } @{ $TV{$family}{kids} } );
print "
";
print "
";
}

It gave me this error with Perl 5.005_3:

Use of uninitialized value at ./p275 line 68.

I was able to correct it via changing the line to a for loop as follows:

# print the whole thing
foreach $family ( keys %TV ) {
print "the $family";
print " is on during @{ $TV{$family}{nights} }
";
print "its members are:
";
for $who ( @{ $TV{$family}{members} } ) {
print " $who->{name} ($who->{role}), age $who->{age}
";
}
- --> for $who ( @{ $TV{$family}{members} } ) {
- --> if ( $who->{role} eq "lead" ) {
- --> print "it turns out that $who->{name} has ";
- --> last;
- --> }
- --> }
- --> #print "it turns out that $TV{$family}{'lead'} has ";
print scalar ( @{ $TV{$family}{kids} } ), " kids named ";
print join (", ", map { $_->{name} } @{ $TV{$family}{kids} } );
print "
";
print "
";
}

Anonymous   
Printed Page 318
Example under heading Instance Variable Inheritance

I RAN THE SAMPLE:

package Base;

sub new
{
my $type = shift;
my $self = {};
$self->{buz} = 42;
return bless $self, $type;
}

package Derived;
@ISA = qw(Base);

sub new
{
my $type = shift;
my $self = Base->new;
$self{biz} = 11;
return bless $self, $type;
}

package main;

$a = Derived->new;
print "buz = ", $a->{buz}, "
";
print "biz = ", $a->{biz}, "
";

NO VALUE APPEARS FOR $a->{biz}

Anonymous   
Printed Page 333
-1(octnum) is alphabetized as if it were an el. It's a one.

Anonymous   
Printed Page 349-350
The example code for the server contains the line


print CLIENT "Hello there, $name ....

It should read

print Client "Hello there, $name ....

Anonymous   
Printed Page 350
10th line of code in first example

The non-forking server contains a call to REAPER on the SIG{CHLD} handle, even
though that code is not in the non-forking version, and that version never
spawns any children.

Anonymous   
Printed Page 353
The server code is missing lots of other declarations; it does not

compile on its own. The authors mention this after the code, but I missed it
the first time. The example should either be more vague (don't have the
shebang which suggests that the code is complete) or more explicit. Also, the
$paddr variable is not declared.

Anonymous   
Printed Page 437
4th paragraph

The value of $path in the example should have a "/" at the end. Should read:

$path eq '/virgil/aeneid/',

Anonymous   
Printed Page 440
In the description of File::Find, which begins on p. 339, the very first

line reads:

chdired to $File::Find::dir when find() is called.

It should read:

chdired to $File::Find::dir when wanted() is called.

Anonymous   
Printed Page 443
The 9/96 printing lists supposed Perl built-in functions like gets which

are not described elsewhere.

Anonymous   
Printed Page 451
7th paragraph up from bottom, first line

This is in the second edition:

$opt_foo = 'blech'

should be

$foo = 'blech'

Anonymous   
Printed Page 497
Bottom

Please see description of problem in:

http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1999-12/msg00111.html

Additionally Sleepycat reports that in multi-user environments they may have
to close and reopen the database behind your back, in which case the lock is
simply lost.

(Mentioned again because it is not in your published errata, and because it
appeared in the faq-o-matic on www.perl.com.)

Anonymous   
Printed Page 537
paragraph -2:

"$keyword{$_}" should be "$keywords{$_}".

Anonymous   
Printed Page 608
indirect object:

fonts messed up (or do I miss the joke?)

Anonymous   
Printed Page 621
paragraph 1:

"INChash" should be "INC hash."

INDEX:
The index is incomplete. For example these functions aren't there. The
English names for a bunch of variables aren't there either, such as
autoflush.index suggestion} an index entry for $#array pointing to the
discussion on page 49 may help readers understand that is a special evaluation
on arrays related to scalar evaluation. It is unrelated to the deprecated use
of $# as a special variable.

INDEX:
May I suggest that touch (p. 239) be added to the index for the next Camel
rev. This would be helpful for people who are looking up how to do this (and
it is in italics after all :-)

INDEX:
Many of the references in the index table lead you to a page which does not
conain the indexed word. (for example, in the index 'flush' is referenced at
page 70, but nothing on that page.)

{suggestion for future edition}
Just a note to say: In a future addition of the Camel, please be sure to add

move("/dev1/fileA","/dev2/fileB");

to the discussion of File::Copy in the Camel (p. 438). It's in the newer pod,
so this may not even require a reminder, but I don't know how you do your
minor revisions :-)

Anonymous   
Printed Page 621
under :

Add an item "1, 2, 3, ... (see backreferences)."

Anonymous   
Printed Page 622
under $ variables:

$& $' $` and $+ are on page 66, not page 65.

Anonymous   
Printed Page 628
do SUBROUTINE operator

The do entry in the index should delete the word SUBROUTINE, as the pages
cited are for the non-deprecated do block as well.

Anonymous