Appendix A
Perl4 to Perl5 Traps




NOTE:

Most of what follows in this appendix is taken directly from the PERLTRAP manual section, which the author maintains. It's included here for your convenience in making the transition from Perl4 to Perl5. The latest revision of this document is always available within the Perl distribution.


Practicing Perl4 programmers should take note of the following Perl4 to Perl5 conversion-
specific traps.

They're generally ordered according to the following list: Discontinuance, Deprecation, Anything that's been fixed as a Perl4 bug,
and BugFix traps removed as a Perl4 feature, or deprecated as a Perl4 feature with the intent to encourage usage of
some other Perl5 feature.

Parsing traps Traps that appear to stem from the new parser.

Numerical traps Traps having to do with numerical or mathematical operators.

General data type traps Traps involving Perl standard data types.

Context traps--scalar, Traps related to context within lists and scalar
list contexts statements/declarations.

Precedence Traps Traps related to the precedence of parsing, evaluation, and execution of code.

General Regular Expression Traps related to the use of pattern matching.
traps using s///, and so on

Subroutine, Signal, Traps related to the use of signals and signal
Sorting traps handlers, general subroutines, and sorting,
along with sorting subroutines.

OS traps OS-specific traps.

DBM traps Traps specific to the use of dbmopen() and specific dbm implementations.

Unclassified traps Everything else.

If you find an example of a conversion trap that is not listed here, please submit it to the Perl5 Porters <perl5-porters@nicoh.com> for inclusion. Also note that at least some of these can be caught with the command-line option, -w.

Discontinuance, Deprecation, and BugFix Traps

Anything that has been discontinued, deprecated, or fixed as a bug from Perl4.

Discontinuance

package test;

$_legacy = 1;

package main;

print "\$_legacy is ",$_legacy,"\n";

# perl4 prints: $_legacy is 1

# perl5 prints: $_legacy is

goto marker1;

for(1){

marker1:

print "Here I is!\n";

}

# perl4 prints: Here I is!

# perl5 dumps core (SEGV)

$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

if { 1 } {

print "True!";

}

else {

print "False!";

}

# perl4 prints: True!

# perl5 errors: syntax error at test.pl line 1, near "if {"

@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

