Of course, each programmer has his own preferences regarding formatting, but there are some general principles that make your programs easy to read, understand, and maintain.
The main thing is that your programs should always run with the -w flag. If necessary, you can purposefully disable this action for specific sections of code through the no warnings or the $^W variable. Also, you should always run programs using use strict , or understand clearly why you are not doing this. The use sigtrap and use diagnosticsuse sigtrap can also be useful. ')
As for the code design aesthetics, the only thing Larry really cares about is that the closing curly bracket of a multi-line block must be aligned vertically with the keyword that starts the whole construction. In addition, he has other preferences that are not so serious:
Indents in 4 columns.
The opening brace, if possible, on the same line with the keyword, otherwise aligned with it vertically.
The space before the opening brace in a multi-line block.
A single-line block can be placed on a single line, including braces.
Do not write spaces before a semicolon.
The semicolon is omitted in “short” one-line blocks.
Spaces around most operators.
Spaces around "complex" constructions (inside curly brackets).
Blank lines between parts of code that perform different tasks.
Non-pressed else .
No spaces are written between the function name and the opening parenthesis.
Spaces after each comma.
Long lines break after operators (excluding and and or ).
After the last closing bracket in the line must be a space.
Vertically align similar elements.
Omit excessive punctuation if clarity does not suffer from this.
Larry has a rationale for all of these pieces, but he does not argue that everyone thinks the same way he does.
Here are a few other more significant clearance questions to think about:
If you CAN do something in a certain way, it does not mean that you MUST do this. Pearl is designed to give you several ways to do the same thing, try to choose from these methods more visual. For example, this:
open(FOO,$foo) || die"Can't open $foo: $!";
better than this:
die"Can't open $foo: $!"unlessopen(FOO,$foo);
because the second option hides the basic meaning of this expression in the condition. On the other hand,
print"Starting analysis\n"if $verbose;
better than
$verbose && print"Starting analysis\n";
because the point here is not whether the user typed -v or not.
Similarly, if the operator has arguments with default values, this does not mean that you need to use them. The default values ​​are for lazy system programmers writing disposable programs. If you want your program to be easy to read, consider using arguments.
Again, just because you CAN omit brackets in many places doesn’t mean that you should. Compare:
returnprintreversesort num values %array; returnprint(reverse(sort num (values(%array))));
If in doubt, put brackets. At the very least, this will allow some poor fellow to poke the % key in vi .
Even if you have no doubt, think about the mental balance of the person who will maintain the code after you, and who will probably put the brackets in the wrong place.
Do not make meaningless passes through the cycle from top to bottom, because Pearl provides the last operator, which allows you to exit in the middle. Just make a small “underreporting” to show it more clearly:
LINE: for (;;) { statements; last LINE if $foo; next LINE if /^#/; statements; }
Do not be afraid to use loop labels - they are there for convenience, as well as for interrupting multilevel loops. See the previous example.
Avoid using grep() , map() or `return quotes' in an empty context when you simply throw away the values ​​they return. All of these functions return values, so enable them. Alternatively, use the foreach() or the system() function.
For portability, if you use some functions that may not be implemented on some machines, test these constructs in eval to see the errors that occur. If you know in which version or in which patch the function is implemented, check $] ( $PERL_VERSION in the English module) to see if it is there. The Config module also allows you to find out the values ​​defined by the Configure program when installing Perl.
Choose memorable identifiers. If you can't remember what your reminder means, you have a problem.
If short identifiers like $gotit perfectly acceptable, then in long identifiers you should use underscores to separate words. It is usually much easier to read $var_names_like_this than $VarNamesLikeThis , especially for those for whom English is not native.
Package names have some exceptions to this rule. Pearl unofficially reserves lower-case module names for pragmas such as integer or strict . Other modules must begin with a capital letter and use mixed case, if possible without underscores, due to the limitations of primitive file systems, in which the names of files representing modules must fit in several bytes.
You may find it useful to use a register to indicate the scope or assignment of a variable. For example:
Names of functions and methods seem to work best in lower case. For example, $obj->as_string() .
You can use a leading underscore to indicate that this variable or function should not be used outside the package in which they are declared.
If you have a really tricked regular expression, use the /x modifier and add a few spaces to make the expression look not so scary. Do not use a slash as a delimiter if the regular expression itself contains slashes or backslashes.
Use the new operators and and or to get rid of too many brackets in list operators, as well as not to complicate reading with punctuation operators like && and || . Call your subroutines just as if they were functions or list operators to get rid of extra brackets and ampersands.
Use here-documents instead of re-writing print() .
Align similar elements vertically, especially in designs that are still too long to fit on one line.
Always check the return code of system calls. A good error message should be sent to STDERR and include an indication of which program caused the problem, which system call and arguments were executed with an error, and also (VERY IMPORTANT) should contain a standard system message about what went wrong not this way. Here is a simple but comprehensive example:
opendir(D, $dir) ordie"can't opendir $dir: $!";
Vertically align translated characters when it makes sense:
tr [abc] [xyz];
Think about reuse. Why spend your mind power on a one-time exhaust, if you can do something that will work again and again? Try to summarize your code. Try to write a module or class. Try to make your script cleaner with use strict and use warnings (or -w ). Try to share your code. Try to change your view of the world. Try ... oh well.
Try to document the code and use the Pod format on an ongoing basis. There are several general agreements here:
Use C<> for the names of functions, variables and modules (and generally everything that can be considered part of the code, such as file descriptors or special values). Note that function names are easier to read if they have brackets after the name, like this - function() .
Use B<> for command names such as cat or grep .
Use F<> or C<> for file names. F<> should be the only Pod code for file names, but most Pod converters will display it in italics, due to which paths in Unix and Windows containing forward and back slashes may look poorly readable and using C<> looks better.