This book is designed to help you write better Perl code: in fact, the best Perl code
you possibly can. It's a collection of 256 guidelines covering various aspects of the art
of coding, including layout, name selection, choice of data and control structures,
program decomposition, interface design and implementation, modularity, object
orientation, error handling, testing, and debugging. These guidelines have-been
developed and refined over a programming career spanning 22 years. They're
designed to work well together, and to produce code that is clear, robust, efficient,
maintainable, and concise.
Mind you, that's not easy to achieve. Conciseness can be the natural enemy of clar-
ity; efficiency the nemesis of maintainability. And armouring code to make it suffi-
ciently robust can undermine clarity, efficiency, conciseness, and maintainability.
Sometimes it's a case of: "Choose any one."
This book doesn't try to offer the one true universal and unequivocal set of best prac-
tices. There are as many ways of measuring code quality, and as many dimensions in
which code can be judged, as there are programmers to make those assessments.
Each programmer and each programming team will have their own opinions about
the most important and desirable attributes of code.
What this book offers instead is a set of best practices: a set that is coherent, widely
applicable, balanced in its aims, and that is based on real-world experience of how
code is actually written, rather than on someone's ivory-tower theories on how code
. ought to be created. Most of all, it's a set of practices that actually work, and that many
developers around the world are already using. Much like Peri itself, these guidelines
are about helping you to get your job done, without getting in the way.
If you're an experienced developer, it's almost certain that you won't like all of the
suggestions that follow. You will find some of them unnatural or counterintuitive;
others may feel excessively rigid and un-Perlish. Maybe they'll just seem unnecessar-
ily different from the ways you're used to writing software, and from the long-
ingrained coding habits you find so comfortable.
Try to put those feelings aside as you read through the advice in this book. Review it
as you would any other proposed code enhancement: analyze the arguments that are
made for these new practices; ask yourself whether you've ever fallen into the traps
they seek to avoid; consider whether the coding techniques suggested here might be
worth trying.
Just thinking about these issues--becoming conscious of the way you currently write
code--can be of enormous benefit, even if you don't adopt a single one of the recom-
mendations that follow.
Contents of This Book
Chapter 1, Best Practices, explains why it might be worth reassessing your current
coding practices. It discusses how coding styles are evolved, and sets out three broad
criteria against which any existing or proposed coding practice can be assessed. The
chapter also explains why good coding habits matter and suggests how they can be
developed.
Chapter 2, Code Layout, tackles the many contentious issues of code layout. It sug-
gests how to set out block delimiters; how to visually distinguish built-ins and key-
words from subroutines and variables; where to place operators, terminators,
delimiters, and other punctuation; how to improve readability by the consistent use
of whitespace; the optimal width for code lines and block indents; how to set out
lists of values; and where to break long expressions. It concludes by recommending a
convenient tool that automates most of these layout tasks.
Chapter 3, Naming Conventions, presents a series of guidelines that can help you
choose more descriptive names for variables, subroutines, and namespaces. It also
demonstrates how the various components of a consistent naming scheme can work
together to improve the overall maintainability of code, both by making it more read-
able and by reducing the need for deobfuscatory comments.
Chapter 4, Values and Expressions, provides a simple set of rules that can help you
avoid common pitfalls when creating character strings, numbers, and lists. Topics
include how to avoid unintended variable interpolation (and non-interpolation), reli-
able and readable approaches to nonprintable characters, defining constants, avoid-
ing barewords, and taming heredocs, commas, long numbers, and lists.
Chapter 5, Variables, explores a robust approach to using variables. It explains the
inherent drawbacks Of package or punctuation variables, suggesting safer alterna-
tives where possible, and safer practices where there are no alternatives. The second
half of the chapter presents several efficient and maintainable techniques of handling
data in arrays and hashes using the "container slicing" mechanism.
Chapter 6, Control Structures, examines Perl's richvariety of control structures,
encouraging the use of those that are easier to maintain, less error-prone, or more
efficient. The chapter provides a set of simple guidelines for deciding which of for,
while, or map is most appropriate for a given task. The effective use of iterator vari-
ables is also discussed, including the common case of needing to iterate hash entries
by key and value simultaneously.
Chapter 7, Documentation, suggests a series of techniques that can make document-
ing your code less tedious, and therefore more likely. It advocates a template-based
approach to both user and technical documentation, and discusses when, where, and
how to write useful and accurate comments.
Chapter 8, Built-in Functions, discusses better ways of using some of Perl's most pop-
ular built-in functions, including sort, reverse, scalar, eval, unpack, split, substr,
values, select, sleep, map, and grep. It also summarizes the many other useful "non-
built-in" builtins provided by two modules from the standard Perl distribution and
one from CPAN.
Chapter 9, Subroutines, describes efficient and maintainable ways to write subrou-
tines in Peri, including the use of positional, named, and optional arguments, argu-
ment validation and defaults, safe calling and return conventions, predictable return
values in various contexts, and why subroutine prototypes and implicit returns
should be avoided.
Chapter 10, I/0, explains how to open and close files reliably, when to use line-based
input, how to correctly detect interactive applications, the importance of prompting,
and how best to provide feedback to users during long non-interactive tasks.
Chapter 11, References, offers advice on demystifying Perl's many dereferencing syn-
taxes, discusses why symbolic references create more problems than they solve, and
recommends ways to prevent cyclic reference chains from causing memory leaks.
Chapter 12, Regular Expressions, presents guidelines for using regular expressions. It
recommends the use of extended formatting, suggests a simple but unusual fix for
Perl's confusing "single-line" and "multiline" matching modes, warns of the perils of
matching whitespace too precisely, shows how to avoid using the error-prone
numeric variables, presents a robust approach to building complex regexes that are
still maintainable, gives several hints on optimizing slow matches, and concludes by
explaining when not to use regular expressions.
Chapter 13, Error Handling, advocates a coherent exception-based approach to error
handling, and explains why exceptions are preferable to special return values or
flags. It also recommends the use of exception objects, and explores in detail how
they can be declared, created, thrown, caught, and handled.
Chapter 14, Command-Line Processing, addresses the design and implementation of
command-line interfaces, both for individual programs and for application suites. It
recommends several modules that can make your command-line interfaces more
consistent and predictable, and at the same time can considerably reduce the effort
required to implement those interfaces.
Chapter 15, Objects, and Chapter 16, Class Hierarchies, offer a robust and efficient
approach to creating objects and class hierarchies in Peri. This approach provides fully
encapsulated objects with no performance penalty, and supports single and multiple
inheritance without the usual problems of attribute collision, incomplete initialization,
partial destruction, or incorrect method autoloading. Chapter 16 also introduces a new
module that allows these robust and efficient classes to be built semi-automatically.
Chapter 17, Modules, looks at non-object-oriented modules, exploring the best ways
to create them, design their interfaces, declare and check their version numbers, and
refactor existing code into them. This chapter also discusses the many existing mod-
ules that are freely available as part of the Peri standard library and on CPAN.
Chapter 18, Testing and Debugging, encourages the use of testing, advocating test-
driven design and development using the core Test:: modules. It also offers tips on
effective debugging techniques, including a description of various modules and other
free tools that can make debugging easier.
Chapter 19, Miscellanea, offers several additional guidelines on miscellaneous topics
such as revision control, interfacing to code written in other languages, processing
configuration files, text formatting, tied variables, benchmarking and profiling your
code, caching techniques, and some general advice on refactoring.
Appendix A, Essential Perl Best Practices, summarizes the 30 most important guide-
lines in the book in three one-page lists. Appendix B, Peri Best Practices, lists all 256
guidelines, with cross-references to their chapters and locations. Appendix C, Editor
Configurations, provides some useful configuration options for the Vim, Vile, Emacs,
TextWrangler, and BBEdit text editors. Appendix D, Recommended Modules and
Utilities, lists and cross-references the various modules recommended throughout the
book, and provides a brief summary of their most useful subroutines. Appendix E
offers a short bibliography.