Perl Best Practices and over 2 million other books are available for Amazon Kindle . Learn more

Buy New

or
Sign in to turn on 1-Click ordering.
Buy Used
Used - Good See details
Price: 5.36

or
 
   
More Buying Choices
Have one to sell? Sell yours here
Start reading Perl Best Practices on your Kindle in under a minute.

Don't have a Kindle? Get your Kindle here, or download a FREE Kindle Reading App.

Perl Best Practices [Paperback]

Damian Conway
4.7 out of 5 stars  See all reviews (6 customer reviews)
Price: 30.99 & FREE Delivery in the UK. Details
o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o
Only 2 left in stock (more on the way).
Dispatched from and sold by Amazon. Gift-wrap available.
Want it Monday, 14 July? Choose Express delivery at checkout. Details
‹  Return to Product Overview

Product Description

Review

"If you are looking for a book to teach you how to program Perl, this is definitely not what you need. Also, if you are cranking out quick Perl scripts to solve one-time tasks, it might not be worth the effort to read this book. However, if you are fairly comfortable with the language and are looking for ways to improve your code, this book would be a wonderful addition to your bookshelf." - James Mohr, Linux Magazine, November 2005

Book Description

Standards and Styles for Developing Maintainable Code

From the Publisher

Perl Best Practices offers a collection of 256 guidelines on the art of coding to help you write better Perl code--in fact, the best Perl code you possibly can. The guidelines cover code layout, naming conventions, choice of data and control structures, program decomposition, interface design and implementation, modularity, object orientation, error handling, testing, and debugging.

About the Author

