Errata

Advanced Perl Programming

Errata for Advanced Perl Programming

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 xix

http://tpj.com/tpj.com/tpj/contest

should read

http://tpj.com/tpj/contest

Anonymous   
Printed Page xix
The Obfuscated C Code Contest's URL is

http://www.ioccc.org/

The Perl Journal's Obfuscated Perl Contest URL has a duplicate "tpj.com", but
there seem to be other problems. It *appears* to now be at

http://fahrenheit-451.media.mit.edu/tpj/contest/

Anonymous   
Printed Page xx
the FTPMAIL-section:

The cd-command should end in "advanced_perl", not "advanced.perl", shouldn't
it?

Anonymous   
Printed Page page 330

which reads:

sv_setpv(SV *, char *)

Note two arguments in table 20-1, and three in the example (pg 355).
Perhaps the example was intended to be a call to sv_setpvn ? Or perhaps the third argument in the example
was not meant to be there?

Anonymous   
Printed Page page
} Possible bugs a reader found in the module Msg.pl

I tested it on AIX and perl5.004_01.

- The BEGIN block does not work as expected. It seems that $blocking_supported
in this block is some other value as the my $blocking_supported = 0; defined
in the program. I also don't understand this, (it should work ??)

- The function calls $conn->set_non_blocking(), $conn->set_blocking() will
not work as intended; in these functions fcntl is called with the hash
reference. It should be:

