Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

next'ing out of a "foreach" loop within a subroutine

by awohld (Hermit)
on Oct 30, 2005 at 03:53 UTC ( [id://503952]=perlquestion: print w/replies, xml ) Need Help??

awohld has asked for the wisdom of the Perl Monks concerning the following question:

I have this code:
foreach $row (@array) { &routine($row); } sub routine { if ($row != '10') { print "stuff"; } else { next; } }
When I'm running it and hit a value of "10" I get a message saying "Exiting subroutine via next"

Is there a way to get the "foreach" loop to go to the next array element from within the subroutine?

Or do I have to "return" a value from the subroutine, then "next" from within the "foreach" loop that way? Is there a better way to do this?

Replies are listed 'Best First'.
Re: next'ing out of a "foreach" loop within a subroutine
by grinder (Bishop) on Oct 30, 2005 at 09:37 UTC
    Is there a better way to do this?

    A better way, in my opinion, would be to have the return value of routine indicate whether the for loop should move onto the next value.

    foreach $row (@array) { next unless routine($row); # more code here } sub routine { if ($row != '10') { print "stuff"; return 1; } else { return 0; } }

    A minor issue with your code as posted: You cannot say $row != '10'. You are using numeric equality against a string. The correct technique is to either compare against a number $row != 10 or compare using string equality $row ne '10'.

    You can get Perl to help you with looking out for problems like this if you have warnings switched on. To enable them, add a use warnings; somewhere in the file.

    • another intruder with the mooring in the heart of the Perl

      Just a nit...

      You cannot say $row != '10'.

      I'd agree it isn't good code, but you can do it; and perl won't complain even with strict and warnings on.

      -sauoq
      "My two cents aren't worth a dime.";
      
Re: next'ing out of a "foreach" loop within a subroutine
by pg (Canon) on Oct 30, 2005 at 03:59 UTC
    "Is there a way to get the "foreach" loop to go to the next array element from within the subroutine?"

    Whether this is possible is irrelevant, as this is a bad idea any way. It is a bad idea as it breaks the modulization.

    In your demo code, that next is useless any way.

    By the way, your routine never took the parameter passed in.

    Just to tame your curiosity, try this for once, but never use it in your real code:

    use strict; use warnings; my @array = (9 .. 11); foreach my $row (@array) { &routine($row); } sub routine { my $row = shift; if ($row != 10) { print "stuff"; } else { last; } }

    This prints only one "stuff", so that that last actually ended the foreach loop.

      Yes, I see why it's a bad idea.

      So the "last" ends the foreach loop since a subroutine returns by default the result of the last operation right?
        "So the "last" ends the foreach loop since a subroutine returns by default the result of the last operation right?"

        The result of the last operation is not the last operation, right? So this does not provide an answer.

        If the last statement comes without a LABEL, it ends the innermost enclosing loop. Semantically, a sub is a block, and in the demo code, the innermost enclosing loop is that foreach loop.

        It is just the way the language was designed. You can argue that this should never happen, and the last statement inside a sub should not impact any loop outside the sub.

        So the "last" ends the foreach loop since a subroutine returns by default the result of the last operation right?
        No. If you use next or last to exit a subroutine, the subroutine doesn't return a value; the next code to execute will a new iteration of the loop or the code after the loop, not the code receiving whatever the sub would have returned if it had returned.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://503952]
Approved by Zaxo
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (5)
As of 2024-04-24 18:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found