О КОПИРАЙТАХ |
Вся предоставленная на этом сервере информация собрана нами из разных источников. Если Вам кажется, что публикация каких-то документов нарушает чьи-либо авторские права, сообщите нам об этом. |
|
|
|
|
Previous | Next
The biggest goof of all is forgetting to use the -w switch, which points out many errors. The second
biggest goof is not using use strict when it's appropriate.
Apart from those, there are certain traps that almost everyone falls into, and
other traps you'll fall into only if you come from a particular culture. We've
separated these out in the following sections.
- Putting a comma after the filehandle in a print statement.
Although it looks extremely regular and pretty to say:
print STDOUT, "goodbye", $adj, "world!\n"; # WRONG
this is nonetheless incorrect, because of that first comma. What you
want instead is:
print STDOUT "goodbye", $adj, "world!\n"; # ok
The syntax is this way so that you can say:
print $filehandle "goodbye", $adj, "world!\n";
where $filehandle is a scalar holding the name of a filehandle at
run-time. This is distinct from:
print $notafilehandle, "goodbye", $adj, "world!\n";
where $notafilehandle is simply a string that is added to the list
of things to be printed. See Indirect Object in the glossary.
- Using == instead of eq and != instead of ne. The == and
!= operators are
numeric tests. The other two are
string tests. The strings
"123" and "123.00" are
equal as numbers, but not equal as strings. Also, any non-numeric
string is numerically equal to zero. Unless you are dealing with
numbers, you almost always want the string comparison operators
instead.
-
Forgetting the trailing semicolon. Every statement in
Perl is terminated by a semicolon or the end of a block. Newlines
aren't statement terminators as they are in awk
or Python.
- Forgetting that a BLOCK requires braces. Naked
statements are not BLOCKs. If you are creating a
control structure such as a while or an
if that requires one or more
BLOCKs, you must use braces
around each BLOCK.
- Not saving $1, $2, and so on, across regular expressions.
Remember that every new m/atch/ or
s/ubsti/tute/ will set (or clear, or mangle) your
$1, $2 . . . variables, as well as $`, $', and
$&. One way to save them right
away is to evaluate the match within a list context, as in:
($one,$two) = /(\w+) (\w+)/;
- Not realizing that a local also changes
the variable's value within other subroutines called within the scope
of the local. It's easy to forget that local is a run-time statement that does dynamic
scoping, because there's no equivalent in languages like C. See
local in Chapter 3, Functions.
Usually you wanted a my anyway.
- Losing track of brace pairings.
A good text editor will help you find the pairs. Get one.
- Using loop control statements in do {} while.
Although the braces in this control structure look suspiciously
like part of a loop BLOCK, they aren't.
- Saying @foo[1] when you mean $foo[1].
The @foo[1] reference is an array slice, and means an
array consisting of the single element $foo[1].
Sometimes, this doesn't make any difference, as in:
print "the answer is @foo[1]\n";
but it makes a big difference for things like:
@foo[1] = <STDIN>;
which will slurp up all the rest of STDIN,
assign the first line to
$foo[1], and discard everything else. This is probably not what you
intended. Get into the habit of thinking that $ means a single
value, while @ means a list of values, and you'll do okay.
- Forgetting to select the right filehandle before setting $^, $~, or
$|. These variables depend on the
currently selected filehandle, as determined by
select(FILEHANDLE).
The initial filehandle so selected is STDOUT. You
should really be using the filehandle methods from the FileHandle
module instead. See Chapter 7, The Standard Perl Library.
Practicing Perl Programmers should take note of the following:
- Remember that many operations behave differently in a list context
than they do in a scalar one. Chapter 3, Functions has all the details.
- Avoid barewords if you can, especially all lowercase ones.
You can't tell just by looking at it whether a word is
a function or a bareword string. By using quotes on strings and
parentheses around function call arguments, you won't ever get them confused.
In fact, the pragma use strict at the beginning of your program
makes barewords a compile-time error--probably a good thing.
- You can't tell just by looking which built-in functions are unary
operators (like chop and
chdir), which are list operators
(like print and unlink),
and which are argumentless (like time).
You'll want to learn them from Chapter 2, The Gory Details. Note also
that user-defined subroutines are by default list operators, but can
be declared as unary operators with a prototype of ($).
- People have a hard time remembering that some functions default to
$_, or @ARGV, or whatever, while others do not. Take
the time to learn which are which, or avoid default arguments.
- <FH> is not the
name of a filehandle, but an angle operator that does a line-input
operation on the handle. This confusion usually manifests itself when
people try to print to the angle
operator:
print <FH> "hi"; # WRONG, omit angles
- Remember also that data read by the angle operator is assigned to
$_ only when the file read is the sole
condition in a while loop:
while (<FH>) { }
while ($_ = <FH>) { }..
<FH>; # data discarded!
- Remember not to use = when you need =~;
the two constructs are quite different:
$x = /foo/; # searches $_, puts result in $x
$x =~ /foo/; # searches $x, discards result
- Use my for local variables whenever you can get away with
it (but see "Formats" in Chapter 2, The Gory Details for where you can't).
Using local actually gives a local value to a global
variable, which leaves you open to unforeseen side effects
of dynamic scoping.
- Don't localize a module's exported variables. If you localize an
exported variable, its exported value will not change. The local name
becomes an alias to a new value but the external name is still an alias
for the original.
Accustomed awk users should take special note of the following:
- The English module, loaded via
use English;
allows you to refer to special variables (like $RS) using
their awk names; see the end of Chapter 2, The Gory Details for details.
- Semicolons are required after all simple statements in Perl (except
at the end of a block). Newline is not a statement delimiter.
- Curlies are required on if and while blocks.
- Variables begin with $ or @ in Perl.
- Arrays index from 0, as do string positions in substr and
index.
- You have to decide whether your array has numeric or string indices.
- You have to decide whether you want numeric or string comparisons.
- Hash values do not spring into existence upon reference.
- Reading an input line does not split it for you. You get to split it
yourself to an array. And the split operator has different
arguments than you might guess.
- The current input line is normally in $_, not $0. It
generally does not have the newline stripped. ($0 is the name of the program executed.) See
Chapter 2, The Gory Details.
-
$1, $2, and so on, do not refer to fields--they
refer to substrings matched by the last pattern match.
-
The print operator
does not add field and record separators unless you set $, and $\.
($OFS and $ORS if you're using
English.)
-
You must open your
files before you print to them.
- The range operator is .. rather than comma. The comma operator works (more or less) as in does C.
-
The match binding operator is
=~, not ~.
(~ is the 1's complement operator, as in C.)
-
The exponentiation operator is
**, not ^.
^ is the bitwise XOR operator, as in C. (You
know, one could get the feeling that awk is
basically incompatible with C.)
-
The concatenation operator is dot
(.), not "nothing". (Using "nothing" as an
operator would render /pat/ /pat/ unparsable, since
the third slash would be interpreted as a division operator--the
tokener is in fact slightly context sensitive for operators like
/, ?, and
<. And, in fact, a dot itself can be the
beginning of a number.)
- The next, exit,
and continue
keywords work differently.
- The following variables work differently:
|