Damian Conway holds a PhD in Computer Science and is an honorary Associate Professor with the School of Computer Science and Software Engineering at Monash University, Melbourne, Australia.Currently he runs an international IT training company--Thoughtstream--which provides programmer development from beginner to masterclass level throughout Europe, North America, and Australasia.Damian was the winner of the 1998, 1999, and 2000 Larry Wall Awards for Practical Utility. The best technical paper at the annual Perl Conference was subsequently named in his honour. He is a member of the technical committee for The Perl Conference, a keynote speaker at many Open Source conferences, a former columnist for The Perl Journal, and author of the book Object Oriented Perl. In 2001 Damian received the first "Perl Foundation Development Grant" and spent 20 months working on projects for the betterment of Perl.A popular speaker and trainer, he is also the author of numerous well-known Perl modules, including Parse::RecDescent (a sophisticated parsing tool), Class::Contract (design-by-contract programming in Perl), Lingua::EN::Inflect (rule-based English transformations for text generation), Class::Multimethods (multiple dispatch polymorphism), Text::Autoformat (intelligent automatic reformatting of plaintext), Switch (Perl's missing case statement), NEXT (resumptive method dispatch), Filter::Simple (Perl-based source code manipulation), Quantum::Superpositions (auto-parallelization of serial code using a quantum mechanical metaphor), and Lingua::Romana::Perligata (programming in Latin).Most of his time is now spent working with Larry Wall on the design of the new Perl 6 programming language.

Excerpt. © Reprinted by permission. All rights reserved.

CHAPTER 9 Subroutines

If you have a procedure with ten parameters, you probably missed some.
—Alan Perlis

Subroutines are one of the two primary problem-decomposition tools available in Perl, modules being the other. They provide a convenient and familiar way to break a large task down into pieces that are small enough to understand, concise enough to implement, focused enough to test, and simple enough to debug.

In effect, subroutines allow programmers to extend the Perl language, creating useful new behaviours with sensible names. Having written a subroutine, you can immediately forget about its internals, and focus solely on the abstracted process or function it implements.

So the extensive use of subroutines helps to make a program more modular, which in turn makes it more robust and maintainable. Subroutines also make it possible to structure the actions of programs hierarchically, at increasingly high levels of abstraction, which improves the readability of the resulting code.

That’s the theory, at least. In practice, there are plenty of ways that using subroutines can make code less robust, buggier, less concise, slower, and harder to understand. The guidelines in this chapter focus on avoiding those outcomes.

Call Syntax

Call subroutines with parentheses but without a leading &

It’s possible to call a subroutine without parentheses, if it has already been declared in the current namespace:
sub coerce

# and later...

my $expected_count = coerce $input, $INTEGER, $ROUND_ZERO;

But that approach can quickly become much harder to understand:

fix my $gaze, upon each %suspect;

More importantly, leaving off the parentheses on subroutines makes them harder to distinguish from builtins, and therefore increases the mental search space when the reader is confronted with either type of construct. Your code will be easier to read and understand if the subroutines always use parentheses and the built-in functions always don’t:

my $expected_count = coerce($input, $INTEGER, $ROUND_ZERO);

fix(my $gaze, upon(each %suspect));

Some programmers still prefer to call a subroutine using the ancient Perl 4 syntax, with an ampersand before the subroutine name:

&coerce($input, $INTEGER, $ROUND_ZERO);

&fix(my $gaze, &upon(each %suspect));

Perl 5 does support that syntax, but nowadays it’s unnecessarily cluttered. Barewords is forbidden under use strict, so there are far fewer situations in which a subroutine call has to be disambiguated.

On the other hand, the ampersand itself is visually ambiguous; it can also signify a bitwise AND operator, depending on context. And context can be extremely subtle:

$curr_pos = tell &get_mask( ); # means: tell(get_mask( ))
$curr_time = time &get_mask( ); # means: time() & get_mask( )

Prefixing with & can also lead to other subtle (but radical) differences in behaviour:

sub fix {
my (@args) = @_ ? @_ : $_; # Default to fixing $_ if no args provided

# Fix each argument by grammatically transforming it and then printing it...
for my $arg (@args) {
$arg =~ s/\A the \b/some/xms;
$arg =~ s/e \z/es/xms;
print $arg;
}

return;
}

# and later...

&fix('the race'); # Works as expected, prints: 'some races'

for ('the gaze', 'the adhesive') {

&fix; # Doesn't work as expected: looks like it should fix($_),
# but actually means fix(@_), using this scope's @_!
# See the 'perlsub' manpage for details
}

All in all, it’s clearer, less ambiguous, and less error-prone to reserve the &subname syntax for taking references to named subroutines:

set_error_handler( \&log_error );

Just use parentheses to indicate a subroutine call:

coerce($input, $INTEGER, $ROUND_ZERO);

fix( my $gaze, upon(each %suspect) );

$curr_pos = tell get_mask( );
$curr_time = time & get_mask( );

And always use the parentheses when calling a subroutine, even when the subroutine takes no arguments (like get_mask( )). That way it’s immediately obvious that you intend a subroutine call:

curr_obj( )->update($status); # Call curr_obj( ) to get an object,
# then call the update( )method on that object

and not a typename:

curr_obj->update($status); # Maybe the same (if currobj( ) already declared),
# otherwise call update( ) on class 'curr_obj'

Homonyms

Don’t give subroutines the same names as built-in functions

If you declare a subroutine with the same name as a built-in function, subsequent invocations of that name will still call the builtin...except when occasionally they don’t. For example:

sub lock {
my ($file) = @_;
return flock $file, LOCK_SH;
}

sub link {
my ($text, $url) = @_;
return qq{$text};
}

lock($file); # Calls 'lock' subroutine; built-in 'lock' hidden
print link($text, $text_url); # Calls built-in 'link'; 'link' subroutine hidden

Perl considers some of its builtins (like link) to be "more built-in" than others (like lock), and chooses accordingly whether to call your subroutine of the same name. If the builtin is "strongly built-in", an ambiguous call will invoke it, in preference to any subroutine of the same name. On the other hand, if the builtin is "weakly builtin", an ambiguous call will invoke the subroutine of the same name instead.

Even if these subroutines did always work as expected, it’s simply too hard to maintain code where the program-specific subroutines and the language’s keywords overlap:

sub crypt { return "You're in the tomb of @_\n" }
sub map { return "You have found a map of @_\n" }
sub chop { return "You have chopped @_\n" }
sub close { return "The @_ is now closed\n" }
sub hex { return "A hex has been cast on @_\n" }

print crypt( qw( Vlad Tsepes ) ); # Subroutine or builtin?

for my $reward (qw( treasure danger) ) {
print map($reward, 'in', $location); # Subroutine or builtin?
}

print hex('the Demon'); # Subroutine or builtin?
print chop('the Demon'); # Subroutine or builtin?

‹  Return to Product Overview