=head1 DESCRIPTION
-The biggest trap of all is forgetting to use the B<-w> switch; see
-L<perlrun>. The second biggest trap is not making your entire program
-runnable under C<use strict>. The third biggest trap is not reading
-the list of changes in this version of Perl; see L<perldelta>.
+The biggest trap of all is forgetting to C<use warnings> or use the B<-w>
+switch; see L<perllexwarn> and L<perlrun>. The second biggest trap is not
+making your entire program runnable under C<use strict>. The third biggest
+trap is not reading the list of changes in this version of Perl; see
+L<perldelta>.
=head2 Awk Traps
The following variables work differently:
Awk Perl
- ARGC $#ARGV or scalar @ARGV
+ ARGC scalar @ARGV (compare with $#ARGV)
ARGV[0] $0
FILENAME $ARGV
FNR $. - something
=item *
System calls such as link(), unlink(), rename(), etc. return nonzero for
-success, not 0.
+success, not 0. (system(), however, returns zero for success.)
=item *
You cannot discern from mere inspection which builtins
are unary operators (like chop() and chdir())
and which are list operators (like print() and unlink()).
-(User-defined subroutines can be B<only> list operators, never
-unary ones.) See L<perlop>.
+(Unless prototyped, user-defined subroutines can B<only> be list
+operators, never unary ones.) See L<perlop> and L<perlsub>.
=item *
}
# perl4 prints: Here I is!
- # perl5 dumps core (SEGV)
+ # perl5 errors: Can't "goto" into the middle of a foreach loop
=item * Discontinuance
String interpolation of the C<$#array> construct differs when braces
are to used around the name.
- @ = (1..3);
+ @a = (1..3);
print "${#a}";
# perl4 prints: 2
Assigning C<undef> to a glob has no effect in Perl 5. In Perl 4
it undefines the associated scalar (but may have other side effects
-including SEGVs).
+including SEGVs). Perl 5 will also warn if C<undef> is assigned to a
+typeglob. (Note that assigning C<undef> to a typeglob is different
+than calling the C<undef> function on a typeglob (C<undef *foo>), which
+has quite a few effects.
+
+ $foo = "bar";
+ *foo = undef;
+ print $foo;
+
+ # perl4 prints:
+ # perl4 warns: "Use of uninitialized variable" if using -w
+ # perl5 prints: bar
+ # perl5 warns: "Undefined value assigned to typeglob" if using -w
=item * (Scalar String)
=item * (list, builtin)
-C<sprintf()> funkiness (array argument converted to scalar array count)
-This test could be added to t/op/sprintf.t
+C<sprintf()> is prototyped as ($;@), so its first argument is given scalar
+context. Thus, if passed an array, it will probably not do what you want,
+unlike Perl 4:
@z = ('%s%s', 'foo', 'bar');
$x = sprintf(@z);
- if ($x eq 'foobar') {print "ok 2\n";} else {print "not ok 2 '$x'\n";}
+ print $x;
- # perl4 prints: ok 2
- # perl5 prints: not ok 2
+ # perl4 prints: foobar
+ # perl5 prints: 3
-C<printf()> works fine, though:
+C<printf()> works the same as it did in Perl 4, though:
+ @z = ('%s%s', 'foo', 'bar');
printf STDOUT (@z);
- print "\n";
# perl4 prints: foobar
# perl5 prints: foobar
-Probably a bug.
-
=back
=head2 Precedence Traps
open(FOO || die);
# perl4 opens or dies
- # perl5 errors: Precedence problem: open FOO should be open(FOO)
+ # perl5 opens FOO, dying only if 'FOO' is false, i.e. never
=item * Precedence
}
sub doit{local($_) = shift; print "Got $_ "}
- # perl4 prints: blah blah blah
+ # perl4 prints: Got blah Got blah Got blah Got blah
# perl5 prints: infinite loop blah...
=item * Regular Expression
my($left,$right) = @_;
return sub { $_[0] =~ /$left stuff $right/o; };
}
+ $good = build_match('foo','bar');
+ $bad = build_match('baz','blarch');
+ print $good->('foo stuff bar') ? "ok\n" : "not ok\n";
+ print $bad->('baz stuff blarch') ? "ok\n" : "not ok\n";
+ print $bad->('foo stuff bar') ? "not ok\n" : "ok\n";
+
+For most builds of Perl5, this will print:
+ok
+not ok
+not ok
build_match() will always return a sub which matches the contents of
$left and $right as they were the I<first> time that build_match()
was called, not as they are in the current call.
-This is probably a bug, and may change in future versions of Perl.
-
=item * Regular Expression
If no parentheses are used in a match, Perl4 sets C<$+> to
$SIG{'TERM'} = SeeYa;
print "SIGTERM is now $SIG{'TERM'}\n";
- # perl4 prints: SIGTERM is main'SeeYa
- # perl5 prints: SIGTERM is now main::1
+ # perl4 prints: SIGTERM is now main'SeeYa
+ # perl5 prints: SIGTERM is now main::1 (and warns "Hasta la vista, baby!")
Use B<-w> to catch this one
reverse is no longer allowed as the name of a sort subroutine.
sub reverse{ print "yup "; $a <=> $b }
- print sort reverse a,b,c;
+ print sort reverse (2,1,3);
- # perl4 prints: yup yup yup yup abc
- # perl5 prints: abc
+ # perl4 prints: yup yup 123
+ # perl5 prints: 123
+ # perl5 warns (if using -w): Ambiguous call resolved as CORE::reverse()
=item * warn() won't let you specify a filehandle.
=item * Interpolation
-The construct "this is $$x" used to interpolate the pid at that
-point, but now apparently tries to dereference $x. C<$$> by itself still
-works fine, however.
+The construct "this is $$x" used to interpolate the pid at that point, but
+now tries to dereference $x. C<$$> by itself still works fine, however.
+ $s = "a reference";
+ $x = *s;
print "this is $$x\n";
# perl4 prints: this is XXXx (XXX is the current pid)
- # perl5 prints: this is
+ # perl5 prints: this is a reference
=item * Interpolation
Similarly, watch out for:
- $foo = "array";
+ $foo = "baz";
print "\$$foo{bar}\n";
- # perl4 prints: $array{bar}
+ # perl4 prints: $baz{bar}
# perl5 prints: $
-Perl 5 is looking for C<$array{bar}> which doesn't exist, but perl 4 is
-happy just to expand $foo to "array" by itself. Watch out for this
+Perl 5 is looking for C<$foo{bar}> which doesn't exist, but perl 4 is
+happy just to expand $foo to "baz" by itself. Watch out for this
especially in C<eval>'s.
=item * Interpolation
=item * C<split> on empty string with LIMIT specified
- $string = '';
+ $string = '';
@list = split(/foo/, $string, 2)
Perl4 returns a one element list containing the empty string but Perl5