diff options
author | Perl 5 Porters <perl5-porters@africa.nicoh.com> | 1996-07-29 06:27:52 +0000 |
---|---|---|
committer | Charles Bailey <bailey@genetics.upenn.edu> | 1996-07-29 06:27:52 +0000 |
commit | 6dbacca0944d998c28b59441b6ee324c2bdbf843 (patch) | |
tree | 9d976a6d8f8334772ce0319555838561713166ed /pod/perltrap.pod | |
parent | f3517c325cecf563203613cbc5de19cb890bd4b0 (diff) | |
download | perl-6dbacca0944d998c28b59441b6ee324c2bdbf843.tar.gz |
perl 5.003_01: pod/perltrap.pod
Typos and pod formatting corrected
Perl4 - Perl5 traps revised extensively
Diffstat (limited to 'pod/perltrap.pod')
-rw-r--r-- | pod/perltrap.pod | 1040 |
1 files changed, 936 insertions, 104 deletions
diff --git a/pod/perltrap.pod b/pod/perltrap.pod index dd219c064b..be58bc52e2 100644 --- a/pod/perltrap.pod +++ b/pod/perltrap.pod @@ -58,7 +58,7 @@ comparisons. =item * Reading an input line does not split it for you. You get to split it -yourself to an array. And split() operator has different +yourself to an array. And the split() operator has different arguments. =item * @@ -172,7 +172,7 @@ Variables begin with "$" or "@" in Perl. =item * -printf() does not implement the "*" format for interpolating +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. @@ -231,7 +231,7 @@ Sharp shell programmers should take note of the following: =item * -The backtick operator does variable interpretation without regard to +The backtick operator does variable interpolation without regard to the presence of single quotes in the command. =item * @@ -293,7 +293,7 @@ People have a hard time remembering that some functions default to $_, or @ARGV, or whatever, but that others which you might expect to do not. -=item * +=item * The <FH> construct is not the name of the filehandle, it is a readline operation on that handle. The data read is only assigned to $_ if the @@ -303,7 +303,7 @@ file read is the sole condition in a while loop: while ($_ = <FH>) { }.. <FH>; # data discarded! -=item * +=item * Remember not to use "C<=>" when you need "C<=~>"; these two constructs are quite different: @@ -318,9 +318,9 @@ loop control on. =item * -Use my() for local variables whenever you can get away with +Use C<my()> for local variables whenever you can get away with it (but see L<perlform> for where you can't). -Using local() actually gives a local value to a global +Using C<local()> actually gives a local value to a global variable, which leaves you open to unforeseen side-effects of dynamic scoping. @@ -332,75 +332,567 @@ external name is still an alias for the original. =back -=head2 Perl4 Traps +=head2 Perl4 to Perl5 Traps -Penitent Perl 4 Programmers should take note of the following -incompatible changes that occurred between release 4 and release 5: +Practicing Perl4 Programmers should take note of the following +Perl4-to-Perl5 specific traps. + +They're crudely ordered according to the following list: =over 4 -=item * +=item Discontinuance, Deprecation, and BugFix traps -C<@> now always interpolates an array in double-quotish strings. Some programs -may now need to use backslash to protect any C<@> that shouldn't interpolate. +Anything that's been fixed as a perl4 bug, removed as a perl4 feature +or deprecated as a perl4 feature with the intent to encourage usage of +some other perl5 feature. -=item * +=item Parsing Traps -Barewords that used to look like strings to Perl will now look like subroutine -calls if a subroutine by that name is defined before the compiler sees them. -For example: +Traps that appear to stem from the new parser. - sub SeeYa { die "Hasta la vista, baby!" } - $SIG{'QUIT'} = SeeYa; +=item Numerical Traps -In Perl 4, that set the signal handler; in Perl 5, it actually calls the -function! You may use the B<-w> switch to find such places. +Traps having to do with numerical or mathematical operators. -=item * +=item General data type traps -Symbols starting with C<_> are no longer forced into package C<main>, except -for $_ itself (and @_, etc.). +Traps involving perl standard data types. -=item * +=item Context Traps - scalar, list contexts + +Traps related to context within lists, scalar statements/declarations. + +=item Precedence Traps + +Traps related to the precedence of parsing, evaluation, and execution of +code. + +=item General Regular Expression Traps using s///, etc. + +Traps related to the use of pattern matching. + +=item Subroutine, Signal, Sorting Traps + +Traps related to the use of signals and signal handlers, general subroutines, +and sorting, along with sorting subroutines. + +=item OS Traps + +OS-specific traps. + +=item DBM Traps + +Traps specific to the use of C<dbmopen()>, and specific dbm implementations. + +=item Unclassified Traps + +Everything else. + +=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 C<-w>. + +=head2 Discontinuance, Deprecation, and BugFix traps + +Anything that has been discontinued, deprecated, or fixed as +a bug from perl4. -Double-colon is now a valid package separator in an identifier. Thus these -behave differently in perl4 vs. perl5: +=over 4 + +=item * Discontinuance + +Symbols starting with "_" are no longer forced into package main, except +for C<$_> itself (and C<@_>, etc.). + + package test; + $_legacy = 1; - print "$a::$b::$c\n"; + package main; + print "\$_legacy is ",$_legacy,"\n"; + + # perl4 prints: $_legacy is 1 + # perl5 prints: $_legacy is + +=item * Deprecation + +Double-colon is now a valid package separator in a variable name. Thus these +behave differently in perl4 vs. perl5, since the packages don't exist. + + $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 -=item * +Given that C<::> is now the preferred package delimiter, it is debatable +whether this should be classed as a bug or not. +(The older package delimiter, ' ,is used here) -C<s'$lhs'$rhs'> now does no interpolation on either side. It used to -interpolate C<$lhs> but not C<$rhs>. + $x = 10 ; + print "x=${'x}\n" ; + + # perl4 prints: x=10 + # perl5 prints: Can't find string terminator "'" anywhere before EOF -=item * +Also see precedence traps, for parsing C<$:>. -The second and third arguments of splice() are now evaluated in scalar -context (as the book says) rather than list context. +=item * BugFix -=item * +The second and third arguments of C<splice()> are now evaluated in scalar +context (as the Camel says) rather than list context. -These are now semantic errors because of precedence: + sub sub1{return(0,2) } # return a 2-elem array + sub sub2{ return(1,2,3)} # return a 3-elem array + @a1 = ("a","b","c","d","e"); + @a2 = splice(@a1,&sub1,&sub2); + print join(' ',@a2),"\n"; + + # perl4 prints: a b + # perl5 prints: c d e - shift @list + 20; - $n = keys %map + 20; +=item * Discontinuance -Because if that were to work, then this couldn't: +You can't do a C<goto> into a block that is optimized away. Darn. - sleep $dormancy + 20; + goto marker1; -=item * + for(1){ + marker1: + print "Here I is!\n"; + } + + # perl4 prints: Here I is! + # perl5 dumps core (SEGV) + +=item * Discontinuance + +It is no longer syntactically legal to use whitespace as the name +of a variable, or as a delimiter for any kind of quote construct. +Double darn. + + $a = ("foo bar"); + $b = q baz ; + print "a is $a, b is $b\n"; + + # perl4 prints: a is foo bar, b is baz + # perl5 errors: Bare word found where operator expected + +=item * Discontinuance + +The archaic while/if BLOCK BLOCK syntax is no longer supported. + + if { 1 } { + print "True!"; + } + else { + print "False!"; + } + + # perl4 prints: True! + # perl5 errors: syntax error at test.pl line 1, near "if {" + +=item * BugFix + +The C<**> operator now binds more tightly than unary minus. +It was documented to work this way before, but didn't. + + print -4**2,"\n"; + + # perl4 prints: 16 + # perl5 prints: -16 + +=item * Discontinuance + +The meaning of C<foreach{}> has changed slightly when it is iterating over a +list which is not an array. This used to assign the list to a +temporary array, but no longer does so (for efficiency). This means +that you'll now be iterating over the actual values, not over copies of +the values. Modifications to the loop variable can change the original +values. + + @list = ('ab','abc','bcd','def'); + foreach $var (grep(/ab/,@list)){ + $var = 1; + } + print (join(':',@list)); + + # perl4 prints: ab:abc:bcd:def + # perl5 prints: 1:1:bcd:def + +To retain Perl4 semantics you need to assign your list +explicitly to a temporary array and then iterate over that. For +example, you might need to change + + foreach $var (grep(/ab/,@list)){ + +to + + foreach $var (@tmp = grep(/ab/,@list)){ + +Otherwise changing $var will clobber the values of @list. (This most often +happens when you use C<$_> for the loop variable, and call subroutines in +the loop that don't properly localize C<$_>.) + +=item * Deprecation + +Some error messages will be different. + +=item * Discontinuance + +Some bugs may have been inadvertently removed. :-) + +=back + +=head2 Parsing Traps + +Perl4-to-Perl5 traps from having to do with parsing. + +=over 4 + +=item * Parsing + +Note the space between . and = + + $string . = "more string"; + print $string; + + # perl4 prints: more string + # perl5 prints: syntax error at - line 1, near ". =" + +=item * Parsing + +Better parsing in perl 5 + + sub foo {} + &foo + print("hello, world\n"); + + # perl4 prints: hello, world + # perl5 prints: syntax error + +=item * Parsing + +"if it looks like a function, it is a function" rule. + + print + ($foo == 1) ? "is one\n" : "is zero\n"; + + # perl4 prints: is zero + # perl5 warns: "Useless use of a constant in void context" if using -w + +=back + +=head2 Numerical Traps + +Perl4-to-Perl5 traps having to do with numerical operators, +operands, or output from same. + +=over 5 + +=item * Numerical + +Formatted output and significant digits + + print 7.373504 - 0, "\n"; + printf "%20.18f\n", 7.373504 - 0; + + # Perl4 prints: + 7.375039999999996141 + 7.37503999999999614 + + # Perl5 prints: + 7.373504 + 7.37503999999999614 + +=item * Numerical + +Large integer trap with autoincrement + + $a = $b = 2147483647; + print "$a $b\n"; + $a += 1; + $b++; + print "$a $b\n"; + + # perl4 prints: + 2147483647 2147483647 + 2147483648 2147483648 + + # perl5 prints: + 2147483647 2147483647 + 2147483648 -2147483648 + +=item * Numerical + +Assignment of return values from numeric equality tests +does not work in perl5 when the test evaluates to false (0). +Logical tests now return an null, instead of 0 + + $p = ($test == 1); + print $p,"\n"; + + # perl4 prints: 0 + # perl5 prints: + +Also see the L<General Regular Expression Traps> tests for another example +of this new feature... + +=back + +=head2 General data type traps + +Perl4-to-Perl5 traps involving most data-types, and their usage +within certain expressions and/or context. + +=over 5 + +=item * (Arrays) + +Negative array subscripts now count from the end of the array. + + @a = (1, 2, 3, 4, 5); + print "The third element of the array is $a[3] also expressed as $a[-2] \n"; + + # perl4 prints: The third element of the array is 4 also expressed as + # perl5 prints: The third element of the array is 4 also expressed as 4 + +=item * (Arrays) + +Setting C<$#array> lower now discards array elements, and makes them +impossible to recover. + + @a = (a,b,c,d,e); + print "Before: ",join('',@a); + $#a =1; + print ", After: ",join('',@a); + $#a =3; + print ", Recovered: ",join('',@a),"\n"; + + # perl4 prints: Before: abcde, After: ab, Recovered: abcd + # perl5 prints: Before: abcde, After: ab, Recovered: ab + +=item * (Hashes) + +Hashes get defined before use + + local($s,@a,%h); + die "scalar \$s defined" if defined($s); + die "array \@a defined" if defined(@a); + die "hash \%h defined" if defined(%h); + + # perl4 prints: + # perl5 dies: hash %h defined + +=item * (Globs) + +glob assignment from variable to variable will fail if the assigned +variable is localized subsequent to the assignment + + @a = ("This is Perl 4"); + *b = *a; + local(@a); + print @b,"\n"; + + # perl4 prints: This is Perl 4 + # perl5 prints: + + # Another example + + *fred = *barney; # fred is aliased to barney + @barney = (1, 2, 4); + # @fred; + print "@fred"; # should print "1, 2, 4" + + # perl4 prints: 1 2 4 + # perl5 prints: Literal @fred now requires backslash + +=item * (Scalar String) + +Changes in unary negation (of strings) +This change effects both the return value and what it +does to auto(magic)increment. + + $x = "aaa"; + print ++$x," : "; + print -$x," : "; + print ++$x,"\n"; + + # perl4 prints: aab : -0 : 1 + # perl5 prints: aab : -aab : aac + +=item * (Constants) + +perl 4 lets you modify constants: + + $foo = "x"; + &mod($foo); + for ($x = 0; $x < 3; $x++) { + &mod("a"); + } + sub mod { + print "before: $_[0]"; + $_[0] = "m"; + print " after: $_[0]\n"; + } + + # perl4: + # before: x after: m + # before: a after: m + # before: m after: m + # before: m after: m + + # Perl5: + # before: x after: m + # Modification of a read-only value attempted at foo.pl line 12. + # before: a + +=item * (Scalars) + +The behavior is slightly different for: + + print "$x", defined $x + + # perl 4: 1 + # perl 5: <no output, $x is not called into existence> + +=item * (Variable Suicide) + +Variable suicide behavior is more consistent under Perl 5. +Perl5 exhibits the same behavior for associative arrays and scalars, +that perl4 exhibits only for scalars. + + $aGlobal{ "aKey" } = "global value"; + print "MAIN:", $aGlobal{"aKey"}, "\n"; + $GlobalLevel = 0; + &test( *aGlobal ); + + sub test { + local( *theArgument ) = @_; + local( %aNewLocal ); # perl 4 != 5.001l,m + $aNewLocal{"aKey"} = "this should never appear"; + print "SUB: ", $theArgument{"aKey"}, "\n"; + $aNewLocal{"aKey"} = "level $GlobalLevel"; # what should print + $GlobalLevel++; + if( $GlobalLevel<4 ) { + &test( *aNewLocal ); + } + } + + # Perl4: + # MAIN:global value + # SUB: global value + # SUB: level 0 + # SUB: level 1 + # SUB: level 2 + + # Perl5: + # MAIN:global value + # SUB: global value + # SUB: this should never appear + # SUB: this should never appear + # SUB: this should never appear + +=back + +=head2 Context Traps - scalar, list contexts + +=over 5 + +=item * (list context) + +The elements of argument lists for formats are now evaluated in list +context. This means you can interpolate list values now. + + @fmt = ("foo","bar","baz"); + format STDOUT= + @<<<<< @||||| @>>>>> + @fmt; + . + write; + + # perl4 errors: Please use commas to separate fields in file + # perl5 prints: foo bar baz + +=item * (scalar context) + +The C<caller()> function now returns a false value in a scalar context +if there is no caller. This lets library files determine if they're +being required. + + caller() ? (print "You rang?\n") : (print "Got a 0\n"); + + # perl4 errors: There is no caller + # perl5 prints: Got a 0 + +=item * (scalar context) + +The comma operator in a scalar context is now guaranteed to give a +scalar context to its arguments. + + @y= ('a','b','c'); + $x = (1, 2, @y); + print "x = $x\n"; + + # Perl4 prints: x = c # Thinks list context interpolates list + # Perl5 prints: x = 3 # Knows scalar uses length of list + +=item * (list, builtin) + +C<sprintf()> funkiness (array argument converted to scalar array count) +This test could be added to t/op/sprintf.t + + @z = ('%s%s', 'foo', 'bar'); + $x = sprintf(@z); + if ($x eq 'foobar') {print "ok 2\n";} else {print "not ok 2 '$x'\n";} + + # perl4 prints: ok 2 + # perl5 prints: not ok 2 + +C<printf()> works fine, though: + + 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. + +=item * + +These are now semantic errors because of precedence: + + @list = (1,2,3,4,5); + %map = ("a",1,"b",2,"c",3,"d",4); + $n = shift @list + 2; # first item in list plus 2 + print "n is $n, "; + $m = keys %map + 2; # number of items in hash plus 2 + print "m is $m\n"; + + # perl4 prints: n is 3, m is 6 + # perl5 errors and fails to compile + +=item * Precedence The precedence of assignment operators is now the same as the precedence of assignment. Perl 4 mistakenly gave them the precedence of the associated operator. So you now must parenthesize them in expressions like /foo/ ? ($a += 2) : ($a -= 2); - + Otherwise - /foo/ ? $a += 2 : $a -= 2; + /foo/ ? $a += 2 : $a -= 2 would be erroneously parsed as @@ -408,115 +900,455 @@ would be erroneously parsed as On the other hand, - $a += /foo/ ? 1 : 2; + $a += /foo/ ? 1 : 2; now works as a C programmer would expect. -=item * +=item * Precedence -C<open FOO || die> is now incorrect. You need parens around the filehandle. -While temporarily supported, using such a construct will -generate a non-fatal (but non-suppressible) warning. + open FOO || die; -=item * +is now incorrect. You need parens around the filehandle. +Otherwise, perl5 leaves the statement as it's default precedence: -The elements of argument lists for formats are now evaluated in list -context. This means you can interpolate list values now. + open(FOO || die); + + # perl4 opens or dies + # perl5 errors: Precedence problem: open FOO should be open(FOO) -=item * +=item * Precedence -You can't do a C<goto> into a block that is optimized away. Darn. +perl4 gives the special variable, C<$:> precedence, where perl5 +treats C<$::> as main C<package> -=item * + $a = "x"; print "$::a"; + + # perl 4 prints: -:a + # perl 5 prints: x + +=item * Precedence -It is no longer syntactically legal to use whitespace as the name -of a variable, or as a delimiter for any kind of quote construct. -Double darn. +concatenation precedence over filetest operator? -=item * + -e $foo .= "q" + + # perl4 prints: no output + # perl5 prints: Can't modify -e in concatenation -The caller() function now returns a false value in a scalar context if there -is no caller. This lets library files determine if they're being required. +=item * Precedence -=item * +Assignment to value takes precedence over assignment to key in +perl5 when using the shift operator on both sides. + + @arr = ( 'left', 'right' ); + $a{shift @arr} = shift @arr; + print join( ' ', keys %a ); + + # perl4 prints: left + # perl5 prints: right + +=back + +=head2 General Regular Expression Traps using s///, etc. + +All types of RE traps. + +=over 5 + +=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 +'$' in string) + + $a=1;$b=2; + $string = '1 2 $a $b'; + $string =~ s'$a'$b'; + print $string,"\n"; + + # perl4 prints: $b 2 $a $b + # perl5 prints: 1 2 $a $b + +=item * Regular Expression C<m//g> now attaches its state to the searched string rather than the -regular expression. +regular expression. (Once the scope of a block is left for the sub, the +state of the searched string is lost) + + $_ = "ababab"; + while(m/ab/g){ + &doit("blah"); + } + sub doit{local($_) = shift; print "Got $_ "} + + # perl4 prints: blah blah blah + # perl5 prints: infinite loop blah... + +=item * Regular Expression + +If no parentheses are used in a match, Perl4 sets C<$+> to +the whole match, just like C<$&>. Perl5 does not. + + "abcdef" =~ /b.*e/; + print "\$+ = $+\n"; + + # perl4 prints: bcde + # perl5 prints: + +=item * Regular Expression + +substitution now returns the null string if it fails + + $string = "test"; + $value = ($string =~ s/foo//); + print $value, "\n"; + + # perl4 prints: 0 + # perl5 prints: + +Also see L<Numerical Traps> for another example of this new feature. + +=item * Regular Expression + +C<s`lhs`rhs`> (using backticks) is now a normal substitution, with no +backtick expansion + + $string = ""; + $string =~ s`^`hostname`; + print $string, "\n"; + + # perl4 prints: <the local hostname> + # perl5 prints: hostname + +=item * Regular Expression + +Stricter parsing of variables used in regular expressions + + s/^([^$grpc]*$grpc[$opt$plus$rep]?)//o; + + # perl4: compiles w/o error + # perl5: with Scalar found where operator expected ..., near "$opt$plus" + +an added component of this example, apparently from the same script, is +the actual value of the s'd string after the substitution. +C<[$opt]> is a character class in perl4 and an array subscript in perl5 + + $grpc = 'a'; + $opt = 'r'; + $_ = 'bar'; + s/^([^$grpc]*$grpc[$opt]?)/foo/; + print ; + + # perl4 prints: foo + # perl5 prints: foobar + +=item * Regular Expression + +Under perl5, C<m?x?> matches only once, like C<?x?>. Under perl4, it matched +repeatedly, like C</x/> or C<m!x!>. + + $test = "once"; + sub match { $test =~ m?once?; } + &match(); + if( &match() ) { + # m?x? matches more then once + print "perl4\n"; + } else { + # m?x? matches only once + print "perl5\n"; + } + + # perl4 prints: perl4 + # perl5 prints: perl5 -=item * -C<reverse> is no longer allowed as the name of a sort subroutine. +=back + +=head2 Subroutine, Signal, Sorting Traps -=item * +The general group of Perl4-to-Perl5 traps having to do with +Signals, Sorting, and their related subroutines, as well as +general subroutine traps. Includes some OS-Specific traps. -B<taintperl> is no longer a separate executable. There is now a B<-T> -switch to turn on tainting when it isn't turned on automatically. +=over 5 -=item * +=item * (Signals) -Double-quoted strings may no longer end with an unescaped C<$> or C<@>. +Barewords that used to look like strings to Perl will now look like subroutine +calls if a subroutine by that name is defined before the compiler sees them. -=item * + sub SeeYa { warn"Hasta la vista, baby!" } + $SIG{'TERM'} = SeeYa; + print "SIGTERM is now $SIG{'TERM'}\n"; + + # perl4 prints: SIGTERM is main'SeeYa + # perl5 prints: SIGTERM is now main::1 -The archaic C<while/if> BLOCK BLOCK syntax is no longer supported. +Use B<-w> to catch this one +=item * (Sort Subroutine) -=item * +reverse is no longer allowed as the name of a sort subroutine. -Negative array subscripts now count from the end of the array. + sub reverse{ print "yup "; $a <=> $b } + print sort reverse a,b,c; + + # perl4 prints: yup yup yup yup abc + # perl5 prints: abc -=item * +=back -The comma operator in a scalar context is now guaranteed to give a -scalar context to its arguments. +=head2 OS Traps + +=over 5 + +=item * (SysV) + +Under HPUX, and some other SysV OS's, one had to reset any signal handler, +within the signal handler function, each time a signal was handled with +perl4. With perl5, the reset is now done correctly. Any code relying +on the handler _not_ being reset will have to be reworked. + +5.002 and beyond uses sigaction() under SysV + + sub gotit { + print "Got @_... "; + } + $SIG{'INT'} = 'gotit'; + + $| = 1; + $pid = fork; + if ($pid) { + kill('INT', $pid); + sleep(1); + kill('INT', $pid); + } else { + while (1) {sleep(10);} + } + + # perl4 (HPUX) prints: Got INT... + # perl5 (HPUX) prints: Got INT... Got INT... + +=item * (SysV) + +Under SysV OS's, C<seek()> on a file opened to append C<E<gt>E<gt>> now does +the right thing w.r.t. the fopen() man page. e.g. - When a file is opened +for append, it is impossible to overwrite information already in +the file. + + open(TEST,">>seek.test"); + $start = tell TEST ; + foreach(1 .. 9){ + print TEST "$_ "; + } + $end = tell TEST ; + seek(TEST,$start,0); + print TEST "18 characters here"; + + # perl4 (solaris) seek.test has: 18 characters here + # perl5 (solaris) seek.test has: 1 2 3 4 5 6 7 8 9 18 characters here -=item * -The C<**> operator now binds more tightly than unary minus. -It was documented to work this way before, but didn't. -=item * +=back -Setting C<$#array> lower now discards array elements. +=head2 Interpolation Traps -=item * +=over 5 -delete() is not guaranteed to return the old value for tie()d arrays, -since this capability may be onerous for some modules to implement. +=item * Interpolation -=item * +@ now always interpolates an array in double-quotish strings. + + print "To: someone@somewhere.com\n"; + + # perl4 prints: To:someone@somewhere.com + # perl5 errors : Literal @somewhere now requires backslash + +=item * Interpolation + +Perl4-to-Perl5 traps having to do with how things get interpolated +within certain expressions, statements, contexts, or whatever. + +Double-quoted strings may no longer end with an unescaped $ or @. + + $foo = "foo$"; + $bar = "bar@"; + print "foo is $foo, bar is $bar\n"; + + # perl4 prints: foo is foo$, bar is bar@ + # perl5 errors: Final $ should be \$ or $name + +Note: perl5 DOES NOT error on the terminating @ in $bar + +=item * Interpolation The construct "this is $$x" used to interpolate the pid at that -point, but now tries to dereference $x. C<$$> by itself still +point, but now apparently tries to dereference C<$x>. C<$$> by itself still works fine, however. -=item * + print "this is $$x\n"; -The meaning of foreach has changed slightly when it is iterating over a -list which is not an array. This used to assign the list to a -temporary array, but no longer does so (for efficiency). This means -that you'll now be iterating over the actual values, not over copies of -the values. Modifications to the loop variable can change the original -values. To retain Perl 4 semantics you need to assign your list -explicitly to a temporary array and then iterate over that. For -example, you might need to change + # perl4 prints: this is XXXx (XXX is the current pid) + # perl5 prints: this is + +=item * Interpolation + +Creation of hashes on the fly with C<eval "EXPR"> now requires either both +C<$>'s to be protected in the specification of the hash name, or both curlies +to be protected. If both curlies are protected, the result will be compatible +with perl4 and perl5. This is a very common practice, and should be changed +to use the block form of C<eval{}> if possible. - foreach $var (grep /x/, @list) { ... } + $hashname = "foobar"; + $key = "baz"; + $value = 1234; + eval "\$$hashname{'$key'} = q|$value|"; + (defined($foobar{'baz'})) ? (print "Yup") : (print "Nope"); + + # perl4 prints: Yup + # perl5 prints: Nope + +Changing + + eval "\$$hashname{'$key'} = q|$value|"; to - foreach $var (my @tmp = grep /x/, @list) { ... } + eval "\$\$hashname{'$key'} = q|$value|"; -Otherwise changing C<$var> will clobber the values of @list. (This most often -happens when you use C<$_> for the loop variable, and call subroutines in -the loop that don't properly localize C<$_>.) +causes the following result: -=item * + # perl4 prints: Nope + # perl5 prints: Yup -Some error messages will be different. +or, changing to -=item * + eval "\$$hashname\{'$key'\} = q|$value|"; + +causes the following result: + + # perl4 prints: Yup + # perl5 prints: Yup + # and is compatible for both versions + + +=item * Interpolation + +perl4 programs which unconsciously rely on the bugs in earlier perl versions. + + perl -e '$bar=q/not/; print "This is $foo{$bar} perl5"' + + # perl4 prints: This is not perl5 + # perl5 prints: This is perl5 + +=item * Interpolation + +You also have to be careful about array references. + + print "$foo{" + + perl 4 prints: { + perl 5 prints: syntax error + +=item * Interpolation + +Similarly, watch out for: + + $foo = "array"; + print "\$$foo{bar}\n"; + + # perl4 prints: $array{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 +especially in C<eval>'s. + +=item * Interpolation + +C<qq()> string passed to C<eval> + + eval qq( + foreach \$y (keys %\$x\) { + \$count++; + } + ); + + # perl4 runs this ok + # perl5 prints: Can't find string terminator ")" -Some bugs may have been inadvertently removed. +=back + +=head2 DBM Traps + +General DBM traps. + +=over 5 + +=item * DBM + +Existing dbm databases created under perl4 (or any other dbm/ndbm tool) +may cause the same script, run under perl5, to fail. The build of perl5 +must have been linked with the same dbm/ndbm as the default for C<dbmopen()> +to function properly without C<tie>'ing to an extension dbm implementation. + + dbmopen (%dbm, "file", undef); + print "ok\n"; + + # perl4 prints: ok + # perl5 prints: ok (IFF linked with -ldbm or -lndbm) + + +=item * DBM + +Existing dbm databases created under perl4 (or any other dbm/ndbm tool) +may cause the same script, run under perl5, to fail. The error generated +when exceeding the limit on the key/value size will cause perl5 to exit +immediately. + + dbmopen(DB, "testdb",0600) || die "couldn't open db! $!"; + $DB{'trap'} = "x" x 1024; # value too large for most dbm/ndbm + print "YUP\n"; + + # perl4 prints: + dbm store returned -1, errno 28, key "trap" at - line 3. + YUP + + # perl5 prints: + dbm store returned -1, errno 28, key "trap" at - line 3. =back + +=head2 Unclassified Traps + +Everything else. + +=item * Unclassified + +C<require>/C<do> trap using returned value + +If the file doit.pl has: + + sub foo { + $rc = do "./do.pl"; + return 8; + } + print &foo, "\n"; + +And the do.pl file has the following single line: + + return 3; + +Running doit.pl gives the following: + + # perl 4 prints: 3 (aborts the subroutine early) + # perl 5 prints: 8 + +Same behavior if you replace C<do> with C<require>. + +=back + +As always, if any of these are ever officially declared as bugs, +they'll be fixed and removed. + |