use English;allows you to refer to special variables (like $/) with names (like $RS), as though they were in awk; see the perlvar manpage for details.
Awk Perl ARGC $#ARGV or scalar @ARGV ARGV[0] $0 FILENAME $ARGV FNR $. - something FS (whatever you like) NF $#Fld, or some such NR $. OFMT $# OFS $, ORS $\ RLENGTH length($&) RS $/ RSTART length($`) SUBSEP $;
while (<FH>) { } while (defined($_ = <FH>)) { }.. <FH>; # data discarded!
$x = /foo/; $x =~ /foo/;
They're crudely ordered according to the following list:
If you find an example of a conversion trap that is not listed here, please submit it to Bill Middleton <wjm@best.com> for inclusion. Also note that at least some of these can be caught with -w.
package test; $_legacy = 1;
package main; print "\$_legacy is ",$_legacy,"\n";
# perl4 prints: $_legacy is 1 # perl5 prints: $_legacy is
$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: 3Given that :: 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)
$x = 10 ; print "x=${'x}\n" ;
# perl4 prints: x=10 # perl5 prints: Can't find string terminator "'" anywhere before EOFYou 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 $:.
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
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: Bareword 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 {"
print -4**2,"\n";
# perl4 prints: 16 # perl5 prints: -16
@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:defTo 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 $_ for the loop variable, and call subroutines in the loop that don't properly localize $_.)
$_ = ' hi mom'; print join(':', split);
# perl4 prints: :hi:mom # perl5 prints: hi:mom
perl -e'print "attached to -e"' 'print "separate arg"'
# perl4 prints: separate arg # perl5 prints: attached to -e
perl -e
# perl4 prints: # perl5 dies: No code specified for -e.
@x = ('existing'); print push(@x, 'first new', 'second new');
# perl4 prints: second new # perl5 prints: 3
print "foo";\015 print "bar";
# perl4 prints: foobar # perl5.003 prints: foobar # perl5.004 dies: Illegal character \015 (carriage return)See the perldiag manpage for full details.
$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
print 7.373504 - 0, "\n"; printf "%20.18f\n", 7.373504 - 0;
# Perl4 prints: 7.375039999999996141 7.37503999999999614
# Perl5 prints: 7.373504 7.37503999999999614
use Math::BigInt;
$p = ($test == 1); print $p,"\n";
# perl4 prints: 0 # perl5 prints:Also see the section on General Regular Expression Traps using s///, etc. for another example of this new feature...
@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
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
@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: In string, @fred now must be written as \@fred
$x = "aaa"; print ++$x," : "; print -$x," : "; print ++$x,"\n";
# perl4 prints: aab : -0 : 1 # perl5 prints: aab : -aab : aac
$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
print "$x", defined $x
# perl 4: 1 # perl 5: <no output, $x is not called into existence>
$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
@fmt = ("foo","bar","baz"); format STDOUT= @<<<<< @||||| @>>>>> @fmt; . write;
# perl4 errors: Please use commas to separate fields in file # perl5 prints: foo bar baz
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
@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 2printf() works fine, though:
printf STDOUT (@z); print "\n";
# perl4 prints: foobar # perl5 prints: foobarProbably a bug.
@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);Otherwise
/foo/ ? $a += 2 : $a -= 2would be erroneously parsed as
(/foo/ ? $a += 2 : $a) -= 2;On the other hand,
$a += /foo/ ? 1 : 2;now works as a C programmer would expect.
open FOO || die;is now incorrect. You need parentheses around the filehandle. Otherwise, perl5 leaves the statement as its default precedence:
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
$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...
sub build_match { my($left,$right) = @_; return sub { $_[0] =~ /$left stuff $right/o; }; }build_match() will always return a sub which matches the contents of $left and $right as they were the 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.
"abcdef" =~ /b.*e/; print "\$+ = $+\n";
# perl4 prints: bcde # perl5 prints:
$string = "test"; $value = ($string =~ s/foo//); print $value, "\n";
# perl4 prints: 0 # perl5 prints:Also see the section on Numerical Traps for another example of this new feature.
$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"an added component of this example, apparently from the same script, is the actual value of the s'd string after the substitution. [$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
$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
$test = "foop"; for (1..3) { print $1 while ($test =~ /(o)/g); # pos $test = 0; # to get old behavior }
# perl4 prints: oooooo # perl5.004 prints: ooYou may always reset the iterator yourself as shown in the commented line to get the old behavior.
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::1Use -w to catch this one
sub reverse{ print "yup "; $a <=> $b } print sort reverse a,b,c;
# perl4 prints: yup yup yup yup abc # perl5 prints: abc
warn STDERR "Foo!";
# perl4 prints: Foo! # perl5 prints: String found where operator expected
Since version 5.002, Perl 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...
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
print "To: someone@somewhere.com\n";
# perl4 prints: To:someone@somewhere.com # perl5 errors : In string, @somewhere now must be written as \@somewhere
$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 $nameNote: perl5 DOES NOT error on the terminating @ in $bar
@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|Note that you can use strict; to ward off such trappiness under perl5.
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: NopeChanging
eval "\$$hashname{'$key'} = q|$value|";to
eval "\$\$hashname{'$key'} = q|$value|";causes the following result:
# perl4 prints: Nope # perl5 prints: Yupor, 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: $Perl 5 is looking for $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 eval's.
eval qq( foreach \$y (keys %\$x\) { \$count++; } );
# perl4 runs this ok # perl5 prints: Can't find string terminator ")"
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.
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: 8Same behavior if you replace do with require.
$string = ''; @list = split(/foo/, $string, 2)Perl4 returns a one element list containing the empty string but Perl5 returns an empty list.
As always, if any of these are ever officially declared as bugs, they'll be fixed and removed.