=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
use English;
allows you to refer to special variables (like C<$/>) with names (like
-C<$RS>), as though they were in B<awk>; see L<perlvar> for details.
+$RS), as though they were in B<awk>; see L<perlvar> for details.
=item *
=item *
-$E<lt>I<digit>E<gt> does not refer to fields--it refers to substrings matched
+$<I<digit>> does not refer to fields--it refers to substrings matched
by the last match pattern.
=item *
The concatenation operator is ".", not the null string. (Using the
null string would render C</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 "E<gt>".
+slightly context sensitive for operators like "/", "?", and ">".
And in fact, "." itself can be the beginning of a number.)
=item *
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
The C<break> and C<continue> keywords from C become in
Perl C<last> and C<next>, respectively.
-Unlike in C, these do I<NOT> work within a C<do { } while> construct.
+Unlike in C, these do I<not> work within a C<do { } while> construct.
=item *
=item *
-C<printf()> does not implement the "*" format for interpolating
-field widths, but it's trivial to use interpolation of double-quoted
-strings to achieve the same effect.
-
-=item *
-
Comments begin with "#", not "/*".
=item *
=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 *
=item *
-The E<lt>FHE<gt> construct is not the name of the filehandle, it is a readline
+The <FH> construct is not the name of the filehandle, it is a readline
operation on that handle. The data read is assigned to $_ only if the
file read is the sole condition in a while loop:
=item *
-Remember not to use "C<=>" when you need "C<=~>";
+Remember not to use C<=> when you need C<=~>;
these two constructs are quite different:
$x = /foo/;
=back
If you find an example of a conversion trap that is not listed here,
-please submit it to Bill Middleton <F<wjm@best.com>> for inclusion.
-Also note that at least some of these can be caught with B<-w>.
+please submit it to <F<perlbug@perl.org>> for inclusion.
+Also note that at least some of these can be caught with the
+C<use warnings> pragma or the B<-w> switch.
=head2 Discontinuance, Deprecation, and BugFix traps
$a=1;$b=2;$c=3;$var=4;
print "$a::$b::$c ";
print "$var::abc::xyz\n";
-
+
# perl4 prints: 1::2::3 4::abc::xyz
# perl5 prints: 3
}
# perl4 prints: Here I is!
- # perl5 dumps core (SEGV)
+ # perl5 errors: Can't "goto" into the middle of a foreach loop
=item * Discontinuance
# perl4 prints: second new
# perl5 prints: 3
-=item * Discontinuance
-
-In Perl 4 (and versions of Perl 5 before 5.004), C<'\r'> characters in
-Perl code were silently allowed, although they could cause (mysterious!)
-failures in certain constructs, particularly here documents. Now,
-C<'\r'> characters cause an immediate fatal error. (Note: In this
-example, the notation B<\015> represents the incorrect line
-ending. Depending upon your text viewer, it will look different.)
-
- print "foo";\015
- print "bar";
-
- # perl4 prints: foobar
- # perl5.003 prints: foobar
- # perl5.004 dies: Illegal character \015 (carriage return)
-
-See L<perldiag> for full details.
-
=item * Deprecation
Some error messages will be different.
=item * Discontinuance
+In Perl 4, if in list context the delimiters to the first argument of
+C<split()> were C<??>, the result would be placed in C<@_> as well as
+being returned. Perl 5 has more respect for your subroutine arguments.
+
+=item * Discontinuance
+
Some bugs may have been inadvertently removed. :-)
=back
# perl4 prints: is zero
# perl5 warns: "Useless use of a constant in void context" if using -w
+=item * Parsing
+
+String interpolation of the C<$#array> construct differs when braces
+are to used around the name.
+
+ @a = (1..3);
+ print "${#a}";
+
+ # perl4 prints: 2
+ # perl5 fails with syntax error
+
+ @ = (1..3);
+ print "$#{a}";
+
+ # perl4 prints: {a}
+ # perl5 prints: 2
+
=back
=head2 Numerical Traps
Also see L<"General Regular Expression Traps using s///, etc.">
for another example of this new feature...
+=item * Bitwise string ops
+
+When bitwise operators which can operate upon either numbers or
+strings (C<& | ^ ~>) are given only strings as arguments, perl4 would
+treat the operands as bitstrings so long as the program contained a call
+to the C<vec()> function. perl5 treats the string operands as bitstrings.
+(See L<perlop/Bitwise String Operators> for more details.)
+
+ $fred = "10";
+ $barney = "12";
+ $betty = $fred & $barney;
+ print "$betty\n";
+ # Uncomment the next line to change perl4's behavior
+ # ($dummy) = vec("dummy", 0, 0);
+
+ # Perl4 prints:
+ 8
+
+ # Perl5 prints:
+ 10
+
+ # If vec() is used anywhere in the program, both print:
+ 10
+
=back
=head2 General data type traps
# perl4 prints:
# perl5 dies: hash %h defined
+Perl will now generate a warning when it sees defined(@a) and
+defined(%h).
+
=item * (Globs)
glob assignment from variable to variable will fail if the assigned
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
=item * Regular Expression
C<s'$lhs'$rhs'> now does no interpolation on either side. It used to
-interpolate C<$lhs> but not C<$rhs>. (And still does not match a literal
+interpolate $lhs but not $rhs. (And still does not match a literal
'$' in string)
$a=1;$b=2;
}
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
-C<$left> and C<$right> as they were the I<first> time that build_match()
+$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 * (SysV)
-Under SysV OSes, C<seek()> on a file opened to append C<E<gt>E<gt>> now does
+Under SysV OSes, C<seek()> on a file opened to append C<<< >> >>> now does
the right thing w.r.t. the fopen() manpage. e.g., - When a file is opened
for append, it is impossible to overwrite information already in
the file.
print "To: someone@somewhere.com\n";
# perl4 prints: To:someone@somewhere.com
- # perl5 errors : In string, @somewhere now must be written as \@somewhere
+ # perl < 5.6.1, error : In string, @somewhere now must be written as \@somewhere
+ # perl >= 5.6.1, warning : Possible unintended interpolation of @somewhere in string
=item * Interpolation
=item * Interpolation
-The construct "this is $$x" used to interpolate the pid at that
-point, but now apparently tries to dereference C<$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