So, labels can be used to specify which loop next
and last
apply to. In Perl, next
does what continue
does in most languages (it probably could not be called continue
because that's the word used to introduce a continue
block), and last
does what break
does in most languages.
next
is intuitively named because, after the continue
block runs, it goes to the next iteration of the loop. The effect is simply to skip over the rest of the body of the loop. But last
is not intuitively named, because, after the continue
block runs, it doesn't go to the last iteration of the loop -- instead, the loop is done. So next
goes to the next iteration, but last
causes the current iteration to be the last one.
I do not know of any other languages that have continue
blocks (though I imagine Perl 6, which is a different language from Perl 5, has them). So, in a sense, next
and last
don't do exactly what break
and continue
do in most languages, because most languages don't have continue
blocks, but Perl does and next
and last
respect them.
Note that, if a loop has no continue
block, then it is as though it had a continue
block that was empty, and next
and last
immediately go directly to the next iteration or immediately break out of the loop, respectively.
Loops do not have to have labels (and in general I suggest not using them without reason). next
and last
work without labels, because whether or not the loop is labeled, using them with no label argument causes them to apply to the innermost loop in which they appear. When you do label a loop, the label does not have to be named like the loop variables; I just happened to do that here. It is often useful to do so but never required.
Labels and continue
blocks are separate in the sense that all four combinations of having a label or not and having a continue block or not are permitted. Labels can appear elsewhere than atop a loop, because in addition to being used to let you specify which loop you want next
or last
to use, they can also be jumped to with goto
. I recommend trying goto OWL
and goto GAME
at various points while running that script.
Even when the label does appear atop a loop, goto
behaves very differently from next
and last
. It does not respect continue
blocks, and if a loop appears after a label that you jump to using goto
, then that loop starts over again from the beginning. It is easier (i.e., possible) to demonstrate that with for
loops than with while
loops.
Labels have loop-specific behavior (if one wants to attribute behavior to them rather than the code that uses them) because of next
and last
, but there is absolutely nothing loop-specific about goto
. Many languages have goto
, and programmers are discouraged from using it in almost all of them, except in situations where it is clearly more useful to use it than other flow control constructs.
Some people say that one should only use goto
when it is the only option, but it's actually never the only option; however, occasionally it may be the clearest option. Usually it is not. Some programmers insist on never using goto
, but there is a substantial amount of code written by experts that does use it.
However, in a language like Perl you generally need it even less than in a language like C, because Perl has sophisticated flow control constructs like continue
blocks and labels that let you apply next
and last
to a particular loop.
Spaghetti code is a pejorative phrase for source code that has a complex and tangled control structure, especially one using many GOTO statements, exceptions, threads, or other "unstructured" branching constructs. It is named such because program flow is conceptually like a bowl of spaghetti, i.e. twisted and tangled. Spaghetti code can be caused by several factors, such as continuous modifications by several people with different programming styles over a long life cycle. Structured programming greatly decreases the incidence of spaghetti code.
== History ==
An early reference that contributed...
To compare Perl to a couple other languages: Java has labels but no goto
, and you can use break
(which is like Perl's last
) or continue
(which is like Perl's next
) with an optional label.
Similarly, Bash uses break
and continue
to mean the same things they mean in Java, and, like Java, Bash does not have goto
. However, bash
does not have labels either. Instead, in Bash, if you want break
or continue
to apply to any loop but the innermost one, then you can pass them an optional numeric argument to indicate the level. The higher number, the more out the loop is that is being broken or continued.
C uses break
and continue
to mean the same things they mean in Java (that's where Java got them), but C does not have any feature to make break
or continue
act on any loop but the innermost loop. However, C does have labels and goto
, which are sometimes used for that purpose.
Particularly relevant is the first paragraph of the entry on goto
in perldoc perlfunc
(you can run perldoc -f goto
to see just the entry on goto
):
The "goto LABEL" form finds the statement labeled with LABEL and
resumes execution there. It can't be used to get out of a block or
subroutine given to "sort". It can be used to go almost anywhere
else within the dynamic scope, including out of subroutines, but
it's usually better to use some other construct such as "last" or
"die". The author of Perl has never felt the need to use this form
of "goto" (in Perl, that is; C is another matter). (The difference