PERLFAQ7 7
PERLFAQ7
NAMEDESCRIPTION æè¿°
AUTHOR AND COPYRIGHT
è¯è
NAME
perlfaq7 - 综åçé®é¢ (2003/07/24 02:17:21)
DESCRIPTION æè¿°
æ¬è讨论综åç Perl è¯è¨é®é¢ï¼ä¸éäºå¨å¶ä»æææ®µè½ä¸è®¨è®ºçé®é¢
æè½æ¿å° Perlç BNF/yacc/REåï¼
没æ BNF , 使¯ä½ å¯ä»¥ä»æºä»£ç ç perly.y æä»¶ç yacc è¯æ³ä¸- èªè¡å½çº³ï¼å¦æä½ è¶³å¤åæ¢çè¯ãè¯æ³ä¾èµäºé常æºè½çè¯æ³åæï¼å æ- ¤ä¹è¦åå¤å¥½é读 toke.cã
ç¨ Chaim Frenkelçè¯ï¼"Perlçè¯æ³æ æ³è¢«ç®åå°å¯ä»¥ç¨ BNF 表示ãè§£æPerlç工使¯åæ£äº yaccãlexerãçé¾åéåä¹é´ã"
$@%*è¿äºç¬¦å·æ¯ä»ä¹ææï¼ææä¹ç¥é使¶è¯¥ä½¿ç¨ä»ä»¬å¢ï¼
å®ä»¬é½æ¯ç±»åéå®ç¬¦å·ï¼å¨ perldata ä¸è¯¦è¿°ï¼
$
æ éå¼ï¼æ°åï¼å符串æå¼ç¨
@ æ°ç»
%
æ£åï¼å³èæ°ç»
&
åç¨åºï¼ä¹å°±æ¯å½æ°ï¼è¿ç¨ï¼æ¹æ³
*
代表è¿ä¸ªç¬¦å·çææç±»åãå¨çæ¬4ä¸ï¼å¯ä»¥ç¨ä½æéï¼ä½æ¯å¨æ°ç
perl
ä¸å¯ä»¥åªç¨å¼ç¨å°±å¯ä»¥äº
æäºå¶ä»ç符å·ä½ å¯è½ä¼ç¢°å°ä½å´ä¸æ¯æå®å½¢æç¨çæï¼
<>
è¿æ¯ç¨æ¥ä»ä¸ä¸ªæä»¶å¥æéè¾å¥ä¸ä»½è®°å½
\
åææ ·ä¸è¥¿çå¼ç¨
注æ < FILE > 䏿¯ç¨æ¥æå®æä»¶ç±»åï¼äº¦éæ¤å¥æçååãå®åªæ¯ å°<>è¿ä¸ªè¿ç®ç¬¦ä½ç¨å¨ FILEè¿ä¸ªå¥æä¸ã卿 éä¸ä¸æ (scalar context) ä¸- ï¼å®èª FILE ææä¸æ¬¡è¯»å¥ä¸è¡ (å¯ï¼è¯¥è¯´ä¸ç¬è®°å½ï¼åç $/)ï¼å¨åºåæå¢ (list context)ä¸ï¼å䏿¬¡å° å¨é¨çå容读 å¥ãå½å¯¹æ¡£æ¡ä½¿ç¨å¼ã峿å¶å® <>ä¹å¤çå¨ä½ãæçè³åªæ¯æå°æ ææ¶ï¼åè®°ä¸è¦ä½¿ç¨ <>ãä¸é¢çç¨æ³æ¯æ- £ç¡®çï¼"eof(FH)", "seek(FH, 0, 2)" 以å "copying from STDIN to FILE ".
å串å å¼å·æä½¿ç¨åå·åéå·æ¯å¦ç»å¯¹å¿è¦/è¿æ¯å®å¨æ²¡å¿è¦ï¼
é常ä¸ä¸ªæ²¡æå ä¸å½¢æç¬¦å·çå (bareword)æ¯ä¸é被纳å¥å¼å·éçï¼ä½å¨å¤§å¤æ°çæåµä¸æè®¸è¯¥è¿ä¹å (å¨ "use strict" ä¸åæ¯å¿é¡»ç)ãä½ç±ä¸ä¸ªç®åçå- (ä¸è½æ¯ä¸ä¸ªå·²å®ä¹çå¯å½æ°ä¹åç§°)æææçç´¢å¼å¼ï¼å "=>" 左端çè¿ç®å- ï¼é½ä¼è¢«è§ä¸ºå·²çº³å¥å¼å·äºï¼
è¿äº
åè¿äºä¸æ ·
------------ ---------------
$foo{line} $foo{"line"}
bar => stuff "bar" => stuff
ä¸ä¸ªåºåæ«ç«¯çåå·å¯æå¯æ ï¼ä¸ä¸ªåºåçæåä¸ä¸ªéå·äº¦åãè¯å¥½çåä½é£æ ¼ (åçperlstyle)ä¸å»ºè®®é¤äºå¨åè¡ç¨å¼ (one-liners)çæåµå¤é½å°ä»ä»¬å ä¸å»ï¼
if ($whoops) {
exit 1 }
@nums = (1, 2, 3);
if ($whoops) {
exit 1;
}
@lines = (
"There Beren came from mountains cold",
"And lost he wandered under leaves",
);
æå¦ä½è·³è¿ä¸äºä¼ åå¼ï¼
ä¸ç§æ¹æ³æ¯å°ä¼ åå¼å½ä½åºåæ¥å¯¹å¾ï¼ç¶åç¨ç´¢å¼æ¥æåå¶ä¸çæä¸ªä½ç½®ï¼
$dir = (getpwnam($user))[7];
å¦ä¸ç§æ¹æ³å°±æ¯å¨çå·å·¦ç«¯ç¨ undef ä½åç´ ï¼
($dev, $ino, undef, undef, $uid, $gid) = stat($file);
ä¹å¯ä»¥ç¨ä¸ä¸ªåè¡¨çæ®µæ¥ä»éæ©ä½ éè¦çåç´ ï¼
($dev, $ino, $uid, $gid) = ( stat($file) )[0,1,4,5];
æå¦ä½ææ¶æ»¤æè¦å讯æ¯ï¼
妿æ£å¨è¿è¡ Perl 5.6.0 ææ´é«çæ¬ï¼ "use warnings" ç¼ç¨å¯ä»¥å¯¹è- ¦åå¦ä½äº§çè¿è¡å¾å¥½çæ§å¶ãåè§ perllexwarn ä¸çç»è
{
no warnings; #
ææ¶å³æè¦å讯æ¯
$a = $b + $c; #
æç¥éè¿äºåæ°å¯è½æªå®ä¹
}
妿è¿è¡æ§çæ¬ç Perlï¼åé $ˆW (å¨ perlvar ä¸æè®°è½½) æ§å¶äºè¿ä¸ªåçè¿è¡æ¶è- ¦åï¼
{
local $ˆW = 0; #
ææ¶å³æè¦å讯æ¯
$a = $b + $c; #
æç¥éè¿äºåæ°å¯è½æªå®ä¹
}
注æï¼åææçæ ç¹ç¬¦å·åæ°ä¸æ ·ï¼ç®åä¸è½å¯¹ $ˆW ç¨ my()ï¼åªè½ç¨ local()ã
ä»ä¹æ¯ä¸ä¸ªæ©å?
ä¸ç§ä» Perlå¼å«ç¼è¯å¥½ç Cç¨å¼ç çæ¹æ³ãé读 perlxstutæ¯ä¸ªå¤äºè§£æ©å(extensions)çå¥½æ¹æ³ã
ä¸ºä½ Perlè¿ç®åçä¼å顺åºå Cçä¸ä¸æ ·ï¼
äºå®ä¸å®ä»¬æ¯ç¸åçãææ Perlèª Cåè¿æ¥çè¿ç®åé½å·å¤ä¸åæ¥å¨ C ä¸- ç¸åçä¼å顺åºãé®é¢åºå¨é£äº C没æçè¿ç®å- ï¼ç¹å«æ¯é£äºå°å¶å³æ¹ä¸å¾å½æåºåæå¢å¯¹å¾ç彿°ï¼ä¾å¦ print, chmod, execçç- ãè¿ç±»ç彿°è¢«ç§°ä½åºåè¿ç®å("list operators")ï¼å¨ perlopçä¼å顺åºè¡¨ä¸- å°±æ¯è¿ä¹ç§°å¼ã
ä¸ä¸ªå¸¸ç¯çéè¯¯åæ¯ï¼
unlink $file ⎪⎪ die "snafu";
è¿ä¼è¢«è§£è¯å¨çææ¯ï¼
unlink ($file ⎪⎪ die "snafu");
è¦é¿åæ¤é®é¢ï¼é¡»å 䏿¬å·ææ¯ç¨è¶ä½ä¼åç "or" è¿ç®åï¼
(unlink $file)
⎪⎪ die "snafu";
unlink $file or die "snafu";
è¿äºâè±æçâè¿ç®å (and, or, xor,å not)æ¯å»æè®¾è®¡æè¾ä¸è¬åºåè¿ç®å- ä½çä¼å顺åºï¼è¿å°±æ¯ä¸ºäºè§£å³åè¿°çç¶åµã
å¦ä¸ä¸ªæ¥æåºäººææçä¼å顺åºèä¸ºææ°ãå®çè³é«äºè´å·ï¼è¿ä½¿å¾ "-2**2"åæè´åè鿣åãä»åæ¶ä¹ä¼âåå³é â(right-associate)ï¼æææ¯è¯´ "2**3**2" 代表äºç乿¬¡æ¹ï¼è䏿¯å«çå¹³æ¹ã
Although it has the same precedence as in C, Perl’s "?:" operator produces an lvalue. This assigns $x to either $a or $b, depending on the trueness of $maybe:
($maybe ? $a : $b) = $x;
æå¦ä½å£°æ/å建ä¸ä¸ªæ°æ®ç»æï¼
ä¸è¬æ¥è¯´ï¼æä»¬ä¸ ‘‘声撒 ä¸ä¸ªç»æãç¨ä¸ä¸ª (é常æ¯å¿åç) æ£åçå¼ç¨ (hash reference)å³å¯ãåç perlref 以å perldscï¼é颿æ´å¤èµæã以䏿¯ä¸ä¸ªèä¾ï¼
$person = {}; #
new anonymous hash
$person->{AGE} = 24; # set field AGE to 24
$person->{NAME} = "Nat"; # set field NAME to
"Nat"
å¦æä½ è¦çæ¯æ´ä¸¥è°¨çåæ³ï¼çç perltoot ã
å¦ä½å建ä¸ä¸ªæ¨¡åï¼
ä¸ä¸ªæ¨¡ç»å°±æ¯ä¸ä¸ªæ¾å¨ååæ¡£æ¡éçå裹(package)ãä¾å¦ï¼Hello::There模ç»ä¼æ¾å¨Hello/There.pmãperlmod éæè¯¦å°½è¯´æãExporter ä¹ä¼å¾æå¸®å©ãå¦æä½ æ£å¨åä¸ä¸ª C ææ¯æ··åäº Cå Perl çæ¨¡ç»ï¼é£ä¹ä½ 就该读 perlxstut ã
The "h2xs" program will create stubs for all the important stuff for you:
% h2xs -XA -n My::Module
The "-X" switch tells "h2xs" that you are not using "XS" extension code. The "-A" switch tells "h2xs" that you are not using the AutoLoader, and the "-n" switch specifies the name of the module. See h2xs for more details.
å¦ä½å建ä¸ä¸ªç±»ï¼
perltoot é颿坹äºç±»å对象çä»ç»ï¼ perlobj å perlbot 乿ã
å¦ä½ç¥éä¸ä¸ªå鿝妿¯æ±¡æçï¼
å¯ä»¥ä½¿ç¨ Scalar::Util 模åä¸ç tainted() 彿° (å¯ä» CPAN è·åï¼ä¹åå«å¨ Perl 5.8.0 ä¸)ãåè§ perlsec ä¸ç "Laundering and Detecting Tainted Data" ã
ä»ä¹æ¯éåï¼
å³äºéåç说æï¼è¯·ç perlref ã
éå (closure)æ¯ä¸ªç²¾ç¡®ä½åå¾é¾è§£éçè®¡ç®æºç§å¦åè¯ãå¨ Perl éé¢ï¼é- 忝以å¿å彿°ç形弿¥å®ç°ï¼å·ææç»åç§ä½äºè¯¥å½æ°èå´ä¹å¤çæå- å¼åæ°å¼çè½åãè¿äºå¤é¨çæååæ°ä¼ç¥å¥å°ä¿çå®ä»¬å¨éå彿°æåå®ä¹æ¶çå¼ (æ·±è¿ç»)ã
妿ä¸ä¸ªç¨å¼è¯è¨å®¹è®¸å½æ°éåå¦ä¸ä¸ªå½æ°çè¯ (å Perl å°±æ¯)ï¼é- åä¾¿å·ææä¹ãè¦æ³¨æçæ¯ï¼æäºè¯è¨è½æä¾å¿å彿°çåè½ï¼ä½å´æ æ³æ£ç¡®å¤çéåï¼ Python è¿ä¸ªè¯è¨ä¾¿æ¯ä¸ä¾ãå¦æè¦æ³å¤äºè§£é- åçè¯ï¼å»ºè®®ä½ 廿¾æ¬åè½æ§ç¨å¼è®¾è®¡çæç§ä¹¦æ¥çãSchemeè¿ä¸ªè¯- è¨ä¸ä»æ¯æ´éåï¼æ´é¼å±å¤å 使ç¨ã
以䏿¯ä¸ªå¸åç产ç彿°ç彿°ï¼
sub
add_function_generator {
return sub { shift + shift };
}
$add_sub =
add_function_generator();
$sum = $add_sub->(4,5); # $sum is 9 now.
éåç¨èµ·æ¥å°±åæ¯ä¸ª 彿°æ ·æ¿ï¼å¶ä¸ä¿çäºä¸äºå¯ä»¥å¨ç¨ååå¡«å¥çç©ºæ ¼ã add_function_generator() æéåçå¿å彿°å¨ææ¯ä¸æ¥è®²å¹¶ä¸è½ç®æ¯ä¸ä¸ªé- åï¼å ä¸ºå®æ²¡æç¨å°ä»»ä½ä½å¨è¿ä¸ªå½æ°èå´ä¹å¤çæååæ°ã
æä¸é¢è¿ä¸ªä¾ååä¸é¢è¿ä¸ª make_adder()彿°å¯¹ç§ä¸ä¸ï¼ä¸é¢è¿ä¸ªå½æ°æéåçå¿å彿°ä¸- 使ç¨äºä¸ä¸ªå¤é¨çæååæ°ãè¿ç§æåå¤é¨å½æ°ç使³éè¦ç± Perléåä¸ä¸ªéå½çéåï¼å æ- ¤é£ä¸ªæååæ°å¨å¿å彿°äº§ç乿¶çå¼ä¾¿æ°¸ä¹å°è¢«éè¿é åéã
sub make_adder {
my $addpiece = shift;
return sub { shift + $addpiece };
}
$f1 =
make_adder(20);
$f2 = make_adder(555);
è¿æ ·ä¸æ¥ "&$f1($n)" æ°¸è¿ä¼æ¯ 20å ä¸ä½ ä¼ è¿å»çå¼ $n ï¼è "&$f2($n)" å° æ°¸è¿ä¼æ¯ 555å ä¸ä½ ä¼ è¿å»çå¼ $nã$addpiece çå¼ä¼å¨éåä¸ä¿ç䏿¥ã
éå卿¯è¾å®éçåºåä¸ä¹å¸¸ç¨å¾å°ï¼è¬å¦å½ä½ æ³æä¸äºç¨å¼ç ä¼ å¥ä¸ä¸ªå½æ°æ¶ï¼
my $line;
timeout( 30, sub { $line = <STDIN> } );
å¦æè¦æ§è¡çç¨å¼ç å½åæ¯ä»¥å串çå½¢å¼ä¼ å¥çè¯ï¼å³ ’$line = <STDIN>’ ï¼é£ä¹ timeout() è¿ä¸ªåæ³ç彿°å¨åå°è¯¥å½æ°è¢«å¼å«æ¶æå¨çèå´åä¾¿æ æ³åæ·å $line è¿ä¸ªæååæ°çå¼äºã
ä»ä¹æ¯åéèªæï¼æåºè¯¥ææ ·é²æ¢å®ï¼
åæ°èªææçæ¯ (ææ¶ææ¯æ°¸ä¹)å°å¤±å»ä¸ä¸ªåæ°çå¼ãé æè¿ä¸ªç°è±¡çåå æ¯åèå´çå®ç my() å local()åéåæ foreach()åååæ°å彿°åæ°ç¸äºå½±å æè´ãè¿å»å¾å®¹æå¶å°ä¸¢å¤±åéï¼ç°å¨å°±å°é¾å¤äºï¼å¯ä»¥è¯è¯è¿æ®µä»£ç ï¼
my $f =
"foo";
sub T {
while ($i++ < 3) { my $f = $f; $f .= "bar";
print $f, "\n" }
}
T;
print "Finally $f\n";
æå个 "bar" å è¿å»ç $f åæ°åºè¯¥æ¯ä¸ä¸ªæ°ç $f (å 为 "my $f" 卿¯ä¸ªå¾ªç¯é½åºè¯¥åé ä¸ä¸ªæ°çåºååæ°)ãç¶èï¼å®éä¸å¹¶é妿¤ãè¿ä¸ªèè«ææ°ç Perl çæ¬ä¸å·²è¢«ä¿®æ£ (å¨ 5.004_05, 5.005_03 å 5.005_56 䏿µè¯è¿)ã
å¦ä½ä¼ é/è¿åä¸ä¸ª{彿° Function, æä»¶å¥æ FileHandle, æ°ç» Array,æ£å Hash, æ¹æ³ Method, æ£åè¡¨è¾¾å¼ Regex}?
é¤äºæ£è§è¡¨ç°å¼è¿ä¸ªç¹ä¾å¤ï¼ä½ éè¦ä»¥ä¼ åèå¼çæ¹å¼ä¼ èµæç»è¿äºç©ä»¶ãåç perlsub ä¸ç "Pass by Reference"ï¼é颿é对æ¤é®é¢ç讨论ï¼ä»¥å perlref é颿å¼ç¨çèµè®¯ã
åè§ä¸é¢ç
‘‘Passing
Regexes’’ï¼å¦ä¹ å¦ä½ä¼ 鿣å表达å¼ã
ä¼ éåéå彿°
ä¸è¬çåæ°å彿°æ¯ç¸å½ç®åçï¼åªè¦ä¼ ä¸ä¸ªæåç°åçå¿ååæ°æå½æ°çåèå¼å³å¯ï¼
func( \$some_scalar );
func(
\@some_array );
func( [ 1 .. 10 ] );
func(
\%some_hash );
func( { this => 10, that => 20 } );
func(
\&some_func );
func( sub { $_[0] ** $_[1] } );
ä¼ éæä»¶å¥æ
å¨ Perl5.6 ä¸- ï¼ä½ å¯ä»¥ç¨æ éåé表示æä»¶å¥æï¼å¹¶å°å®ä¸å¶ä»æ éåæ ·å¤ç
open my $fh,
$filename or die "Cannot open $filename! $!";
func( $fh );
sub func {
my $passed_fh = shift;
my $line =
<$fh>;
}
å¨ Perl5.6 ä¹åï¼å¿é¡»ç¨ *FH æ "\*FH" è¯æ³ãè¿å«å "typeglobs"--åè§ perldata ä¸ç "Typeglobs and Filehandles" å perlsub ä¸ç "Pass by Reference"ã
ä¼ éæ£å表达å¼
è¦ä¼ 鿣å表达å¼ï¼ä½ éè¦ä½¿ç¨è¶³å¤æ°ç Perl åè¡ï¼è¶³ä»¥æ¯æ "qr//" æé æ¹å¼ççæ¬ï¼ä¼ éå符串ï¼ä½¿ç¨ä¸ä¸ªæè·å¼å¸¸ç evalï¼æèå¶ä»æ´èªæçåæ³ã
è¿éæä¸ä¸ªå¦ä½ä¼ 鿣å表达å¼å符串çä¾åï¼ä½¿ç¨ "qr//":
sub compare($$)
{
my ($val1, $regex) = @_;
my $retval = $val1 =˜ /$regex/;
return $retval;
}
$match = compare("old McDonald", qr/d.*D/i);
注æ "qr//" å¦ä½å许å¨åé¢å 䏿 å¿ãè¿ä¸ªæ¨¡å¼å¨ç¼è¯æè¢«ç¼è¯ï¼å°½ç®¡å®åæ¥ææ§è¡ã "qr//" 表示æ³è½ç¶å¥½ç¨ï¼ä½æ¯ç´å° 5.005 åè¡ä¸- æå¼å¥ãå¨é£ä¹åï¼ä½ å¿é¡»ç¨ä¸ç´è§çåæ³ãä¾å¦ï¼å¦ææ²¡æ "qr//" çè¯:
sub compare($$)
{
my ($val1, $regex) = @_;
my $retval = eval { $val1 =˜ /$regex/ };
die if $@;
return $retval;
}
$match = compare("old McDonald", q/($?i)d.*D/);
ç¡®ä¿ä½ 没æä»»ä½è¿æ ·çä¸è¥¿ï¼
return eval "\$val =˜ /$regex/"; # WRONG
å¦åå«äººä¼é åå¼å·æ¬èµ·æ¥çå串以å eval åéè§£è¯çæ¬è´¨èå·å·æå¥ shellæä»¤æ¥ä½åäºãä¾å¦ï¼
$pattern_of_evil = ’danger ${ system("rm -rf * &") } danger’;
eval "\$string =˜ /$pattern_of_evil/";
æ³å¦é常éå¸¸èªæçæ¹æ³ç读èå¯ä»¥åè O’Reilly åºç Mastering Regular Expressionsè¿æ¬ä¹¦ï¼ä½èæ¯ Jeffrey Friedlãå¶ä¸ç¬¬ 273页ç Build_MatchMany_Function()ç¹å«çæè¶£ãå¨ perlfaq2ä¸å¯ä»¥æ¾å°æå³æ¬ä¹¦ çèµæã
ä¼ éæ¹æ³
è¦ä¼ éä¸ä¸ªå¯¹è±¡æ¹æ³ç»ä¸ä¸ªå½æ°ï¼å¯ä»¥è¿æ ·åï¼
call_a_lot(10,
$some_obj, "methname")
sub call_a_lot {
my ($count, $widget, $trick) = @_;
for (my $i = 0; $i < $count; $i++) {
$widget->$trick();
}
}
æèï¼ä½¿ç¨ä¸ä¸ªé忥åå«è¿ä¸ªå¯¹è±¡ï¼å®çæ¹æ³è°ç¨ååæ°ï¼
my $whatnot =
sub { $some_obj->obfuscate(@args) };
func($whatnot);
sub func {
my $code = shift;
&$code();
}
ä¹å¯ä»¥ç ç©¶ UNIVERSAL ç±»å«ä¸ç can()æ¹æ³ (éäºæ å Perl çæ¬ä¸)ã
How do I create a static variable?
å°±åä¸ Perlç¸å³çå¶ä»äºæä¸æ ·ï¼‘‘æ¡æ¡å¤§è·¯éç½é©¬’’ (TMTOWTDI)ã对å¶ä»è¯è¨æ¥è¯´å«å ‘‘éæåæ°’’ (static variable)çä¸è¥¿ï¼å¨ Perléé¢å¯è½æ¯ä¸ä¸ªå½æ°ç§æçåæ°(åªæè¯¥å½æ°èªå·±çå¾å°ï¼ä¸å¨ä¸åçå¼å«é´ä¿æå®å¼)ï¼ææ¯ä¸ä¸ªæ¡£æ¡ç§æ(file-private)åæ°(åªæåä¸ä¸ªæ¡£æ¡ä¸- ç彿°æçå¾å°)ã
以ä¸å°±æ¯å®ä½å½æ°ç§æåæ°çç¨å¼ï¼
BEGIN {
my $counter = 42;
sub prev_counter { return --$counter }
sub next_counter { return $counter++ }
}
prev_counter() å next_counter() å°ä¼å±ç¨ä¸ä¸ªäºç¼è¯æ¶åå§åçç§æåæ° $counterã
è¦å£°æä¸ä¸ªæ¡£æ¡ç§æ(file-private)åæ°ï¼ä½ ä»ç¶å¾ä½¿ç¨ my()ï¼å°å®æ¾å¨æ¡£æ¡å¼å¤´å¤æå¤å´ãå设ç°å¨æ¯å¨ Pax.pm è¿ä¸ªæ¡£æ¡éï¼
package Pax;
my $started = scalar(localtime(time()));
sub begun { return $started }
å½ç¨ "use Pax" æ "require Pax" è½½å¥æ- ¤æ¨¡ç»æ¶ï¼è¿ä¸ªåæ°å°±ä¼è¢«åå§åãä¸è¿å®ä¸ä¼è¢«èµæºåæ¶ï¼åå¶ä»åºäºææèå´ç忰飿·ï¼å为 begun()彿°è¦ç¨å°å®ï¼ä½æ¯æ²¡æå¶ä»å½æ°è½æ·åå®ãè¿ä¸ªåæ°ä¸è½ä»¥ $Pax::started ç形弿¥æ·åï¼å ä¸ºå®æåå¨çèå´ä¸æ¤å裹æ å³ãå®å- å¨çèå´æ¯è¿ä¸ªæ¡£æ¡ã坿³è§å°ï¼ä¸ä¸ªæ¡£æ¡éå¯ä»¥æ¾å¥½å个å裹ï¼èææçåè£¹é½æ·ååä¸ä¸ªç§æåæ°ï¼ä½ä»å¦ä¸ä¸ªæ¡£æ¡ä¸- ï¼å³ä½¿æ¯å±äºåä¸ä¸ªå裹(package)ï¼ä¹ä¸è½åå¾å®çå¼ã
åè§ perlsub ä¸ç "Persistent Private Variables" çç»è.
What’s the difference between dynamic and lexical (static) scoping? Between local() and my()?
local($x) å°å¨ååæ° $xçåå¼åèµ·æ¥ï¼å¹¶å¨æ¤å½æ°æ§è¡æé´èµäºä¸ä¸ªæ° å¼ï¼æ- ¤å¼å¯ä»¥ä»æ¤å½æ°æå¼å«çå¶ä»å½æ°éçè§ãè¿æ´ä¸ªæ- ¥éª¤æ¯å¨æ§è¡æé´å®æçï¼æä»¥æå«å卿èå´éå (dynamic scoping)ãlocal()å½±åçæ¯å¨ååæ°ï¼æèç§°ä½åè£¹åæ°æå¨æåæ°ã
"my($x)" ä¼åé ä¸ä¸ªåªè½å¨ç®åè¿ä¸ªå½æ°éçå¾è§çæ°åæ°ãè¿ä¸ªæ- ¥éª¤æ¯å¨ç¼è¯æå®æ(compile-time)ï¼æä»¥ç§°ä½æå- 弿æ¯éæèå´éåãmy()æ»æ¯ä½ç¨å¨ç§æåæ°ï¼ä¹ç§°ä½æå- å¼åæ°æ(ä¸å½å°)ç§°ä½éæ(èå´éå)åæ°ã
ä¾å¦ï¼
sub visible {
print "var has value $var\n";
}
sub dynamic {
local $var = ’local’; #
为å¨å±åéææ¶èµå¼
visible(); # è°ç¨ $var åé
}
sub lexical {
my $var = ’private’; #
æ°çç§æåé
$var
visible(); # (å¨ sub
ä½ç¨åä¹å¤ä¸å¯è§)
}
$var = ’global’;
visible(); #
prints global
dynamic(); # prints local
lexical(); # prints global
ä½ å¯ä»¥åç°å¨æ´ä¸ªè¿ç¨ä¸ ‘‘private’’è¿ä¸ªå¼é½å°ä¸åºæ¥ã飿¯å 为 $varçå¼åªåå¨äºlexical() 彿°çåºåéé¢ï¼å¯¹å®æå¼å«ç彿°æ¥è¯´æ¯çä¸å°çã
æ»ç»æ¥è¯´ï¼local()ä¸ä¼äº§çä½ æ³åä¸- çç§æãåºååæ°ãå®åªæ¯å°ä¸ä¸ªææ¶ç弿äºä¸ä¸ªå¨ååæ°ãå¦æä½ è¦çæ¯ç§æçåæ°ï¼é£ä¹ my() ææ¯ä½ è¦æ¾çã
åè§ perlsub ä¸ç "Private Variables via my()" 以å "Temporary Values via local()" æ¥è·å详æ
å¨åå¨åååé¨åéçä½ç¨åä¸ï¼å¦ä½ååä¸ä¸ªå¨æåéï¼
å¦æä½ ç¥éä½ æå¨çæ¯åªä¸ä¸ªå裹(package)çè¯ï¼ä½ å¯ä»¥ç´æ¥æåï¼å°±åå $Some_Pack::var è¿æ ·ã注æ $::var è¿ä¸ªåæ³ å¹¶é表示ç®åæ¤å裹 (package) åç卿忰 $varï¼èæ¯æå¨ mainå裹(package) éçé£ä¸ªï¼å°±çä»·äº $main::var ã
use vars
’$var’;
local $var = "global";
my $var = "lexical";
print
"lexical is $var\n";
print "global is $main::var\n";
å¯éçï¼å¯ä»¥ä½¿ç¨ç¼è¯å¨æä»¤ our() æ¥å¨å½åéæä½ç¨åä¸å¼å¥å¨æåé
require 5.006; #
our() did not exist before 5.6
use vars ’$var’;
local $var =
"global";
my $var = "lexical";
print "lexical is $var\n";
{
our $var;
print "global is $var\n";
}
æ·±è¿æ¥åæµè¿æ¥æä»ä¹ä¸åï¼
卿·±è¿ç»ä¸ï¼å¿å彿°ä¸æç¨å°çæå- å¼åæ°å¼æ¯ä»¥è¯¥å½æ°äº§çæ¶æå¨çèå´ä¸ºåã卿µè¿ç»ä¸- ï¼è¿äºåæ°å¼æ¯ä»¥å½æ°è¢«å¼å«æ¶æå¨çèå´ä¸ºåï¼å¦æå¨è¿ä¸ªèå´ä¸- æ°å·§æååçåæ°ï¼ä¾¿ä½¿ç¨è¿äºå½å°åæ°çå¼ãPerlæ»æ¯ä½¿ç¨æåå¼åæ°(å°±æ¯ä»¥ my()åéç)å¼çæ·±è¿ç»ãç¶èï¼å¨æåæ°(ä¹ç§°ä½å¨å(global)ï¼åºå(local)ï¼æå裹(package)åæ°)å¨åæä¸æ¯æµè¿ç»ãå°±æè¿å½ä½æ¯å°ç¨å®ä»¬çå¦ä¸ä¸ªçç±å¥½ äºã请åè "ä»ä¹æ¯éå" ä¸èã
为ä»ä¹
local()伿 =å·å³è¾¹ä»¥åºåæå¢æ¥å¯¹å¾ãè <FH> è¿ä¸ªé读ç å¨ä½ï¼å°±å Perlé许å¤ç彿°ä»¥åè¿ç®å- 䏿·ï¼ä¼èªå¨å辨åºèªå·±è¢«å¼å«æ¶æå¨çæå¢å¹¶ä¸éåéå½ç使³ãä¸è¬æ¥è¯´ï¼scalar()彿°å¯ä»¥å¸®ç¹å¿ãè¿ä¸ªå½æ°å®éä¸å¯¹èµææ¬èº«ä¸ä¼æä»»ä½ä½ç¨(ä¸ä¸è¬æè®¤ä¸ºçç¸å)ï¼ä½æ¯ä¼åè¯å®æä½ç¨ç彿°è¦ä»¥å¯¹å¾çº¯éå¼çæ¹æ³æ¥è¿ç®ã妿é£ä¸ªå½æ°æ²¡æé¢åå®ä¹å¥½ç¢°å°çº¯éæå¢çè¡ä¸ºï¼é£ä¹å®å½ç¶ä¹å¸®ä¸äºä½(ä¾å¦ sort() 彿°)ã
ç¶èï¼å¨ä»¥ä¸è¿ä¸ªä¾å (local...)ä¸ï¼åªè¦çç¥æ¬å·ä¾¿å¯å¼ºå¶ä½¿ç¨æ éæå¢ï¼
local($foo) =
<FILE>; # WRONG
local($foo) = scalar(<FILE>); # ok
local $foo = <FILE>; # right
å¶å®å¨è¿ä¸ªä¾åä¸ï¼æè®¸ä½ 该æ¹ç¨æåå¼åæ° (lexical variables)ï¼ä¸è¿ä¼ç¢°å° çé®é¢è·ä¸é¢ä¸æ ·ï¼
my($foo) =
<FILE>; # WRONG
my $foo = <FILE>; # right
å¦ä½éå®ä¹ä¸ä¸ªåå»ºå½æ°ï¼æä½ç¬¦ æèæ¹æ³ï¼
为ä»ä¹è¦è¿ä¹åï¼ :-)
å¦æä½ è¦è¦çææä¸ªåå»ºå½æ°ï¼ä¾å¦è¯´ open()ï¼é£ä½ å¾å°å¶å®ä¹ä»å¦ä¸ä¸ªæ¨¡ç»è½½ å¥ãåè perlsub ä¸ç Overriding Builtin Functionsãå¨ "Class::Template" éé¢ä¹æä¸ªèä¾ã
å¦æä½ è¦è¦çæä¸ä¸ª Perlè¿ç®åï¼åæ¯ "+" æ "**", é£ä½ è¯¥ä½¿ç¨ "use overload" è¿ä¸ªç¼ç¨ï¼å¨ overload ä¸æè®°è½½ã
å¦æä½ è¦è¦çç¶ç±»å« (parent class)éçæ¹æ³å¼å« (method calls)ï¼è¯·ç perltoot ä¸ç Overridden Methods ã
è°ç¨å½æ°æ¶ &foo å foo() ç形弿ä»ä¹ä¸å?
å½ä½ ç¨ &fooçæ¹å¼å¼å«ä¸ä¸ªå½æ°æ¶ï¼ä½ çäºè®©è¿ä¸ªå½æ°æ·åä½ ç®å @_éé¢çå¼ï¼åæ¶ä¹è·³è¿ååå®ä¹ (prototypes)ä¸ç¨ãè¿è¡¨å¼æ¤å½æ°æå°çæ¯ä½ 彿¶ç @_ï¼ èéä¸ä¸ªç©ºç @_ï¼è½ç¶ä¸¥æ ¼è®²èµ·æ¥å®ä¹ä¸è½ç®æ¯ä¸ª bug (使¯å¨ perlsubé颿¯è¿ä¹è¯´ç)ä½å¨å¤§é¨ä»½æåµä¸ï¼è¿ä¹ç®ä¸ä¸æ¯ä¸ªç¹å«åè½ã
å½ä½ ç¨ &foo()çæ¹å¼å¼å«ä½ ç彿°æ¶ï¼ä½ ä¼å¾å°ä¸ä¸ªæ°ç @_ï¼ä½æ¯ååå®ä¹ ä»ç¶ä¼è¢«é¿å¼ä¸ç¨ã
å¨ä¸è¬æåµä¸ï¼ä½ è¯¥ç¨ foo()çæ¹å¼å»å¼å«å½æ°ãåªæå¨ç¼è¯å¨å·²äºåç¥éè¿ä¸ªå½æ°çå®ä¹æ¶ï¼æ¬å·æè½çç¥ï¼è- ¬å¦å½è¿ä¸ªå½æ°æå¨çæ¨¡ç»æå裹被 use (ä½å¦ææ¯è¢« requireåä¸è¡)æ¶ï¼ææ¯éè¿ååæåæ use subs宣åç- æ¹æ³ï¼è®©ç¼è¯å¨åæ¥è§¦å°è¿ä¸ªå½æ°çå®ä¹ãç¨è¿ç§å¼å«æ¹å¼ï¼å³ä½¿æ¯å½æ¬å·çææ¶ï¼ä½é½ä¼å¾å°ä¸ä¸ªå¹²åç @_ï¼ä¸ä¼æä»»ä½ä¸è¯¥åºç°çæ§å¼æ®çå¨ä¸é¢ã
å¦ä½å建ä¸ä¸ªåæ¯è¯å¥ï¼
è¿ä¸ªé®é¢å¨ perlsyn æä»¶éææ´è¯¦å°½çè§£éãç®åæ¥è¯´ï¼å 为 Perlæ¬èº«å·²æä¾äºå¤ç§ä¸åçæ¡ä»¶æµè¯æ¹æ³å¯ä¾ä½¿ç¨ (æ°å¼æ¯è¾ãå串æ¯è¾ã globæ¯è¾ãæ£è§è¡¨ç¤ºå¼ 对åºãè¦çæ¯è¾ï¼åå¶å®)ï¼æä»¥å¹¶æ²¡ææ£å¼ç caseåè¿°è¯æ³ãè½ç¶èª perl1èµ·è¿å°±ä¸ç´æ¯è®¸å¤äººæç¼çä¸ä¸ªé¡¹ç®ï¼ä½åLarryææ³å³å®ææ·ææ¯åç°è¿åè½çæå¥½æ¹æ³ï¼åæ- ¤è¿æ¯å°å®ç¥æã
ä» Perl 5.8 å¼å§ï¼è¦ä½¿ç¨ swtich å caseï¼å¯ä»¥ä½¿ç¨ Switch æ©å±ï¼å°±æ¯è¿æ ·ï¼
use Switch;
æ¤åå°±å¯ä»¥ç¨ switch å case äº. It is not as fast as it could be because it’s not really part of the language (it’s done using source filters) but it is available, and it’s very flexible.
But if one wants to use pure Perl, the general answer is to write a construct like this:
for
($variable_to_test) {
if (/pat1/) { } # do something
elsif (/pat2/) { } # do something else
elsif (/pat3/) { } # do something else
else { } # default
}
ä¸é¢è¿ä¸ªç®åç switchèä¾ä»¥æ¨¡å¼å¯¹åºä¸ºåºç¡ãæä»¬å°è¦åçæ¯å¯¹å¨åå¨ $whatchamacallitéé¢çåèå¼ (reference)çç±»åè¿è¡å¤éæ¡ä»¶ç夿- ããè¯æ³¨ï¼$whatchamacallit å½æä¸º $what_you_might_call_itã
SWITCH: for (ref $whatchamacallit) {
/ˆ$/ && die "not a reference";
/SCALAR/
&& do {
print_scalar($$ref);
last SWITCH;
};
/ARRAY/
&& do {
print_array(@$ref);
last SWITCH;
};
/HASH/
&& do {
print_hash(%$ref);
last SWITCH;
};
/CODE/
&& do {
warn "can’t print function ref";
last SWITCH;
};
# DEFAULT
warn "User defined type skipped";
}
See "perlsyn/"Basic BLOCKs and Switch Statements"" for many other examples in this style.
Sometimes you should change the positions of the constant and the variable. For example, let’s say you wanted to test which of many answers you were given, but in a case-insensitive way that also allows abbreviations. You can use the following technique if the strings all start with different characters or if you want to arrange the matches so that one takes precedence over another, as "SEND" has precedence over "STOP" here:
chomp($answer =
<>);
if ("SEND" =˜ /ˆ\Q$answer/i) { print
"Action is send\n" }
elsif ("STOP" =˜ /ˆ\Q$answer/i) { print
"Action is stop\n" }
elsif ("ABORT" =˜ /ˆ\Q$answer/i) { print
"Action is abort\n" }
elsif ("LIST" =˜ /ˆ\Q$answer/i) { print
"Action is list\n" }
elsif ("EDIT" =˜ /ˆ\Q$answer/i) { print
"Action is edit\n" }
A totally different approach is to create a hash of function references.
my %commands = (
"happy" => \&joy,
"sad", => \&sullen,
"done" => sub { die "See ya!" },
"mad" => \&angry,
);
print "How
are you? ";
chomp($string = <STDIN>);
if ($commands{$string}) {
$commands{$string}->();
} else {
print "No such command: $string\n";
}
å¦ä½æè·å¯¹æªå®ä¹åéï¼å½æ°ææ¹æ³ç访é®ï¼
å¨ perlsub ä¸ç "Autoloading" å perltoot ä¸ç " AUTOLOAD: Proxy Methods" é æå°ç AUTOLOAD æ¹æ³è®©ä½ è½ææå¯¹äºæªå®ä¹å½æ°ä¸æ¹æ³çå¼å«ã
When it comes to undefined variables that would trigger a warning under "use warnings", you can promote the warning to an error.
use warnings FATAL => qw(uninitialized);
为ä»ä¹æ¾ä¸å°åå«å¨åä¸ä¸ªæä»¶ä¸çæ¹æ³ï¼
ä¸äºå¯è½çåå ï¼ä½ ç¨çç»§æ¿ç»ææ··äºãä½ æ¼éäºè¯¥æ¹æ³çåå- ï¼ææ¯ç©ä»¶çç±»å«é误ãè¿äºäºå¨ perltooté齿æ´è¯¦å°½ç说æãåæ¶ä½ ä¹å¯ä»¥ç¨ "print ref($object)" æ¥æ¾åº $object è¿ä¸ªç©ä»¶æ¯è¢«å½å°åªä¸ªç±»å«åºä¸ã
å¦ä¸ä¸ªå¯è½çåå æ¯ä½ å¨ Perlè¿ä¸ç¥éè¿ä¸ªå裹 (package)å- å¨ä¹åä¾¿å°æä¸ªç±»å«åç§°å¨é´æ¥å¼ç©ä»¶è¯æ³ä¸ä½¿ç¨ (ä¾å¦ "find Guru "Samy"")ãæå¥½æ¯å¨å¼å§ä½¿ç¨ä½çå裹åï¼åç¡®å®é½å·²ç»åæå®ä»¬å®ä¹å¥½äºï¼å¦æä½ç¨çæ¯ use èé requireçè¯ï¼è¿ä»¶äºä¾¿ä¼èªå¨å¤ç好ãä¸ç¶çè¯ï¼ç¡®å®ä½ 使ç¨ç®- 头å¼è¯æ³ (ä¾å¦ï¼"Guru->find("Samy")"))ãå¨perlobj éé¢å¯¹äºç©ä»¶çè®°å·æè¯¦å°½è§£éã
Make sure to read about creating modules in perlmod and the perils of indirect objects in "Method Invocation" in perlobj.
å¦ä½æ¾å°å½åçåï¼
å¦æåªæ¯ä¸ä¸ªéæçç¨å¼çè¯ï¼ä½ å¯ä»¥ç¨ä¸é¢çæ¹æ³æ¾åºç®åæ£è¢«ç¼è¯çå裹为ä½ï¼
my $packname = __PACKAGE__;
ä½å¦ææ¯ä¸ä¸ªæ¹æ³çè¯ï¼èä¸å°åºçé误讯æ¯ä¸è¦åå«å¼å«æ¤æ¹æ³çç©ä»¶ (ä¸è§å¾å°±æ¯æè¿ä¸ªæ¹æ³ç¼è¯è¿å»çé£ä¸ªç©ä»¶)åï¼
sub amethod {
my $self = shift;
my $class = ref($self) ⎪⎪ $self;
warn "called me from a $class object";
}
å¦ä½æ³¨éæå¤§åç perl 代ç ï¼
ç¨ååµ PODæ ¼å¼çæ¹æ³æç¨å¼ç åæ³¨è§£ãå°è¦æ³¨éæçååå«å¨ POD æ è®°å, ä¾å¦ "=for nobody" å "=cut" (æ å¿ç POD åçç»æ).
# è¿æ¯ç¨å¼
=for nobody
all of this stuff
æ¥ä¸æ¥æ¤å¤ææçæåé½ä¼è¢«å¿½ç¥
=cut
# program continues
The pod directives cannot go just anywhere. You must put a pod directive where the parser is expecting a new statement, not just in the middle of an expression or some other arbitrary grammar production.
See perlpod for more details.
How do I clear a package?
Use this code, provided by Mark-Jason Dominus:
sub
scrub_package {
no strict ’refs’;
my $pack = shift;
die "Shouldn’t delete main package"
if $pack eq "" ⎪⎪ $pack eq
"main";
my $stash = *{$pack . ’::’}{HASH};
my $name;
foreach $name (keys %$stash) {
my $fullname = $pack . ’::’ . $name;
# Get rid of everything with that name.
undef $$fullname;
undef @$fullname;
undef %$fullname;
undef &$fullname;
undef *$fullname;
}
}
Or, if you’re using a recent release of Perl, you can just use the Symbol::delete_package() function instead.
How can I use a variable as a variable name?
Beginners often think they want to have a variable contain the name of a variable.
$fred = 23;
$varname = "fred";
++$$varname; # $fred now 24
This works sometimes, but it is a very bad idea for two reasons.
The first reason is that this technique only works on global variables. That means that if $fred is a lexical variable created with my() in the above example, the code wouldn’t work at all: you’d accidentally access the global and skip right over the private lexical altogether. Global variables are bad because they can easily collide accidentally and in general make for non-scalable and confusing code.
Symbolic references are forbidden under the "use strict" pragma. They are not true references and consequently are not reference counted or garbage collected.
The other reason why using a variable to hold the name of another variable is a bad idea is that the question often stems from a lack of understanding of Perl data structures, particularly hashes. By using symbolic references, you are just using the package’s symbol-table hash (like %main::) instead of a user-defined hash. The solution is to use your own hash or a real reference instead.
$USER_VARS{"fred"}
= 23;
$varname = "fred";
$USER_VARS{$varname}++; # not $$varname++
There we’re using the %USER_VARS hash instead of symbolic references. Sometimes this comes up in reading strings from the user with variable references and wanting to expand them to the values of your perl program’s variables. This is also a bad idea because it conflates the program-addressable namespace and the user-addressable one. Instead of reading a string and expanding it to the actual contents of your program’s own variables:
$str =
’this has a $fred and $barney in it’;
$str =˜ s/(\$\w+)/$1/eeg; # need double eval
it would be better to keep a hash around like %USER_VARS and have variable references actually refer to entries in that hash:
$str =˜ s/\$(\w+)/$USER_VARS{$1}/g; # no /e here at all
That’s faster, cleaner, and safer than the previous approach. Of course, you don’t need to use a dollar sign. You could use your own scheme to make it less confusing, like bracketed percent symbols, etc.
$str =
’this has a %fred% and %barney% in it’;
$str =˜ s/%(\w+)%/$USER_VARS{$1}/g; # no /e here at
all
Another reason that folks sometimes think they want a variable to contain the name of a variable is because they don’t know how to build proper data structures using hashes. For example, let’s say they wanted two hashes in their program: %fred and %barney, and that they wanted to use another scalar variable to refer to those by name.
$name =
"fred";
$$name{WIFE} = "wilma"; # set %fred
$name =
"barney";
$$name{WIFE} = "betty"; # set %barney
This is still a symbolic reference, and is still saddled with the problems enumerated above. It would be far better to write:
$folks{"fred"}{WIFE}
= "wilma";
$folks{"barney"}{WIFE} = "betty";
And just use a multilevel hash to start with.
The only times that you absolutely must use symbolic references are when you really must refer to the symbol table. This may be because it’s something that can’t take a real reference to, such as a format name. Doing so may also be important for method calls, since these always go through the symbol table for resolution.
In those cases, you would turn off "strict ’refs’" temporarily so you can play around with the symbol table. For example:
@colors = qw(red
blue green yellow orange purple violet);
for my $name (@colors) {
no strict ’refs’; # renege for the block
*$name = sub { "<FONT
COLOR=’$name’>@_</FONT>" };
}
All those functions (red(), blue(), green(), etc.) appear to be separate, but the real code in the closure actually was compiled only once.
So, sometimes you might want to use symbolic references to directly manipulate the symbol table. This doesn’t matter for formats, handles, and subroutines, because they are always global--you can’t use my() on them. For scalars, arrays, and hashes, though--and usually for subroutines-- you probably only want to use hard references.
What does "bad interpreter" mean?
The "bad interpreter" message comes from the shell, not perl. The actual message may vary depending on your platform, shell, and locale settings.
If you see "bad interpreter - no such file or directory", the first line in your perl script (the "shebang" line) does not contain the right path to perl (or any other program capable of running scripts). Sometimes this happens when you move the script from one machine to another and each machine has a different path to perl---/usr/bin/perl versus /usr/local/bin/perl for instance.
If you see "bad interpreter: Permission denied", you need to make your script executable.
In either case, you should still be able to run the scripts with perl explicitly:
% perl script.pl
If you get a message like "perl: command not found", perl is not in your PATH , which might also mean that the location of perl is not where you expect it so you need to adjust your shebang line.
AUTHOR AND COPYRIGHT
Copyright (c) 1997-2002 Tom Christiansen and Nathan Torkington. All rights reserved.
This documentation is free; you can redistribute it and/or modify it under the same terms as Perl itself.
Irrespective of its distribution, all code examples in this file are hereby placed into the public domain. You are permitted and encouraged to use this code in your own programs for fun or for profit as you see fit. A simple comment in the code giving credit would be courteous but is not required.
è¯è
é彦éï¼è§ç¾é¾ï¼ä¸¤åªèèå·¥ä½å®¤
è·
æ¬é¡µé¢ä¸æçç±ä¸æ
man
æå页计åæä¾ã
䏿 man
æå页计åï¼https://github.com/man-pages-zh/manpages-zh