fcntl($_[0]->{sock} , ...

- On AIX when syswrite blocks, $! will be set to "Resource temporarily
unavailable" instead of EAGAIN. So _err_will_block() will not work as expected.
This is not a bug of course but a machine dependency.

{example archive} There are a couple of things in the tetris.pl example which
are in the examples archive for Advanced Perl Programming that don't seem to
work quite right.

My perl : 5.005_02
My Tk.pm : Tk800.012

At line 482 (the first statement in sub create_screen{}), the program as
shipped does:

$w_top= MainWindow->new('Tetris - Perl/Tk') ;

which dies with

"Odd number of argsMainWindow->new(Tetris - Perl/Tk)"

This one can be fixed by:

$w_top = MainWindow->new() ;
$w_top->title('Tetris - Perl/Tk') ;


The second one is little more subtle. On line 154, the comparison "$new_col >
$MAX_COLS" isn't right--there *are* ten columns, but they're numbered starting
from zero. You can demonstrate the problem with this by moving pieces to the
right edge and rotating them. Depending on the shape of the piece, you can
get the piece to run off the edge of the playfield and stick.

To fix this, all you have to do is change the comparison to:

($new_col >= $MAX_COLS)

{EXAMPLES}
ftp://ftp.oreilly.com/published/oreilly/nutshell/advanced_perl/examples.tar.gz

The file "examples/Jeeves/lib/Ast.pm":

sub get_prop_value {
my ($this, $prop_name) = $_[0];
return $this->{$prop_name};
}

should be

sub get_prop_value {
my ($this, $prop_name) = @_;
return $this->{$prop_name};
}

Tetris Bug Fix:

Bug = when object is on the right
wall and you rotate - the object can be frozen before it hits bottom and
the object will partially go outside the right boundry.

sub rotate {
# rotates the block counter_clockwise
return if (!@cells);
my $cell;
# Calculate the pivot position around which to turn
# The pivot is at (average x, average y) of all cells
my $row_total = 0; my $col_total = 0;
my ($row, $col);
my @cols = map {$_ % $MAX_COLS} @cells;
my @rows = map {int($_ / $MAX_COLS)} @cells;
foreach (0 .. $#cols) {
$row_total += $rows[$_];
$col_total += $cols[$_];
}
my $pivot_row = int ($row_total / @cols + 0.5); # pivot row
my $pivot_col = int ($col_total / @cols + 0.5); # pivot col
# To position each cell counter_clockwise, we need to do a small
# transformation. A row offset from the pivot becomes an equivalent
# column offset, and a column offset becomes a negative row offset.
my @new_cells = ();
my @new_rows = ();
my @new_cols = ();
my ($new_row, $new_col);
while (@rows) {
$row = shift @rows;
$col = shift @cols;
# Calculate new $row and $col
$new_col = $pivot_col + ($row - $pivot_row);
$new_row = $pivot_row - ($col - $pivot_col);
$cell = $new_row * $MAX_COLS + $new_col;
# Check if the new row and col are invalid (is outside or
#something
# is already occupying that cell)
# If valid, then no-one should be occupying it.
if (($new_row < 0) || ($new_row > $MAX_ROWS) ||
($new_col < 0) || ($new_col > $MAX_COLS -1 ) ||
$heap[$cell]) {
return 0;
}
push (@new_rows, $new_row);
push (@new_cols, $new_col);
push (@new_cells, $cell);
}
# Move the UI tiles to the appropriate coordinates
my $i= @new_rows-1;
while ($i >= 0) {
$new_row = $new_rows[$i];
$new_col = $new_cols[$i];
$w_heap->coords($tile_ids[$i],
$new_col * $TILE_WIDTH, #x0
$new_row * $TILE_HEIGHT, #y0
($new_col+1) * $TILE_WIDTH, #x1
($new_row+1) * $TILE_HEIGHT);
$i--;
}
@cells = @new_cells;
1; # Success
}

Anonymous   
Printed Page 11
5th paragraph

The way references to anonymous values behave in Perl is not at all the way
pointers to anonymous values behave in C. In C, if you make a pointer to a
variable that goes out of scope, the pointer will point to "garbage". In Perl,
the garbage collector ensures that if a references refers to a variable that
goes out of scope, that the reference will remain valid. Perl references behave
like Java references.

Anonymous   
Printed Page 13
line 8:

Apostrophes around /bin/rm * should be back ticks.

Anonymous   
Printed Page 14
Figure 1-2

The line:

name sue

should be:

name Sue

Anonymous   
Printed Page 14
last paragraph

There are two ways that C can implement "multidimensional arrays": either as
arrays of arrays, or arrays of pointers to arrays. The way Perl implements
multidimensional arrays is similar to C's arrays of pointers to arrays, like
in the following code:

int **a = malloc(10 * sizeof(int *));
for (i = 0; i < 10; i++)
a[i] = malloc(10 * sizeof(int));

C also can have arrays of arrays, like in the following code:

int a[10][10];

C's arrays of arrays are laid out in a contiguous stream of bytes. When the
statement is made the Perl implements multidimensional arrays is a way similar
to C, the author explains that pointers are used, as in the first example, but
that the data is contiguous, as in the second example. The bottom line is that
Perl's multidimensional arrays are totally unlike the vast majority of C
multidimensional arrays, which are arrays of arrays. Perl's multidimensional
arrays are, however, very much like Java's multidimensional arrays.

Anonymous   
Printed Page 14
2nd line at top of page

$sue{'children'} = [\%john, \%peggy];

should be:
$sue{'children'} = \[\%john, \%peggy];

As printed: erroneously sets the hash value to an anonymous array instead of a reference to an anonymous array.

Inov8r  Oct 26, 2010 
Printed Page 24
Figure 2-1

last line of C shaded box on left side of diagram should read

} foo = {10, "good" };

Anonymous   
Printed Page 25
MAT2 should have 3 rows to be usable in Example 2-1, page 26.

Anonymous   
Printed Page 26
line 11 in Example 2-1


push (@{$matrix_name}, @row;) # insert the row-array into

should read

push (@{$matrix_name}, @row); # insert the row-array into

Anonymous   
Printed Page 28, 29
sample data files / sample code

The sample data files on 28 list student Garibaldi as id 52003; the sample
code on 29 lists Garibaldi as id 42343.

Anonymous   
Printed Page 29
para. 5:

The example student structure doesn't list any courses, but the following text
discusses foreign keys versus references as though courses were listed in the
sample. The text also refers to HS201 as a course taken by Garibaldi; in
fact, it's listed in the data files as a course taught by Schumacher and not
taken by Garibaldi.

Anonymous   
Printed Page 30
Example 2-3

In Ex 2-3, there needs to be an an elsif clause to read the professor's name
into curr_prof->{name}. Try

elsif ($line =~ /^Name:.*s*(.*)/) {
$curr_prof->{name} = $1;
}

