📄 perlsyn.1
字号:
\& \& default {\& die q(I don\*(Aqt know what to do with $foo);\& }\& }.Ve.PP\&\f(CW\*(C`given(EXPR)\*(C'\fR will assign the value of \s-1EXPR\s0 to \f(CW$_\fRwithin the lexical scope of the block, so it's similar to.PP.Vb 1\& do { my $_ = EXPR; ... }.Ve.PPexcept that the block is automatically broken out of by asuccessful \f(CW\*(C`when\*(C'\fR or an explicit \f(CW\*(C`break\*(C'\fR..PPMost of the power comes from implicit smart matching:.PP.Vb 1\& when($foo).Ve.PPis exactly equivalent to.PP.Vb 1\& when($_ ~~ $foo).Ve.PPIn fact \f(CW\*(C`when(EXPR)\*(C'\fR is treated as an implicit smart match most of thetime. The exceptions are that when \s-1EXPR\s0 is:.IP "o" 4.IX Item "o"a subroutine or method call.IP "o" 4.IX Item "o"a regular expression match, i.e. \f(CW\*(C`/REGEX/\*(C'\fR or \f(CW\*(C`$foo =~ /REGEX/\*(C'\fR,or a negated regular expression match \f(CW\*(C`$foo !~ /REGEX/\*(C'\fR..IP "o" 4.IX Item "o"a comparison such as \f(CW\*(C`$_ < 10\*(C'\fR or \f(CW\*(C`$x eq "abc"\*(C'\fR(or of course \f(CW\*(C`$_ ~~ $c\*(C'\fR).IP "o" 4.IX Item "o"\&\f(CW\*(C`defined(...)\*(C'\fR, \f(CW\*(C`exists(...)\*(C'\fR, or \f(CW\*(C`eof(...)\*(C'\fR.IP "o" 4.IX Item "o"A negated expression \f(CW\*(C`!(...)\*(C'\fR or \f(CW\*(C`not (...)\*(C'\fR, or a logicalexclusive-or \f(CW\*(C`(...) xor (...)\*(C'\fR..PPthen the value of \s-1EXPR\s0 is used directly as a boolean.Furthermore:.IP "o" 4.IX Item "o"If \s-1EXPR\s0 is \f(CW\*(C`... && ...\*(C'\fR or \f(CW\*(C`... and ...\*(C'\fR, the testis applied recursively to both arguments. If \fIboth\fRarguments pass the test, then the argument is treatedas boolean..IP "o" 4.IX Item "o"If \s-1EXPR\s0 is \f(CW\*(C`... || ...\*(C'\fR or \f(CW\*(C`... or ...\*(C'\fR, the testis applied recursively to the first argument..PPThese rules look complicated, but usually they will do whatyou want. For example you could write:.PP.Vb 1\& when (/^\ed+$/ && $_ < 75) { ... }.Ve.PPAnother useful shortcut is that, if you use a literal arrayor hash as the argument to \f(CW\*(C`when\*(C'\fR, it is turned into areference. So \f(CW\*(C`given(@foo)\*(C'\fR is the same as \f(CW\*(C`given(\e@foo)\*(C'\fR,for example..PP\&\f(CW\*(C`default\*(C'\fR behaves exactly like \f(CW\*(C`when(1 == 1)\*(C'\fR, which isto say that it always matches..PPSee \*(L"Smart matching in detail\*(R" for more informationon smart matching..PP\fIBreaking out\fR.IX Subsection "Breaking out".PPYou can use the \f(CW\*(C`break\*(C'\fR keyword to break out of the enclosing\&\f(CW\*(C`given\*(C'\fR block. Every \f(CW\*(C`when\*(C'\fR block is implicitly ended witha \f(CW\*(C`break\*(C'\fR..PP\fIFall-through\fR.IX Subsection "Fall-through".PPYou can use the \f(CW\*(C`continue\*(C'\fR keyword to fall through from onecase to the next:.PP.Vb 5\& given($foo) {\& when (/x/) { say \*(Aq$foo contains an x\*(Aq; continue }\& when (/y/) { say \*(Aq$foo contains a y\*(Aq }\& default { say \*(Aq$foo contains neither an x nor a y\*(Aq }\& }.Ve.PP\fISwitching in a loop\fR.IX Subsection "Switching in a loop".PPInstead of using \f(CW\*(C`given()\*(C'\fR, you can use a \f(CW\*(C`foreach()\*(C'\fR loop.For example, here's one way to count how many times a particularstring occurs in an array:.PP.Vb 5\& my $count = 0;\& for (@array) {\& when ("foo") { ++$count }\& }\& print "\e@array contains $count copies of \*(Aqfoo\*(Aq\en";.Ve.PPOn exit from the \f(CW\*(C`when\*(C'\fR block, there is an implicit \f(CW\*(C`next\*(C'\fR.You can override that with an explicit \f(CW\*(C`last\*(C'\fR if you're onlyinterested in the first match..PPThis doesn't work if you explicitly specify a loop variable,as in \f(CW\*(C`for $item (@array)\*(C'\fR. You have to use the defaultvariable \f(CW$_\fR. (You can use \f(CW\*(C`for my $_ (@array)\*(C'\fR.).PP\fISmart matching in detail\fR.IX Subsection "Smart matching in detail".PPThe behaviour of a smart match depends on what type of thingits arguments are. It is always commutative, i.e. \f(CW\*(C`$a ~~ $b\*(C'\fRbehaves the same as \f(CW\*(C`$b ~~ $a\*(C'\fR. The behaviour is determinedby the following table: the first row that applies, in eitherorder, determines the match behaviour..PP.Vb 3\& $a $b Type of Match Implied Matching Code\& ====== ===== ===================== =============\& (overloading trumps everything)\&\& Code[+] Code[+] referential equality $a == $b\& Any Code[+] scalar sub truth $b\->($a)\&\& Hash Hash hash keys identical [sort keys %$a]~~[sort keys %$b]\& Hash Array hash slice existence grep {exists $a\->{$_}} @$b\& Hash Regex hash key grep grep /$b/, keys %$a\& Hash Any hash entry existence exists $a\->{$b}\&\& Array Array arrays are identical[*]\& Array Regex array grep grep /$b/, @$a\& Array Num array contains number grep $_ == $b, @$a\& Array Any array contains string grep $_ eq $b, @$a\&\& Any undef undefined !defined $a\& Any Regex pattern match $a =~ /$b/\& Code() Code() results are equal $a\->() eq $b\->()\& Any Code() simple closure truth $b\->() # ignoring $a\& Num numish[!] numeric equality $a == $b\& Any Str string equality $a eq $b\& Any Num numeric equality $a == $b\&\& Any Any string equality $a eq $b\&\&\& + \- this must be a code reference whose prototype (if present) is not ""\& (subs with a "" prototype are dealt with by the \*(AqCode()\*(Aq entry lower down)\& * \- that is, each element matches the element of same index in the other\& array. If a circular reference is found, we fall back to referential\& equality.\& ! \- either a real number, or a string that looks like a number.Ve.PPThe \*(L"matching code\*(R" doesn't represent the \fIreal\fR matching code,of course: it's just there to explain the intended meaning. Unlike\&\f(CW\*(C`grep\*(C'\fR, the smart match operator will short-circuit whenever it can..PP\fICustom matching via overloading\fR.IX Subsection "Custom matching via overloading".PPYou can change the way that an object is matched by overloadingthe \f(CW\*(C`~~\*(C'\fR operator. This trumps the usual smart match semantics.See overload..PP\fIDifferences from Perl 6\fR.IX Subsection "Differences from Perl 6".PPThe Perl 5 smart match and \f(CW\*(C`given\*(C'\fR/\f(CW\*(C`when\*(C'\fR constructs are notabsolutely identical to their Perl 6 analogues. The most visibledifference is that, in Perl 5, parentheses are required aroundthe argument to \f(CW\*(C`given()\*(C'\fR and \f(CW\*(C`when()\*(C'\fR. Parentheses in Perl 6are always optional in a control construct such as \f(CW\*(C`if()\*(C'\fR,\&\f(CW\*(C`while()\*(C'\fR, or \f(CW\*(C`when()\*(C'\fR; they can't be made optional in Perl5 without a great deal of potential confusion, because Perl 5would parse the expression.PP.Vb 3\& given $foo {\& ...\& }.Ve.PPas though the argument to \f(CW\*(C`given\*(C'\fR were an element of the hash\&\f(CW%foo\fR, interpreting the braces as hash-element syntax..PPThe table of smart matches is not identical to that proposed by thePerl 6 specification, mainly due to the differences between Perl 6'sand Perl 5's data models..PPIn Perl 6, \f(CW\*(C`when()\*(C'\fR will always do an implicit smart matchwith its argument, whilst it is convenient in Perl 5 tosuppress this implicit smart match in certain situations,as documented above. (The difference is largely because Perl 5does not, even internally, have a boolean type.).Sh "Goto".IX Xref "goto".IX Subsection "Goto"Although not for the faint of heart, Perl does support a \f(CW\*(C`goto\*(C'\fRstatement. There are three forms: \f(CW\*(C`goto\*(C'\fR\-LABEL, \f(CW\*(C`goto\*(C'\fR\-EXPR, and\&\f(CW\*(C`goto\*(C'\fR\-&NAME. A loop's \s-1LABEL\s0 is not actually a valid target fora \f(CW\*(C`goto\*(C'\fR; it's just the name of the loop..PPThe \f(CW\*(C`goto\*(C'\fR\-LABEL form finds the statement labeled with \s-1LABEL\s0 and resumesexecution there. It may not be used to go into any construct thatrequires initialization, such as a subroutine or a \f(CW\*(C`foreach\*(C'\fR loop. Italso can't be used to go into a construct that is optimized away. Itcan be used to go almost anywhere else within the dynamic scope,including out of subroutines, but it's usually better to use some otherconstruct such as \f(CW\*(C`last\*(C'\fR or \f(CW\*(C`die\*(C'\fR. The author of Perl has never felt theneed to use this form of \f(CW\*(C`goto\*(C'\fR (in Perl, that is\*(--C is another matter)..PPThe \f(CW\*(C`goto\*(C'\fR\-EXPR form expects a label name, whose scope will be resolveddynamically. This allows for computed \f(CW\*(C`goto\*(C'\fRs per \s-1FORTRAN\s0, but isn'tnecessarily recommended if you're optimizing for maintainability:.PP.Vb 1\& goto(("FOO", "BAR", "GLARCH")[$i]);.Ve.PPThe \f(CW\*(C`goto\*(C'\fR\-&NAME form is highly magical, and substitutes a call to thenamed subroutine for the currently running subroutine. This is used by\&\f(CW\*(C`AUTOLOAD()\*(C'\fR subroutines that wish to load another subroutine and thenpretend that the other subroutine had been called in the first place(except that any modifications to \f(CW@_\fR in the current subroutine arepropagated to the other subroutine.) After the \f(CW\*(C`goto\*(C'\fR, not even \f(CW\*(C`caller()\*(C'\fRwill be able to tell that this routine was called first..PPIn almost all cases like this, it's usually a far, far better idea to use thestructured control flow mechanisms of \f(CW\*(C`next\*(C'\fR, \f(CW\*(C`last\*(C'\fR, or \f(CW\*(C`redo\*(C'\fR instead ofresorting to a \f(CW\*(C`goto\*(C'\fR. For certain applications, the catch and throw pair of\&\f(CW\*(C`eval{}\*(C'\fR and \fIdie()\fR for exception processing can also be a prudent approach..Sh "PODs: Embedded Documentation".IX Xref "POD documentation".IX Subsection "PODs: Embedded Documentation"Perl has a mechanism for intermixing documentation with source code.While it's expecting the beginning of a new statement, if the compilerencounters a line that begins with an equal sign and a word, like this.PP.Vb 1\& =head1 Here There Be Pods!.Ve.PPThen that text and all remaining text up through and including a linebeginning with \f(CW\*(C`=cut\*(C'\fR will be ignored. The format of the interveningtext is described in perlpod..PPThis allows you to intermix your source codeand your documentation text freely, as in.PP.Vb 1\& =item snazzle($)\&\& The snazzle() function will behave in the most spectacular\& form that you can possibly imagine, not even excepting\& cybernetic pyrotechnics.\&\& =cut back to the compiler, nuff of this pod stuff!\&\& sub snazzle($) {\& my $thingie = shift;\& .........\& }.Ve.PPNote that pod translators should look at only paragraphs beginningwith a pod directive (it makes parsing easier), whereas the compileractually knows to look for pod escapes even in the middle of aparagraph. This means that the following secret stuff will beignored by both the compiler and the translators..PP.Vb 5\& $a=3;\& =secret stuff\& warn "Neither POD nor CODE!?"\& =cut back\& print "got $a\en";.Ve.PPYou probably shouldn't rely upon the \f(CW\*(C`warn()\*(C'\fR being podded out forever.Not all pod translators are well-behaved in this regard, and perhapsthe compiler will become pickier..PPOne may also use pod directives to quickly comment out a sectionof code..Sh "Plain Old Comments (Not!)".IX Xref "comment line # preprocessor eval".IX Subsection "Plain Old Comments (Not!)"Perl can process line directives, much like the C preprocessor. Usingthis, one can control Perl's idea of filenames and line numbers inerror or warning messages (especially for strings that are processedwith \f(CW\*(C`eval()\*(C'\fR). The syntax for this mechanism is the same as for mostC preprocessors: it matches the regular expression.PP.Vb 5\& # example: \*(Aq# line 42 "new_filename.plx"\*(Aq\& /^\e# \es*\& line \es+ (\ed+) \es*\& (?:\es("?)([^"]+)\e2)? \es*\& $/x.Ve.PPwith \f(CW$1\fR being the line number for the next line, and \f(CW$3\fR beingthe optional filename (specified with or without quotes)..PPThere is a fairly obvious gotcha included with the line directive:Debuggers and profilers will only show the last source line to appearat a particular line number in a given file. Care should be taken notto cause line number collisions in code you'd like to debug later..PPHere are some examples that you should be able to type into your commandshell:.PP.Vb 6\& % perl\& # line 200 "bzzzt"\& # the \`#\*(Aq on the previous line must be the first char on line\& die \*(Aqfoo\*(Aq;\& _\|_END_\|_\& foo at bzzzt line 201.\&\& % perl\& # line 200 "bzzzt"\& eval qq[\en#line 2001 ""\endie \*(Aqfoo\*(Aq]; print $@;\& _\|_END_\|_\& foo at \- line 2001.\&\& % perl\& eval qq[\en#line 200 "foo bar"\endie \*(Aqfoo\*(Aq]; print $@;\& _\|_END_\|_\& foo at foo bar line 200.\&\& % perl\& # line 345 "goop"\& eval "\en#line " . _\|_LINE_\|_ . \*(Aq "\*(Aq . _\|_FILE_\|_ ."\e"\endie \*(Aqfoo\*(Aq";\& print $@;\& _\|_END_\|_\& foo at goop line 345..Ve
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -