Perl Best Practices

Errata for Perl Best Practices

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 xxi
top of page, 2nd line down && 14th line down

... extrapolate from those particulars to excellent general advice. ?should be? ... extrapolate from those particulars excellent general advice. (remove 'to') -and- ... and his valiant defence of "unless". should be ... and his valiant defense of "unless". (spelling of defense)

Note from the Author or Editor:
Fixed spelling of defence to defense in [6/09] printing.

Anonymous   
Printed Page 15
Last paragraph of Section 2.6., Operators.

The final paragraph of Section 2.6., Operators, states, "Named unary operators should be treated like builtins, and spaced from their operands appropriately"; however, the first example given fails to account for operator precedence: my $tan_theta = sin $theta / cos $theta; This is clearly intended to calculate the tangent of an angle theta by dividing the sine of theta by the cosine of theta: sin(theta) / cos(theta) However, because the precedence of the division operator "/" is higher than the precedence of the named unary operators "sin" and "cos," the result is actually calculated as follows: sin( theta / cos(theta) ) Here is one possible correct form of the example: my $tan_theta = sin($theta) / cos($theta) Here is a shell transcript that proves that the code snippet in the book produces the wrong result, and that the form immediately above produces the correct result: $ perl -e '$theta = 1; print(sin $theta / cos $theta, " ");' 0.961050079349205 $ perl -e '$theta = 1; print(sin($theta) / cos($theta), " ");' 1.5574077246549 $ perl -e 'use Math::Trig; $theta = 1; print(tan($theta), " ");' 1.5574077246549 I characterized this as "serious technical mistake" because this chapter is supposed to demonstrate best practices for code layout, yet the author's own formatting advice from Section 2.4, Don't use unnecessary parentheses for builtins and "honorary" builtins, appears to have led to the construction of an erroneous expression in Section 2.6. Perhaps the omission of parentheses on named unary operators in expressions should not be held up as a best practice. At the very least, some additional discussion of this pitfall of Perl operator precedence might be in order.

Anonymous   
Printed Page 29
last line of first code block, line starts with "add_step"

In the call to add_step(), there is a space after the opening "(" but no space before the corresponding ")". I'm assuming that's an error, since there is no discussion of doing anything like that on purpose.

Anonymous  May 09, 2010 
Printed Page 35
perltidyrc file