Anonymous   
Printed Page 30
Example 2-3

On pages 30 and 31 in Ex 2-3 and 2-4, change all occurances of {name} to
{Name}, to be consistent with the other hash keys especially since the student
hash on page 29 uses "Name".

Anonymous   
Printed Page 30
first code, before last line

The file F is opened but is not closed.

Anonymous   
Printed Page 31
code line 4, Regex in Line 4

/(A-Za-z]+).*(d+)-(d+)/

This won't work for Starting-Hours >= 10, because the .* in front of the first
(d+) will get the first digit. The d+ will only get the second digit. Make
.* non-greedy (.*?) or change it to [^0-9]* to prevent it from "eating" digits.

Anonymous   
Printed Page 31
lines 7 and 13 in Example 2.4

course_get_hours: sub course_get_hours{...} is missing.

Anonymous   
Printed Page 31
Example 2-4, line 10

... $course_taught
";

should be

... $r1_courses->[$i]
";

Anonymous   
Printed Page 31
first code line 10

The line "$to = 19 if $to == 7;" is not needed. It is handled by the next line
that tests for $to <= 7.

Anonymous   
Printed Page 31
line 12 of Example 2.4

"for $j" should start with $i+1 (instead of $i) to avoid checking overlaps of
a course with itself.

Anonymous   
Printed Page 31
line 12 of "Example 2.4"

What you have:
for $j ($i+1 .. etc.)
What it should be:
foreach $j ($i+1 .. etc.)

Anonymous   
Printed Page 31
second code, line -11

There is no variable

$course_taught

even through is it referenced in this print statement. Should be

$r_courses->[$i].

Anonymous   
Printed Page 31
line -4 of Example 2.4

