📄 appa.htm
字号:
</UL>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>$string = "test";</P>
<P>$value = ($string =~ s/foo//);</P>
<P>print $value, "\n";</P>
<P># perl4 prints: 0</P>
<P># perl5 prints:
</BLOCKQUOTE>
</BLOCKQUOTE>
<UL>
<LI>Also see the section "Numerical Traps" for another example of this
new feature.
<LI>s'lhs'rhs' (using backticks) is now a normal substitution, with no backtick expansion.
</UL>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>$string = "";</P>
<P>$string =~ s'^'hostname';</P>
<P>print $string, "\n";</P>
<P># perl4 prints: <the local hostname></P>
<P># perl5 prints: hostname
</BLOCKQUOTE>
</BLOCKQUOTE>
<UL>
<LI>Stricter parsing of variables is used in regular expressions.
</UL>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>s/^([^$grpc]*$grpc[$opt$plus$rep]?)//o;</P>
<P># perl4: compiles w/o error</P>
<P># perl5: with Scalar found where operator expected ..., near "$opt$plus"
</BLOCKQUOTE>
</BLOCKQUOTE>
<UL>
<LI>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.
</UL>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>$grpc = 'a';</P>
<P>$opt = 'r';</P>
<P>$_ = 'bar';</P>
<P>s/^([^$grpc]*$grpc[$opt]?)/foo/;</P>
<P>print ;</P>
<P># perl4 prints: foo</P>
<P># perl5 prints: foobar
</BLOCKQUOTE>
</BLOCKQUOTE>
<UL>
<LI>Under Perl5, m?x? matches only once, like ?x?. Under Perl4, it matched repeatedly,
like <BR>
/x/ or m!x!.
</UL>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>$test = "once";</P>
<P>sub match { $test =~ m?once?; }</P>
<P>&match();</P>
<P>if( &match() ) {</P>
<P># m?x? matches more then once</P>
<P>print "perl4\n";</P>
<P>} else {</P>
<P># m?x? matches only once</P>
<P>print "perl5\n";</P>
<P>}</P>
<P># perl4 prints: perl4</P>
<P># perl5 prints: perl5
</BLOCKQUOTE>
</BLOCKQUOTE>
<H3 ALIGN="CENTER"><A NAME="Heading23"></A><FONT COLOR="#000077">Subroutine, Signal,
Sorting Traps</FONT></H3>
<P>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.
<H4 ALIGN="CENTER"><A NAME="Heading24"></A><FONT COLOR="#000077">Signal Handler Subroutines</FONT></H4>
<UL>
<LI>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.
</UL>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>sub SeeYa { warn"Hasta la vista, baby!" }</P>
<P>$SIG{`TERM'} = SeeYa;</P>
<P>print "SIGTERM is now $SIG{`TERM'}\n";</P>
<P># perl4 prints: SIGTERM is main'SeeYa</P>
<P># perl5 prints: SIGTERM is now main::1
</BLOCKQUOTE>
</BLOCKQUOTE>
<UL>
<LI>Use -w to catch this one.
</UL>
<H4 ALIGN="CENTER"><A NAME="Heading25"></A><FONT COLOR="#000077">Sort Subroutine</FONT></H4>
<UL>
<LI>reverse is no longer allowed as the name of a sort subroutine.
</UL>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>sub reverse{ print "yup "; $a <=> $b }</P>
<P>print sort reverse a,b,c;</P>
<P># perl4 prints: yup yup yup yup abc</P>
<P># perl5 prints: abc
</BLOCKQUOTE>
</BLOCKQUOTE>
<H4 ALIGN="CENTER"><A NAME="Heading26"></A><FONT COLOR="#000077">warn() Filehandle</FONT></H4>
<H4 ALIGN="CENTER"><FONT COLOR="#000077"></FONT></H4>
<UL>
<LI>Although it always printed to STDERR, warn() would let you specify a filehandle
in Perl4. With Perl5 it does not.
</UL>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>warn STDERR "Foo!";</P>
<P># perl4 prints: Foo!</P>
<P># perl5 prints: String found where operator expected
</BLOCKQUOTE>
</BLOCKQUOTE>
<H3 ALIGN="CENTER"><A NAME="Heading27"></A><FONT COLOR="#000077">System V OS Traps</FONT></H3>
<H3 ALIGN="CENTER"><FONT COLOR="#000077"></FONT></H3>
<UL>
<LI>Under HPUX, and some other System V Operating Systems, one had to reset any signal
handler, within the signal handler function, each time a signal was handled when
using Perl4. With Perl5, the reset is now done correctly. Any code relying on the
handler not being reset will have to be reworked.
<P>
<LI>Perl5.002 and later uses sigaction() to handle signals under System V.
</UL>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>sub gotit {</P>
<P>print "Got @_... ";</P>
<P>}</P>
<P>$SIG{`INT'} = 'gotit';</P>
<P>$| = 1;</P>
<P>$pid = fork;</P>
<P>if ($pid) {</P>
<P>kill(`INT', $pid);</P>
<P>sleep(1);</P>
<P>kill(`INT', $pid);</P>
<P>} else {</P>
<P>while (1) {sleep(10);}</P>
<P>}</P>
<P># perl4 (HPUX) prints: Got INT...</P>
<P># perl5 (HPUX) prints: Got INT... Got INT...
</BLOCKQUOTE>
</BLOCKQUOTE>
<H3 ALIGN="CENTER"><A NAME="Heading28"></A><FONT COLOR="#000077">Interpolation Traps</FONT></H3>
<H3 ALIGN="CENTER"><FONT COLOR="#000077"></FONT></H3>
<P>Perl4 to Perl5 traps having to do with how things get interpolated within certain
expressions, statements, contexts, or whatever.
<UL>
<LI>@ now always interpolates an array in double-quotish strings.
</UL>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>print "To: someone@somewhere.com\n";</P>
<P># perl4 prints: To:someone@somewhere.com</P>
<P># perl5 errors : Literal @somewhere now requires backslash
</BLOCKQUOTE>
</BLOCKQUOTE>
<UL>
<LI>Double-quoted strings may no longer end with an unescaped $ or @.
</UL>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>$foo = "foo$";</P>
<P>$bar = "bar@";</P>
<P>print "foo is $foo, bar is $bar\n";</P>
<P># perl4 prints: foo is foo$, bar is bar@</P>
<P># perl5 errors: Final $ should be \$ or $name
</BLOCKQUOTE>
</BLOCKQUOTE>
<UL>
<LI>Note: Perl5 does not error on the terminating @ in $bar.
<P>
<LI>m Perl now sometimes evaluates arbitrary expressions inside braces that occur
within double quotes (usually when the opening brace is preceded by $ or @).
</UL>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>@www = "buz";</P>
<P>$foo = "foo";</P>
<P>$bar = "bar";</P>
<P>sub foo { return "bar" };</P>
<P>print "|@{w.w.w}|${main'foo}|";</P>
<P># perl4 prints: |@{w.w.w}|foo|</P>
<P># perl5 prints: |buz|bar|
</BLOCKQUOTE>
</BLOCKQUOTE>
<UL>
<LI>Note that you can use strict; to ward off such trappiness under Perl5.
<P>
<LI>The quoted string "this is $$x" used to interpolate the pid at that
point but now tries to dereference $x. $$ by itself still works fine.
</UL>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>print "this is $$x\n";</P>
<P># perl4 prints: this is XXXx (XXX is the current pid)</P>
<P># perl5 prints: this is
</BLOCKQUOTE>
</BLOCKQUOTE>
<UL>
<LI>Creation of hashes on the fly with 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.
</UL>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>$hashname = "foobar";</P>
<P>$key = "baz";</P>
<P>$value = 1234;</P>
<P>eval "\$$hashname{`$key'} = q|$value|";</P>
<P>(defined($foobar{`baz'})) ? (print "Yup") : (print "Nope");</P>
<P># perl4 prints: Yup</P>
<P># perl5 prints: Nope</P>
<P>Changing</P>
<P>eval "\$$hashname{`$key'} = q|$value|";</P>
<P>to</P>
<P>eval "\$\$hashname{`$key'} = q|$value|";</P>
<P>causes the following result:</P>
<P># perl4 prints: Nope</P>
<P># perl5 prints: Yup</P>
<P>or, changing to</P>
<P>eval "\$$hashname\{`$key'\} = q|$value|";</P>
<P>causes the following result:</P>
<P># perl4 prints: Yup</P>
<P># perl5 prints: Yup</P>
<P># and is compatible for both versions
</BLOCKQUOTE>
</BLOCKQUOTE>
<UL>
<LI>Watch out forPerl4 programs which unconsciously rely on the bugs in earlier Perl
versions.
</UL>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>perl -e '$bar=q/not/; print "This is $foo{$bar} perl5"'</P>
<P># perl4 prints: This is not perl5</P>
<P># perl5 prints: This is perl5
</BLOCKQUOTE>
</BLOCKQUOTE>
<UL>
<LI>You also have to be careful about array references.
</UL>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>print "$foo{"</P>
<P>perl 4 prints: {</P>
<P>perl 5 prints: syntax error
</BLOCKQUOTE>
</BLOCKQUOTE>
<UL>
<LI>Similarly, watch out for
</UL>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>$foo = "array";</P>
<P>print "\$$foo{bar}\n";</P>
<P># perl4 prints: $array{bar}</P>
<P># perl5 prints: $
</BLOCKQUOTE>
</BLOCKQUOTE>
<UL>
<LI>Perl5 is looking for $array{bar} which doesn't exist, but Perl4 is happy just
to expand $foo to "array" by itself. Watch out for this especially in eval()s.
<P>
<LI>m qq() string passed to eval.
</UL>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>eval qq(</P>
<P>foreach \$y (keys %\$x\) {</P>
<P>\$count++;</P>
<P>}</P>
<P>);</P>
<P># perl4 runs this ok</P>
<P># perl5 prints: Can't find string terminator ")"
</BLOCKQUOTE>
</BLOCKQUOTE>
<H3 ALIGN="CENTER"><A NAME="Heading29"></A><FONT COLOR="#000077">DBM Traps</FONT></H3>
<H3 ALIGN="CENTER"><FONT COLOR="#000077"></FONT></H3>
<P>General DBM traps.
<UL>
<LI>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 dbmopen() to function properly without
tieing to an extension dbm implementation.
</UL>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>dbmopen (%dbm, "file", undef);</P>
<P>print "ok\n";</P>
<P># perl4 prints: ok</P>
<P># perl5 prints: ok (IFF linked with -ldbm or -lndbm)
</BLOCKQUOTE>
</BLOCKQUOTE>
<UL>
<LI>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.
</UL>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>dbmopen(DB, "testdb",0600) || die "couldn't open db! $!";</P>
<P>$DB{`trap'} = "x" x 1024; # value too large for most dbm/ndbm</P>
<P>print "YUP\n";</P>
<P># perl4 prints:</P>
<P>dbm store returned -1, errno 28, key "trap" at - line 3.</P>
<P>YUP</P>
<P># perl5 prints:</P>
<P>dbm store returned -1, errno 28, key "trap" at - line 3.
</BLOCKQUOTE>
</BLOCKQUOTE>
<H3 ALIGN="CENTER"><A NAME="Heading30"></A><FONT COLOR="#000077">Unclassified Traps</FONT></H3>
<H2 ALIGN="CENTER"></H2>
<H3 ALIGN="CENTER"><FONT COLOR="#000077"><BR>
<BR>
</FONT></H3>
<P>Everything else.
<UL>
<LI>require/do trap using returned value.
<LI>If the file doit.pl has
</UL>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>sub foo {</P>
<P>$rc = do "./do.pl";</P>
<P>return 8;</P>
<P>}</P>
<P>print &foo, "\n";
</BLOCKQUOTE>
</BLOCKQUOTE>
<UL>
<LI>and the do.pl file has the following single line
</UL>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>return 3;
</BLOCKQUOTE>
</BLOCKQUOTE>
<UL>
<LI>running doit.pl gives the following
</UL>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P># perl 4 prints: 3 (aborts the subroutine early)</P>
<P># perl 5 prints: 8
</BLOCKQUOTE>
</BLOCKQUOTE>
<UL>
<LI>The same behavior occurs if you replace do with require.
<P>
<LI>As always, if any of these are ever officially declared as bugs, they'll be fixed
and removed.<FONT COLOR="#000077"></FONT>
</UL>
<H2 ALIGN="CENTER"><A HREF="ch16.htm" tppabs="http://210.32.137.15/ebook/Web%20Programming%20with%20Perl%205/ch16.htm"><IMG SRC="blanprev.gif" tppabs="http://210.32.137.15/ebook/Web%20Programming%20with%20Perl%205/blanprev.gif" WIDTH="37" HEIGHT="37"
ALIGN="BOTTOM" BORDER="2"></A><A HREF="index-1.htm" tppabs="http://210.32.137.15/ebook/Web%20Programming%20with%20Perl%205/index-1.htm"><IMG SRC="blantoc.gif" tppabs="http://210.32.137.15/ebook/Web%20Programming%20with%20Perl%205/blantoc.gif" WIDTH="42"
HEIGHT="37" ALIGN="BOTTOM" BORDER="2"></A>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -