in reply to Re: next and last within subs
in thread next and last within subs

This is basically what i'm doing. The other problem with exiting the sub with next or last is that it seems to completely exit the loop when at least in two cases I want to just move on to the next iteration.
foreach (@array) { if ($something) { # do stuff if ($something1) { # time to move to next iteration of loop before_next_stuff(); } } if ($somethingelse) { # do some other stuff before_next_stuff(); } # more stuff in loop before_next_stuff(); } sub before_next_stuff { # lots o stuff if ($x > $stop) { last; } elsif ($y ne $text) { foobar(); } else { next; } }

Replies are listed 'Best First'.
Re^3: next and last within subs
by oakb (Scribe) on Jul 11, 2014 at 21:36 UTC
    Trying to control a loop from a subroutine called from inside the loop is just asking for trouble. It might seem like it will work... it might even work in some circumstances... but most likely it's just going to fail. Can you see how Perl is confused by your instructions? Basically, you're trying to use a subroutine for loop control when you should be doing some form of nesting, and leave loop control inside the loop:

    sub before_next_stuff { # lots o stuff } MAINJOB: foreach ( @array ) { if ( $something ) { # do stuff if ( $something_1 ) { # time to move to next iteration # of the loop before_next_stuff(); # you should only include this # loop control here if you must if ( $x > $stop ) { last MAINJOB; } elsif ( $y ne $text ) { foobar(); } else { next MAINJOB; } } } if ( $something_else ) { # do some other stuff before_next_stuff(); # you should only include this # loop control here if you must if ( $x > $stop ) { last MAINJOB; } elsif ( $y ne $text ) { foobar(); } else { next MAINJOB; } } # more stuff in loop before_next_stuff(); if ( $x > $stop ) { last MAINJOB; } elsif ( $y ne $text ) { foobar(); } # no "next" necessary here }


    A big part of effective and elegant programming is to structure your loops so that controlling them is mostly a matter of natural flow. However, there are times when "natural flow" is simply impossible, and you need some way of interrupting loop flow -- which is why Perl has next and last functions. But they should still be used as sparingly as possible.

    Bottom line: loop control should never be farmed out to a sub external to the loop. You can abstract everything else out into subs, but control needs to stay internal.

    PS- Any time I have nested or complex loops, I use explicit labels (like "MAINJOB", above). They help both Perl and me (much more me than Perl) keep track of which loop is being controlled at any given time.

Re^3: next and last within subs
by Anonymous Monk on Jul 11, 2014 at 20:25 UTC

    Sounds like you want to return from the sub, rather than try to manipulate the loop outside the sub.