Although not for the faint of heart (nor for the pure of
heart), Perl does support a goto
operator. There
are three forms: goto
LABEL
, goto
EXPR
, and goto
&
NAME
.
The goto
LABEL
form finds the statement labeled with LABEL
and resumes execution there. It cant be used to jump into any
construct that requires initialization, such as a subroutine or a
foreach
loop. It also can't be used to jump into a
construct that has been optimized away (see Chapter 18). It can be used to go
almost anywhere else within the current block or any block in your
dynamic scope (that is, a block you were called from). You can even
goto
out of subroutines, but it's usually better to
use some other construct. The author of Perl has never felt the need
to use this form of goto
(in Perl, that is--C is
another matter).
The goto
EXPR
form is just a generalization of
goto
LABEL
. It expects
the expression to produce a label name, whose location obviously has
to be resolved dynamically by the interpreter. This allows for
computed gotos per FORTRAN, but isn't necessarily recommended if
you're optimizing for maintainability:
goto(("FOO", "BAR", "GLARCH")[$i]); # hope 0 <= i < 3 @loop_label = qw/FOO BAR GLARCH/; goto $loop_label[rand @loop_label]; # random teleport
In almost all cases like this, it's usually a far, far better
idea to use the structured control flow mechanisms of
next
, last
, or
redo
instead of resorting to a
goto
. For certain applications, a hash of
references to functions or the catch-and-throw pair of
eval
and die
for exception
processing can also be prudent approaches.
The goto
&
NAME
form is highly magical
and sufficiently removed from the ordinary goto
to
exempt its users from the opprobrium to which goto
users are customarily subjected. It substitutes a call to the named
subroutine for the currently running subroutine. This behavior is used
by AUTOLOAD
subroutines to load another subroutine
and then pretend that the other subroutine was called in the first
place. After the goto
, not even
caller
will be able to tell that this routine was
called first. The autouse
,
AutoLoader
, and SelfLoader
modules all use this strategy to define functions the first time
they're called, and then to jump right to them without anyone ever
knowing the functions weren't there all along.