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

I recently wrote an program that loops through a text file line-by-line and prints the output on a html page generated on the fly by said program. The problem is that it is dying randomly during looping. Sometimes it'll be after the first line, others it'll be halfway. It's random :(

Unfortunately, I cannot post the actual code here, but the example below is structurally indentical:

my @numbers = ('1','2','3','4','5'); NUMBER: foreach my $number(@numbers){ eval { next_loop(); } } sub next_loop { next NUMBER; }


But this works fine:

my @numbers = ('1','2','3','4','5'); NUMBER: foreach my $number(@numbers){ next NUMBER; } }


Any ideas as to why the first example might have problems?

Replies are listed 'Best First'.
Re: loop labels and script dying
by liz (Monsignor) on Sep 03, 2003 at 13:06 UTC
    Yikes.

    I can't get this to break between 5.6.0 and 5.8.1. Although I think this is butt ugly and probably shouldn't be allowed to be executable at all ;-)

    I guess we need to know more about the version of Perl and environment you're running this in.

    Liz

Re: loop labels and script dying
by dragonchild (Archbishop) on Sep 03, 2003 at 13:07 UTC
    I'm guessing you're using mod_perl. The answer is, I think, because NUMBER isn't in scope when next is called. Try enabling warnings.

    I would recommend returning from next_loop() either 1 or 0 and doing next_loop() && next NUMBER; in the main loop.

    ------
    We are the carpenters and bricklayers of the Information Age.

    The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

Re: loop labels and script dying
by ChrisS (Monk) on Sep 03, 2003 at 13:08 UTC
    Why are you using the next inside the foreach loop, when the foreach loop itself will iterate over the list of numbers?
    my @numbers = (1..6); foreach my $number (@numbers) { print $number; }
    If you need to exit on a specific condition, use last:
    my @numbers = (1..6); foreach my $number (@numbers) { last if $number == 4; print $number; }
    If you want to continue based on a subroutine, you probably don't need to eval it, just call it, unless you'll be using it to do primitive error handling.
    my @numbers = (1..6); foreach my $number (@numbers) { next if next_loop($number); print $number; } sub next_loop { # return some true or false value my $num = shift; return ($num % 2); # will skip over odd numbers }
      I'm going to guess it's something like:
      foreach my $foo (@foos) { # Do common processing next if is_done_processing(foo); # Do more processing next if is_done_now?(foo); # Do still more processing next if can_we_go_now??(foo); # Do cruel and unusual processing last if is_dead(foo) or is_suing_programmer(foo); }

      ------
      We are the carpenters and bricklayers of the Information Age.

      The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6

      Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.