missing closing brace (opening { in line -8 is unbalanced)

Anonymous   
Printed Page 33
line 1 of first code example

die "..." should terminate with $! instead of $:.

Anonymous   
Printed Page 36

} elseif ($ref_type eq "SCALAR") {

should read

} elsif ($ref_type =~ /SCALAR/) {

Anonymous   
Printed Page 38
first sentence after code:

Example 14-4 does not, as stated, invoke the "cascade" method.

Anonymous   
Printed Page 42
code under heading "Typeglobs":

Change the lines:

print "@potato
"; #prints "Wow!"
print @potato, "
"; #prints "idahorusset"

to

print @potato, "
"; #prints "Wow!"
print "@potato
"; #prints "idaho russet"

(The comments are just a little off.)

Anonymous   
Printed Page 53
line 11:

comment should be: # Prints "Batman and Robin
"

Anonymous   
Printed Page 53
3rd line of last example:

comment should read: # prints "foo called
"

Anonymous   
Printed Page 54
Example 4-1, line 11

The line

&($rhOptions{"_default_"});

appears to reference the function but it has no parameter list.

should be

&($rhOptions{"_default_"})();

Anonymous   
Printed Page 54
second code example

I could not get the reference call to the "default" subroutine to work in the
dispatch table example:

&{$rhOptions{"_default_"}};

Nor could I get the reader's (unofficial) correction to work.

Copying the example code given in the book's code a block above the
aforementioned line did, however, work:

i.e.

else {
if(exists $rhOptions->{"_default_"}) {
$rsub = $rhOptions->{_default_};
&$rsub();
}
}

Anonymous   
Printed Page 61
Example 4-3

First line of the routine "even_number_printer_gen" should be:
my ($input) = $_{0};
or
my ($input) = shift;

Anonymous   
Printed Page 63


print $random_iter1(), " ", $random_iter2(), "
"

should be

print $random_iter1->(), " ", $random_iter2->(), "
"

or

print &$random_iter1(), " ", &$random_iter2(), "
"

Anonymous   
Printed Page 68
Figure 5-1:

Lines 1 and 2 of the figure should be swapped to match the code on page 67.

Anonymous   
Printed Page 71
under exceptions.pl

"catch takes a piece of code as a string (instead of as a block, as the previous example)"

My question is: should the 'catch' in the referenced example have as its argument a block? It doesn't
seem to.

Anonymous   
Printed Page 75
section 5.5.1 under Example 5.2:

It says:

"If @patterns contains the three strings "^abc", "ghi", "efg$",
for example, the code supplied to eval looks like this:

while (<>) {if (/^foo/ && /bar$/ && /ghi/) {print $_;}}"

The Perl code line should read:

"while (<>) {if (/^abc/ && /ghi/ && /efg$/) {print $_;}}"

Anonymous   
Printed Page 77
line 11


$tmp .= " " x (7 - length($tmp));

extends $tmp to its size of 7 characters. Of course, that is only necessary if
$tmp might be shorter than 7 characters. But that is impossible, as $s is
extended (in line 9) enough to guarantee the length of 7 characters for $tmp.

The same applies to lines 13/15 and to the generating sourcecode on page 79.

Anonymous   
Printed Page 79
This one is stylistic--it doesn't actually matter on the code given, but

given that using $` is, um, considered harmful, wouldn't the tab expansion
code be better represented as:

while ($buf =~ m/ /g) {
my $loc = pos($buf) - 1;
substr ($buf,$loc,1) = ' ' x (8 - ($loc % 8));
}

Anonymous   
Printed Page 79
line -6:

# expand leading tabs first-the common case

The comment suggests that leading tabs are expanded first for efficiency, but
it is almost always a bad idea to code for efficiency--at least until you've
benchmarked the code.

You might want to show how to expand leading tabs separately for instructional
value, but then the comment should say that.

Anonymous   
Printed Page 82
1st paragraph in 'Java'

The author states that it is not possible to generate new java code on the fly.

It is possible to get the compile class and make it compile a new .java
file and then get the compiled class by Class.forName...

compilerArgs = new String[5];
compilerArgs[0] = "-classpath";
compilerArgs[1] = "/usr/lib/java/jre/lib/rt.jar:...";
compilerArgs[2] = "-d";
compilerArgs[3] = outputDir;
compilerArgs[4] = javaFilename;

compilerClass = Class.forName( "com.sun.tools.javac.Main");
compilerObject = compilerClass.newInstance();
compileMethod = compilerClass.getMethod( "compile",
new Class[] { (new String [] {}).getClass() });
compileResult = ( (Integer) compileMethod.invoke( compilerObject,
new Object[] { compilerArgs } ) ).intValue();
if ( compileResult == 0 ) {
System.out.println( "compile was successfully...");
}

Anonymous   
Printed Page 83
Don Pardo's papers have left the URL given, and no forwarding information

is provided.

Anonymous   
Printed Page 83
the WWW links by Don Pardo

the www links and papers by Don Pardo:

http://www.cs.washington.edu/homes/pardo/rtcg.d/index.html
should be ...
http://www.cs.washington.edu/research/compiler/rtcg.html

Anonymous  Apr 26, 2015 
Printed Page 85
3rd code example

The line

package B;

should be in bold since it is the point of the example.

Anonymous   
Printed Page 88
para. 1, lines 1-2:

"Perl first looks for the file given to use() or require()
in the current directory and then looks up the @INC built-in
array to search the include paths."

This sentence is incorrect. Perl searches for used or require'd files in @INC.
By default, the current directory is in @INC, but it is at the end, so it is
searched *after* all the other paths in @INC.

Anonymous   
Printed Page 92
two thirds down the page

"Example 6-1 shows one way to do write this subroutine"
^^^^^^^^

Anonymous   
Printed Page 93
line -1:

"The double colon gets translated to a filename separator,
because the colon has a special significance for DOS
filenames."

Well...no. The double colon gets translated to a filename separator so that
the package name becomes a valid path. Consider:

OS Package -> Path
Unix Foo::Bar -> Foo/Bar.pm
DOS Foo::Bar -> FooBar.pm

Saying that the double colon is translated in order to accommodate DOS
misapprehends both the translation mechanism and the history of Perl, which
was originally developed for Unix, not DOS.

Anonymous   
Printed Page 95
2nd paragraph in "Accessing the Symbol Table"

"We will also use this property is in Chapter 11,"
^^

Anonymous   
Printed Page 105
(and following pages):

The entries "hours_worked" and "overtime_hours_worked" are being used in
"compute_ytd_income," but are nowhere defined.

Anonymous   
Printed Page 109
It is not impossible to achieve the same effect in one line with the

indirect notation. See the Camel book, p295.

Anonymous   
Printed Page 111
para. 2, line 4:

"allocate uses this to bless the object directly into
the inherited class."

Derived classes "inherit" things from base classes. You can reasonably say
that a derived classes "inherits" its base class. But even granting some abuse
of notation, it is wrong to refer to a derived class as the "inherited" class.

This is particularly unfortunate in this paragraph, because it is essential
that the user clearly understand the inheritance relationships in order to
understand why allocate() shouldn't hardcode the class name.

The sentence might be better written as

"allocate uses this to bless the object directly into
the HourlyEmployee class."

Anonymous   
Printed Page 118
sub price has one too many }s (I think this is right, but don't

want to rely on my own scant Perl knowledge. -efm)

Anonymous   
Printed Page 119
After line 6 in Example 7-1, I had to add


use StoreItem;

before

@ISA = qw(StoreItem);

Anonymous   
Printed Page 121
In the "Resources" section of chapter 7, there is a reference to the

comp.object FAQ. The URL given brings one to an empty directory; it appears
that comp.object no longer has a FAQL.

Anonymous   
Printed Page 121
"Resources" section

comp.object FAQ apparently is now archived at:

http://www.faqs.org/faqs/by-newsgroup/comp/comp.object.html

Anonymous   
Printed Page 127
2nd line below Figure 8-2

"@free" should read "@_free".

Anonymous   
Printed Page 130
code sample 2:

Delete line 4: "my (@retcal);".

Anonymous   
Printed Page 136
There is a general way to get interface inheritance in Perl. Define your

data-structure in a way that uses an object in the class that you want to
inherit from. (That is, use containment.) Do not include that package in
@ISA. Use an AUTOLOAD subroutine for unknown calls that passes the base
object to the class that you inherit from. BINGO! You have a module that
inherits an interface even if the base class changes.

Anonymous   
Printed Page 140
In table 9-1, in the right-hand column, the FETCH could maybe do

with a:

my $obj = shift;
$obj->get_temp();

and the STORE:

my ($obj, $t) = @_;
$obj->set_temp($t);

At the moment there's a mix of $obj and $ac.

Anonymous   
Printed Page 142
In Table 9-2, perhaps you could add a ";" after lines 1 and 3 in column

1 to match the other lines.

Anonymous   
Printed Page 143
sub FETCH {

If the first line requested from the tied array is the second line of the file the
seek will fail. Change:

if ($index > @$rl_offsets) {

To either:

if ($index > $#$rl_offsets) {

Or:

if ($index >= @$rl_offsets) {

Anonymous   
Printed Page 144
Example 9-2, line 13


last if $last_index > $index;

Perhaps it should read

last if $last_index >= $index;

so it does not overshoot the line.

Anonymous   
Printed Page 156
code sample 1, line -1:

syswrite(F, $msg, length($msg)); # can also use write() or print()

This is bizarre and/or wrong. The ordinary way to code this is

print F $msg;

Using syswrite() might make the code run a bit faster, but it also invites
bugs from programmers who forget (or don't know) that mixing syswrite() and
print() is treacherous.

write() is for outputting formats: it won't work at all.

Anonymous   
Printed Page 160
Berkeley DB, 1st para, 2nd line

Is "B+Tree" correct? (Shouldn't the "+" be a "-"?)

Anonymous   
Printed Page 162-163
lines -2 and -1

$sth = $dbh->prepare('insert into emptable (name, age)
values (?, ?)');

and

$sth->execute($id, $name, $age);

These two lines seem inconsistent. There are 2 question marks in the prepare()
call, but 3 parameters in the execute() call.

Anonymous   
Printed Page 184
code sample, lines 9 and 10 (rule 2)


$query =~ s/\[# Hopefully 200 and 201 aren't being
$query =~ s/\["]/201/g; # being used.

The first line is not correct. It should probably appear as follows:

$query =~ s/\[']/200/g; # Hopefully 200 and 201 aren't
$query =~ s/\["]/201/g; # being used.


Anonymous   
Printed Page 190
-8:

(TCP/IP) "Transport" should read "Transmission."

Anonymous   
Printed Page 191, 192, 194
In the code samples "LocalHost" should be "LocalAddress."

Anonymous   
Printed Page 196
The code is a continuation of the same example but $main_sock changes to

$main_socket.

Anonymous   
Printed Page 204
second code, line 6


print "Server created. Waiting for events";

should be

print "Server created. Waiting for events.
";

Anonymous   
Printed Page 213
code in the BEGIN block

eval {
require POSIX; POSIX->import(qw(F_SETFL O_NONBLOCK EAGAIN));
};

should be:

eval {
require POSIX; POSIX->import(qw(F_GETFL F_SETFL O_NONBLOCK EAGAIN));
};

F_GETFL is missing.

Anonymous   
Printed Page 213
Code just before and in the BEGIN block

The downloaded code Msg.pm has the following line before the BEGIN block:

my $blocking_supported = 0;

This line is missing in the printed version. The assignment is executed after the BEGIN block, negating the assignment of 1 there - as a result set_non_blocking and set_blocking never do anything. Replace by:

my $blocking_supported; # executed after BEGIN block

Replace the last line of the BEGIN block

$blocking_supported = 1 unless $@;

by

$blocking_supported = ($@) ? 0 : 1; # executed before my $blocking_supported;

Also include F_GETFL in the POSIX->import(qw()); - reported previously



John E. Wulff  Oct 29, 2012 
Printed Page 218
lines 5 and 7

"new_rpc_server" should read "new_server."

Anonymous   
Printed Page 220
sub _incoming_msg

Using Perl 5.8 on Linux it appears that the behaviour of defined() on blank values
has changed.

I found I needed to add this last line to the _incoming_msg routine. On the "final"
call to this routine, $msg is defined, but empty.

sub _incoming_msg {
my ($conn, $msg, $err) = @_;
return if ($err); # Need better error handling.
return unless defined($msg);
if ($msg eq "") {return{}}; # perl 5.8 seems to treat defined differently

Anonymous   
Printed Page 228
Lines 15, 18, 21 (Heading : Images as line 1)


$image = $label->Bitmap(file => 'face.xbm'); etc

Each of these lines must read

$image = $label->Bitmap(-file => 'face.xbm'); etc....

ie, must have a hyphen before the word "file" (also on the CD).

Anonymous   
Printed Page 231
2nd code block

$canvas->coords ($id, 10, 100);

should be

$canvas->coords ($id, 10, 100, 100, 100);

# needs four coordinates.

Anonymous   
Printed Page 235, 246
Are the keys -expand, -fill, -side and -text correct? If yes, I'd

liked to read an explanation for these "funny" negative keys somewhere.

Anonymous   
Printed Page 238
second para below code:

Change "explicitly using the add method" to "explicitly using the insert
method."

Anonymous   
Printed Page 239
second line of code:

"[N$widget]" should be "[$widget]".

Anonymous   
Printed Page 243
Example 14-7:

Basically, the named parameters to the hlist methods should all start with a
hyphen: "image =>" should be "-image =>", "text =>" should be "-text =>",
"imagetext" should be "-imagetext", etc.

Anonymous   
Printed Page 251
first footnote

www.neosoft.com is an ISP, not a resource for Tcl/TK.

Now if I can just find a complete reference to the technique on page 239 about
multiple list boxes with one scrollbar. Your example doesn't describe how to
have the scrollbar actually send the yview command to multiple widgets, it
just talks around it and implies that it's possible. Multiple text boxes can
send the yscrollcommand to the scrollbar - that's fine. It's just getting the
scrollbar to send the yview command to more than one text box needs an actual
example. The text talks about keeping multiple boxes in synch, but then just
describes how to get the yview command sent to a single widget.

Anonymous   
Printed Page 282
Table 17-1, Directives Recognized by Jeeves

Table 17-1 mentions tHAT Jeeves recognizes "@IF, @ELSIF, @ELSE, @END" as
directives for the Template Parser.

These directives are not recognized by either Jeeves or the template parser.
They are not found on CPAN or in the associated examples tar ball on your FTP
site.

The bad directives are also mentioned in the postscript documentation in the
examples tar ball.

Anonymous   
Printed Page 283
Regex containing "FOREACH" (line 11)

} elsif ($line =~ /^s*@FOREACHs*(w*)s*(.*)s*/i {

The last s* is useless, because .* will "eat" all whitespace. Why not write
(w+) instead od (w*) to ensure that at least one word-char. is present?

Anonymous   
Printed Page 302

On page 302 of Advanced Perl Programming, there is a typo in the draw_mandel code.
The code reads

INIT:
if (width > 400) {
fprintf (stderr,"Width cannot exceed 400. Truncating.
";
width = 400;
}

while it should read:

INIT:
if (width > 400) {
fprintf (stderr,"Width cannot exceed 400. Truncating.
");
width = 400;
}

The ) at the end of fprintf is missing.

Anonymous   
Printed Page 314
1st paragraph

not a bug, but a Bad Thing

page 314, the author creates a custom perl interpreter called ex.

The problem is, on each UN*X system, the standard text editor is vi, which can
also be invoked as view (read-only mode) or ex (command line mode). Depending
on your PATH setting, you might get either the text editor or the custom perl
interpreter when you type:

ex search.pl

Yet, page 39 and page 127, the author frowns upon using the same identifier
for a scalar and an array, for example. IMHO, this is confusing but not
dangerous. On the other hand, the present ex problem is confusing *and*
dangerous. The custom perl interpreter ought to get another name.

Anonymous   
Printed Page 316
Ex. 19-3:

Near the end of the example, there are these lines:

for (num = 1; num <= 7; num++) {
char buf[20];*buf = '';

that should be

for (num = 1; num <= 7; num++) {
char buf[20];
*buf = '';

I believe.

There are also a lot of tabs in code (that's how I found this) that should be
cleaned up.

Anonymous   
Printed Page 317
last line:

The URL might need to be changed to:

"http://perl.apache.org/"

Anonymous   
Printed Page 319-371
In the examples of chapter 20 there are many possible buffer

overflows. All the strcpy should be strncpy.

Anonymous   
Printed Page 325
lines 2 and 3:

In Figure 20-2 I can see only one of the two mentioned pointers to "add's
children. But maybe I didn't understand it.

Anonymous   
Printed Page 330
11th definition

The book lists svREFCNT_dev(SV *), but the actual function is SvREFCNT_dec(SV
*). Note the capitalization of the first letter. See the prototype in Perl
5.6.0, sv.h.

Anonymous   
Printed Page 330
5th macro listed - table 20-1

APP 1st edition (aug 97)

The listing for the fifth macro on page 330, table 20-1, reads as follows:

'sv_setpv (SV*, char *,
int len'

It is missing the terminating paren (and possibly a semi-colan).

An additional, though probably more stylistic inconsistancy is that only some of the listings in this
table are semi-colan terminated.

Anonymous   
Printed Page 331
There is a reference to the function sv_dump(SV*). This function will

only produce useful output if you have DEBUGGING #DEFINED when you compile
Perl. If you do not have DEBUGGING defined, then the call will produce no
output.

Anonymous   
Printed Page 340
very first line, edition of 8/1997

"So if xhv_keys exceeds xhv_fill, Perl takes it ..."

xhv_fill should be xhv_max (source: perl-5.6.1/hv.c:423)

Anonymous   
Printed Page 355
Second code listing (3rd paragraph)

APP - first edition (aug. '97)

In the second code listing on page 355 (Ch 20, section 'The Called Side: Hand-Coding an XSUB, subsection
'Returning a variable list of results') has the following statement:

sv_setpv(ST(i), "hello", 0); /* Like modifying $_[i] */

I'm not certain of the error here, but this call is inconsistant with the definition given in table 20-1

Anonymous   
Printed Page 390
paragraph numbered 22

In Appendix B, paragraph 22, the line

${"i"} = 10; # sets $foo to 10

should read either (most likely)

${"$i"} = 10; # sets $foo to 10

or (unlikely)

${"i"} = 10; # sets $i to 10

Anonymous