-pt=1 should be: -pt=2 because throughout the book if, while, for parenthesized expressions have tightly bound parentheses. if ($x == $y) { instead of: if ( $x == $y ) {

Jon Bjornstad  Sep 28, 2010 
Printed Page 35
middle

The perltidy option listed as -pt=1 should instead be -pt=2. Examples of code throughout the book are mostly formatted with -pt=2 so this should be the one used in perltidy, yes?

Jon Bjornstad  Apr 15, 2011 
Printed Page 38
third code block

The end of line comment for the third line is one place too far to the left, so it fails to line up with all of the other end of line comments in that code block. You need one more space between the ; and # in the line: my $estimated_net_worth; # not: $value

Anonymous  May 09, 2010 
Printed Page 40
top code block

while (my $month = prompt -menu => $MONTH_NAMES) { for my $book ( @catalog ) { print "$ISBN_for{$book} $title_of{$book}: $sales_from[$month] "; } } According to section '2.4. Builtins', only builtins do not need "unnecessary parentheses". Prompt is not a builtin and therefore should have parentheses in order to "visually distinguish between subroutine calls and calls to builtins".

Anonymous   
Printed Page 42
second code listing (in boldface)

As noted in the comments of the first (non-boldface) code example on the page, the _ref variables should use dereferencing arrows to access values. Thus, the two lines: my $gap = $opts_ref{cols} - length $text; my $left = $opts_ref{centred} ? int($gap/2) : 0; should read instead: my $gap = $opts_ref->{cols} - length $text; my $left = $opts_ref->{centred} ? int($gap/2) : 0;

Anonymous   
Printed Page 42
middle

When displaying the $opts_ref{cols} error it should not be in bold font. From page xviii - Constant-width bold indicates commands and other text that should be typed literally by the user, and code examples that demonstrate recommended practices.

Jon Bjornstad  Jul 13, 2012 
Printed Page 44
Second code sample (middle of page)

Shouldn't $tax_form be $tax_form_ref, especially this close to the Reference Variables recommendation?

Anonymous   
Printed Page 44
first code block in "Underscores" section

There is a double space between "next FORM if $notional_tax_paid" and "< $MIN_ASSESSABLE;", for no apparent reason.

Anonymous  May 09, 2010 
Printed Page 47
first code block

There is a double space between "$connection_Mbps" and "= get_bitrate ..."

Anonymous  May 09, 2010 
Printed Page 80
first code block

You break your own rules slightly with the line: open my $pipe, '/cdrom/install |' since this is neither three-argument open nor IO::File open (page 207) It should be: open my $pipe, '-|', '/cdrom/install' (yes it's a constant string so it's not unsafe, but rules are rules. Allow that and you're half way to allowing q{open my $pipe, "$foo |"} so long as you "know" that $foo is safe. Ok, maybe only a quarter of the way, but it's the thin end of a slippery slope.)

Anonymous  May 09, 2010 
Printed Page 100
4th line up from bottom of page (last line before code snippet)

Function name is incorrect - it should be odd() (the function from the previous code snippet), but the text refers to even() which DNE: "... then a better solution is usually to "inline" the call to even(), replacing ..." -Should Be- "... then a better solution is usually to "inline" the call to odd(), replacing ..."

Anonymous   
Printed Page 121
2nd code block,

There are 2 extra spaces before the closing curlybrace at the end of the line starting with "logged => sub ...". These extra spaces are not present when the same code appears on page 120.

Anonymous  May 09, 2010 
Printed Page 126
first code block

The space before the "*" is missing in the line: my $projected = $client->{activity}* $value;

Anonymous  May 09, 2010 
Printed Page 131
example marked "updated code"

The example for Loop Labels does not seem to fulfill its intention, to 'give up trying to contact clients if any of their numbers is marked "Do Not Call"'. The code as written gives up for a client only if the FIRST phone number in the client's list has a "Do Not Call". Otherwise, it uses that number as the preferred number to send an ad even if a subsequent phone number has a "Do Not Call". The "last PHONE_NUMBER;" statement ensures that subsequent phone numbers are not checked.

Anonymous  Oct 10, 2008 
Printed Page 144
2nd code block

There is an extra space before the = in the line: if ($QFETM_func_ref = get_GET()) {

Anonymous  May 09, 2010 
Printed Page 164
Code example near bottom of page

Sample code in book describing the Sort::Maker module has a usage/syntax error and will not compile. Please see my usenet post regarding this issue (in GoogleGroups: http://tinyurl.com/j4hzg) and also the reply in this thread from Uri Guttman (author of the Sort::Maker module) confirming the error.

Anonymous   
Printed, PDF Page 171
last paragraph

Scalar::Util also provides a several other exportable subroutines that are not described here. should be: Scalar::Util also provides several other exportable subroutines that are not described here.

Anonymous  Jul 22, 2012 
Printed Page 182
1st code block

The way you format the multi-line return statement is inconsistent with the way a very similar return is formatted on page 179: on page 179 the string concatenation dots are lined up under the "n" of "return" so that each of the concatenated strings starts in the same column. However, on page 182 the dots are placed under the "$" of $arg_ref instead.

Anonymous  May 09, 2010 
Printed Page 195
Example code

In the discussion of prototypes, the example code includes a subroutine called "clip_to_range" that takes $min, $max, and @data as parameters. Based on that information, I expected the code to return only those data elements that are between $min and $max. Inspection of the code, however, revealed that through the use of List::Util's min and max routines data elements that were less than $min were changed to $min and those greater than $max were changed to $max. The code in question is map { max( $min, min( $max, $_ ) ) } @data. For example, given $min = 1, $max = 3, and @data = ( 0 .. 4 ) I expected the subroutine to return ( 1, 2, 3 ). It actually returns ( 1, 1, 2, 3, 3 ). If this is the intended behavior of the subroutine, I suggest renaming it (as the use of "clip" implies cutting and removing) and/or adding a comment that indicates that is the intended behavior. If the code itself is in error, one simple fix might be something like grep { ($min <= $_) && ($_ <= $max) } @data.

Anonymous   
Printed Page 195
third code block

Unbalanced spaces in the call to clip_to_range(); you have a space after the opening "(" but no space before the closing ")".

Anonymous  May 09, 2010 
Printed Page 198-199
bottom of 198, top of 199

Note: I found this in the PDF sample chapter from the book's web site; I have not verified whether it is in a full copy of the book itself. I did not find it in the errata. There is a code snippet that starts on the bottom of page 198 and continues on the top of page 199. The code consists of four if statements with two comment lines in the body of each statement. The second comment line is incorrect in each of the statements. They begin: # so if the block is ... whereas they should be: # so the if block is ... That is, "if" and "the" are transposed. This code snippet parallels a code snippet on page 197. The code on that page does not have this problem.

Anonymous   
Printed Page 220
last code example (and first code example p 221 as well)

Replace -onechar with -one_char

Anonymous   
Printed Page 242
1st paragraph

Regexp::Autoflags does not exist in CPAN.

Anonymous   
Printed Page 275
sub load_header_from comment

Comment: $ Read to end-of-"line"... should be: # Read to end-of-"line"... ^

Anonymous   
Printed Page 292
Code paragraph

I believe the code should not be shown in bold, as it represents an example of something that is wrong.

Anonymous   
Printed Page 304
Last word

The last word, 'it', should have a footnote explaining that the unlinking process proposed does not work under MS Windows, and that IO::InSitu should be used instead.

Anonymous   
Printed Page 327
File::System->list_files

When I run the script I get this: File::System->list_files There is no mention of using File::System in this portion of the book. I installed File::System and added use File::System at the top of the script and it validates, but when I run it it says: Can't locate object method "list_files" via package "File::System" at /Users/bradrice/lib/perl5/File/Hierarchy.pm line 26.

Anonymous   
Printed Page 399
3rd last line

Violation of "don't use barewords" rule in: prompt -line, '>' which should be changed to: prompt '-line', '>' There's another error at the top of page 40 where: prompt -menu => $MONTH_NAMES could be changed to: prompt '-menu' => $MONTH_NAMES but at least the "fat comma" forces the left hand side to be stringified.

Anonymous   
Printed Page 410
Perl6::Export::Attrs issues

One of the most important paradigm shifts in this book is getting users to use Class::Std module to build new perl modules (which ROCKS by the way). However, Perl6::Export::Attrs is not compatible with Class::Std. This shoudl be pointed out in the book. Or the modules need to be fixed.

Anonymous   
Printed Page 466-467
{19.14} Ch. Miscellanea, Sect. Enbugging

(http://safari.oreilly.com/0596001738/9780596001735-CHP-19-SECT-14); The code refactoring is mildly flawed because the original $target_name = $1 and last is not behaving the same way as the refactored $target_name = $name; last CANDIDATE; for value "0", i.e. the candidate string is "Name: 0; "

Anonymous