=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 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 *
-Variables begin with "$" or "@" in Perl.
+Variables begin with "$", "@" or "%" in Perl.
=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 *
-Variables begin with "$" or "@" in Perl.
-
-=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.
+Variables begin with "$", "@" or "%" in Perl.
=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: x=10
# perl5 prints: Can't find string terminator "'" anywhere before EOF
+You can avoid this problem, and remain compatible with perl4, if you
+always explicitly include the package name:
+
+ $x = 10 ;
+ print "x=${main'x}\n" ;
+
Also see precedence traps, for parsing C<$:>.
=item * BugFix
The second and third arguments of C<splice()> are now evaluated in scalar
context (as the Camel says) rather than list context.
- sub sub1{return(0,2) } # return a 2-elem array
- sub sub2{ return(1,2,3)} # return a 3-elem array
+ sub sub1{return(0,2) } # return a 2-element list
+ sub sub2{ return(1,2,3)} # return a 3-element list
@a1 = ("a","b","c","d","e");
@a2 = splice(@a1,&sub1,&sub2);
print join(' ',@a2),"\n";
}
# 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
# perl4 prints: 0
# perl5 prints:
-Also see the L<General Regular Expression Traps using s///, etc.>
-tests for another example of this new feature...
+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
# 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
# perl4 prints: This is Perl 4
# perl5 prints:
- # Another example
+=item * (Globs)
+
+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). 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.
- *fred = *barney; # fred is aliased to barney
- @barney = (1, 2, 4);
- # @fred;
- print "@fred"; # should print "1, 2, 4"
+ $foo = "bar";
+ *foo = undef;
+ print $foo;
- # perl4 prints: 1 2 4
- # perl5 prints: In string, @fred now must be written as \@fred
+ # 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
Perl4-to-Perl5 traps involving precedence order.
+Perl 4 has almost the same precedence rules as Perl 5 for the operators
+that they both have. Perl 4 however, seems to have had some
+inconsistencies that made the behavior differ from what was documented.
+
=over 5
=item * Precedence
-LHS vs. RHS when both sides are getting an op.
+LHS vs. RHS of any assignment operator. LHS is evaluated first
+in perl4, second in perl5; this can affect the relationship
+between side-effects in sub-expressions.
@arr = ( 'left', 'right' );
$a{shift @arr} = shift @arr;
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 * Precedence
-concatenation precedence over filetest operator?
+perl4 had buggy precedence for the file test operators vis-a-vis
+the assignment operators. Thus, although the precedence table
+for perl4 leads one to believe C<-e $foo .= "q"> should parse as
+C<((-e $foo) .= "q")>, it actually parses as C<(-e ($foo .= "q"))>.
+In perl5, the precedence is as documented.
-e $foo .= "q"
=item * Precedence
-Assignment to value takes precedence over assignment to key in
-perl5 when using the shift operator on both sides.
+In perl4, keys(), each() and values() were special high-precedence operators
+that operated on a single hash, but in perl5, they are regular named unary
+operators. As documented, named unary operators have lower precedence
+than the arithmetic and concatenation operators C<+ - .>, but the perl4
+variants of these operators actually bind tighter than C<+ - .>.
+Thus, for:
- @arr = ( 'left', 'right' );
- $a{shift @arr} = shift @arr;
- print join( ' ', keys %a );
+ %foo = 1..10;
+ print keys %foo - 1
- # perl4 prints: left
- # perl5 prints: right
+ # perl4 prints: 4
+ # perl5 prints: Type of arg 1 to keys must be hash (not subtraction)
+
+The perl4 behavior was probably more useful, if less consistent.
=back
=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
# perl5 prints: perl5
-=item * Regular Expression
-
-Under perl4 and upto version 5.003, a failed C<m//g> match used to
-reset the internal iterator, so that subsequent C<m//g> match attempts
-began from the beginning of the string. In perl version 5.004 and later,
-failed C<m//g> matches do not reset the iterator position (which can be
-found using the C<pos()> function--see L<perlfunc/pos>).
-
- $test = "foop";
- for (1..3) {
- print $1 while ($test =~ /(o)/g);
- # pos $test = 0; # to get old behavior
- }
-
- # perl4 prints: oooooo
- # perl5.004 prints: oo
-
-You may always reset the iterator yourself as shown in the commented line
-to get the old behavior.
-
=back
=head2 Subroutine, Signal, Sorting Traps
$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
=over 5
-=item * Unclassified
-
-C<require>/C<do> trap using returned value
+=item * C<require>/C<do> trap using returned value
If the file doit.pl has:
Same behavior if you replace C<do> with C<require>.
+=item * C<split> on empty string with LIMIT specified
+
+ $string = '';
+ @list = split(/foo/, $string, 2)
+
+Perl4 returns a one element list containing the empty string but Perl5
+returns an empty list.
+
=back
As always, if any of these are ever officially declared as bugs,