The while or until statement can have an optional extra block: the continue block. This block is executed every time the block is continued, either by ...
Skiptomaincontent
ProgrammingPerl,3rdEditionby
GetfullaccesstoProgrammingPerl,3rdEditionand60K+othertitles,withfree10-daytrialofO'Reilly.
There'salsoliveonlineevents,interactivecontent,certificationprepmaterials,andmore.
Startyourfreetrial
LoopStatementsAllloopstatementshaveanoptional
LABELintheirformalsyntax.(Youcanput
alabelonanystatement,butithasaspecialmeaningtoaloop.)If
present,thelabelconsistsofanidentifierfollowedbyacolon.It's
customarytomakethelabeluppercasetoavoidpotentialconfusion
withreservedwords,andsoitstandsoutbetter.AndalthoughPerl
won'tgetconfusedifyouusealabelthatalreadyhasameaninglike
iforopen,yourreadersmight.
whileanduntilStatementsThewhilestatementrepeatedly
executestheblockaslongasEXPRis
true.Ifthewordwhileisreplacedbytheword
until,thesenseofthetestisreversed;that
is,itexecutestheblockonlyaslongas
EXPRremainsfalse.Theconditionalis
stilltestedbeforethefirstiteration,though.Thewhileor
untilstatementcanhaveanoptionalextrablock:
thecontinueblock.Thisblockisexecutedevery
timetheblockiscontinued,eitherbyfallingofftheendofthe
firstblockorbyanexplicitnext(a
loop-controloperatorthatgoestothenextiteration).The
continueblockisnotheavilyusedinpractice,
butit'sinheresowecandefinetheforloop
rigorouslyinthenextsection.Unliketheforeachloopwe'llseeina
moment,awhileloopneverimplicitlylocalizes
anyvariablesinitstestcondition.Thiscanhave"interesting"
consequenceswhenwhileloopsuseglobalsfor
loopvariables.Inparticular,seeSection2.11.2inChapter2forhowimplicitassignment
totheglobal$_canoccurincertain
whileloops,alongwithanexampleofhowtodeal
withtheproblembyexplicitlylocalizing$_.For
otherloopvariables,however,it'sbesttodeclarethemwith
my,asinthenextexample.Avariabledeclaredinthetestconditionofa
whileoruntilstatementis
visibleonlyintheblockorblocksgovernedbythattest.Itisnot
partofthesurroundingscope.Forexample:while(my$line=){
$line=lc$line;
}
continue{
print$line;#stillvisible
}
#$linenowoutofscopehereHerethescopeof$lineextendsfromits
declarationinthecontrolexpressionthroughouttherestofthe
loopconstruct,includingthecontinueblock,but
notbeyond.Ifyouwantthescopetoextendfurther,declarethe
variablebeforetheloop.forLoopsThethree-partforloophasthree
semicolon-separatedexpressionswithinitsparentheses.These
expressionsfunctionrespectivelyastheinitialization,the
condition,andthere-initializationexpressionsoftheloop.All
threeexpressionsareoptional(butnotthesemicolons);ifomitted,
theconditionisalwaystrue.Thus,thethree-part
forloopcanbedefinedintermsofthe
correspondingwhileloop.This:LABEL:
for(my$i=1;$i<=10;$i++){
…
}islikethis:{
my$i=1;
LABEL:
while($i<=10){
…
}continue{
$i++;
}
}exceptthatthere'snotreallyanouterblock.(Wejustput
onetheretoshowhowthescopeofthemyis
limited.)Ifyouwanttoiteratethroughtwovariables
simultaneously,justseparatetheparallelexpressionswith
commas:for($i=0,$bit=0;$i<32;$i++,$bit<<=1){
print"Bit$iisset\n"if$mask&$bit;
}
#thevaluesin$iand$bitpersistpasttheloopOrdeclarethosevariablestobevisibleonlyinsidethe
forloop:for(my($i,$bit)=(0,1);$i<32;$i++,$bit<<=1){
print"Bit$iisset\n"if$mask&$bit;
}
#loop'sversionsof$iand$bitnowoutofscopeBesidesthenormalloopingthrougharrayindices,
forcanlenditselftomanyotherinteresting
applications.Itdoesn'tevenneedanexplicitloopvariable.Here's
oneexamplethatavoidstheproblemyougetwhenyouexplicitlytest
forend-of-fileonaninteractivefiledescriptor,causingyour
programtoappeartohang.$on_a_tty=-tSTDIN&&-tSTDOUT;
subprompt{print"yes?"if$on_a_tty}
for(prompt();;prompt()){
#dosomething
}Anothertraditionalapplicationforthethree-part
forloopresultsfromthefactthatallthree
expressionsareoptional,andthedefaultconditionistrue.Ifyou
leaveoutallthreeexpressions,youhavewrittenaninfinite
loop:for(;;){
…
}Thisisthesameaswriting:while(1){
…
}Ifthenotionofinfiniteloopsbothersyou,we
shouldpointoutthatyoucanalwaysfalloutoftheloopatany
pointwithanexplicitloop-controloperatorsuchas
last.Ofcourse,ifyou'rewritingthecodeto
controlacruisemissile,youmaynotactuallyneedanexplicitloop
exit.Theloopwillbeterminatedautomaticallyattheappropriate
moment.[3]foreachLoopsTheforeachloopiteratesovera
listofvaluesbysettingthecontrolvariable
(VAR)toeachsuccessiveelementofthe
list:foreachVAR(LIST){
…
}Theforeachkeywordisjusta
synonymfortheforkeyword,soyoucanuse
foreachandfor
interchangeably,whicheveryouthinkismorereadableinagiven
situation.IfVARisomitted,theglobal
$_isused.(Don'tworry--Perlcaneasily
distinguishfor(@ARGV)fromfor($i=0;
$i$hash{$key}\n";
}Thatlastoneisthecanonicalwaytoprintoutthevaluesof
ahashinsortedorder.Seethekeysand
sortentriesinChapter29formoreelaborate
examples.Thereisnowaywithforeachtotellwhere
youareinalist.Youmaycompareadjacentelementsbyremembering
thepreviousoneinavariable,butsometimesyoujusthavetobreak
downandwriteathree-partforloopwith
subscripts.That'swhattheotherkindoffor
loopistherefor,afterall.IfLISTconsistsentirely
ofassignablevalues(meaningvariables,generally,notenumerated
constants),youcanmodifyeachofthosevariablesbymodifying
VARinsidetheloop.That'sbecausethe
foreachloopindexvariableisanimplicitalias
foreachiteminthelistthatyou'reloopingover.Notonlycanyou
modifyasinglearrayinplace,youcanalsomodifymultiplearrays
andhashesinasinglelist:foreach$pay(@salaries){#grant8%raises
$pay*=1.08;
}
for(@christmas,@easter){#changemenu
s/ham/turkey/;
}
s/ham/turkey/for@christmas,@easter;#samething
for($scalar,@array,values%hash){
s/^\s+//;#stripleadingwhitespace
s/\s+$//;#striptrailingwhitespace
}Theloopvariableisvalidonlyfromwithinthedynamicor
lexicalscopeoftheloopandwillbeimplicitlylexicalifthe
variablewaspreviouslydeclaredwithmy.This
rendersitinvisibletoanyfunctiondefinedoutsidethelexical
scopeofthevariable,evenifcalledfromwithinthatloop.
However,ifnolexicaldeclarationisinscope,theloopvariable
willbealocalized(dynamicallyscoped)globalvariable;this
allowsfunctionscalledfromwithinthelooptoaccessthat
variable.Ineithercase,anypreviousvaluethelocalizedvariable
hadbeforetheloopwillberestoredautomaticallyuponloop
exit.Ifyouprefer,youmayexplicitlydeclarewhichkindof
variable(lexicalorglobal)touse.Thismakesiteasierfor
maintainersofyourcodetoknowwhat'sreallygoingon;otherwise,
they'llneedtosearchbackupthroughenclosingscopesfora
previousdeclarationtofigureoutwhichkindofvariableit
is:formy$i(1..10){…}#$ialwayslexical
forour$Tick(1..10){…}#$TickalwaysglobalWhenadeclarationaccompaniestheloopvariable,theshorter
forspellingispreferredover
foreach,sinceitreadsbetterinEnglish.Here'showaCorJavaprogrammermightfirstthinktocodeup
aparticularalgorithminPerl:for($i=0;$i$ary2[$j]){
last;#Can'tgotoouterloop.:-(
}
$ary1[$i]+=$ary2[$j];
}
#thisiswherethatlasttakesme
}Buthere'showaveteranPerlprogrammermightdoit:WID:foreach$this(@ary1){
JET:foreach$that(@ary2){
nextWIDif$this>$that;
$this+=$that;
}
}SeehowmucheasierthatwasinidiomaticPerl?It'scleaner,
safer,andfaster.It'scleanerbecauseit'slessnoisy.It'ssafer
becauseifcodegetsaddedbetweentheinnerandouterloopslater
on,thenewcodewon'tbeaccidentallyexecuted,since
next(explainedbelow)explicitlyiteratesthe
outerloopratherthanmerelybreakingoutoftheinnerone.And
it'sfasterbecausePerlexecutesaforeach
statementmorerapidlythanitwouldtheequivalent
forloop,sincetheelementsareaccessed
directlyinsteadofthroughsubscripting.Butwriteithoweveryoulike.TMTOWTDI.Likethewhilestatement,the
foreachstatementcanalsotakea
continueblock.Thisletsyouexecuteabitof
codeatthebottomofeachloopiterationnomatterwhetheryougot
thereinthenormalcourseofeventsorthrougha
next.Speakingofwhich,nowwecanfinallysayit:
nextisnext.LoopControlWementionedthatyoucanputa
LABELonalooptogiveitaname.The
loop'sLABELidentifiestheloopforthe
loop-controloperatorsnext,
last,andredo.The
LABELnamestheloopasawhole,notjust
thetopoftheloop.Hence,aloop-controloperatorreferringtothe
loopdoesn'tactually"goto"thelooplabelitself.Asfarasthe
computerisconcerned,thelabelcouldjustaseasilyhavebeen
placedattheendoftheloop.Butpeoplelikethingslabeledatthe
top,forsomereason.Loopsaretypicallynamedfortheitemtheloopisprocessing
oneachiteration.Thisinteractsnicelywiththeloop-control
operators,whicharedesignedtoreadlikeEnglishwhenusedwithan
appropriatelabelandastatementmodifier.Thearchetypalloop
worksonlines,sothearchetypallooplabelis
LINE:,andthearchetypalloop-controloperator
issomethinglikethis:nextLINEif/^#/;#discardcommentsThesyntaxfortheloop-controloperatorsis:lastLABEL
nextLABEL
redoLABELTheLABELisoptional;ifomitted,
theoperatorreferstotheinnermostenclosingloop.Butifyouwant
tojumppastmorethanonelevel,youmustusea
LABELtonametheloopyouwantto
affect.ThatLABELdoesnothavetobein
yourlexicalscope,thoughitprobablyoughttobe.Butinfact,the
LABELcanbeanywhereinyourdynamic
scope.Ifthisforcesyoutojumpoutofaneval
orsubroutine,Perlissuesawarning(uponrequest).Justasyoumayhaveasmany
returnoperatorsinafunctionasyoulike,you
mayhaveasmanyloop-controloperatorsinaloopasyoulike.This
isnottobeconsideredwickedorevenuncool.Duringtheearlydays
ofstructuredprogramming,somepeopleinsistedthatloopsand
subroutineshaveonlyoneentryandoneexit.Theone-entrynotion
isstillagoodidea,buttheone-exitnotionhasledpeopleto
writealotofunnaturalcode.Muchofprogrammingconsistsof
traversingdecisiontrees.Adecisiontreenaturallystartswitha
singletrunkbutendswithmanyleaves.Writeyourcodewiththe
numberofloopexits(andfunctionreturns)thatisnaturaltothe
problemyou'retryingtosolve.Ifyou'vedeclaredyourvariables
withreasonablescopes,everythinggetsautomaticallycleanedupat
theappropriatemoment,nomatterhowyouleavetheblock.Thelastoperatorimmediately
exitstheloopinquestion.Thecontinueblock,
ifany,isnotexecuted.Thefollowingexamplebombsoutoftheloop
onthefirstblankline:LINE:while(){
lastLINEif/^$/;#exitwhendonewithmailheader
…
}Thenextoperatorskipstherestofthe
currentiterationoftheloopandstartsthenextone.Ifthereisa
continueclauseontheloop,itisexecutedjust
beforetheconditionisre-evaluated,justlikethethirdcomponent
ofathree-partforloop.Thusitcanbeusedto
incrementaloopvariable,evenwhenaparticulariterationofthe
loophasbeeninterruptedbyanext:LINE:while(){
nextLINEif/^#/;#skipcomments
nextLINEif/^$/;#skipblanklines
…
}continue{
$count++;
}Theredooperatorrestartstheloopblock
withoutevaluatingtheconditionalagain.The
continueblock,ifany,isnotexecuted.This
operatorisoftenusedbyprogramsthatwanttofibtothemselves
aboutwhatwasjustinput.Supposeyouwereprocessingafilethat
sometimeshadabackslashattheendofalinetocontinuethe
recordonthenextline.Here'showyoucoulduse
redoforthat:while(<>){
chomp;
if(s/\\$//){
$_.=<>;
redounlesseof;#don'treadpasteachfile'seof
}
#nowprocess$_
}whichisthecustomaryPerlshorthandforthemoreexplicitly
(andtediously)writtenversion:LINE:while(defined($line=)){
chomp($line);
if($line=~s/\\$//){
$line.=;
redoLINEunlesseof(ARGV);
}
#nowprocess$line
}Here'sanexamplefromarealprogramthatusesall
threeloop-controloperators.Althoughthisparticularstrategyof
parsingcommand-lineargumentsislesscommonnowthatwehavethe
Getopts::*modulesbundledwithPerl,it'sstill
aniceillustrationoftheuseofloop-controloperatorsonnamed,
nestedloops:ARG:while(@ARGV&&$ARGV[0]=~s/^-(?=.)//){
OPT:for(shift@ARGV){
m/^$/&&do{nextARG;};
m/^-$/&&do{lastARG;};
s/^d//&&do{$Debug_Level++;redoOPT;};
s/^l//&&do{$Generate_Listing++;redoOPT;};
s/^i(.*)//&&do{$In_Place=$1||".bak";nextARG;};
say_usage("Unknownoption:$_");
}
}Onemorepointaboutloop-controloperators.Youmay
havenoticedthatwearenotcallingthem"statements".That's
becausetheyaren'tstatements--althoughlikeanyexpression,they
canbeusedasstatements.Youcanalmostthinkofthemasunary
operatorsthatjusthappentocauseachangeincontrolflow.Soyou
canusethemanywhereitmakessensetousetheminanexpression.
Infact,youcanevenusethemwhereitdoesn'tmakesense.One
sometimesseesthiscodingerror:openFILE,$file
orwarn"Can'topen$file:$!\n",nextFILE;#WRONGTheintentisfine,butthenextFILEis
beingparsedasoneoftheargumentstowarn,
whichisalistoperator.Sothenextexecutes
beforethewarngetsachancetoemitthe
warning.Inthiscase,it'seasilyfixedbyturningthe
warnlistoperatorintothe
warnfunctioncallwithsomesuitablysituated
parentheses:openFILE,$file
orwarn("Can'topen$file:$!\n"),nextFILE;#okayHowever,youmightfinditeasiertoreadthis:unless(openFILE,$file){
warn"Can'topen$file:$!\n";
nextFILE;
}[3]Thatis,thefalloutfromthelooptendstooccur
automatically.
GetProgrammingPerl,3rdEditionnowwiththeO’Reillylearningplatform.
O’Reillymembersexperienceliveonlinetraining,plusbooks,videos,anddigitalcontentfromnearly200publishers.
Startyourfreetrial
Don’tleaveempty-handed
GetMarkRichards’sSoftwareArchitecturePatternsebooktobetterunderstandhowtodesigncomponents—andhowtheyshouldinteract.
It’syours,free.
Getitnow
Close