A thread from last July, WRT bug ID 20000717.003 [1], suggested that we may
want to revisit the behavior of flow control expressions within the context
of a subroutine.
The current behavior is to find the closest (labelled) enclosing loop
(dynamically, not lexically), and treat that as the target for the flow
control expression - unwinding any stacks necessary. It does
produce a warning with '-w'.
The following code demonstrates:
#!/usr/bin/perl -w
$a = 'a'; $c = 0;
sub frok {
return gork(@_);
}
sub gork {
my ($a) = @_;
redo if $a eq 'd' && ! $c++;
next if $a eq 'h';
last if $a eq 'o';
return ++$a;
}
while ( $a++ ) {
print "1. $a\n";
$a = frok($a);
print "2. $a\n";
}
continue {
print "3. $a\n";
}
print "Done\n";
The suggested alternative was to treat loop control expressions which would
exit the subroutine to be equivalent to 'return;'
The main argument against the current behavior related to "action at a
distance", and code needing to protect itself from poorly written callbacks.
FWIW, here's my opinion. (I'm in favor of the current behavior.)
1) The current behavior, however heinous, actually has a use. There's no
value added in having five ways to return undef.
2) It reflects the intended use. The programmer was most likely trying to
execute *some* form of loop control, however misguided they may have been.
Perhaps the subroutine was originally code in a larger loop, and the code
was shuffled off to a subroutine to make the loop simpler. Perhaps the
coder mistakenly thought the subroutine was a loop. The current behavior
allows the preservation of the first if it were intended, and warns on the
second, if it weren't.
Most likely, if a coder intends to return, they actually return. Granted,
there's an implicit return off the end of a function, and perhaps the coder
thought 'last' may get them there. But instead of returning the value of
the last statement, you return nothing. And with no warning. And that
helps 'last', but not the other three. 'next' is nonsensical, 'redo' even
more so, and a 'goto' that doesn't just doesn't seem right.
3) It's consistent. The same behavior currently happens within an eval
block. If you were to define 'return;', you'd have to also redress eval
behavior.
Does anyone wish to argue for any other behavior, or may we consider this
revisited?
[1] http://www.mail-archive.com/perl5-porters@perl.org/msg12899.html
--
Bryan C. Warnock
[EMAIL PROTECTED]