use strict
.
allows you to refer to special variables (like $RS) as though they were in awk; see the perlvar manpage for details.
if
s and while
s.
$,
and $\
. You can set $OFS and $ORS if you're using
the English module.
/pat/ /pat/
unparsable, since the third slash
would be interpreted as a division operator--the tokener is in fact
slightly context sensitive for operators like ``/'', ``?'', and ``>''.
And in fact, ``.'' itself can be the beginning of a number.)
next
, exit
, and continue
keywords work differently.
The following variables work differently:
if
's and while
's.
elsif
rather than else if
.
break
and continue
keywords from C become in
Perl last
and next
, respectively.
Unlike in C, these do NOT work within a do { } while
construct.
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.
ARGV
must be capitalized. $ARGV[0]
is C's argv[1]
, and argv[0]
ends up in $0
.
kill -l
to find their names on your system.
...
, rather than comma.
BEGIN
blocks, which
execute at compile time).
=
'' when you need ``=~
'';
these two constructs are quite different:
do {}
construct isn't a real loop that you can use
loop control on.
my()
for local variables whenever you can get away with
it (but see the perlform manpage
for where you can't).
Using local()
actually gives a local value to a global
variable, which leaves you open to unforeseen side-effects
of dynamic scoping.
They're crudely ordered according to the following list:
dbmopen()
, and specific dbm implementations.
-w
.
$_
itself (and @_
, etc.).
Given 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)
Also see precedence traps, for parsing $:
.
splice()
are now evaluated in scalar
context (as the Camel says) rather than list context.
goto
into a block that is optimized away. Darn.
**
operator now binds more tightly than unary minus.
It was documented to work this way before, but didn't.
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 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
to
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 $_
.)
split
with no arguments now behaves like split ' '
(which doesn't
return an initial null field if $_ starts with whitespace), it used to
behave like split /\s+/
(which does).
Also see the General Regular Expression Traps tests for another example of this new feature...
$#array
lower now discards array elements, and makes them
impossible to recover.
@fmt = (``foo'',``bar'',``baz''); format STDOUT= @<<<<< @||||| @>>>>> @fmt; . write; # perl4 errors: Please use commas to separate fields in file # perl5 prints: foo bar baz
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.
sprintf()
funkiness (array argument converted to scalar array count)
This test could be added to t/op/sprintf.t
printf()
works fine, though:
Probably a bug.
would be erroneously parsed as
On the other hand,
now works as a C programmer would expect.
is now incorrect. You need parens around the filehandle. Otherwise, perl5 leaves the statement as it's default precedence:
$:
precedence, where perl5
treats $::
as main package
s'$lhs'$rhs'
now does no interpolation on either side. It used to
interpolate $lhs
but not $rhs
. (And still does not match a literal
'$' in string)
m//g
now attaches its state to the searched string rather than the
regular expression. (Once the scope of a block is left for the sub, the
state of the searched string is lost)
$+
to
the whole match, just like $&
. Perl5 does not.
Also see Numerical Traps for another example of this new feature.
s`lhs`rhs`
(using backticks) is now a normal substitution, with no
backtick expansion
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
m?x?
matches only once, like ?x?
. Under perl4, it matched
repeatedly, like /x/
or m!x!
.
Use -w to catch this one
5.002 and beyond uses sigaction() under SysV
seek()
on a file opened to append >>
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
Note: perl5 DOES NOT error on the terminating @ in $bar
$
or @
).
Note that you can use strict;
to ward off such trappiness under perl5.
$x
. $$
by itself still
works fine, however.
eval ``EXPR''
now requires either both
$
'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 eval{}
if possible.
Changing
to
causes the following result:
or, changing to
causes the following result:
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.
qq()
string passed to eval
dbmopen()
to function properly without tie
'ing to an extension dbm implementation.
require
/do
trap using returned value
If the file doit.pl has:
And the do.pl file has the following single line:
Running doit.pl gives the following:
Same behavior if you replace do
with require
.