So, you don't have time to read Damian Conway's "Perl Best Practices" book, to understand his "256 guidelines on the art of coding to help you write better Perl code"? Hear Randal Schwartz provide the executive summary, including pointing out where Randal disagrees with Damian, and why. This high-speed overview will help you understand "code layout, naming conventions, choice of data and control structures, program decomposition, interface design and implementation, modularity, object orientation, error handling, testing, and debugging." But using shorter words.
Report
Share
Report
Share
1 of 278
Download to read offline
More Related Content
Perl best practices v4
1. Perl Best
Practices
Randal L. Schwartz
merlyn@stonehenge.com
version 4.3 on 11 Jun 2017
This document is copyright 2006,2007,2008, 2017 by Randal L. Schwartz, Stonehenge Consulting Services, Inc.
2. Introduction
⢠This talk organized according to âPerl Best Practicesâ
⢠With my own twist along the way
⢠Perhaps I should call this âsecond Best Practicesâ?
3. Chapter 2. Code Layout
⢠Thereâs more than one way to indent it
⢠This isnât Python
⢠Blessing and a curse
⢠Youâre writing for two readers:
⢠The compiler (and it doesnât care)
⢠Your maintenance programmer
⢠Best to ensure the maintenance programmer doesnât
hunt you down with intent to do serious bodily harm
⢠You are the maintenance programmer three months later
4. Section 2.1. Bracketing
⢠Indent like K&R
⢠Paren pairs at end of opening line, and beginning of close:â¨
my @items = (â¨
12,â¨
19,â¨
);
⢠Similar for control ďŹow:â¨
if (condition) {â¨
true branch;â¨
} else {â¨
false branch;â¨
}
5. Section 2.2. Keywords
⢠Put a space between keyword and following punctuation:â¨
if (...) { ... } else { ... }â¨
while (...) { ... }
⢠Not âif(...)â
⢠Itâs easier to pick out the keyword from the rest of the
code that way
⢠Keywords are important!
6. Section 2.3. Subroutines andVariables
⢠Keep subroutine names cuddled with args:â¨
foo(3, 5) # not foo (3, 5)
⢠Keep variable indexing cuddled with variables:â¨
$x[3] # not $x [3]
⢠If you didnât know you could do that, forget that you can!
7. Section 2.4. Builtins
⢠Avoid unnecessary parens for built-ins
⢠Good:â¨
print $x;
⢠Bad:â¨
print($x);
⢠But donât avoid the necessary parens:â¨
warn(âsomething is wrongâ), next if $x > 3;
⢠Without the parens, that would have executed ânextâ
too early
8. Section 2.5. Keys and Indices
⢠Separate complex keys from enclosing brackets:â¨
$x[ complex() * expression() ]
⢠But donât use this for trivial keys:â¨
$x[3]
⢠The extra whitespace helps the reader ďŹnd the brackets
9. Section 2.6. Operators
⢠Add whitespace around binary operators if it helps to
see the operands:â¨
print $one_value + $two_value[3];â¨
print 3+4; # wouldnât help much here
⢠Donât add whitespace after a preďŹx unary operator:â¨
$x = !$y; # no space after !
10. Section 2.7. Semicolons
⢠Put a semicolon after every statement
⢠Yeah, even the ones at the end of a block:
if ($condition) {
state1;
state2;
state3; # even here
}
⢠Very likely, this code will be edited
⢠Occasionally, a missing semicolon is not a syntax error
⢠Exception: blocks on a single line:
if ($foo) { this } else { that }
11. Section 2.8. Commas
⢠Include comma after every list element:â¨
my @days = (â¨
âSundayâ,â¨
âMondayâ,â¨
);
⢠Easier to add new items
⢠Donât need two different behaviors
⢠Easier to swap items
12. Section 2.9. Line Lengths
⢠Damian says âuse 78 character linesâ
⢠Iâd say keep it even shorter
⢠Long lines are hard to read
⢠Long lines might wrap if sent in email
⢠Long lines are harder to copypasta for reuse
13. Section 2.10. Indentation
⢠Damian says âuse 4-column indentation levelsâ
⢠I use Emacs cperl-mode, and use whatever it does
⢠Yeah, thereâs probably some conďŹguration to adjust it
⢠Better still, write your code where the indentation is
clear
14. Section 2.11. Tabs
⢠Indent with spaces, not tabs
⢠Tabs expand to different widths per user
⢠If you must use tabs, ensure all tabs are at the beginning
of line
⢠You can generally tell your text editor to insert spaces
⢠For indentation
⢠When you hit the tab key
⢠And you should do that!
15. Section 2.12. Blocks
⢠Damian says âNever place two statements on the same
lineâ
⢠Except when itâs handy
⢠Statements are a logical chunk
⢠Whitespace break helps people
⢠Also helps cut-n-paste
⢠Also keeps the lines from getting too long (see earlier)
16. Section 2.13. Chunking
⢠Code in commented paragraphs
⢠Whitespace between chunks is helpful
⢠Chunk according to logical steps
⢠Interpreting @_ separated from the next step in a
subroutine
⢠Add leading comments in front of the paragraph for a
logical-step description
⢠Donât use comments for user docs, use POD
17. Section 2.14. Elses
⢠Damian says âDonât cuddle an elseâ
⢠Cuddled:â¨
} else {
⢠Uncuddled:â¨
}â¨
else {
⢠I disagree. I like cuddled elses
⢠They save a line
⢠I recognize â} else {â as âswitching from true to falseâ
⢠Think of it as the âbatwing elseâ
18. Section 2.15. Vertical Alignment
⢠Align corresponding items vertically
⢠(Hard to show in a variable-pitch font)
⢠Something like:â¨
$foo = $this + $that;â¨
$bartholomew = $the + $other;
⢠Yeah, thatâs pretty
⢠For me, itâd be more time ďŹdding in the editor rather
than coding
⢠Again, your choice is yours
19. Section 2.16. Breaking Long Lines
⢠Break long expressions before an operator:â¨
print $offsetâ¨
+ $rate * $timeâ¨
+ $fudge_factorâ¨
;
⢠The leading operator is âout of placeâ enough
⢠Leads the reader to know this is a continuation
⢠Allows for a nice comment on each line too
⢠Lineup should be with the piece in the ďŹrst line
⢠Again, this seems like a lot of work in an editor
⢠Emacs cperl-mode can line up on an open paren
20. Section 2.17. Non-Terminal Expressions
⢠If it simpliďŹes things, name a subexpression
⢠Instead of:â¨
my $result = $foo + (very complicated thing) + $bar;
⢠Useâ¨
my $meaningful_name = very complicated thing;â¨
my $result = $foo + $meaningful_name + $bar;
⢠Donât use an meaningless name
⢠This also helps in debugging
⢠Set a breakpoint after the intermediate computation
⢠Put a watchpoint on that value
⢠Thereâs no winner in the âeliminate variablesâ contest
21. Section 2.18. Breaking by Precedence
⢠Break the expression at lowest precedence
⢠To break up: $offset + $rate * $time
⢠Good:â¨
$offsetâ¨
+ $rate * $time
⢠Bad:â¨
$offset + $rateâ¨
* $time
⢠Keep same level of precedence at same visual level
22. Section 2.19. Assignments
⢠Break long assignments before the operator
⢠To ďŹx:â¨
$new_offset = $offset + $rate * $time;
⢠Bad:â¨
$new_offset = $offsetâ¨
+ $rate * $time;
⢠Good:â¨
$new_offsetâ¨
= $offsetâ¨
+ $rate * $time;
⢠Often I put the assignment on the previous line
⢠Damian would disagree with me on that
23. Section 2.20. Ternaries
⢠Use ?: in columnsâ¨
my $resultâ¨
= $test1 ? $test1_trueâ¨
: $test2 ? $test2_trueâ¨
: $test3 ? $test3_trueâ¨
: $else_value;
⢠Of course, Damian also lines up the question marks
⢠Conclusion: Damian must have a lot of time on his hands
24. Section 2.21. Lists
⢠Parenthesize long lists
⢠Helps to show beginning and ending of related things
⢠Also tells Emacs how to group and indent it:â¨
print (â¨
$one,â¨
$two,â¨
$three,â¨
);
⢠Nice setting: (cperl-indent-parens-as-block t)
25. Section 2.22. Automated Layout
⢠Use a consistent layout
⢠Pick a style, and stick with it
⢠Use perltidy to enforce it
⢠But donât waste time reformatting everything
⢠Lifeâs too short to get into ďŹghts on this
26. Chapter 3. Naming Conventions
⢠Syntactic consistency
⢠Related things look similar
⢠Semantic consistency
⢠Names of things reďŹect their purpose
28. Section 3.2. Booleans
⢠Name booleans after their test
⢠Scalars:â¨
$has_potentialâ¨
$has_been_checkedâ¨
$is_internalâ¨
$loading_is_ďŹnished
⢠Subroutines:â¨
is_excessiveâ¨
has_child_record
⢠Often starts with is or has
29. Section 3.3. ReferenceVariables
⢠Damian says âmark variables holding a ref to end in _refâ:â¨
my $items_ref = @items;
⢠I generally do this, but just use ârefâ:â¨
my $itemsref = @items;
⢠Rationale: ordinary scalars and refs both go in to scalar
vars
⢠Need some way of distinguishing typing information
⢠use-strict-refs helps here too
30. Section 3.4. Arrays and Hashes
⢠Give arrays plural names:â¨
@itemsâ¨
@recordsâ¨
@input_ďŹles
⢠Give hashes singular names:â¨
%optionâ¨
%highest_ofâ¨
%total_for
⢠âMappingâ hashes should end in a connector
31. Section 3.5. Underscores
⢠Use underscores to separate names
⢠$total_paid instead of $totalpaid
⢠Helps to distinguish items
⢠What was âremembersthelens.comâ?
⢠Not âremembers the lensâ as I thought
⢠Itâs âremember st helensâ!
⢠Not CamelCase (except for some package names)
32. Section 3.6. Capitalization
⢠The more capitalized, the more global it is
⢠All lowercase for local variables:â¨
$item @queries %result_of
⢠Mixed case for package/class names:â¨
$File::Finder
⢠Uppercase for constants:â¨
$MODE $HOURS_PER_DAY
⢠Exception: uppercase acronyms and proper names:â¨
CGI::Prototype
33. Section 3.7. Abbreviations
⢠Abbreviate identiďŹers by preďŹx
⢠$desc rather than $dscn
⢠$len rather than $lngth
⢠But $ctrl rather than $con, since itâs familiar
⢠$msg instead of $mess
⢠$tty instead of $ter
34. Section 3.8. Ambiguous Abbreviations
⢠Donât abbreviate beyond meaning
⢠Is $term_val
⢠TerminationValid
⢠TerminalValue
⢠Is $temp
⢠Temperature
⢠Temporary
⢠Context and comments are useful
⢠con & com r u
35. Section 3.9. Ambiguous Names
⢠Avoid ambiguous names
⢠last (ďŹnal or previous)
⢠set (adjust or collection)
⢠left (direction, what remains)
⢠right (direction, correct, entitlement)
⢠no (negative,ânumberâ)
⢠record (verb or noun)
⢠second (time or position)
⢠close (nearby or shut)
⢠use (active usage, or category of function)
36. Section 3.10. Utility Subroutines
⢠Use underscore preďŹx as âinternal use onlyâ
⢠Obviously, this wonât stop anyone determined to do it
⢠But itâs a clue that itâs maybe not a good idea
⢠External interface:â¨
sub you_call_this {â¨
... _internal_tweaking(@foo) ...;â¨
}â¨
sub _internal_tweaking { ... }
⢠Historical note: broken in Perl4
⢠Made the subroutine a member of ALL packages
38. Section 4.1. String Delimiters
⢠Damian says âUse double quotes when youâre
interpolatingâ
⢠Example:âhello $personâ
⢠But âhello worldâ (note single quotes)
⢠In contrast, I always use double quotes
⢠Iâm lazy
⢠I often edit code later to add something that needs it
⢠Thereâs no efďŹciency difference
⢠Perl compiles âfooâ and âfooâ identically
39. Section 4.2. Empty Strings
⢠Use q{} for the empty string
⢠The rest of this page intentionally left blank
⢠And empty
40. Section 4.3. Single-Character Strings
⢠Likewise, use q{X} for the single character X.
⢠Again, I can disagree with this
⢠But it helps these stand out:â¨
my $result = join(q{,},â¨
âthisâ,â¨
âthatâ,â¨
);
⢠That ďŹrst comma deserves a bit of special treatment.
41. Section 4.4. Escaped Characters
⢠Use named escapes instead of magical constants
⢠Bad:âx7fx06x18Zâ
⢠Good:â¨
use charnames qw{:full};â¨
âN{DELETE}N{ACKNOWLEDGE}N{CANCEL}Zâ
⢠For some meaning of âgoodâ
⢠Damian claims that is âself documentingâ
⢠Yeah, right
42. Section 4.5. Constants
⢠Create constants with the Readonly module
⢠Donât use âconstantâ, even though itâs core
⢠use constant PI => 3;
⢠You canât interpolate these easily:
⢠print âIn indiana, pi is @{[PI]}nâ;
⢠Instead, get Readonly from the CPAN:
⢠Readonly my $PI => 3;
⢠Now you can interpolate:
⢠print âIn indiana, pi is $PInâ;
⢠Or consider Const::Fast or Attribute::Constant
⢠20 to 30 times faster than Readonly
⢠neilb.org/reviews/constants.html for more
43. Section 4.6. Leading Zeros
⢠Donât pad decimal numbers with leading 0âs
⢠They become octal
⢠001, 002, 004, 008
⢠Only barfs on 008!
⢠Damian says âdonât use leading 0âs everâ
⢠Use oct() for octal values: oct(600) instead of 0600
⢠Yeah, right
⢠Could confuse some readers
⢠But only those who havenât read the Llama
44. Section 4.7. Long Numbers
⢠Use underscores in long numbers
⢠Instead of 123456, write 123_456
⢠What? You didnât know?
⢠Yeah, underscores in a number are ignored
⢠12_34_56 is also the same
⢠As is 1________23456
⢠Works in hex/oct too:â¨
0xFF_FF_00_FF
45. Section 4.8. Multiline Strings
⢠Layout multiline strings over multiple lines
⢠Sure, you can do this:â¨
my $message = âYou idiot!â¨
You should have enabled the frobulator!â¨
â;
⢠Use this instead:â¨
my $messageâ¨
= âYou idiot!nââ¨
.âYou should have enabled the formulator!nââ¨
;
⢠This text can be autoindented more nicely
46. Section 4.9. Here Documents
⢠Use a here-doc for more than two lines
⢠Such as:â¨
my $usage = <<âEND_USAGEâ;â¨
1) insert plugâ¨
2) turn on powerâ¨
3) wait 60 seconds for warm upâ¨
4) pull plug if sparks appear during warm upâ¨
END_USAGE
47. Section 4.10. Heredoc Indentation
⢠Use a âtheredocâ when a heredoc would have been
indented:â¨
use Readonly;â¨
Readonly my $USAGE = <<âEND_USAGEâ;â¨
1) insert plugâ¨
2) turn on powerâ¨
END_USAGE
⢠Now you can use it in any indented codeâ¨
if ($usage_error) {â¨
print $USAGE;â¨
}
48. Section 4.11. Heredoc Terminators
⢠Make heredocs end the same
⢠Suggestion:âEND_â followed by the type of thing
⢠END_MESSAGE
⢠END_SQL
⢠END_OF_WORLD_AS_WE_KNOW_IT
⢠All caps to stand out
49. Section 4.12. Heredoc Quoters
⢠Always use single or double quotes around terminator
⢠Makes it clear what kind of interpolation is being used
⢠<<âEND_FOOâ gets double-quote interpolation
⢠<<âEND_FOOâ gets single-quote
⢠Default is actually double-quote
⢠Most people donât know that
50. Section 4.13. Barewords
⢠Grrr
⢠Donât use barewords
⢠You canât use them under strict anyway
⢠Instead of: @months = (Jan, Feb, Mar);
⢠Use: @months = qw(Jan Feb Mar);
51. Section 4.14. Fat Commas
⢠Reserve => for pairs
⢠As in:â¨
my %score = (â¨
win => 30,â¨
tie => 15,â¨
loss => 10,â¨
);
⢠Donât use it to replace comma
⢠Bad: rename $this => $that
⢠What if $this is âFOOâ: use constant FOO => âFileâ
⢠rename FOO => $that would be a literal âFOOâ
instead
52. Section 4.15. Thin Commas
⢠Donât use commas in place of semicolons as sequence
⢠Bad:â¨
($a = 3), print â$anâ;
⢠Good:â¨
$a = 3; print â$anâ;
⢠If a sequence is desired where an expression must be...
⢠Use a do-block:â¨
do { $a = 3; print â$anâ };
53. Section 4.16. Low-Precedence Operators
⢠Donât mix and/or/not with && || ! in the same expression
⢠Too much potential confusion:
not $ďŹnished || $result
⢠Not the same as !$ďŹnished || $result
⢠Reserve and/or/not for outer control ďŹow:
print $foo if not $this;
unlink $foo or die;
55. Section 4.18. List Membership
⢠Consider any() from List::MoreUtils:â¨
if (any { $requested_slot == $_ } @allocated_slots) { ... }
⢠Stops checking when a true value has been seen
⢠However, for âeqâ test, use a predeďŹned hash:â¨
my @ACTIONS = qw(open close read write);â¨
my %ACTIONS = map { $_ => 1 } @ACTIONS;â¨
....â¨
if ($ACTIONS{$ďŹrst_word}) { ... } # seen an action
57. Section 5.1. LexicalVariables
⢠Use lexicals, not package variables
⢠Lexical access is guaranteed to be in the same ďŹle
⢠Unless some code passes around a reference to it
⢠Package variables can be accessed anywhere
⢠Including well-intentioned but broken code
58. Section 5.2. PackageVariables
⢠Donât use package variables
⢠Except when required by law
⢠Example: @ISA
⢠Example: @EXPORT, @EXPORT_OK, etc
⢠Otherwise, use lexicals
59. Section 5.3. Localization
⢠Always localize a temporarily modiďŹed package var
⢠Example:â¨
{â¨
local $BYPASS_AUDIT = 1;â¨
delete_any_traces(@items);â¨
}
⢠Any exit from the block restores the global
⢠You canât always predict all exits from the block
60. Section 5.4. Initialization
⢠Initialize any localized var
⢠Without that, you get undef!
⢠Example:â¨
local $YAML::Indent = $YAML::Indent;â¨
if ($local_indent) {â¨
$YAML::Indent = $local_indent;â¨
}
⢠Weird ďŹrst assignment creates local-but-same value
61. Section 5.5. PunctuationVariables
⢠Damian says âuse Englishâ
⢠I say âno - use commentsâ
⢠How is $OUTPUT_FIELD_SEPARATOR better than $,
⢠given that you probably wonât use it anyway
⢠Use it, but comment it:â¨
{â¨
local $, = â,â; # set output separatorâ¨
...â¨
}
62. Section 5.6. Localizing Punctuation
Variables
⢠Always localize the punctuation variables
⢠Example: slurping:â¨
my $ďŹle = do { local $/; <HANDLE> };
⢠Important to restore value at end of block
⢠Items called within the block still see new value
63. Section 5.7. MatchVariables
⢠Donât âuse Englishâ on $& or $` or $â
⢠Always âuse English qw(-no_match_vars)â
⢠Otherwise, your program slows down
⢠Consider Regexp::MatchContext
⢠L-value PREMATCH(), MATCH(), POSTMATCH()
64. Section 5.8. Dollar-Underscore
⢠Localize $_ if youâre using it in a subroutine
⢠Example:â¨
sub foo {â¨
...â¨
local $_ = âsomethingâ;â¨
s/foo/bar/;â¨
}
⢠Now the replacement doesnât mess up the outer $_
65. Section 5.9. Array Indices
⢠Use negative indices where possible
⢠Negative values count from the end
⢠$some_array[-1] same as
$some_array[$#some_array]
⢠$foo[-2] same as $foo[$#foo-1]
⢠$foo[-3] same as $foo[$#foo-2]
⢠Sadly, canât use in range
⢠$foo[1..$#foo] is all-but-ďŹrst
⢠Cannot replace with $foo[1..-1]
66. Section 5.10. Slicing
⢠Use slices when retrieving and storing related hash/array
items
⢠Example:â¨
@frames[-1, -2, -3]â¨
= @active{âtopâ,âprevâ,âbackupâ};
⢠Note that both array slice and hash slice use @ sigil
67. Section 5.11. Slice Layout
⢠Line up your slicing
⢠Example from previous slide:â¨
@frames[ -1, -2, -3]â¨
= @active{âtopâ,âprevâ,âbackupâ};
⢠Yeah, far more typing than I have time for
⢠Damian must have lots of spare time
68. Section 5.12. Slice Factoring
⢠Match up keys and values for those last examples
⢠For example:â¨
Readonly my %MAPPING = (â¨
top => -1,â¨
prev => -2,â¨
backup => -3,â¨
);
⢠Now use keys/values with that for the assignment:â¨
@frames[values %MAPPING]â¨
= @active{keys %MAPPING};
⢠Doesnât matter that the result is unsorted. It Just Works.
70. Section 6.1. If Blocks
⢠Use block if, not postďŹx if.
⢠Bad:â¨
$sum += $measurement if deďŹned $measurement;
⢠Good:â¨
if (deďŹned $measurement) {â¨
$sum += $measurement;â¨
}
71. Section 6.2. PostďŹx Selectors
⢠So when can we use postďŹx if?
⢠For ďŹow of control!
⢠last FOO if $some_condition;
⢠die âhorriblyâ unless $things_worked_out;
⢠next, last, redo, return, goto, die, croak, throw
72. Section 6.3. Other PostďŹx ModiďŹers
⢠Donât use postďŹx unless/for/while/until
⢠Says Damian
⢠If the controlled expression is simple enough, go ahead
⢠Good:â¨
print âho ho $_â for @some_list;
⢠Bad:â¨
deďŹned $_ and print âho ho $_ââ¨
for @some_list;
⢠Replace that with:â¨
for (@some_list) {â¨
print âho ho $_â if deďŹned $_;â¨
}
73. Section 6.4. Negative Control Statements
⢠Donât use unless or until at all
⢠Replace unless with if-not
⢠Replace until with while-not
⢠Says Damian
⢠My exclusion: Donât use âunless .. elseâ
⢠unless(not $foo and $bar) { ... } else { ... }
⢠Arrrgh!
⢠And remember your DeMorganâs laws
⢠Replace not(this or that) with not this and not that
⢠Replace not(this and that) with not this or not that
⢠Often, that will simplify things
74. Section 6.5. C-Style Loops
⢠Avoid C-style for loops
⢠Says Damian
⢠I say theyâre ok for this:
for (my $start = 0; $start <= 100; $start += 3) { ... }
75. Section 6.6. Unnecessary Subscripting
⢠Avoid subscripting arrays and hashes in a loop
⢠Compare:â¨
for my $n (0..$#items) { print $items[$n] }
⢠With:â¨
for my $item (@items) { print $item }
⢠And:â¨
for my $key (keys %mapper) { print $mapper{$key} }
⢠With:â¨
for my $value (values %mapper) { print $value }
⢠Canât replace like this if you need the index or key
76. Section 6.7. Necessary Subscripting
⢠Use Data::Alias or Lexical::Alias
⢠Donât subscript more than once in a loop:â¨
for my $k (sort keys %names) {â¨
if (is_bad($names{$k})) {â¨
print â$names{$k} is badâ; ...
⢠Instead, alias the value:â¨
for my $k (sort keys %names) {â¨
alias my $name = $names{$k};
⢠The $name is read/write!
⢠Requires Data::Alias or Lexical::Alias
77. Section 6.8. IteratorVariables
⢠Always name your foreach loop variable
⢠Unless $_ is more natural
⢠for my $item (@items) { ... }
⢠Example of $_:
s/foo/bar/ for @items;
78. Section 6.9. Non-Lexical Loop Iterators
⢠Always use âmyâ with foreach
⢠Bad:â¨
for $foo (@bar) { ... }
⢠Good:â¨
for my $foo (@bar) { ... }
79. Section 6.10. List Generation
⢠Use map instead of foreach to transform lists
⢠Bad:â¨
my @output;â¨
for (@input) {â¨
push @output, some_func($_);â¨
}
⢠Good:â¨
my @output = map some_func($_), @input;
⢠Concise, faster, easier to read at a glance
⢠Can also stack them easier
80. Section 6.11. List Selections
⢠Use grep and ďŹrst to search a list
⢠Bad:â¨
my @output;â¨
for (@input) {â¨
push @output, $_ if some_func($_);â¨
}
⢠Good:â¨
my @output = grep some_func($_), @input;
⢠But ďŹrst:â¨
use List::Util qw(ďŹrst);â¨
my $item = ďŹrst { $_ > 30 } @input;
81. Section 6.12. List Transformation
⢠Transform list in place with foreach, not map
⢠Bad:â¨
@items = map { make_bigger($_) } @items;
⢠Good:â¨
$_ = make_bigger($_) for @items;
⢠Not completely equivalent
⢠If make_bigger in a list context returns varying items
⢠But generally what youâre intending
82. Section 6.13. Complex Mappings
⢠If the map block is complex, make it a subroutine
⢠Keeps the code easier to read
⢠Names the code for easier recognition
⢠Permits testing the subroutine separately
⢠Allows reusing the same code for more than one map
83. Section 6.14. List Processing Side Effects
⢠Modifying $_ in map or grep alters the input!
⢠Donât do that
⢠Instead, make a copy:â¨
my @result = map {â¨
my $copy = $_;â¨
$copy =~ s/foo/bar/g;â¨
$copy;â¨
} @input;
⢠Note that the last expression evaluated is the result
⢠Donât use return!
85. Section 6.16. Value Switches
⢠Use table lookup instead of cascaded equality tests
⢠Rather than:â¨
if ($n eq âopenâ) { $op = âoâ }â¨
elsif ($n eq âcloseâ } { $op = âcâ }â¨
elsif ($n eq âeraseâ } { $op = âeâ }
⢠Use:â¨
my %OPS = (open => âoâ, close => âcâ, erase => âeâ);â¨
...â¨
if (my $op = $OPS{$n}) { ... } else { ... }
⢠Table should be initialized once
86. Section 6.17. Tabular Ternaries
⢠Sometimes, cascaded ?: are the best
⢠Test each condition, return appropriate value
⢠Example:
my $result
= condition1 ? result1
: condition2 ? result2
: condition3 ? result3
: fallbackvalue
;
87. Section 6.18. do-while Loops
⢠Donât.
⢠Do-while loops do not respect last/next/redo
⢠If you need test-last, use a naked block:â¨
{â¨
...â¨
...â¨
redo if SOME CONDITION;â¨
}
⢠last/next/redo works with this block nicely
88. Section 6.19. Linear Coding
⢠Reject as many conditions as early as possible
⢠Isolate disqualifying conditions early in the loop
⢠Use ânextâ with separate conditions
⢠Example:
while (<....>) {
next unless /S/; # skip blank lines
next if /^#/; # skip comments
chomp;
next if length > 20; # skip long lines
...
}
89. Section 6.20. Distributed Control
⢠Donât throw everything into the loop control
⢠âEvery loop should have a single exitâ is bogus
⢠Exit early, exit often, as shown by previous item
90. Section 6.21. Redoing
⢠Use redo with foreach to process the same item
⢠Better than a while loop where the item count may or
may not be incremented
⢠No, i didnât really understand the point of this, either
91. Section 6.22. Loop Labels
⢠Label loops used with last/next/redo
⢠last/next/redo provide a limited âgotoâ
⢠But itâs still sometimes confusing
⢠Always label your loops for these:
LINE: while (<>) { ... next LINE if $cond; ... }
⢠The labels should be the noun of the thing being
processed
⢠Makes âlast LINEâ read like English!
93. Section 7.1. Types of Documentation
⢠Be clear about the audience
⢠Is this for users? or maintainers?
⢠User docs should go into POD
⢠Maintainer docs can be in comments
⢠Might also be good to have those in separate PODs
94. Section 7.2. Boilerplates
⢠Create POD templates
⢠Understand the standard POD
⢠Enhance it with local standards
⢠Donât keep retyping your name and email
⢠Consider Module::Starter
95. Section 7.3. Extended Boilerplates
⢠Add customized POD headers:
⢠Examples
⢠Frequently Asked Questions
⢠Common Usage Mistakes
⢠See Also
⢠Disclaimer of Warranty
⢠Acknowledgements
96. Section 7.4. Location
⢠Use POD for user docs
⢠Keep the user docs near the code
⢠Helps ensure the user docs are in sync
97. Section 7.5. Contiguity
⢠Keep the POD together in the source ďŹle
⢠Says Damian
⢠I like the style of âlittle code, little podâ
⢠Bit tricky though, since you have to get the right =cut:
=item FOO
text about FOO
=cut
sub FOO { ... }
98. Section 7.6. Position
⢠Place POD at the end of the ďŹle
⢠Says Damian
⢠Nice though, because you can add __END__ ahead
⢠This is true of the standard h2xs templates
⢠Hard to do if itâs intermingled though
⢠My preference:
⢠mainline code
⢠top of POD page
⢠subroutines intermingled with POD
⢠bottom of POD page
⢠â1;â __END__ and <DATA> (if needed)
99. Section 7.7. Technical Documentation
⢠Organize the tech docs
⢠Make each section clear as to audience and purpose
⢠Donât make casual user accidentally read tech docs
⢠Scares them off from using your code, perhaps
100. Section 7.8. Comments
⢠Use block comments for major comments:â¨
#########################â¨
# Called with: $foo (int), $bar (arrayref)â¨
# Returns: $item (in scalar context), @items (in list)
⢠Teach your editor a template for these
101. Section 7.9. Algorithmic Documentation
⢠Use full-line comments to explain the algorithm
⢠PreďŹx any âchunkâ of code
⢠Donât exceed a single line
⢠If longer, refactor the code to a subroutine
⢠Put the long explanation as a block comment
102. Section 7.10. Elucidating Documentation
⢠Use end-of-line comments to point out weird stuff
⢠Obviously, deďŹnition of âweirdâ might vary
⢠Example:
local $/ = â0â; # NUL, not newline
chomp; # using modiďŹed $/ here
103. Section 7.11. Defensive Documentation
⢠Comment anything that has puzzled or tricked you
⢠Example:â¨
@options = map +{ $_ => 1 }, @input; # hash not block!
⢠Think of the reader
⢠Think of yourself three months from now
⢠Or at 3am tomorrow
104. Section 7.12. Indicative Documentation
⢠If you keep adding comments for âtrickyâ stuff...
⢠... maybe you should just change your style
⢠That last example can be rewritten:â¨
@options = map { { $_ => 1 } } @input;
⢠Of course, some might consider nested curlies odd
105. Section 7.13. Discursive Documentation
⢠Use âinvisible PODâ for longer technical notes
⢠Start with =for KEYWORD
⢠Include paragraph with no embedded blank lines
⢠End with blank line and =cut
⢠As in:
=for Clarity:
Every time we reboot, this code gets called.
Even if it wasnât our fault. I mean really!
Yeah, thatâs our story and weâre sticking to it.
=cut
106. Section 7.14. Proofreading
⢠Check spelling, syntax, sanity
⢠Include both user and internal docs
⢠Better yet, get someone else to help you
⢠Hard to tell your own mistakes with docs
⢠Could make this part of code/peer review
108. Section 8.1. Sorting
⢠Donât recompute sort keys inside sort
⢠Sorting often compares the same item against many
others
⢠Recomputing means wasted work
⢠Consider a caching solution
⢠Simple cache
⢠Schwartzian Transform
109. Section 8.2. Reversing Lists
⢠Use reverse to reverse a list
⢠Donât sort { $b cmp $a } - reverse sort!
⢠Use reverse to make descending ranges:
my @countdown = reverse 0..10;
110. Section 8.3. Reversing Scalars
⢠Use scalar reverse to reverse a string
⢠Add the âscalarâ keyword to make it clear
⢠Beware of:â¨
foo(reverse $bar)
⢠This is likely list context
⢠Reversing a single item list is a no-op!
⢠Suggest: foo(scalar reverse $bar)
111. Section 8.4. Fixed-Width Data
⢠Use unpack to extract ďŹxed-width ďŹelds
⢠Example:â¨
my ($x, $y, $z)â¨
= unpack â@0 A6 @8 A10 @20 A8â, $input;
⢠The @ ensures absolute position
112. Section 8.5. Separated Data
⢠Use split() for simple variable-width ďŹelds
⢠First arg of string-space for awk-like behavior:â¨
my @columns = split â â, $input;
⢠Leading/trailing whitespace is ignored
⢠Multiple whitespace is a single delimiter
⢠Trailing whitespace is ignored
⢠Otherwise, leading delimiters are signiďŹcant:â¨
my @cols = split /s+/,â foo barâ;
⢠$cols[0] = empty string
⢠$cols[1] = âfooâ
114. Section 8.7. String Evaluations
⢠Avoid string eval
⢠Harder to debug
⢠Slower (ďŹring up compiler at runtime)
⢠Might create security holes
⢠Generally unnecessary
⢠Runtime data should not affect program space
115. Section 8.8. Automating Sorts
⢠Sort::Maker (CPAN) is your friend
⢠Can build
⢠Schwartzian Transform
⢠Or-cache (Orcish)
⢠Gutmann Rosler Transform
116. Section 8.9. Substrings
⢠Use 4-arg substr() instead of lvalue substr()
⢠Old way:â¨
substr($x, 10, 3) = âHelloâ; # replace 10..12 with âHelloâ
⢠New way (for some ancient meaning of ânewâ):â¨
substr($x, 10, 3,âHelloâ); # replace, and return old
⢠Slightly faster
117. Section 8.10. HashValues
⢠Remember that values is an lvalue
⢠Double all values:â¨
$_ *= 2 for values %somehash;
⢠Same as:â¨
for (keys %somehash) {â¨
$somehash{$_} *= 2;â¨
}
⢠But with less typing!
118. Section 8.11. Globbing
⢠Use glob(), not <...>
⢠Save <...> for ďŹlehandle reading
⢠Works the same way:â¨
<* .*> same as glob â* .*â
⢠Donât use multiple arguments
119. Section 8.12. Sleeping
⢠Avoid raw select for sub-second sleeps
⢠use Time::HiRes qw(sleep);â¨
sleep 1.5;
⢠Says Damian
⢠I think âselect undef, undef, undef, 1.5â is just ďŹne
⢠Far more portable
⢠If youâre scared of select, hide it behind a subroutine
120. Section 8.13. Mapping and Grepping
⢠Always use block-form of map/grep
⢠Never use the expression form
⢠Too easy to get the âexpressionâ messed up
⢠Works:â¨
map { join â:â, @$_ } @some_values
⢠Doesnât work:â¨
map join â:â, @$_, @some_values;
⢠Block form has no trailing comma after the block
⢠Might need disambiguating semicolon:â¨
map {; ... other stuff here } @input
121. Section 8.14. Utilities
⢠Use the semi-builtins in Scalar::Util and List::Util
⢠These are core with modern Perl
⢠Scalar::Util has: blessed, refaddr, reftype, readonly, tainted,
openhandle, weaken, unweaken, is_weak, dualvar,
looks_like_number, isdual, isvstring, set_prototype
⢠List::Util has: reduce, any, all, none, notall, ďŹrst, max,
maxstr, min, minstr, product, sum, sum0, pairs, unpairs,
pairkeys, pairvalues, pairgrep, pairďŹrst, pairmap, shufďŹe,
uniq, uniqnum, uniqstr
⢠reduce is cool:
⢠my $factorial = reduce { $a * $b } 1..20;
⢠my $commy = reduce { â$a, $bâ } @strings;
122. Chapter 9. Subroutines
⢠Making your program modular
⢠Nice unit of reuse
⢠GIving name to a set of steps
⢠Isolating local variables
123. Section 9.1. Call Syntax
⢠Use parens
⢠Donât use &
⢠Bad: &foo
⢠Good: foo()
⢠Parens help them stand out from builtins
⢠Lack of ampersand means (rare) prototypes are honored
⢠Still need the ampersand for a reference though: &foo
124. Section 9.2. Homonyms
⢠Donât overload the built-in functions
⢠Perl has weird rules about which have precedence
⢠Sometimes your code is picked (lock)
⢠Sometimes, the original is picked (link)
125. Section 9.3. Argument Lists
⢠Unpack @_ into named variables
⢠$_[3] is just ugly
⢠Even compared to the rest of Perl
⢠Unpack your args:
⢠my ($name, $rank, $serial) = @_;
⢠Use âshiftâ form for more breathing room:
⢠my $name = shift; # âFlintstone, Fredâ
⢠my $rank = shift; # 1..10
⢠my $serial = shift; # 7-digit integer
⢠Modern Perl can also have signatures
⢠Built-in starting in 5.20 (but primitive)
⢠Damian now recommends (his) Method::Signatures
126. Section 9.4. Named Arguments
⢠Use named parameters if more than three
⢠Three positional parameters is enough
⢠For more than three, use a hash:
⢠my %options = %{+shift};
⢠my $name = $options{name} || die â?â;
⢠Pass them as a hashref:
⢠my_routine({name => âRandalâ})
⢠This catches the odd-number of parameters at the caller,
not the callee.
127. Section 9.5. Missing Arguments
⢠Use deďŹnedness rather than boolean to test for
existence
⢠Bad:
if (my $directory = shift) { ... }
⢠What if $directory is â0â? Legal!
⢠Better:
if (deďŹned(my $directory = shift)) { ... }
⢠Or:
if (@_) { my $directory = shift; ... }
⢠Automatically processed for item-at-a-time built-ins:â¨
while (my $f = readdir $d) { ⌠}
128. Section 9.6. Default ArgumentValues
⢠Set up default arguments early
⢠Avoids temptation to use a quick boolean test later:â¨
my ($text, $arg_ref) = @_;â¨
my $thing = exists $arg_ref->{thing}â¨
? $arg_ref->{thing} :âdefault thingâ;â¨
my $other = exists $arg_ref->{other}â¨
? $arg_ref->{other} :âdefault otherâ;
⢠Or maybe:â¨
my %args = (thing => âdefault thingâ,â¨
other => âdefault otherâ, %$arg_ref);
129. Section 9.7. Scalar ReturnValues
⢠Indicate scalar return with âreturn scalarâ
⢠Ensures that list context doesnât ruin your day
⢠Example: returning grep for count (true/false)â¨
sub big10 { return grep { $_ > 10 } @_ }
⢠Works ok when used as boolean:â¨
if (big10(@input)) { ... }
⢠Or even to get the count:â¨
my $big_uns = big10(@input);
⢠But breaks weird when used in a list:â¨
some_other_sub($foo, big10(@input), $bar);
⢠Fixed: sub big10 { return scalar grep { $_ > 10 } @_ }
130. Section 9.8. Contextual ReturnValues
⢠Make list-returning subs intuitive in scalar context
⢠Consider the various choices:
⢠Count of items (like grep/map/arrayname)
⢠Serialized string representation (localtime)
⢠First item (caller, each, select, unpack)
⢠ânextâ item (glob, readline)
⢠last item (splice, various slices)
⢠undef (sort)
⢠third(!) item (getpwnam)
⢠See http://www.perlmonks.org/index.pl?node_id=347416
131. Section 9.9. Multi-Contextual Return
Values
⢠Consider Contextual::Return
⢠Appropriately Damian-ized (regretfully discouraged now)â¨
use List::Util qw(ďŹrst);â¨
use Contextual::Return;â¨
sub deďŹned_samples_in {â¨
return (â¨
LIST { grep { deďŹned $_} @_ }â¨
SCALAR { ďŹrst { deďŹned $_} @_ }â¨
);â¨
}
⢠It does more, much more. So much more:
⢠VOID, BOOL, NUM, STR, REF, FAIL, LAZY, LVALUEâŚ
133. Section 9.11. Implicit Returns
⢠Always use explicit return
⢠Perl returns the last expression evaluated
⢠But make it explicit:
⢠return $this;
⢠Easier to see that the return value is expected
⢠Protects against someone adding an extra line to the
subroutine, breaking the return
134. Section 9.12. Returning Failure
⢠use âreturn;â for undef/empty list return
⢠Not âreturn undef;â
⢠Thus it falls out of lists correctly:â¨
my @result = map { yoursub($_) } @input;
⢠If the caller wants the undef, they can say so:â¨
my @result = map { scalar yoursub($_) } @input;
135. Chapter 10. I/O
⢠Itâs off to work we go
⢠If a program didnât have I/O
⢠Could you still tell it ran?
136. Section 10.1. Filehandles
⢠Donât use bareword ďŹlehandles
⢠Canât easily pass them around
⢠Canât easily localize them
⢠Canât make them âgo out of scopeâ
137. Section 10.2. Indirect Filehandles
⢠Use indirect ďŹlehandles:
⢠open my $foo,â<â, $someinput or die;
⢠They close automatically
⢠Can be passed to/from subroutines
⢠Can be stored in aggregates
⢠Might need readline() or print {...} though
⢠my $line = readline $inputs[3];
⢠print { $output_for{$day} } @list;
138. Section 10.3. Localizing Filehandles
⢠If you must use a package ďŹlehandle, localize it
⢠local *HANDLE
⢠Beware this also stomps on other package items:
⢠$HANDLE
⢠@HANDLE
⢠%HANDLE
⢠&HANDLE
⢠HANDLE dirhandle
⢠HANDLE format
⢠So, use it sparingly
⢠Thatâs why indirect handles are better
139. Section 10.4. Opening Cleanly
⢠Use IO::File or 3-arg open
⢠IO::File:â¨
use IO::File;â¨
my $in_handle = IO::File->new($name,â<â) or die;
⢠3-arg open (with indirect handle):â¨
open my $in_handle,â<â, $name or die;
⢠3-arg open ensures safety
⢠Even if $name starts with < or > or | or ends with |.
⢠Or whitespace (normally trimmed)
140. Section 10.5. Error Checking
⢠Add error checking or die!
⢠Include the $! as well
⢠open my $handle,â<â, $that_ďŹle
or die âCannot open $that_ďŹle: $!â;
⢠Also check close and print
⢠Close and print can fail
⢠If the ďŹle isnât opened (oops!)
⢠If the ďŹnal ďŹush causes an I/O error (oops!)
141. Section 10.6. Cleanup
⢠Close ďŹlehandles explicitly as soon as possible
⢠Says Damian
⢠Or just let them fall out of scope and use a tight scope
⢠my $line = do { open my $x,â<â,âďŹleâ; scalar <$x> };
142. Section 10.7. Input Loops
⢠Use while(<>), not foreach(<>)
⢠While - reads one line at a time
⢠Exits at undef (no more lines)
⢠Foreach - reads everything at once
⢠No reason to bring everything into memory
⢠Especially when you canât reference it!
143. Section 10.8. Line-Based Input
⢠Similar to previous hint
⢠If you can grab it a line at a time, do it
⢠Bad:â¨
print for grep /ITEM/, <INPUT>;
⢠Good:â¨
while (<INPUT>) { print if /ITEM/ }
144. Section 10.9. Simple Slurping
⢠Slurp in a do-block
⢠Get the entire ďŹle:
my $entire_ďŹle = do { local $/; <$in> };
⢠local here automatically provides undef
⢠The localization protects nearby items
⢠Dangerous if you had $/ = undef in normal code
⢠Better/faster/stronger than: join ââ, <$in>
145. Section 10.10. Power Slurping
⢠Slurp a stream with File::Slurp (from the CPAN)
⢠Read an entire ďŹle:â¨
use File::Slurp qw(read_ďŹle);â¨
my $entire_ďŹle = read_ďŹle $in;
⢠And a few other interesting options
146. Section 10.11. Standard Input
⢠Avoid using STDIN unless you really mean it
⢠Itâs not necessarily the terminal (could be redirected)
⢠Itâs almost never the ďŹles on the command line
⢠It means only âstandard inputâ
⢠Read from ARGV instead:
my $line = <ARGV>; # explicit form
my $line = <>; # implicit (preferred) form
147. Section 10.12. Printing to Filehandles
⢠Always put ďŹlehandles in braces in any print statement
⢠Says Damian
⢠The rest of us do that when itâs complex:
print $foo @data; # simple
print { $hashref->{foo} } @data; # complex
⢠If itâs a bareword or a simple scalar, no need for braces
148. Section 10.13. Simple Prompting
⢠Always prompt for interactive input
⢠Keeps the user from wondering:
⢠Is it running?
⢠Is it waiting for me?
⢠Has it crashed?
⢠Prompt only when interactive though
⢠Donât prompt if part of a pipeline
149. Section 10.14. Interactivity
⢠Test for interactivity with -t
⢠Simple test:â¨
if (-t) { ... STDIN is a terminal }
⢠Damian makes it more complex
⢠Suggests IO::Interactive from CPAN
150. Section 10.15. Power Prompting
⢠Use IO::Prompt for prompting (in CPAN)
⢠my $line = prompt âline, please? â;
⢠Automatically chomps (yeay!)
⢠my $password = prompt âpassword:â,â¨
-echo => â*â;
⢠my $choice = prompt âletterâ, -onechar,â¨
-require => { âmust be [a-e]â => qr/[a-e]/ };
⢠Many more options
⢠Damian followed up with IO::Prompter (even more
options)
151. Section 10.16. Progress Indicators
⢠Interactive apps need progress indicators for long stuff
⢠People need to know âworking? or hung?â
⢠And âCoffee? Or take the afternoon off?â
⢠Good estimates of completion time are handy
⢠Spooky estimates can backďŹre
⢠90% of ticks come within 2 seconds
⢠last 10% takes 5 minutes... oops
152. Section 10.17. Automatic Progress
Indicators
⢠Damianized Smart::Comments in CPAN
⢠Example:
use Smart::Comments;
for my $path (split /:/, $ENV{PATH}) {
### Checking path... done
for my $ďŹle (glob â$path/*â) {
### Checking ďŹles... done
if (-x $ďŹle) { ... }
}
}
153. Section 10.18. AutoďŹushing
⢠Avoid using select() to set autoďŹushing:
select((select($fh), $| = 1)[0]);
⢠Yeah, so I came up with that
⢠I must have been, uh... confused
⢠Use IO::Handle (not needed in Perl 5.14 and later)
⢠Then you can call $fh->autoďŹush(1)
⢠And even *STDOUT->autoďŹush(1)
154. Chapter 11. References
⢠Canât get jobs without them
⢠Canât get to indirect data without them either
⢠Symbolic (soft) references are evil
156. Section 11.2. Braced References
⢠Always use braces for circumďŹex dereferencing
⢠Bad: @$foo[3, 4]
⢠Good: @{$foo}[3, 4]
⢠Makes the deref item clearer
⢠Needed anyway when deref item is complex
⢠Or ďŹip it around to postďŹx form
157. Section 11.3. Symbolic References
⢠Donât
⢠use strict ârefsâ prevents you anyway
⢠If you think of the symbol table as a hash...
⢠... you can see how to move it down a level anyway
⢠Bad: $x = âKâ; ${$x} = 17;
⢠Good: $x = âKâ; $my_hash{$x} = 17;
158. Section 11.4. Cyclic References
⢠Cycles cannot be reference-counted nicely
⢠Break the cycle with weaken
⢠Use weaken for every âupâ link
⢠When kids need to know about their parents
⢠use Scalar::Util qw(weaken);â¨
my $root = {};â¨
my $leaf1 = { parent => $root };â¨
weaken $leaf1->{parent};â¨
my $leaf2 = { parent => $root };â¨
weaken $leaf2->{parent};â¨
push @$root{kids}, $leaf1, $leaf2;
⢠Now we can toss $root nicely
159. Chapter 12. Regular Expressions
⢠Some people, when confronted with a problem, think:â¨
"I know, I'll use regular expressions".â¨
Now they have two problems.â¨
âJamie Zawinski
160. Section 12.1. Extended Formatting
⢠Always use /x
⢠Internal whitespace is ignored
⢠Comments are simple #-to-end-of-line
⢠Hard: /^(.*?)(w+).*?21$/
⢠Easy(er):â¨
/^â¨
(.*?) (w+) # some text and an alpha-wordâ¨
.*? # anythingâ¨
2 1 # the word followed by text againâ¨
$/x
⢠Beware: this will break old regex if youâre not careful
161. Section 12.2. Line Boundaries
⢠Always use /m
⢠^ means
⢠Start of string
⢠Just after any embedded newline
⢠$ means
⢠End of string
⢠Just before any embedded newline
⢠Damian argues that this is closer to what people expect
⢠I say use it when itâs what you want
163. Section 12.4. End of String
⢠Use z not Z or $
⢠Itâs really âend of stringâ
⢠Not âend of string but maybe before nâ
⢠Security hole: if ($value =~ /^d+$/) { ... }
⢠Value could be â35nâ
⢠That might ruin a good day
⢠Fix: if ($value =~ /Ad+z/) { ... }
164. Section 12.5. Matching Anything
⢠Always use /s
⢠Turns . into âmatch anythingâ
⢠Not âmatch anything (except the newline)â
⢠This is more often what people want
⢠Says Damian
⢠Use it when you need it
165. Section 12.6. Lazy Flags
⢠If youâre as crazy as Damian
⢠And as lazy as Damian
⢠Consider Regexp::AutoďŹags
⢠Automatically adds /xms to all regexp
⢠But then notice that the book lies
⢠Because itâs actually Regexp::DefaultFlags in the CPAN
166. Section 12.7. Brace Delimiters
⢠Prefer m{...} to /.../ for multiline regex
⢠Open-close stands out easier
⢠Especially when alone on a line
⢠Heck, use âem even for single line regex
⢠Particularly if the regex contains a slash
⢠Balancing is easy:
m{ abc{3,5} } # âabâ then 3-5 câs
m{ abc{3,5} } # âabc{3,5}â all literal
167. Section 12.8. Other Delimiters
⢠Donât use any other delimiters
⢠Unless youâre sure that Damianâs not looking
⢠But seriously...
⢠m#foo# is cute
⢠But annoying
⢠And m,foo, is downright weird
168. Section 12.9. Metacharacters
⢠Prefer singular character classes to escaped metachars
⢠Instead of â.â, use [.]
⢠Instead of â â (escaped space), use [ ] (space in [])
⢠Advantage: brackets are balanced
169. Section 12.10. Named Characters
⢠Prefer named characters to escaped metacharacters
⢠Example:â¨
use charnames qw(:full);â¨
if ($escape_seq =~ m{â¨
N{DELETE}â¨
N{ACKNOWLEDGE}â¨
N{CANCEL} Zâ¨
}xms) { ... }
⢠Downside: now you have to know these names
⢠Is anyone really gonna type N{SPACE} ?
170. Section 12.11. Properties
⢠Prefer properties to character classes
⢠Works better with Unicode
⢠Such as: qr{ p{Uppercase} p{Alphabetic}* /xms;
⢠âperldoc perlunicodeâ lists the properties
⢠You can even create your own
172. Section 12.13. Unconstrained Repetitions
⢠Be careful when matching âas much as possibleâ
⢠For example:â¨
âActivation=This=thatâ =~ /(.*)=(.*)/
⢠$1 is âActivation=Thisâ!
⢠Consider .*? instead:â¨
âActivation=This=thatâ =~ /(.*?)=(.*)/
⢠Now we have $1 = âActivationâ, $2 = âThis=thatâ
⢠Donât do this blindly:â¨
âActivation=This=thatâ =~ /(.*?)=(.*?)/
⢠Now $2 has nothing!
173. Section 12.14. Capturing Parentheses
⢠Use capturing parens only when capturing
⢠Every ( ... ) in a regex is a capture regex
⢠This affects $1, etc
⢠But it also affects speed
⢠When you donât need to capture, donât!
⢠Use (?: ... )
⢠Yes, a little more typing
⢠But itâs clear that you donât need that value
174. Section 12.15. CapturedValues
⢠Use $1 only when youâre sure you had a match
⢠Common error:â¨
$foo =~ /(.*?)=(.*)/;â¨
push @{$hash{$1}}, $2;
⢠What if the match fails?
⢠Pushes the previous $2 onto the previous $1
⢠Always use $1 with a conditional
⢠Even if it can never match:
⢠Add âor dieâ:â¨
$foo =~ /(.*?)=(.*)/ or die âShould not happenâ;
⢠Then you know something broke somewhere
175. Section 12.16. CaptureVariables
⢠Name your captures
⢠There can be quite a distance between
⢠/ (w+) s+ (w+) /xms
⢠$1, $2
⢠Easy to make mistake, or modify and break things
⢠Instead, name your captures when you can:
⢠my ($given, $surname) = /(w+)s+(w+)/;
⢠If this match fails in a scalar context, it returns false
176. Section 12.17. Piecewise Matching
⢠Tokenize input using /gc
⢠Also called âinchwormingâ
⢠Match string against a series of /G.../gc constructs
⢠If one succeeds, pos() is updated
⢠Example:
{ last if /Gz/gc; # exit at end of string
if (/G(w+)/gc) { push @tokens,âkeyword $1â }
elsif (/G(â.*?â)/gcs) { push @tokens,âquoted $1â }
elsif (/Gs+/gc) { ... ignore whitespace ... }
else { die âCannot parse:â, /G(.*)/s } # grab rest
redo;
}
177. Section 12.18. Tabular Regexes
⢠Build regex from tables
⢠To replace keys of %FOO with values of %FOO
⢠Construct the matching regex:â¨
my $regex = join â|â, map quotemeta,â¨
reverse sort keys %FOO;â¨
$regex = qr/$regex/; # if used more than once
⢠Do the replacement:â¨
$string =~ s/($regex)/$FOO{$1}/g;
⢠It works
178. Section 12.19. Constructing Regexes
⢠Build complex regex from simpler pieces
⢠Example:â¨
my $DIGITS = qr{ d+ (?: [.] d*)? | [.] d+ }xms;â¨
my $SIGN = qr{ [+-] }xms;â¨
my $EXPONENT = qr{ [Ee] $SIGN? d+ }xms;â¨
my $NUMBER = qr{ ( ($SIGN?) ($DIGITS)
($EXPONENT?) ) }xms;
⢠Now you can use /$NUMBER/
179. Section 12.20. Canned Regexes
⢠Use Regexp::Common
⢠Donât reinvent the common regex
⢠Use the expert coding in Regexp::Common
⢠$number =~ /$RE{num}{real}/
⢠$balanced_parens =~ /$RE{balanced}/
⢠$bad_words =~ /$RE{profanity}/
⢠Module comes with 2,315,992 tests (over 4 minutes to
run the tests!)
180. Section 12.21. Alternations
⢠Prefer character classes to single-char alternations
⢠[abc] is far faster than (a|b|c)
⢠As in, 10 times faster
⢠Consider refactoring too
⢠Replace: (a|b|ca|cb|cc)
⢠With: (a|b|c[abc])
⢠Same job, and again faster
181. Section 12.22. Factoring Alternations
⢠An advancement of previous hint
⢠Slow: /with s+ foo|with s+ bar/x
⢠Faster: /with s+ (foo|bar)/x
⢠Keep refactoring until it hurts
⢠Beware changes to $1, etc
⢠Also beware changes to order of attempted matches
183. Section 12.24. String Comparisons
⢠Prefer eq to ďŹxed-pattern regex matches
⢠Donât say $foo =~ /ABARz/
⢠Use $foo eq âBARâ
⢠Donât say $foo =~ /ABARz/i
⢠Use (uc $foo) eq âBARâ
184. Chapter 13. Error Handling
⢠Hopefully, everything works
⢠But when things go bad, you need to know
⢠Sometimes, itâs minor, and just needs repair
⢠Sometimes, itâs major, and needs help
⢠Sometimes, itâs catastrophic
185. Section 13.1. Exceptions
⢠Throw exceptions instead of funny returns
⢠People might forget to test for âundefâ
⢠But they have to work pretty hard to ignore an
exception
⢠Exceptions can be easily caught with eval {}
⢠But better to use Try::Tiny
⢠Or for more ďŹexibility,TryCatch
186. Section 13.2. Builtin Failures
⢠Use Fatal to turn failures into exceptions
⢠Tired of forgetting âor dieâ on âopenâ?
⢠use Fatal qw(:void open);â¨
...â¨
open my $f,âBOGUS FILEâ; # dies!
⢠Yes, ďŹnally open does the right thing
⢠Damian also suggests Lexical::Failure
187. Section 13.3. Contextual Failure
⢠You can tell Fatal to be context-sensitive
⢠So this still works:
⢠unless (open my $f,âBOGUSâ) { ... }
⢠Thatâs dangerous though
⢠People might use it in a non-void context without
checking
⢠Says Damian
⢠I think you can use it with discipline
188. Section 13.4. Systemic Failure
⢠Be careful with system()
⢠Returns 0 (false) if everything is OK
⢠Returns non-zero if something broke
⢠Technically, the return value of wait():
⢠Exit status * 256
⢠Plus 128 if core was dumped
⢠Plus signal number that killed it, if any
⢠0 = âgoodâ, non-zero = âbadâ
⢠Damian suggests WIFEXITED:â¨
use POSIX qw(WIFEXITED);WIFEXITED(system ...)
⢠Or just add â!â in front:â¨
!system âfooâ or die â...â; # no access to $! here!
189. Section 13.5. Recoverable Failure
⢠Throw exceptions on all failures
⢠Including recoverable ones
⢠Easy enough to put an eval {} around it
⢠Donât use undef
⢠Developers donât always check
⢠Says Damian
⢠I say, trust your developers a bit
190. Section 13.6. Reporting Failure
⢠Carp blames someone else
⢠use Carp qw(croak);â¨
... open my $f, $ďŹle or croak â$ďŹle?â;
⢠Now the caller is blamed
⢠Makes sense if itâs the callerâs fault
191. Section 13.7. Error Messages
⢠Error messages should speak user-based terminology
⢠Nobody knows â@fooâ
⢠Better chance of knowing âinput ďŹlesâ
⢠Be as detailed as you can
⢠Remember that this is all youâre likely to get in the bug
report
⢠And they will ďŹle bug reports
192. Section 13.8. Documenting Errors
⢠Document every error message
⢠Explain it in even more detail
⢠Again in the userâs terminology
⢠Nothing more frustrating than a confusing error message
⢠... that isnât explained!
⢠Good example:âperldoc perldiagâ
193. Section 13.9. OO Exceptions
⢠Throw an object instead of text
⢠The object can contain relevant information
⢠Exception catchers can pull info apart
⢠Exception objects can also have nice stringiďŹcations
⢠This helps naive catchers that print âError: $@â
194. Section 13.10. Volatile Error Messages
⢠Relying on catchers to parse text is dangerous
⢠Throwing an object isolates text changes
⢠Additional components can be added later
⢠Likely wonât break existing code
195. Section 13.11. Exception Hierarchies
⢠Use exception objects when exceptions are related
⢠Give them different classes, but common inheritance
⢠Catchers can easily test for categories of exceptions
⢠Or distinguish speciďŹc items when it matters
197. Section 13.13. Exception Classes
⢠Use Exception::Class for nice exceptions
⢠Exception::Class-based exceptions capture:
⢠caller
⢠current ďŹlename, linenumber, package
⢠user data
⢠Stringify nicely for naive displays (customized if needed)
⢠Create hierarchies for classiďŹed handling
⢠Consider âThrowableâ role for Moo or Moose
198. Section 13.14. Unpacking Exceptions
⢠Grab $@ early in your catcher
⢠Then parse and act on it
⢠One of your parsing steps may alter $@ accidentally
⢠Best to capture it ďŹrst!
⢠Or consider Try::Tiny, which puts $@ safely into block-
scoped $_
199. Chapter 14. Command-Line Processing
⢠The great homecoming
⢠In the beginning, everything was command-line
⢠Perl still works well here
⢠But you should follow some standards and conventions
200. Section 14.1. Command-Line Structure
⢠Enforce a single consistent command-line structure
⢠GNU tools
⢠Need I say more?
⢠Every tool, slightly different
⢠Pick a standard, stick with it
⢠Especially amongst a tool suite
⢠If you use -i for input here, use it there too
201. Section 14.2. Command-Line
Conventions
⢠Use consistent APIs for arguments
⢠Require a ďŹag in front of every arg, except ďŹlenames
⢠Use - preďŹx for single-letter ďŹags
⢠Use -- preďŹx for longer ďŹags
⢠Provide long ďŹag aliases for every single-letter ďŹag
⢠Always allow â-â as a ďŹlename
⢠Always use â--â to indicate âend of argsâ
203. Section 14.4. In-situ Arguments
⢠If possible, allow same ďŹle for both input and output
⢠foo_command -i thisďŹle -o thisďŹle
⢠Obviously might require some jiggery
⢠Or IO::InSitu from the CPAN:â¨
my $in_name = ....;â¨
my $out_name = ....;â¨
my ($in, $out) = open_rw($in_name, $out_name);â¨
while (<$in>) { print $out â$.: $_â }
204. Section 14.5. Command-Line Processing
⢠Standardize on a single approach to command-line
processing
⢠Look at Getopt::Long (core)
⢠For a more Damianized approach, Getopt::Declare
⢠Spell out your usage, and the args follow!
⢠Manpage is longer than most program manpages
205. Section 14.6. Interface Consistency
⢠Ensure interface, run-time, and docs are consistent
⢠Usage messages should match what the code does
⢠Simple with Getopt::Declare!
⢠Help docs should match what the manpage says
⢠If Getopt::Declare wasnât enough...
⢠... consider Getopt::Euclid
⢠Constructs your parser from POD
⢠Then the manpage deďŹnitely matches the code!
⢠Again, suitably Damianized
⢠Requires many âaha!â moments to fully understand
206. Section 14.7. Interapplication Consistency
⢠Factor out common CLI items to shared modules
⢠If every tool has -i and -o, donât keep rewriting that
⢠Getopt::Euclid âpod modulesâ can provide common code
⢠Also permits readers to learn it once
⢠Instead of having to recognize it each time
⢠âThis program implements L<Our::Standard::CLI>.â
207. Chapter 15. Objects
⢠Used by practically every large practical program
⢠Even used by many little programs
⢠âThereâs more than one way to implement itâ
⢠Hash-based? Array-based? Inside-out?
⢠Using some framework, or hand-coded?
⢠So whatâs best?
⢠Here we go...
208. Section 15.1. Using OO
⢠Make OO a choice, not a default
⢠Donât introduce needless objects
⢠Especially over-complex frameworks
⢠You probably donât need a different class for every token
209. Section 15.2. Criteria
⢠Use objects if you have the right conditions
⢠Large systems
⢠Obvious large structures
⢠Natural hierarchy (polymorphism and inheritance)
⢠Many different operations on the same data
⢠Same or similar operations on related data
⢠Likely to add new types later
⢠Operator overloading can be used logically
⢠Implementations need to be hidden
⢠System design is already OO
⢠Large numbers of other programmers use your code
211. Section 15.4. Restricted Hashes
⢠Donât
⢠Not really restricted
⢠For every lock, thereâs a means to unlock
⢠Inside-out objects handle most of the needs here
212. Section 15.5. Encapsulation
⢠Donât bleed your guts
⢠Provide methods for all accessors
⢠If you want to provide hashref access
⢠Provide a hashref overload
⢠Prepare to pay the price for such access
⢠Consider inside-out objects to ensure guts are private
213. Section 15.6. Constructors
⢠Give every constructor the same standard name
⢠And thatâs ânewâ, duh
⢠Says Damian
⢠Or, just use whatâs natural
⢠After all, DBI->connect does it.
⢠Or rewrite that as DBI->new({ connect => [...] })
⢠Not likely any time soon
214. Section 15.7. Cloning
⢠Donât clone in your constructor
⢠$instance->new should be an error
⢠If you want an âobject of the same type as...â, use ref:â¨
my $similar = (ref $instance)->new(...);
⢠If you want a proper clone, write a clone/copy routine:â¨
my $clone = $instance->clone;
⢠Note: please stop cargo-culting:â¨
sub new {â¨
my $self = shift;â¨
my $class = ref $self || $self; # badâ¨
...â¨
}
215. Section 15.8. Destructors
⢠Inside out objects need destructors
⢠Or they leak
⢠And be sure to destroy all the parent classes too:â¨
sub DESTROY {â¨
my $deadbody = shift;â¨
... destroy my attributes here ...â¨
for (our @ISA) {â¨
my $can = $_->can(âDESTROYâ);â¨
$deadbody->$can if $can;â¨
}â¨
}
⢠Or use âNEXTâ in the CPAN
216. Section 15.9. Methods
⢠Methods are subroutines
⢠Except methods can be same-named as built-ins
⢠Theyâll never be confused with subroutines
217. Section 15.10. Accessors
⢠Provide separate read and write accessors
⢠Same-named accessors might have spooky non-behavior:â¨
$person->name(ânew nameâ);â¨
$person->rank(ânew rankâ);â¨
$person->serial_number(ânew numberâ); # read only!
⢠Of course, these double-duty routines should abort
⢠But they often donât
⢠Also, differently named accessors easier to grep for
⢠Help understand places a value could change
218. Section 15.11. Lvalue Accessors
⢠Donât use lvalue accessors
⢠Require returning direct access to a variable
⢠No place to do error checking
⢠Or require returning tied var
⢠Slow
⢠Really slow
⢠Like, slower than just a method call
219. Section 15.12. Indirect Objects
⢠Indirect object syntax is broken
⢠Bad: my $item = new Thing;
⢠Good: my $item = Thing->new;
⢠No chance of mis-parse
⢠Mis-parse has bitten someVery Smart People
⢠If you think youâre smarter than someVery Smart People
⢠... let us know how thatâs working out for you
220. Section 15.13. Class Interfaces
⢠Provide optimal interface, not minimal one
⢠Consider common operations and implement them
⢠As class author, you can optimize internally
⢠Class users have to use your published interface
⢠Worse, they might repeat the code, or build layers
⢠Resulting in more wrappers or repeated code!
221. Section 15.14. Operator Overloading
⢠Overload only for natural-mapping operator
⢠Donât just pick operators and map them
⢠Youâll get bit by precedence, most likely
⢠Or leave one out, and really confuse users
⢠Donât make the C++ mistake:â>>â meaning write-to
222. Section 15.15. Coercions
⢠If possible, provide sane coercions:
⢠Boolean (for tests)
⢠Numeric
⢠String
⢠If your object is âlogically emptyâ, then:
if ($your_object) { ... } should return false else true
⢠And â$your_objectâ shouldnât provide a hex address
⢠Overloaded numerics and strings are also used in sorting
224. Section 16.1. Inheritance
⢠Donât manipulate @ISA directly
⢠Prefer âuse parentâ:
use parent qw(This That Other);
⢠Nice side-effect of loading those packages automatically
⢠Or use a framework that establishes this directly
⢠Replaces the heavier-weight âuse baseâ
225. Section 16.2. Objects
⢠Use inside-out objects
⢠Said Damian back in the day
⢠Avoids attribute collisions
⢠Encapsulates attributes securely
⢠These days, somewhat discouraged
⢠Makes objects a bit too opaque
⢠Still useful for hostile subclassing though
226. Section 16.3. Blessing Objects
⢠Never use one-argument bless
⢠Blessing into âthe current packageâ breaks subclassing:â¨
package Parent;â¨
sub new { bless {} }â¨
package Child;â¨
use base qw(Parent);â¨
package main;â¨
my $kid = Child->new;â¨
print ref $kid; # Parent??
⢠That should have been:â¨
package Parent; sub new { bless {}, shift }
227. Section 16.4. Constructor Arguments
⢠Pass constructor args as a hashref
⢠Gives you key/value pairs easily
⢠Broken hashref caught at the caller, not ânewâ
⢠âOdd number of elements...â
⢠Derived class constructor can pick out what it wants
⢠Pass the remaining items up to base-class constructor
228. Section 16.5. Base Class Initialization
⢠Distinguish initializers by class name
⢠To avoid collisions:â¨
my $thing = Child->new(â¨
child => { this => 3, that => 5 },â¨
parent => { other => 7 });
⢠Says Damian
⢠I say it reveals too much of the hierarchy
⢠Gets complex if Parent/Child are refactored
⢠Use logical names for attributes, not class-based names
229. Section 16.6. Construction and
Destruction
⢠Separate construction, initialization, and destruction
⢠Multiple inheritance breaks if every class does its own
bless
⢠Instead, all classes should separate bless from initialize
⢠Suggested name âBUILDâ
⢠Constructor can call base constructor, then all BUILD
routines in hierarchy
⢠Similar strategy for DESTROY
⢠Or just use Moose or Moo
230. Section 16.7. Automating Class
Hierarchies
⢠Build standard class infrastructure automatically
⢠Getting accessors and privacy correct can take special
care
⢠Use inside-out objects for safety and best development
speed
⢠Class::Std or Object::InsideOut
232. Section 16.9. Attribute Building
⢠Initialize and verify attributes automatically
⢠Again, Class::Std or Object::InsideOut to the rescue
⢠Calls BUILD in all the right places
⢠Or attribute hashes can be annotated for the common
case
233. Section 16.10. Coercions
⢠Specify coercions as attributed methods
⢠Again, provided with Class::Std/Object::InsideOut
⢠For numeric context:â¨
sub count : NUMERIFY { return ... }
⢠For string context:â¨
sub as_string : STRINGIFY { return ... }
⢠For boolean context:â¨
sub is_true : BOOLIFY { return ... }
234. Section 16.11. Cumulative Methods
⢠Use attributed cumulative methods instead of SUPER
⢠Class::Std/Object::InsideOut provide CUMULATIVE:â¨
sub items : CUMULATIVE { ... }
⢠When called in a list context, all calls are made
⢠Result is the concatenated separate lists
⢠Scalar context similar
⢠Result is the string concatenation of all calls
⢠No need for âSUPER::â
⢠Works even with multiple inheritance
235. Section 16.12. Autoloading
⢠Donât use AUTOLOAD
⢠Effectively creates a runtime interface
⢠Not a compile time interface
⢠Must be prepared for
⢠Methods you donât want to handle
⢠DESTROY
⢠Calling âNEXTâ for either of those is tricky
236. Chapter 17. Modules
⢠Reusable collections of subroutines and their data
⢠Unit of exchange for the CPAN
⢠Unit of testability internally
237. Section 17.1. Interfaces
⢠Design the moduleâs interface ďŹrst
⢠A bad interface makes a module unusable
⢠Think about how your module will be used
⢠Name things from the userâs perspective
⢠Not from how itâs implemented
⢠Create examples, or even âuse casesâ for your interface
⢠Keep the examples around for your documentation!
238. Section 17.2. Refactoring
⢠Place original code inline
⢠Place duplicated code in a subroutine
⢠Place duplicated subroutines in a module
239. Section 17.3. Version Numbers
⢠Use 3-part version numbers
⢠But vstrings are broken
⢠Didnât get them right until 5.8.1
⢠Deprecating them for 5.10!
⢠Use the âversionâ module from the CPAN:
use version; our $VERSION = qv(â1.0.3â);
⢠Also supports âdevelopment versionsâ:
use version; our $VERSION = qv(â1.5_12â);
240. Section 17.4. Version Requirements
⢠Enforce version requirements programatically
⢠Enforce Perl version:â¨
use 5.008; # 5.8 or greater, only
⢠Enforce package versions:â¨
use List::Util 1.13 qw(max);
⢠Use âuse onlyâ for more precise control
⢠Get âonlyâ from the CPAN
241. Section 17.5. Exporting
⢠Export carefully
⢠Your default export list canât change in the future
⢠Might break something if new items added
⢠Where possible, only on request
⢠Flooding the namespace is counterproductive
⢠Especially with common names, like âfailâ or âdisplayâ
242. Section 17.6. Declarative Exporting
⢠Export declaratively
⢠Perl6::Export::Attrs module:â¨
package Test::Utils; use Perl6::Export::Attrs;â¨
sub ok :Export(:DEFAULT, :TEST, :PASS) { ... }â¨
use pass :Export(:TEST, :PASS) { ... }â¨
use fail :Export(:TEST) { ... }â¨
use skip :Export () { ... } # can leave () off
⢠Now @EXPORT will contain only âokâ (:DEFAULT)
⢠And @EXPORT_OK will contain all 4
⢠And the :TEST and :PASS groups will be set up:â¨
use Test::Utils qw(:PASS); # ok, pass
243. Section 17.7. InterfaceVariables
⢠Export subroutines, not data
⢠Yes, letâs create a module, but then reintroduce global
variables
⢠OK, thatâs a bad idea
⢠Variables have only get/set interface
⢠And very little checking (unless you âtieâ)
⢠Export subroutines to give more control
⢠And more ďŹexibility for the future
245. Section 17.9. The Standard Library
⢠Use core modules when possible
⢠See âperldoc perlmodlibâ
⢠Lots and lots of things
⢠The core gets bigger over time
⢠See Module::Corelist to know when
⢠Command line âcorelistâ
246. Section 17.10. CPAN
⢠Use CPAN modules where feasible
⢠Smarter people than you have hacked the code
⢠Or at least had more time than you have
⢠Reuse generally means higher quality code
⢠Also means communities can form
⢠Questions answered
⢠Pool of talent available
⢠Someone else might ďŹx bugs
⢠metacpan.org has the best interface
247. Chapter 18. Testing and Debugging
⢠We all write perfect software!
⢠In our dreams...
⢠Every code has one bug or more
⢠The trick is... where?
⢠Testing and debugging for the win
248. Section 18.1. Test Cases
⢠Write tests ďŹrst
⢠Turn your examples into tests
⢠Create the tests before coding
⢠Run the tests, which should fail
⢠Code (correctly!)
⢠Now the tests should succeed
⢠Tests are also documentation
⢠So, comment your tests
249. Section 18.2. Modular Testing
⢠Use Test::More
⢠Testing testing testing!
⢠Donât code your tests ad-hoc
⢠Use the proven Perl framework
⢠âperldoc Test::Tutorialâ
250. Section 18.3. Test Suites
⢠For local things, create additional Test::* mixins
⢠Use Test::Harness as a basis for additional tests
⢠New harness is being developed
⢠Separates reporting from detecting
251. Section 18.4. Failure
⢠Write test cases to make sure that failures actually fail
⢠This is psychologically hard sometimes
⢠Have to out-trick yourself
⢠Good task for pairing with someone else
252. Section 18.5. What to Test
⢠Test the likely and the unlikely
⢠Some ideas:
⢠Minimum and maximum, and near those
⢠Empty strings, multiline strings, control characters
⢠undef and lists of undef,â0 but trueâ
⢠Inputs that might never be entered
⢠Non-numeric data for numeric parameters
⢠Missing arguments, extra arguments
⢠Using the wrong version of a module
⢠And every bug youâve ever encountered
⢠The best testers have the most scars
253. Section 18.6. Debugging and Testing
⢠Add new test cases before debugging
⢠A bug report is a test case!
⢠Add it to your test suite
⢠(You do have a test suite, right?)
⢠Then debug.
⢠Youâll know the bug is gone when the test passes
⢠And youâll never accidentally reintroduce that bug!
254. Section 18.7. Strictures
⢠Use strict
⢠Barewords in the wrong place:â¨
my @months = (jan, feb, mar, apr, may, jun,â¨
jul, aug, sep, oct, nov, dec);
⢠Variables that are probably typos:â¨
my $bamm_bamm = 3; .... $bammbamm;
⢠Evil symbolic references:â¨
$data{fred} = âďŹintstoneâ;â¨
...â¨
$data{fred}{age} = 30;
⢠You just set $ďŹintstone{age} to 30!
255. Section 18.8. Warnings
⢠Use warnings
⢠âuse warningsâ catches most beginner mistakes
⢠Beware â-wâ on the command line
⢠Unless you want to debug someone elseâs mistakes when
you use a module
256. Section 18.9. Correctness
⢠Never assume that a warning-free compile implies
correctness
⢠Oh, if life were only that simple!
⢠You have to be more clever at debugging than you were
at coding
257. Section 18.10. Overriding Strictures
⢠Reduce warnings for troublesome spots
⢠Add âno warningsâ in a block:â¨
{â¨
no warnings âredeďŹneâ;â¨
...;â¨
}
⢠The block will narrow down the inďŹuence
⢠Note that this has lexical inďŹuence
⢠Not dynamic inďŹuence
258. Section 18.11. The Debugger
⢠Learn a subset of the debugger:
⢠Starting and exiting
⢠Setting breakpoints
⢠Setting watchpoints
⢠Step into, out of, around
⢠Examining variables
⢠Getting the methods of a class/instance
⢠Getting help
259. Section 18.12. Manual Debugging
⢠Used serialized warnings when debugging âmanuallyâ
⢠Reserve âwarnâ for âif debuggingâ
⢠You shouldnât be using warn for anything else
⢠Automatically goes to STDERR
⢠Or use Log::Log4Perl with debug levels
260. Section 18.13. Semi-Automatic Debugging
⢠Consider âsmart commentsâ rather than warn
⢠As in,âSmart::Commentsâ:â¨
use Smart::Comments;â¨
...â¨
for my $result (@some_messy_array) {â¨
### $resultâ¨
}
⢠Supports assertions too:â¨
### check: ref $resultâ¨
### require: $result->foo > 3
⢠No delivery penalty
⢠Just donât include Smart::Comments!
262. Section 19.1. Revision Control
⢠Use revision control
⢠Essential for team programming
⢠But even good for one person
⢠Great for sharing updates
⢠Helpful for âwhen did it breakâ
⢠And more importantly âwho broke itâ
⢠Also prevents potential loss from hardware failures and
human failures
263. Section 19.2. Other Languages
⢠Integrate non-Perl code with Inline:: modules
⢠Relatively simple
⢠Compared to raw XS codewriting
⢠Caches nicely
⢠Can be shipped pre-expanded with a distro
⢠Can be installed per-user as needed
264. Section 19.3. ConďŹguration Files
⢠Consider ConďŹg::Std
⢠Simple to use:â¨
use ConďŹg::Std;â¨
read_conďŹg â~/.demorcâ => my %conďŹg;â¨
$conďŹg{Interface}{Disclaimer} = âWhatever, dude!â;
⢠Allow user changes to be rewritten for the next run:â¨
write_conďŹg %conďŹg;
⢠Whitespace and comments are preserved!
⢠ConďŹg::General: all that and XML blocks, heredocs,
includes
266. Section 19.5. Ties
⢠Donât
⢠Fairly inefďŹcient
⢠Can be spooky to the naive
⢠Every tied operation can be replaced with an explicit
method call
267. Section 19.6. Cleverness
⢠Donât
⢠Example:â¨
my $max_result =â¨
[$result1=>$result2]->[$result2<=$result1];
⢠Can you spot the bug?
⢠Yeah, itâs min, not max
⢠Better:â¨
use List::Util qw(max);â¨
$max_result = max($result1, $result2);
268. Section 19.7. Encapsulated Cleverness
⢠if you must be clever, at least hide it well!
⢠Worked for the Wizard of Oz for many years
⢠âPay no attention to the man behind the curtain!â
⢠Easy-to-understand interfaces better than scary
comments
⢠Be clever, and hide it
269. Section 19.8. Benchmarking
⢠Donât optimize until you benchmark
⢠Get the code right ďŹrst
⢠Then make it go faster, if necessary
⢠Use the tools
⢠Benchmark
⢠Devel::DProf
⢠Devel::SmallProf
⢠Devel::NYTProf
270. Section 19.9. Memory
⢠Measure data before optimizing it
⢠Use Devel::Size for details:â¨
size(%hash) # measures overheadâ¨
total_size(%hash) # measures overhead + data
⢠Overhead is often surprising
271. Section 19.10. Caching
⢠Look for opportunities to use caches
⢠Subroutines that return the same result
⢠Example: SHA digest of data:â¨
BEGIN {â¨
my %cache;â¨
sub sha1 {â¨
my $input = shift;â¨
return $cache{$input} ||= do {â¨
... expensive calculation here ...â¨
};â¨
}â¨
}
272. Section 19.11. Memoization
⢠Automate subroutine caching via Memoize
⢠No thatâs not a typo
⢠No need to rewrite the same cache logic
⢠Simpler example:â¨
use Memoize;â¨
memoize(âsha1â);â¨
sub sha1 {â¨
expensive calculation hereâ¨
}
⢠Lots of options (deďŹning key, time-based cache)
273. Section 19.12. Caching for Optimization
⢠Benchmark any caching
⢠Cache is always a trade-off
⢠time vs space
⢠time to compute vs time to fetch/store cached value
⢠time to compute vs time to ďŹgure out cache is fresh
⢠Caching isnât necessarily a win
274. Section 19.13. ProďŹling
⢠Donât optimize apps: proďŹle them
⢠Find the hotspots that are slow, and ďŹx them
⢠Use Devel::DProf for subroutine-level visibilities
⢠Use Devel::SmallProf for statement-level
277. Use Perl::Critic
⢠Automatically test your code against various suggestions
made here
⢠Can be conďŹgured to require or ignore guidelines
⢠Consider it âlint for Perlâ
278. In summary
⢠Learn from the ones
who have the most scars
⢠Buy the book...
⢠Damian could use the
money!