perltrap - Perl traps for the unwary
The biggest trap of all is forgetting to use warnings
or use the -w switch; see warnings and perlrun.
The second biggest trap is not making your entire program runnable under use strict
.
The third biggest trap is not reading the list of changes in this version of Perl; see perldelta.
Accustomed awk users should take special note of the following:
-n
or -p
.use English;
allows you to refer to special variables (like $/
) with names (like $RS), as though they were in awk; see perlvar for details.
if
s and while
s.$,
and $\
. You can set $OFS and $ORS if you're using the English module./pat/ /pat/
unparsable, because the third slash would be interpreted as a division operator--the tokenizer is in fact slightly context sensitive for operators like "/", "?", and ">". And in fact, "." itself can be the beginning of a number.)next
, exit
, and continue
keywords work differently.Awk Perl ARGC scalar @ARGV (compare with $#ARGV) ARGV[0] $0 FILENAME $ARGV FNR $. - something FS (whatever you like) NF $#Fld, or some such NR $. OFMT $# OFS $, ORS $\ RLENGTH length($&) RS $/ RSTART length($`) SUBSEP $;
Cerebral C and C++ programmers should take note of the following:
if
's and while
's.elsif
rather than else if
.break
and continue
keywords from C become in Perl last
and next
, respectively. Unlike in C, these do not work within a do { } while
construct. See "Loop Control" in perlsyn.given
/when
and only available in perl 5.10 or newer. See "Switch Statements" in perlsyn.ARGV
must be capitalized. $ARGV[0]
is C's argv[1]
, and argv[0]
ends up in $0
.kill -l
to find their names on your system.Judicious JavaScript programmers should take note of the following:
+
is always addition. $string1 + $string2
converts both strings to numbers and then adds them. To concatenate two strings, use the .
operator.+
unary operator doesn't do anything in Perl. It exists to avoid syntactic ambiguities.for...in
, Perl's for
(also spelled foreach
) does not allow the left-hand side to be an arbitrary expression. It must be a variable:
for my $variable (keys %hash) { ... }
Furthermore, don't forget the keys
in there, as foreach my $kv (%hash) {}
iterates over the keys and values, and is generally not useful ($kv would be a key, then a value, and so on).
foreach my $i (0 .. $#array) {}
. foreach my $v (@array) {}
iterates over the values.if
, while
, foreach
, etc.else if
is spelled elsif
.? :
has higher precedence than assignment. In JavaScript, one can write:
condition ? do_something() : variable = 3
and the variable is only assigned if the condition is false. In Perl, you need parentheses:
$condition ? do_something() : ($variable = 3);
Or just use if
.
my
only affect code after the declaration. You cannot write $x = 1; my $x;
and expect the first assignment to affect the same variable. It will instead assign to an $x
declared previously in an outer scope, or to a global variable.
Note also that the variable is not visible until the following statement. This means that in my $x = 1 + $x
the second $x refers to one declared previously.
my
variables are scoped to the current block, not to the current function. If you write {my $x;} $x;
, the second $x
does not refer to the one declared inside the block.with(object) { method() }
is for
, which can alias $_
to the object:
for ($object) { $_->method; }
this
value.Seasoned sed programmers should take note of the following:
-n
or -p
....
, rather than comma.Sharp shell programmers should take note of the following:
BEGIN
blocks, which execute at compile time).test
uses "=", "!=", "<" etc for string comparisons and "-eq", "-ne", "-lt" etc for numeric comparisons. This is the reverse of Perl, which uses eq
, ne
, lt
for string comparisons, and ==
, !=
<
etc for numeric comparisons.Practicing Perl Programmers should take note of the following:
while (<FH>) { } while (defined($_ = <FH>)) { }.. <FH>; # data discarded!
=
when you need =~
; these two constructs are quite different:
$x = /foo/; $x =~ /foo/;
do {}
construct isn't a real loop that you can use loop control on.my()
for local variables whenever you can get away with it (but see perlform 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.As always, if any of these are ever officially declared as bugs, they'll be fixed and removed.