perlsyn.pod

来自「MSYS在windows下模拟了一个类unix的终端」· POD 代码 · 共 640 行 · 第 1/2 页

POD
640
字号
If any part of LIST is an array, C<foreach> will get very confused ifyou add or remove elements within the loop body, for example withC<splice>.   So don't do that.C<foreach> probably won't do what you expect if VAR is a tied or otherspecial variable.   Don't do that either.Examples:    for (@ary) { s/foo/bar/ }    for my $elem (@elements) {	$elem *= 2;    }    for $count (10,9,8,7,6,5,4,3,2,1,'BOOM') {	print $count, "\n"; sleep(1);    }    for (1..15) { print "Merry Christmas\n"; }    foreach $item (split(/:[\\\n:]*/, $ENV{TERMCAP})) {	print "Item: $item\n";    }Here's how a C programmer might code up a particular algorithm in Perl:    for (my $i = 0; $i < @ary1; $i++) {	for (my $j = 0; $j < @ary2; $j++) {	    if ($ary1[$i] > $ary2[$j]) {		last; # can't go to outer :-(	    }	    $ary1[$i] += $ary2[$j];	}	# this is where that last takes me    }Whereas here's how a Perl programmer more comfortable with the idiom mightdo it:    OUTER: for my $wid (@ary1) {    INNER:   for my $jet (@ary2) {		next OUTER if $wid > $jet;		$wid += $jet;	     }	  }See how much easier this is?  It's cleaner, safer, and faster.  It'scleaner because it's less noisy.  It's safer because if code gets addedbetween the inner and outer loops later on, the new code won't beaccidentally executed.  The C<next> explicitly iterates the other looprather than merely terminating the inner one.  And it's faster becausePerl executes a C<foreach> statement more rapidly than it would theequivalent C<for> loop.=head2 Basic BLOCKs and Switch StatementsA BLOCK by itself (labeled or not) is semantically equivalent to aloop that executes once.  Thus you can use any of the loop controlstatements in it to leave or restart the block.  (Note that this isI<NOT> true in C<eval{}>, C<sub{}>, or contrary to popular beliefC<do{}> blocks, which do I<NOT> count as loops.)  The C<continue>block is optional.The BLOCK construct is particularly nice for doing casestructures.    SWITCH: {	if (/^abc/) { $abc = 1; last SWITCH; }	if (/^def/) { $def = 1; last SWITCH; }	if (/^xyz/) { $xyz = 1; last SWITCH; }	$nothing = 1;    }There is no official C<switch> statement in Perl, because there arealready several ways to write the equivalent.  In addition to theabove, you could write    SWITCH: {	$abc = 1, last SWITCH  if /^abc/;	$def = 1, last SWITCH  if /^def/;	$xyz = 1, last SWITCH  if /^xyz/;	$nothing = 1;    }(That's actually not as strange as it looks once you realize that you canuse loop control "operators" within an expression,  That's just the normalC comma operator.)or    SWITCH: {	/^abc/ && do { $abc = 1; last SWITCH; };	/^def/ && do { $def = 1; last SWITCH; };	/^xyz/ && do { $xyz = 1; last SWITCH; };	$nothing = 1;    }or formatted so it stands out more as a "proper" C<switch> statement:    SWITCH: {	/^abc/ 	    && do {			    $abc = 1;			    last SWITCH;		       };	/^def/ 	    && do {			    $def = 1;			    last SWITCH;		       };	/^xyz/ 	    && do {			    $xyz = 1;			    last SWITCH;		        };	$nothing = 1;    }or    SWITCH: {	/^abc/ and $abc = 1, last SWITCH;	/^def/ and $def = 1, last SWITCH;	/^xyz/ and $xyz = 1, last SWITCH;	$nothing = 1;    }or even, horrors,    if (/^abc/)	{ $abc = 1 }    elsif (/^def/)	{ $def = 1 }    elsif (/^xyz/)	{ $xyz = 1 }    else	{ $nothing = 1 }A common idiom for a C<switch> statement is to use C<foreach>'s aliasing to makea temporary assignment to C<$_> for convenient matching:    SWITCH: for ($where) {		/In Card Names/     && do { push @flags, '-e'; last; };		/Anywhere/          && do { push @flags, '-h'; last; };		/In Rulings/        && do {                    last; };		die "unknown value for form variable where: `$where'";	    }Another interesting approach to a switch statement is arrangefor a C<do> block to return the proper value:    $amode = do {	if     ($flag & O_RDONLY) { "r" }	# XXX: isn't this 0?	elsif  ($flag & O_WRONLY) { ($flag & O_APPEND) ? "a" : "w" }	elsif  ($flag & O_RDWR)   {	    if ($flag & O_CREAT)  { "w+" }	    else                  { ($flag & O_APPEND) ? "a+" : "r+" }	}    };Or         print do {            ($flags & O_WRONLY) ? "write-only"          :            ($flags & O_RDWR)   ? "read-write"          :                                  "read-only";        };Or if you are certainly that all the C<&&> clauses are true, you can usesomething like this, which "switches" on the value of theC<HTTP_USER_AGENT> environment variable.    #!/usr/bin/perl     # pick out jargon file page based on browser    $dir = 'http://www.wins.uva.nl/~mes/jargon';    for ($ENV{HTTP_USER_AGENT}) { 	$page  =    /Mac/            && 'm/Macintrash.html'		 || /Win(dows )?NT/  && 'e/evilandrude.html'		 || /Win|MSIE|WebTV/ && 'm/MicroslothWindows.html'		 || /Linux/          && 'l/Linux.html'		 || /HP-UX/          && 'h/HP-SUX.html'		 || /SunOS/          && 's/ScumOS.html'		 ||                     'a/AppendixB.html';    }    print "Location: $dir/$page\015\012\015\012";That kind of switch statement only works when you know the C<&&> clauseswill be true.  If you don't, the previous C<?:> example should be used.You might also consider writing a hash of subroutine referencesinstead of synthesizing a C<switch> statement.=head2 GotoAlthough not for the faint of heart, Perl does support a C<goto>statement.  There are three forms: C<goto>-LABEL, C<goto>-EXPR, andC<goto>-&NAME.  A loop's LABEL is not actually a valid target fora C<goto>; it's just the name of the loop.The C<goto>-LABEL form finds the statement labeled with LABEL and resumesexecution there.  It may not be used to go into any construct thatrequires initialization, such as a subroutine or a C<foreach> 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 C<last> or C<die>.  The author of Perl has never felt theneed to use this form of C<goto> (in Perl, that is--C is another matter).The C<goto>-EXPR form expects a label name, whose scope will be resolveddynamically.  This allows for computed C<goto>s per FORTRAN, but isn'tnecessarily recommended if you're optimizing for maintainability:    goto(("FOO", "BAR", "GLARCH")[$i]);The C<goto>-&NAME form is highly magical, and substitutes a call to thenamed subroutine for the currently running subroutine.  This is used byC<AUTOLOAD()> 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 C<@_> in the current subroutine arepropagated to the other subroutine.)  After the C<goto>, not even C<caller()>will be able to tell that this routine was called first.In almost all cases like this, it's usually a far, far better idea to use thestructured control flow mechanisms of C<next>, C<last>, or C<redo> instead ofresorting to a C<goto>.  For certain applications, the catch and throw pair ofC<eval{}> and die() for exception processing can also be a prudent approach.=head2 PODs: Embedded DocumentationPerl 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    =head1 Here There Be Pods!Then that text and all remaining text up through and including a linebeginning with C<=cut> will be ignored.  The format of the interveningtext is described in L<perlpod>.This allows you to intermix your source codeand your documentation text freely, as in    =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;	.........    }Note 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.    $a=3;    =secret stuff     warn "Neither POD nor CODE!?"    =cut back    print "got $a\n";You probably shouldn't rely upon the C<warn()> being podded out forever.Not all pod translators are well-behaved in this regard, and perhapsthe compiler will become pickier.One may also use pod directives to quickly comment out a sectionof code.=head2 Plain Old Comments (Not!)Much like the C preprocessor, Perl can process line directives.  Usingthis, one can control Perl's idea of filenames and line numbers inerror or warning messages (especially for strings that are processedwith C<eval()>).  The syntax for this mechanism is the same as for mostC preprocessors: it matches the regular expressionC</^#\s*line\s+(\d+)\s*(?:\s"([^"]+)")?\s*$/> with C<$1> being the linenumber for the next line, and C<$2> being the optional filename(specified within quotes).There 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.Here are some examples that you should be able to type into your commandshell:    % perl    # line 200 "bzzzt"    # the `#' on the previous line must be the first char on line    die 'foo';    __END__    foo at bzzzt line 201.    % perl    # line 200 "bzzzt"    eval qq[\n#line 2001 ""\ndie 'foo']; print $@;    __END__    foo at - line 2001.    % perl    eval qq[\n#line 200 "foo bar"\ndie 'foo']; print $@;    __END__    foo at foo bar line 200.    % perl    # line 345 "goop"    eval "\n#line " . __LINE__ . ' "' . __FILE__ ."\"\ndie 'foo'";    print $@;    __END__    foo at goop line 345.=cut

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?