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]

Reply via email to