in reply to Using next inappropriately inside a sub

Cool! I wonder if it leaves bogus stuff on the call stack. And if after you've nexted, a return inside the for loop would go all freaky.

Replies are listed 'Best First'.
Re^2: Using next inappropriately inside a sub
by salva (Canon) on Mar 29, 2006 at 10:00 UTC
    I wonder if it leaves bogus stuff on the call stack

    No, it is a supported feature.

      I agree. I use this feature in cgrep (see the nextfile function). The only problem with it is that loop labels are (lexically scoped, not dynamically) dynamically scoped, not lexically, so you can never make sure that your loop labels don't accidentally clash with those of a function you call from another module.

      Update: see also Re: How can I return to main loop, not to caller?, and Re: Perl etiquette - eval.

        The only problem with it is that loop labels are lexically scoped, not dynamically, so you can never make sure that your loop labels don't accidentally clash with those of a function you call from another module.
        Huh? Looks dynamic to me:
        #!/usr/bin/env perl use strict; SOME_LOOP: for my $outer (1..2) { print "outer: before callback with $outer\n"; call_my_callback( sub { next SOME_LOOP } ); # you say this should ad +vance "$outer"; print "outer: after callback with $outer\n"; } sub call_my_callback { SOME_LOOP: for my $inner (1..2) { print "inner: before callback with $inner\n"; $_[0]->(); # "neeeexxxt!" print "inner: after callback with $inner\n"; } }
        This runs (as I expected), producing:
        outer: before callback with 1 inner: before callback with 1 inner: before callback with 2 outer: after callback with 1 outer: before callback with 2 inner: before callback with 1 inner: before callback with 2 outer: after callback with 2
        Note that "next" is seeing the inner loop (dynamic, like local variables), not the outer loop (lexical, like my variables). If it had ignored the inner loop (which you can simulate by changing the subroutine loop label to something else), the output would have been:
        outer: before callback with 1 inner: before callback with 1 outer: before callback with 2 inner: before callback with 1
        The way this works is that last/next/redo just pop contexts off the stack until they get to one that has the right name. If they go all the way to the outer program, it's an error. It's a very simple scoping rule, and very predictable, and actually is doing The Right Thing here.

        -- Randal L. Schwartz, Perl hacker
        Be sure to read my standard disclaimer if this is a reply.