foreach $var (grep(/ab/,@list)){

foreach $var (@tmp = grep(/ab/,@list)){

$_ = ' hi mom';

print join(`:', split);

# perl4 prints: :hi:mom

# perl5 prints: hi:mom

Deprecation

$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

$x = 10 ;

print "x=${`x}\n" ;

# perl4 prints: x=10

# perl5 prints: Can't find string terminator "'" anywhere before EOF

BugFix

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

print -4**2,"\n";

# perl4 prints: 16

# perl5 prints: -16

Parsing Traps

Perl4 to Perl5 traps having to do with parsing.

$string . = "more string";

print $string;

# perl4 prints: more string

# perl5 prints: syntax error at - line 1, near ". ="

sub foo {}

&foo

print("hello, world\n");

# perl4 prints: hello, world

# perl5 prints: syntax error

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

Numerical Traps

Perl4 to Perl5 traps having to do with numerical operators, operands, or output from same.

print 7.373504 - 0, "\n";

printf "%20.18f\n", 7.373504 - 0;

# Perl4 prints:

7.375039999999996141

7.37503999999999614

# Perl5 prints:

7.373504

7.37503999999999614

$p = ($test == 1); print $p,"\n";

# perl4 prints: 0

# perl5 prints:

General Data Type Traps

Perl4 to Perl5 traps involving most data types and their usage within certain expressions and/or context.

Scalar Arrays

@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

@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

Hashes

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

Globs

@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

Scalar String

$x = "aaa";

print ++$x," : ";

print -$x," : ";

print ++$x,"\n";

# perl4 prints: aab : -0 : 1

# perl5 prints: aab : -aab : aac

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

Scalars

print "$x", defined $x

# perl 4: 1

# perl 5: <no output, $x is not called into existence>

Variable Suicide

$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

Context Traps--Scalar and List Contexts

Traps that involve scalar versus list contexts.

List Context

@fmt = ("foo","bar","baz");

format STDOUT=

@<<<<< @||||| @>>>>>

@fmt;

.

write;

# perl4 errors: "Please use commas to separate fields in file" if using -w

# perl5 prints: foo bar baz

Scalar Context

caller() ? (print "You rang?\n") : (print "Got a 0\n");

# perl4 errors: There is no caller

# perl5 prints: Got a 0

@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

List--Builtin

@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

printf() works fine, though:

printf STDOUT (@z);

print "\n";

# perl4 prints: foobar

# perl5 prints: foobar

Precedence Traps

Perl4 to Perl5 traps involving precedence of operations and ordering.

@arr = ( 'left', 'right' );

$a{shift @arr} = shift @arr;

print join( ' ', keys %a );

# perl4 prints: left

# perl5 prints: right

@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

/foo/ ? ($a += 2) : ($a -= 2);

/foo/ ? $a += 2 : $a -= 2

(/foo/ ? $a += 2 : $a) -= 2;

$a += /foo/ ? 1 : 2;

open FOO || die;

open(FOO || die);

# perl4 opens or dies

# perl5 errors: Precedence problem: open FOO should be open(FOO)

$a = "x"; print "$::a";

# perl 4 prints: -:a

# perl 5 prints: x

-e $foo .= "q"

# perl4 prints: no output

# perl5 prints: Can't modify -e in concatenation

@arr = ( 'left', 'right' );

$a{shift @arr} = shift @arr;

print join( ' ', keys %a );

# perl4 prints: left

# perl5 prints: right

General Regular Expression Traps Using s///

All types of regular expression and regular expression operator traps.

$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

$_ = "ababab";

while(m/ab/g){

&doit("blah");

}

sub doit{local($_) = shift; print "Got $_ "}

# perl4 prints: blah blah blah

# perl5 prints: infinite loop blah...

$string = "test";

$value = ($string =~ s/foo//);

print $value, "\n";

# perl4 prints: 0

# perl5 prints:

$string = "";

$string =~ s'^'hostname';

print $string, "\n";

# perl4 prints: <the local hostname>

# perl5 prints: hostname

s/^([^$grpc]*$grpc[$opt$plus$rep]?)//o;

# perl4: compiles w/o error

# perl5: with Scalar found where operator expected ..., near "$opt$plus"

$grpc = 'a';

$opt = 'r';

$_ = 'bar';

s/^([^$grpc]*$grpc[$opt]?)/foo/;

print ;

# perl4 prints: foo

# perl5 prints: foobar

$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

Subroutine, Signal, Sorting Traps

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.

Signal Handler Subroutines

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

Sort Subroutine

sub reverse{ print "yup "; $a <=> $b }

print sort reverse a,b,c;

# perl4 prints: yup yup yup yup abc

# perl5 prints: abc

warn() Filehandle

warn STDERR "Foo!";

# perl4 prints: Foo!

# perl5 prints: String found where operator expected

System V OS Traps

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...

Interpolation Traps

Perl4 to Perl5 traps having to do with how things get interpolated within certain expressions, statements, contexts, or whatever.

print "To: someone@somewhere.com\n";

# perl4 prints: To:someone@somewhere.com

# perl5 errors : Literal @somewhere now requires backslash

$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

@www = "buz";

$foo = "foo";

$bar = "bar";

sub foo { return "bar" };

print "|@{w.w.w}|${main'foo}|";

# perl4 prints: |@{w.w.w}|foo|

# perl5 prints: |buz|bar|

print "this is $$x\n";

# perl4 prints: this is XXXx (XXX is the current pid)

# perl5 prints: this is

$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

eval "\$\$hashname{`$key'} = q|$value|";

causes the following result:

# perl4 prints: Nope

# perl5 prints: Yup

or, changing to

eval "\$$hashname\{`$key'\} = q|$value|";

causes the following result:

# perl4 prints: Yup

# perl5 prints: Yup

# and is compatible for both versions

perl -e '$bar=q/not/; print "This is $foo{$bar} perl5"'

# perl4 prints: This is not perl5

# perl5 prints: This is perl5

print "$foo{"

perl 4 prints: {

perl 5 prints: syntax error

$foo = "array";

print "\$$foo{bar}\n";

# perl4 prints: $array{bar}

# perl5 prints: $

eval qq(

foreach \$y (keys %\$x\) {

\$count++;

}

);

# perl4 runs this ok

# perl5 prints: Can't find string terminator ")"

DBM Traps

General DBM traps.

dbmopen (%dbm, "file", undef);

print "ok\n";

# perl4 prints: ok

# perl5 prints: ok (IFF linked with -ldbm or -lndbm)

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.

Unclassified Traps



Everything else.

sub foo {

$rc = do "./do.pl";

return 8;

}

print &foo, "\n";

return 3;

# perl 4 prints: 3 (aborts the subroutine early)

# perl 5 prints: 8