diff options
Diffstat (limited to 'upstream/fedora-rawhide/man1/perlstyle.1')
-rw-r--r-- | upstream/fedora-rawhide/man1/perlstyle.1 | 312 |
1 files changed, 312 insertions, 0 deletions
diff --git a/upstream/fedora-rawhide/man1/perlstyle.1 b/upstream/fedora-rawhide/man1/perlstyle.1 new file mode 100644 index 00000000..35ac98c0 --- /dev/null +++ b/upstream/fedora-rawhide/man1/perlstyle.1 @@ -0,0 +1,312 @@ +.\" -*- mode: troff; coding: utf-8 -*- +.\" Automatically generated by Pod::Man 5.01 (Pod::Simple 3.43) +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. +.ie n \{\ +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds C` +. ds C' +'br\} +.\" +.\" Escape single quotes in literal strings from groff's Unicode transform. +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" +.\" If the F register is >0, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.\" +.\" Avoid warning from groff about undefined register 'F'. +.de IX +.. +.nr rF 0 +.if \n(.g .if rF .nr rF 1 +.if (\n(rF:(\n(.g==0)) \{\ +. if \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. if !\nF==2 \{\ +. nr % 0 +. nr F 2 +. \} +. \} +.\} +.rr rF +.\" ======================================================================== +.\" +.IX Title "PERLSTYLE 1" +.TH PERLSTYLE 1 2024-01-25 "perl v5.38.2" "Perl Programmers Reference Guide" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.if n .ad l +.nh +.SH NAME +perlstyle \- Perl style guide +.SH DESCRIPTION +.IX Header "DESCRIPTION" +Each programmer will, of course, have his or her own preferences in +regards to formatting, but there are some general guidelines that will +make your programs easier to read, understand, and maintain. +.PP +The most important thing is to use strict and warnings in all your +code or know the reason why not to. You may turn them off explicitly for +particular portions of code via \f(CW\*(C`no warnings\*(C'\fR or \f(CW\*(C`no strict\*(C'\fR, and this +can be limited to the specific warnings or strict features you wish to +disable. The \fB\-w\fR flag and \f(CW$^W\fR variable should not be used for this +purpose since they can affect code you use but did not write, such as +modules from core or CPAN. +.PP +A concise way to arrange for this is to use the +\&\f(CW\*(C`use VERSION\*(C'\fR syntax, requesting a version 5.36 +or above, which will enable both the \f(CW\*(C`strict\*(C'\fR and \f(CW\*(C`warnings\*(C'\fR pragmata (as +well as several other useful named features). +.PP +.Vb 1 +\& use v5.36; +.Ve +.PP +Regarding aesthetics of code layout, about the only thing Larry +cares strongly about is that the closing curly bracket of +a multi-line BLOCK should line up with the keyword that started the construct. +Beyond that, he has other preferences that aren't so strong: +.IP \(bu 4 +4\-column indent. +.IP \(bu 4 +Opening curly on same line as keyword, if possible, otherwise line up. +.IP \(bu 4 +Space before the opening curly of a multi-line BLOCK. +.IP \(bu 4 +One-line BLOCK may be put on one line, including curlies. +.IP \(bu 4 +No space before the semicolon. +.IP \(bu 4 +Semicolon omitted in "short" one-line BLOCK. +.IP \(bu 4 +Space around most operators. +.IP \(bu 4 +Space around a "complex" subscript (inside brackets). +.IP \(bu 4 +Blank lines between chunks that do different things. +.IP \(bu 4 +Uncuddled elses. +.IP \(bu 4 +No space between function name and its opening parenthesis. +.IP \(bu 4 +Space after each comma. +.IP \(bu 4 +Long lines broken after an operator (except \f(CW\*(C`and\*(C'\fR and \f(CW\*(C`or\*(C'\fR). +.IP \(bu 4 +Space after last parenthesis matching on current line. +.IP \(bu 4 +Line up corresponding items vertically. +.IP \(bu 4 +Omit redundant punctuation as long as clarity doesn't suffer. +.PP +Larry has his reasons for each of these things, but he doesn't claim that +everyone else's mind works the same as his does. +.PP +Here are some other more substantive style issues to think about: +.IP \(bu 4 +Just because you \fICAN\fR do something a particular way doesn't mean that +you \fISHOULD\fR do it that way. Perl is designed to give you several +ways to do anything, so consider picking the most readable one. For +instance +.Sp +.Vb 1 +\& open(my $fh, \*(Aq<\*(Aq, $foo) || die "Can\*(Aqt open $foo: $!"; +.Ve +.Sp +is better than +.Sp +.Vb 1 +\& die "Can\*(Aqt open $foo: $!" unless open(my $fh, \*(Aq<\*(Aq, $foo); +.Ve +.Sp +because the second way hides the main point of the statement in a +modifier. On the other hand +.Sp +.Vb 1 +\& print "Starting analysis\en" if $verbose; +.Ve +.Sp +is better than +.Sp +.Vb 1 +\& $verbose && print "Starting analysis\en"; +.Ve +.Sp +because the main point isn't whether the user typed \fB\-v\fR or not. +.Sp +Similarly, just because an operator lets you assume default arguments +doesn't mean that you have to make use of the defaults. The defaults +are there for lazy systems programmers writing one-shot programs. If +you want your program to be readable, consider supplying the argument. +.Sp +Along the same lines, just because you \fICAN\fR omit parentheses in many +places doesn't mean that you ought to: +.Sp +.Vb 2 +\& return print reverse sort num values %array; +\& return print(reverse(sort num (values(%array)))); +.Ve +.Sp +When in doubt, parenthesize. At the very least it will let some poor +schmuck bounce on the % key in \fBvi\fR. +.Sp +Even if you aren't in doubt, consider the mental welfare of the person +who has to maintain the code after you, and who will probably put +parentheses in the wrong place. +.IP \(bu 4 +Don't go through silly contortions to exit a loop at the top or the +bottom, when Perl provides the \f(CW\*(C`last\*(C'\fR operator so you can exit in +the middle. Just "outdent" it a little to make it more visible: +.Sp +.Vb 7 +\& LINE: +\& for (;;) { +\& statements; +\& last LINE if $foo; +\& next LINE if /^#/; +\& statements; +\& } +.Ve +.IP \(bu 4 +Don't be afraid to use loop labels\-\-they're there to enhance +readability as well as to allow multilevel loop breaks. See the +previous example. +.IP \(bu 4 +Avoid using \f(CWgrep()\fR (or \f(CWmap()\fR) or `backticks` in a void context, that is, +when you just throw away their return values. Those functions all +have return values, so use them. Otherwise use a \f(CWforeach()\fR loop or +the \f(CWsystem()\fR function instead. +.IP \(bu 4 +For portability, when using features that may not be implemented on +every machine, test the construct in an eval to see if it fails. If +you know what version or patchlevel a particular feature was +implemented, you can test \f(CW$]\fR (\f(CW$PERL_VERSION\fR in \f(CW\*(C`English\*(C'\fR) to see if it +will be there. The \f(CW\*(C`Config\*(C'\fR module will also let you interrogate values +determined by the \fBConfigure\fR program when Perl was installed. +.IP \(bu 4 +Choose mnemonic identifiers. If you can't remember what mnemonic means, +you've got a problem. +.IP \(bu 4 +While short identifiers like \f(CW$gotit\fR are probably ok, use underscores to +separate words in longer identifiers. It is generally easier to read +\&\f(CW$var_names_like_this\fR than \f(CW$VarNamesLikeThis\fR, especially for +non-native speakers of English. It's also a simple rule that works +consistently with \f(CW\*(C`VAR_NAMES_LIKE_THIS\*(C'\fR. +.Sp +Package names are sometimes an exception to this rule. Perl informally +reserves lowercase module names for "pragma" modules like \f(CW\*(C`integer\*(C'\fR and +\&\f(CW\*(C`strict\*(C'\fR. Other modules should begin with a capital letter and use mixed +case, but probably without underscores due to limitations in primitive +file systems' representations of module names as files that must fit into a +few sparse bytes. +.IP \(bu 4 +You may find it helpful to use letter case to indicate the scope +or nature of a variable. For example: +.Sp +.Vb 3 +\& $ALL_CAPS_HERE constants only (beware clashes with perl vars!) +\& $Some_Caps_Here package\-wide global/static +\& $no_caps_here function scope my() or local() variables +.Ve +.Sp +Function and method names seem to work best as all lowercase. +E.g., \f(CW\*(C`$obj\->as_string()\*(C'\fR. +.Sp +You can use a leading underscore to indicate that a variable or +function should not be used outside the package that defined it. +.IP \(bu 4 +If you have a really hairy regular expression, use the \f(CW\*(C`/x\*(C'\fR or \f(CW\*(C`/xx\*(C'\fR +modifiers and put in some whitespace to make it look a little less like +line noise. +Don't use slash as a delimiter when your regexp has slashes or backslashes. +.IP \(bu 4 +Use the \f(CW\*(C`and\*(C'\fR and \f(CW\*(C`or\*(C'\fR operators to avoid having to parenthesize +list operators so much, and to reduce the incidence of punctuation +operators like \f(CW\*(C`&&\*(C'\fR and \f(CW\*(C`||\*(C'\fR. Call your subroutines as if they were +functions or list operators to avoid excessive ampersands and parentheses. +.IP \(bu 4 +Use here documents instead of repeated \f(CWprint()\fR statements. +.IP \(bu 4 +Line up corresponding things vertically, especially if it'd be too long +to fit on one line anyway. +.Sp +.Vb 4 +\& $IDX = $ST_MTIME; +\& $IDX = $ST_ATIME if $opt_u; +\& $IDX = $ST_CTIME if $opt_c; +\& $IDX = $ST_SIZE if $opt_s; +\& +\& mkdir $tmpdir, 0700 or die "can\*(Aqt mkdir $tmpdir: $!"; +\& chdir($tmpdir) or die "can\*(Aqt chdir $tmpdir: $!"; +\& mkdir \*(Aqtmp\*(Aq, 0777 or die "can\*(Aqt mkdir $tmpdir/tmp: $!"; +.Ve +.IP \(bu 4 +Always check the return codes of system calls. Good error messages should +go to \f(CW\*(C`STDERR\*(C'\fR, include which program caused the problem, what the failed +system call and arguments were, and (VERY IMPORTANT) should contain the +standard system error message for what went wrong. Here's a simple but +sufficient example: +.Sp +.Vb 1 +\& opendir(my $dh, $dir) or die "can\*(Aqt opendir $dir: $!"; +.Ve +.IP \(bu 4 +Line up your transliterations when it makes sense: +.Sp +.Vb 2 +\& tr [abc] +\& [xyz]; +.Ve +.IP \(bu 4 +Think about reusability. Why waste brainpower on a one-shot when you +might want to do something like it again? Consider generalizing your +code. Consider writing a module or object class. Consider making your +code run cleanly with \f(CW\*(C`use strict\*(C'\fR and \f(CW\*(C`use warnings\*(C'\fR in +effect. Consider giving away your code. Consider changing your whole +world view. Consider... oh, never mind. +.IP \(bu 4 +Try to document your code and use Pod formatting in a consistent way. Here +are commonly expected conventions: +.RS 4 +.IP \(bu 4 +use \f(CW\*(C`C<>\*(C'\fR for function, variable and module names (and more +generally anything that can be considered part of code, like filehandles +or specific values). Note that function names are considered more readable +with parentheses after their name, that is \f(CWfunction()\fR. +.IP \(bu 4 +use \f(CW\*(C`B<>\*(C'\fR for commands names like \fBcat\fR or \fBgrep\fR. +.IP \(bu 4 +use \f(CW\*(C`F<>\*(C'\fR or \f(CW\*(C`C<>\*(C'\fR for file names. \f(CW\*(C`F<>\*(C'\fR should +be the only Pod code for file names, but as most Pod formatters render it +as italic, Unix and Windows paths with their slashes and backslashes may +be less readable, and better rendered with \f(CW\*(C`C<>\*(C'\fR. +.RE +.RS 4 +.RE +.IP \(bu 4 +Be consistent. +.IP \(bu 4 +Be nice. |