📄 ch10_08.htm
字号:
<tt class="literal">fred</tt>. In that case, we count<tt class="literal">$valid</tt> up by one, and also<tt class="literal">$count{$_}</tt>, keeping a count for each differentword. So, when we finish the two loops, we've counted everyword in every line of input from every file the user wanted us touse.</p><p>We're not going to explain the last few lines. By now, we hopeyou've got stuff like that down already.</p><p>Like <tt class="literal">last</tt>, <tt class="literal">next</tt> may be used inany of the five kinds of <a name="INDEX-699" />loop blocks: <tt class="literal">for</tt>,<tt class="literal">foreach</tt>, <tt class="literal">while</tt>,<tt class="literal">until</tt>, or the naked block. Also, if loop blocksare nested, <tt class="literal">next</tt> works with the innermost one.We'll see how to change that at the end of this section.</p></div><a name="lperl3-CHP-10-SECT-8.3" /><div class="sect2"><h3 class="sect2">10.8.3. The redo Operator</h3><p>The third member of the loop control triad is<tt class="literal">redo</tt><a name="INDEX-700" />. It says to go back to the top of thecurrent loop block, without testing any conditional expression oradvancing to the next iteration. (If you've used C or a similarlanguage, you've never seen this one before. Those languagesdon't have this kind of operator.) Here's an example:</p><blockquote><pre class="code"># Typing testmy @words = qw{ fred barney pebbles dino wilma betty };my $errors = 0;foreach (@words) { ## redo comes here ## print "Type the word '$_': "; chomp(my $try = <STDIN>); if ($try ne $_) { print "Sorry - That's not right.\n\n"; $errors++; redo; # jump back up to the top of the loop }}print "You've completed the test, with $errors errors.\n";</pre></blockquote><p>Like the other two operators, <tt class="literal">redo</tt> will work withany of the five kinds of loop blocks, and it will work with theinnermost loop block when they're nested.</p><p>The big difference between <tt class="literal">next</tt> and<tt class="literal">redo</tt> is that <tt class="literal">next</tt> will advanceto the next iteration, but <tt class="literal">redo</tt> will redo thecurrent iteration. Here's an example program that you can playwith to get a feel for how these three operators work:<a href="#FOOTNOTE-233">[233]</a></p><blockquote class="footnote"><a name="FOOTNOTE-233" /><p>[233]If you've downloaded the example files from theO'Reilly website (as described in the Preface), you'llfind this program called <em class="filename">lnr-example.</em></p></blockquote><blockquote><pre class="code">foreach (1..10) { print "Iteration number $_.\n\n"; print "Please choose: last, next, redo, or none of the above? "; chomp(my $choice = <STDIN>); print "\n"; last if $choice =~ /last/i; next if $choice =~ /next/i; redo if $choice =~ /redo/i; print "That wasn't any of the choices... onward!\n\n";}print "That's all, folks!\n";</pre></blockquote><p>If you just press return without typing anything (try it two or threetimes), the loop counts along from one number to the next. If youchoose <tt class="literal">last</tt> when you get to number four, the loopis done, and you won't go on to number five. If you choose<tt class="literal">next</tt> when you're on four, you're on tonumber five without printing the "onward" message. And ifyou choose <tt class="literal">redo</tt> when you're on four,you're back to doing number four all over again.<a name="INDEX-701" /></p></div><a name="lperl3-CHP-10-SECT-8.4" /><div class="sect2"><h3 class="sect2">10.8.4. Labeled Blocks</h3><p>When you need to work with a <a name="INDEX-702" /><a name="INDEX-703" />loop blockthat's not the innermost one, use a label. Labels in Perl arelike other identifiers -- made of letters, digits, andunderscores, but they can't start with a digit -- however,since they have no prefix character, labels could be confused withthe names of builtin function names, or even with your ownsubroutines' names. So, it would be a poor choice to make alabel called <tt class="literal">print</tt> or <tt class="literal">if</tt>.Because of that, Larry recommends that they be all uppercase. Thatnot only ensures that the label won't conflict with anotheridentifier but it also makes it easy to spot the label in the code.In any case, labels are rare, only showing up in a small percentageof Perl programs.</p><p>To label a loop block, just put the label and a colon in front of theloop. Then, inside the loop, you may use the label after<tt class="literal">last</tt>, <tt class="literal">next</tt>, or<tt class="literal">redo</tt> as needed:</p><blockquote><pre class="code">LINE: while (<>) { foreach (split) { last LINE if /_ _END_ _/; # bail out of the LINE loop ...; }}</pre></blockquote><p>For readability, it's generally nice to put the label at theleft margin, even if the current code is at a higher indentation.Notice that the label names the entire block; it's not markinga target point in the code.<a href="#FOOTNOTE-234">[234]</a></p><blockquote class="footnote"> <a name="FOOTNOTE-234" /><p>[234]This isn't<tt class="literal">goto</tt>, after all.</p> </blockquote><p>In that previous snippet of sample code, the special <tt class="literal">__END__</tt> token marks the end of all input. Once that token showsup, the program will ignore any remaining lines (even from otherfiles).</p><p>It often makes sense to choose a noun as the name of theloop.<a href="#FOOTNOTE-235">[235]</a> Thatis, the outer loop is processing a line at a time, so we called it<tt class="literal">LINE</tt>. If we had to name the inner loop, we wouldhave called it <tt class="literal">WORD</tt>, since it processes a word ata time. That makes it convenient to say things like "(move onto the) <tt class="literal">next</tt> <tt class="literal">WORD</tt>" or"<tt class="literal">redo</tt> (the current)<tt class="literal">LINE</tt>".<a name="INDEX-704" /> <a name="INDEX-705" /> </p><blockquote class="footnote"> <a name="FOOTNOTE-235" /><p>[235]That is, it makes more sense to do that thannot to do that. Perl doesn't care if you call your loop labelsthings like <tt class="literal">XYZZY</tt> or <tt class="literal">PLUGH</tt>.However, unless you were friendly with the Colossal Cave in the70's, you might not get the reference.</p> </blockquote></div><hr width="684" align="left" /><div class="navbar"><table width="684" border="0"><tr><td align="left" valign="top" width="228"><a href="ch10_07.htm"><img alt="Previous" border="0" src="../gifs/txtpreva.gif" /></a></td><td align="center" valign="top" width="228"><a href="index.htm"><img alt="Home" border="0" src="../gifs/txthome.gif" /></a></td><td align="right" valign="top" width="228"><a href="ch10_09.htm"><img alt="Next" border="0" src="../gifs/txtnexta.gif" /></a></td></tr><tr><td align="left" valign="top" width="228">10.7. The for Control Structure</td><td align="center" valign="top" width="228"><a href="index/index.htm"><img alt="Book Index" border="0" src="../gifs/index.gif" /></a></td><td align="right" valign="top" width="228">10.9. Logical Operators</td></tr></table></div><hr width="684" align="left" /><img alt="Library Navigation Links" border="0" src="../gifs/navbar.gif" usemap="#library-map" /><p><p><font size="-1"><a href="copyrght.htm">Copyright © 2002</a> O'Reilly & Associates. All rights reserved.</font></p><map name="library-map"><area shape="rect" coords="1,0,85,94" href="../index.htm"><area shape="rect" coords="86,1,178,103" href="../lwp/index.htm"><area shape="rect" coords="180,0,265,103" href="../lperl/index.htm"><area shape="rect" coords="267,0,353,105" href="../perlnut/index.htm"><area shape="rect" coords="354,1,446,115" href="../prog/index.htm"><area shape="rect" coords="448,0,526,132" href="../tk/index.htm"><area shape="rect" coords="528,1,615,119" href="../cookbook/index.htm"><area shape="rect" coords="617,0,690,135" href="../pxml/index.htm"></map></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -