Code Layout
- Brace and parenthesize in K&R style.
- Separate your control keywords from the following opening bracket.
- Don’t separate subroutine or variable names from the following opening bracket.
- Don’t use unnecessary parentheses for builtins and ‘honorary’ builtins.
- Separate complex keys or indices from their surrounding brackets.
- Use whitespace to help binary operators stand out from their operands.
- Place a semicolon after every statement.
- Place a comma after every value in a multiline list.
- Use 78-column lines.
- Use four-column indentation levels.
- Indent with spaces, not tabs.
- Never place two statements on the same line.
- Code in paragraphs.
- Don’t cuddle an else.
- Align corresponding items vertically.
- Break long expressions before an operator.
- Factor out long expressions in the middle of statements.
- Always break a long expression at the operator of the lowest pos- sible precedence.
- Break long assignments before the assignment operator.
- Format cascaded ternary operators in columns.
- Parenthesize long lists.
- Enforce your chosen layout style mechanically. Naming Conventions
- Use grammatical templates when forming identifiers.
- Name booleans after their associated test.
- Mark variables that store references with a _ref suffix.
- Name arrays in the plural and hashes in the singular.
- Use underscores to separate words in multiword identifiers.
- Distinguish different program components by case.
- Abbr idents by prefx.
- Abbreviate only when the meaning remains unambiguous.
- Avoid using inherently ambiguous words in names.
- Prefix ‘for internal use only’ subroutines with an underscore. Values and Expressions
- Use interpolating string delimiters only for strings that actually interpolate.
- Don’t use "" or '' for an empty string.
- Don’t write one-character strings in visually ambiguous ways.
- Use named character escapes instead of numeric escapes.
- Use named constants, but don’t use constant.
- Don’t pad decimal numbers with leading zeros.
- Use underscores to improve the readability of long numbers.
- Lay out multiline strings over multiple lines.
- Use a heredoc when a multiline string exceeds two lines.
- Use a ‘theredoc’ when a heredoc would compromise your inden- tation.
- Make every heredoc terminator a single uppercase identifier with a standard prefix.
- When introducing a heredoc, quote the terminator.
- Don’t use barewords.
- Reserve => for pairs.
- Don’t use commas to sequence statements.
- Don’t mix high- and low-precedence booleans.
- Parenthesize every raw list.
- Use table-lookup to test for membership in lists of strings; use any() for membership of lists of anything else. Variables
- Avoid using non-lexical variables.
- Don’t use package variables in your own development.
- If you’re forced to modify a package variable, localize it.
- Initialize any variable you localize.
- use English for the less familiar punctuation variables.
- If you’re forced to modify a punctuation variable, localize it.
- Don’t use the regex match variables.
- Beware of any modification via $_.
- Use negative indices when counting from the end of an array.
- Take advantage of hash and array slicing.
- Use a tabular layout for slices.
- Factor large key or index lists out of their slices. Control Structures
- Use block if, not postfix if.
- Reserve postfix if for flow-of-control statements.
- Don’t use postfix unless, for, while, or until.
- Don’t use unless or until at all.
- Avoid C-style for statements.
- Avoid subscripting arrays or hashes within loops.
- Never subscript more than once in a loop.
- Use named lexicals as explicit for loop iterators.
- Always declare a for loop iterator variable with my.
- Use map instead of for when generating new lists from old.
- Use grep and first instead of for when searching for values in a list.
- Use for instead of map when transforming a list in place.
- Use a subroutine call to factor out complex list transformations.
- Never modify $_ in a list function.
- Avoid cascading an if.
- Use table look-up in preference to cascaded equality tests.
- When producing a value, use tabular ternaries.
- Don’t use do…while loops.
- Reject as many iterations as possible, as early as possible.
- Don’t contort loop structures just to consolidate control.
- Use for and redo instead of an irregularly counted while.
- Label every loop that is exited explicitly, and use the label with every next, last, or redo. Documentation
- Distinguish user documentation from technical documentation.
- Create standard POD templates for modules and applications.
- Extend and customize your standard POD templates.
- Put user documentation in source files.
- Keep all user documentation in a single place within your source file.
- Place POD as close as possible to the end of the file.
- Subdivide your technical documentation appropriately.
- Use block templates for major comments.
- Use full-line comments to explain the algorithm.
- Use end-of-line comments to point out subtleties and oddities.
- Comment anything that has puzzled or tricked you.
- Consider whether it’s better to rewrite than to comment.
- Use ‘invisible’ POD sections for longer technical discussions.
- Check the spelling, syntax, and sanity of your documentation. Builtin Functions
- Don’t recompute sort keys inside a sort.
- Use reverse to reverse a list.
- Use scalar reverse to reverse a scalar.
- Use unpack to extract fixed-width fields.
- Use split to extract simple variable-width fields.
- Use Text::CSV_XS to extract complex variable-width fields.
- Avoid string eval.
- Consider building your sorting routines with Sort::Maker.
- Use 4-arg substr instead of lvalue substr.
- Make appropriate use of lvalue values.
- Use glob, not <…>.
- Avoid a raw select for non-integer sleeps.
- Always use a block with a map and grep.
- Use the ‘non-builtin builtins’. Subroutines
- Call subroutines with parentheses but without a leading &.
- Don’t give subroutines the same names as built-in functions.
- Always unpack @_ first.
- Use a hash of named arguments for any subroutine that has more than three parameters.
- Use definedness or existence to test for missing arguments.
- Resolve any default argument values as soon as @_ is unpacked.
- Always return scalar in scalar returns.
- Make list-returning subroutines return the ‘obvious’ value in scalar context.
- When there is no ‘obvious’ scalar context return value, consider Contextual::Return instead.
- Don’t use subroutine prototypes.
- Always return via an explicit return.
- Use a bare return to return failure. I/O
- Don’t use bareword filehandles.
- Use indirect filehandles.
- If you have to use a package filehandle, localize it first. Perl Best Practices Reference Guide Johan Vromans © 2006 Squirrel Consultancy
- Use either the IO::File module or the three-argument form of open.
- Never open, close, or print to a file without checking the outcome.
- Close filehandles explicitly, and as soon as possible.
- Use while (<>), not for (<>).
- Prefer line-based I/O to slurping.
- Slurp a filehandle with a do block for purity.
- Slurp a stream with Perl6::Slurp for power and simplicity.
- Avoid using *STDIN, unless you really mean it.
- Always put filehandles in braces within any print statement.
- Always prompt for interactive input.
- Don’t reinvent the standard test for interactivity.
- Use the IO::Prompt module for prompting.
- Always convey the progress of long non-interactive operations within interactive applications.
- Consider using the Smart::Comments module to automate your progress indicators.
- Avoid a raw select when setting autoflushes. References
- Wherever possible, dereference with arrows.
- Where prefix dereferencing is unavoidable, put braces around the reference.
- Never use symbolic references.
- Use weaken to prevent circular data structures from leaking memory. Regular Expressions
- Always use the /x flag.
- Always use the /m flag.
- Use \A and \z as string boundary anchors.
- Use \z, not \Z, to indicate ‘end of string’.
- Always use the /s flag.
- Consider mandating the Regexp::Autoflags module.
- Use m{…} in preference to /…/ in multiline regexes.
- Don’t use any delimiters other than /…/ or m{…}.
- Prefer singular character classes to escaped metacharacters.
- Prefer named characters to escaped metacharacters.
- Prefer properties to enumerated character classes.
- Consider matching arbitrary whitespace, rather than specific whitespace characters.
- Be specific when matching ‘as much as possible’.
- Use capturing parentheses only when you intend to capture.
- Use the numeric capture variables only when you’re sure that the preceding match succeeded.
- Always give captured substrings proper names.
- Tokenize input using the /gc flag.
- Build regular expressions from tables.
- Build complex regular expressions from simpler pieces.
- Consider using Regexp::Common instead of writing your own regexes.
- Always use character classes instead of single-character alternations.
- Factor out common affixes from alternations.
- Prevent useless backtracking.
- Prefer fixed-string eq comparisons to fixed-pattern regex matches. Error Handling
- Throw exceptions instead of returning special values or setting flags.
- Make failed builtins throw exceptions too.
- Make failures fatal in all contexts.
- Be careful when testing for failure of the system builtin.
- Throw exceptions on all failures, including recoverable ones.
- Have exceptions report from the caller's location, not from the place where they were thrown.
- Compose error messages in the recipient’s dialect.
- Document every error message in the recipient’s dialect.
- Use exception objects whenever failure data needs to be con- veyed to a handler.
- Use exception objects when error messages may change.
- Use exception objects when two or more exceptions are related.
- Catch exception objects in most-derived-first order.
- Build exception classes automatically.
- Unpack the exception variable in extended exception handlers. CommandLine Processing
- Enforce a single consistent command-line structure.
- Adhere to a standard set of conventions in your command-line syntax.
- Standardize your meta-options.
- Allow the same filename to be specified for both input and output.
- Standardize on a single approach to command-line processing.
- Ensure that your interface, run-time messages, and documentation remain consistent.
- Factor out common command-line interface components into a shared module. Objects
- Make object orientation a choice, not a default.
- Choose object orientation using appropriate criteria.
- Don’t use pseudohashes.
- Don’t use restricted hashes.
- Always use fully encapsulated objects.
- Give every constructor the same standard name.
- Don’t let a constructor clone objects.
- Always provide a destructor for every inside-out class.
- When creating methods, follow the general guidelines for subrou- tines.
- Provide separate read and write accessors.
- Don’t use lvalue accessors.
- Don’t use the indirect object syntax.
- Provide an optimal interface, rather than a minimal one.
- Overload only the isomorphic operators of algebraic classes.
- Always consider overloading the boolean, numeric, and string coercions of objects. Class Hierarchies
- Don’t manipulate the list of base classes directly.
- Use distributed encapsulated objects.
- Never use the one-argument form of bless.
- Pass constructor arguments as labeled values, using a hash reference.
- Distinguish arguments for base classes by class name as well.
- Separate your construction, initialization, and destruction processes.
- Build the standard class infrastructure automatically.
- Use Class::Std to automate the deallocation of attribute data.
- Have attributes initialized and verified automatically.
- Specify coercions as :STRINGIFY, :NUMERIFY, and :BOOLIFY methods.
- Use :CUMULATIVE methods instead of SUPER:: calls.
- Don’t use AUTOLOAD(). Modules
- Design the module’s interface first.
- Place original code inline. Place duplicated code in a subroutine. Place duplicated subroutines in a module.
- Use three-part version numbers.
- Enforce your version requirements programmatically.
- Export judiciously and, where possible, only by request.
- Consider exporting declaratively.
- Never make variables part of a module’s interface.
- Build new module frameworks automatically.
- Use core modules wherever possible.
- Use CPAN modules where feasible. Testing and Debugging
- Write the test cases first.
- Standardize your tests with Test::Simple or Test::More.
- Standardize your test suites with Test::Harness.
- Write test cases that fail.
- Test both the likely and the unlikely.
- Add new test cases before you start debugging.
- Always use strict.
- Always turn on warnings explicitly.
- Never assume that a warning-free compilation implies correctness.
- Turn off strictures or warnings explicitly, selectively, and in the smallest possible scope.
- Learn at least a subset of the perl debugger.
- Use serialized warnings when debugging ‘manually’.
- Consider using ‘smart comments’ when debugging, rather than warn statements. Miscellanea
- Use a revision control system.
- Integrate non-Perl code into your applications via the Inline:: modules.
- Keep your configuration language uncomplicated.
- Don’t use formats.
- Don’t tie variables or filehandles.
- Don’t be clever.
- If you must rely on cleverness, encapsulate it.
- Don’t optimize code — benchmark it.
- Don’t optimize data structures — measure them.
- Look for opportunities to use caches.
- Automate your subroutine caching.
- Benchmark any caching strategy you use.
- Don’t optimize applications — profile them.
- Be careful to preserve semantics when refactoring syntax.