1*0Sstevel@tonic-gate=head1 NAME 2*0Sstevel@tonic-gate 3*0Sstevel@tonic-gateperlstyle - Perl style guide 4*0Sstevel@tonic-gate 5*0Sstevel@tonic-gate=head1 DESCRIPTION 6*0Sstevel@tonic-gate 7*0Sstevel@tonic-gateEach programmer will, of course, have his or her own preferences in 8*0Sstevel@tonic-gateregards to formatting, but there are some general guidelines that will 9*0Sstevel@tonic-gatemake your programs easier to read, understand, and maintain. 10*0Sstevel@tonic-gate 11*0Sstevel@tonic-gateThe most important thing is to run your programs under the B<-w> 12*0Sstevel@tonic-gateflag at all times. You may turn it off explicitly for particular 13*0Sstevel@tonic-gateportions of code via the C<no warnings> pragma or the C<$^W> variable 14*0Sstevel@tonic-gateif you must. You should also always run under C<use strict> or know the 15*0Sstevel@tonic-gatereason why not. The C<use sigtrap> and even C<use diagnostics> pragmas 16*0Sstevel@tonic-gatemay also prove useful. 17*0Sstevel@tonic-gate 18*0Sstevel@tonic-gateRegarding aesthetics of code lay out, about the only thing Larry 19*0Sstevel@tonic-gatecares strongly about is that the closing curly bracket of 20*0Sstevel@tonic-gatea multi-line BLOCK should line up with the keyword that started the construct. 21*0Sstevel@tonic-gateBeyond that, he has other preferences that aren't so strong: 22*0Sstevel@tonic-gate 23*0Sstevel@tonic-gate=over 4 24*0Sstevel@tonic-gate 25*0Sstevel@tonic-gate=item * 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate4-column indent. 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate=item * 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gateOpening curly on same line as keyword, if possible, otherwise line up. 32*0Sstevel@tonic-gate 33*0Sstevel@tonic-gate=item * 34*0Sstevel@tonic-gate 35*0Sstevel@tonic-gateSpace before the opening curly of a multi-line BLOCK. 36*0Sstevel@tonic-gate 37*0Sstevel@tonic-gate=item * 38*0Sstevel@tonic-gate 39*0Sstevel@tonic-gateOne-line BLOCK may be put on one line, including curlies. 40*0Sstevel@tonic-gate 41*0Sstevel@tonic-gate=item * 42*0Sstevel@tonic-gate 43*0Sstevel@tonic-gateNo space before the semicolon. 44*0Sstevel@tonic-gate 45*0Sstevel@tonic-gate=item * 46*0Sstevel@tonic-gate 47*0Sstevel@tonic-gateSemicolon omitted in "short" one-line BLOCK. 48*0Sstevel@tonic-gate 49*0Sstevel@tonic-gate=item * 50*0Sstevel@tonic-gate 51*0Sstevel@tonic-gateSpace around most operators. 52*0Sstevel@tonic-gate 53*0Sstevel@tonic-gate=item * 54*0Sstevel@tonic-gate 55*0Sstevel@tonic-gateSpace around a "complex" subscript (inside brackets). 56*0Sstevel@tonic-gate 57*0Sstevel@tonic-gate=item * 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gateBlank lines between chunks that do different things. 60*0Sstevel@tonic-gate 61*0Sstevel@tonic-gate=item * 62*0Sstevel@tonic-gate 63*0Sstevel@tonic-gateUncuddled elses. 64*0Sstevel@tonic-gate 65*0Sstevel@tonic-gate=item * 66*0Sstevel@tonic-gate 67*0Sstevel@tonic-gateNo space between function name and its opening parenthesis. 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gate=item * 70*0Sstevel@tonic-gate 71*0Sstevel@tonic-gateSpace after each comma. 72*0Sstevel@tonic-gate 73*0Sstevel@tonic-gate=item * 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gateLong lines broken after an operator (except "and" and "or"). 76*0Sstevel@tonic-gate 77*0Sstevel@tonic-gate=item * 78*0Sstevel@tonic-gate 79*0Sstevel@tonic-gateSpace after last parenthesis matching on current line. 80*0Sstevel@tonic-gate 81*0Sstevel@tonic-gate=item * 82*0Sstevel@tonic-gate 83*0Sstevel@tonic-gateLine up corresponding items vertically. 84*0Sstevel@tonic-gate 85*0Sstevel@tonic-gate=item * 86*0Sstevel@tonic-gate 87*0Sstevel@tonic-gateOmit redundant punctuation as long as clarity doesn't suffer. 88*0Sstevel@tonic-gate 89*0Sstevel@tonic-gate=back 90*0Sstevel@tonic-gate 91*0Sstevel@tonic-gateLarry has his reasons for each of these things, but he doesn't claim that 92*0Sstevel@tonic-gateeveryone else's mind works the same as his does. 93*0Sstevel@tonic-gate 94*0Sstevel@tonic-gateHere are some other more substantive style issues to think about: 95*0Sstevel@tonic-gate 96*0Sstevel@tonic-gate=over 4 97*0Sstevel@tonic-gate 98*0Sstevel@tonic-gate=item * 99*0Sstevel@tonic-gate 100*0Sstevel@tonic-gateJust because you I<CAN> do something a particular way doesn't mean that 101*0Sstevel@tonic-gateyou I<SHOULD> do it that way. Perl is designed to give you several 102*0Sstevel@tonic-gateways to do anything, so consider picking the most readable one. For 103*0Sstevel@tonic-gateinstance 104*0Sstevel@tonic-gate 105*0Sstevel@tonic-gate open(FOO,$foo) || die "Can't open $foo: $!"; 106*0Sstevel@tonic-gate 107*0Sstevel@tonic-gateis better than 108*0Sstevel@tonic-gate 109*0Sstevel@tonic-gate die "Can't open $foo: $!" unless open(FOO,$foo); 110*0Sstevel@tonic-gate 111*0Sstevel@tonic-gatebecause the second way hides the main point of the statement in a 112*0Sstevel@tonic-gatemodifier. On the other hand 113*0Sstevel@tonic-gate 114*0Sstevel@tonic-gate print "Starting analysis\n" if $verbose; 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gateis better than 117*0Sstevel@tonic-gate 118*0Sstevel@tonic-gate $verbose && print "Starting analysis\n"; 119*0Sstevel@tonic-gate 120*0Sstevel@tonic-gatebecause the main point isn't whether the user typed B<-v> or not. 121*0Sstevel@tonic-gate 122*0Sstevel@tonic-gateSimilarly, just because an operator lets you assume default arguments 123*0Sstevel@tonic-gatedoesn't mean that you have to make use of the defaults. The defaults 124*0Sstevel@tonic-gateare there for lazy systems programmers writing one-shot programs. If 125*0Sstevel@tonic-gateyou want your program to be readable, consider supplying the argument. 126*0Sstevel@tonic-gate 127*0Sstevel@tonic-gateAlong the same lines, just because you I<CAN> omit parentheses in many 128*0Sstevel@tonic-gateplaces doesn't mean that you ought to: 129*0Sstevel@tonic-gate 130*0Sstevel@tonic-gate return print reverse sort num values %array; 131*0Sstevel@tonic-gate return print(reverse(sort num (values(%array)))); 132*0Sstevel@tonic-gate 133*0Sstevel@tonic-gateWhen in doubt, parenthesize. At the very least it will let some poor 134*0Sstevel@tonic-gateschmuck bounce on the % key in B<vi>. 135*0Sstevel@tonic-gate 136*0Sstevel@tonic-gateEven if you aren't in doubt, consider the mental welfare of the person 137*0Sstevel@tonic-gatewho has to maintain the code after you, and who will probably put 138*0Sstevel@tonic-gateparentheses in the wrong place. 139*0Sstevel@tonic-gate 140*0Sstevel@tonic-gate=item * 141*0Sstevel@tonic-gate 142*0Sstevel@tonic-gateDon't go through silly contortions to exit a loop at the top or the 143*0Sstevel@tonic-gatebottom, when Perl provides the C<last> operator so you can exit in 144*0Sstevel@tonic-gatethe middle. Just "outdent" it a little to make it more visible: 145*0Sstevel@tonic-gate 146*0Sstevel@tonic-gate LINE: 147*0Sstevel@tonic-gate for (;;) { 148*0Sstevel@tonic-gate statements; 149*0Sstevel@tonic-gate last LINE if $foo; 150*0Sstevel@tonic-gate next LINE if /^#/; 151*0Sstevel@tonic-gate statements; 152*0Sstevel@tonic-gate } 153*0Sstevel@tonic-gate 154*0Sstevel@tonic-gate=item * 155*0Sstevel@tonic-gate 156*0Sstevel@tonic-gateDon't be afraid to use loop labels--they're there to enhance 157*0Sstevel@tonic-gatereadability as well as to allow multilevel loop breaks. See the 158*0Sstevel@tonic-gateprevious example. 159*0Sstevel@tonic-gate 160*0Sstevel@tonic-gate=item * 161*0Sstevel@tonic-gate 162*0Sstevel@tonic-gateAvoid using grep() (or map()) or `backticks` in a void context, that is, 163*0Sstevel@tonic-gatewhen you just throw away their return values. Those functions all 164*0Sstevel@tonic-gatehave return values, so use them. Otherwise use a foreach() loop or 165*0Sstevel@tonic-gatethe system() function instead. 166*0Sstevel@tonic-gate 167*0Sstevel@tonic-gate=item * 168*0Sstevel@tonic-gate 169*0Sstevel@tonic-gateFor portability, when using features that may not be implemented on 170*0Sstevel@tonic-gateevery machine, test the construct in an eval to see if it fails. If 171*0Sstevel@tonic-gateyou know what version or patchlevel a particular feature was 172*0Sstevel@tonic-gateimplemented, you can test C<$]> (C<$PERL_VERSION> in C<English>) to see if it 173*0Sstevel@tonic-gatewill be there. The C<Config> module will also let you interrogate values 174*0Sstevel@tonic-gatedetermined by the B<Configure> program when Perl was installed. 175*0Sstevel@tonic-gate 176*0Sstevel@tonic-gate=item * 177*0Sstevel@tonic-gate 178*0Sstevel@tonic-gateChoose mnemonic identifiers. If you can't remember what mnemonic means, 179*0Sstevel@tonic-gateyou've got a problem. 180*0Sstevel@tonic-gate 181*0Sstevel@tonic-gate=item * 182*0Sstevel@tonic-gate 183*0Sstevel@tonic-gateWhile short identifiers like $gotit are probably ok, use underscores to 184*0Sstevel@tonic-gateseparate words. It is generally easier to read $var_names_like_this than 185*0Sstevel@tonic-gate$VarNamesLikeThis, especially for non-native speakers of English. It's 186*0Sstevel@tonic-gatealso a simple rule that works consistently with VAR_NAMES_LIKE_THIS. 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gatePackage names are sometimes an exception to this rule. Perl informally 189*0Sstevel@tonic-gatereserves lowercase module names for "pragma" modules like C<integer> and 190*0Sstevel@tonic-gateC<strict>. Other modules should begin with a capital letter and use mixed 191*0Sstevel@tonic-gatecase, but probably without underscores due to limitations in primitive 192*0Sstevel@tonic-gatefile systems' representations of module names as files that must fit into a 193*0Sstevel@tonic-gatefew sparse bytes. 194*0Sstevel@tonic-gate 195*0Sstevel@tonic-gate=item * 196*0Sstevel@tonic-gate 197*0Sstevel@tonic-gateYou may find it helpful to use letter case to indicate the scope 198*0Sstevel@tonic-gateor nature of a variable. For example: 199*0Sstevel@tonic-gate 200*0Sstevel@tonic-gate $ALL_CAPS_HERE constants only (beware clashes with perl vars!) 201*0Sstevel@tonic-gate $Some_Caps_Here package-wide global/static 202*0Sstevel@tonic-gate $no_caps_here function scope my() or local() variables 203*0Sstevel@tonic-gate 204*0Sstevel@tonic-gateFunction and method names seem to work best as all lowercase. 205*0Sstevel@tonic-gateE.g., $obj-E<gt>as_string(). 206*0Sstevel@tonic-gate 207*0Sstevel@tonic-gateYou can use a leading underscore to indicate that a variable or 208*0Sstevel@tonic-gatefunction should not be used outside the package that defined it. 209*0Sstevel@tonic-gate 210*0Sstevel@tonic-gate=item * 211*0Sstevel@tonic-gate 212*0Sstevel@tonic-gateIf you have a really hairy regular expression, use the C</x> modifier and 213*0Sstevel@tonic-gateput in some whitespace to make it look a little less like line noise. 214*0Sstevel@tonic-gateDon't use slash as a delimiter when your regexp has slashes or backslashes. 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gate=item * 217*0Sstevel@tonic-gate 218*0Sstevel@tonic-gateUse the new "and" and "or" operators to avoid having to parenthesize 219*0Sstevel@tonic-gatelist operators so much, and to reduce the incidence of punctuation 220*0Sstevel@tonic-gateoperators like C<&&> and C<||>. Call your subroutines as if they were 221*0Sstevel@tonic-gatefunctions or list operators to avoid excessive ampersands and parentheses. 222*0Sstevel@tonic-gate 223*0Sstevel@tonic-gate=item * 224*0Sstevel@tonic-gate 225*0Sstevel@tonic-gateUse here documents instead of repeated print() statements. 226*0Sstevel@tonic-gate 227*0Sstevel@tonic-gate=item * 228*0Sstevel@tonic-gate 229*0Sstevel@tonic-gateLine up corresponding things vertically, especially if it'd be too long 230*0Sstevel@tonic-gateto fit on one line anyway. 231*0Sstevel@tonic-gate 232*0Sstevel@tonic-gate $IDX = $ST_MTIME; 233*0Sstevel@tonic-gate $IDX = $ST_ATIME if $opt_u; 234*0Sstevel@tonic-gate $IDX = $ST_CTIME if $opt_c; 235*0Sstevel@tonic-gate $IDX = $ST_SIZE if $opt_s; 236*0Sstevel@tonic-gate 237*0Sstevel@tonic-gate mkdir $tmpdir, 0700 or die "can't mkdir $tmpdir: $!"; 238*0Sstevel@tonic-gate chdir($tmpdir) or die "can't chdir $tmpdir: $!"; 239*0Sstevel@tonic-gate mkdir 'tmp', 0777 or die "can't mkdir $tmpdir/tmp: $!"; 240*0Sstevel@tonic-gate 241*0Sstevel@tonic-gate=item * 242*0Sstevel@tonic-gate 243*0Sstevel@tonic-gateAlways check the return codes of system calls. Good error messages should 244*0Sstevel@tonic-gatego to STDERR, include which program caused the problem, what the failed 245*0Sstevel@tonic-gatesystem call and arguments were, and (VERY IMPORTANT) should contain the 246*0Sstevel@tonic-gatestandard system error message for what went wrong. Here's a simple but 247*0Sstevel@tonic-gatesufficient example: 248*0Sstevel@tonic-gate 249*0Sstevel@tonic-gate opendir(D, $dir) or die "can't opendir $dir: $!"; 250*0Sstevel@tonic-gate 251*0Sstevel@tonic-gate=item * 252*0Sstevel@tonic-gate 253*0Sstevel@tonic-gateLine up your transliterations when it makes sense: 254*0Sstevel@tonic-gate 255*0Sstevel@tonic-gate tr [abc] 256*0Sstevel@tonic-gate [xyz]; 257*0Sstevel@tonic-gate 258*0Sstevel@tonic-gate=item * 259*0Sstevel@tonic-gate 260*0Sstevel@tonic-gateThink about reusability. Why waste brainpower on a one-shot when you 261*0Sstevel@tonic-gatemight want to do something like it again? Consider generalizing your 262*0Sstevel@tonic-gatecode. Consider writing a module or object class. Consider making your 263*0Sstevel@tonic-gatecode run cleanly with C<use strict> and C<use warnings> (or B<-w>) in 264*0Sstevel@tonic-gateeffect. Consider giving away your code. Consider changing your whole 265*0Sstevel@tonic-gateworld view. Consider... oh, never mind. 266*0Sstevel@tonic-gate 267*0Sstevel@tonic-gate=item * 268*0Sstevel@tonic-gate 269*0Sstevel@tonic-gateBe consistent. 270*0Sstevel@tonic-gate 271*0Sstevel@tonic-gate=item * 272*0Sstevel@tonic-gate 273*0Sstevel@tonic-gateBe nice. 274*0Sstevel@tonic-gate 275*0Sstevel@tonic-gate=back 276