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

My pipe dream is something like this:

print "Press CRTL-C to skip to next item\n"; $SIG{INT} = sub { print "skipping"; next LOOP; }; LOOP: for $item (@BigList) { print "Slowly processing $item..."; # etc }

But this doesn't work because the LOOP label is not in scope.

Is there an easy way to let user input 'abort' to the next iteration of a loop, or am I forced to introduce event polling throughout the processing section?

--Solo
--
You said you wanted to be around when I made a mistake; well, this could be it, sweetheart.

Replies are listed 'Best First'.
Re: User interactivity in long loops
by Anonymous Monk on Jun 30, 2004 at 15:50 UTC

    How about something like this:

    $SIG{INT} = sub { die "Skip" }
    
    LOOP: for $item (@BigList) {
         eval {
              print "Slowly processing $item..."; 
              # ...
         };
    
         if ($@ eq 'Skip') {
              # The user pressed ^C
              # If you need to clean up after it, do it here
              # Otherwise, this is a no-op
         }
         elsif ($@) {
              # Something else died
              # You may need some cleanup code here too.
         }
         else {
              # This item was processed w/o any interruptions.
         }
    }
    

    So, the concept here is you have wrapped your code in an eval block. If anything dies, it will stop the execution of the eval block at that spot. Outside of the eval block, you can inspect $@ to see if anything died (and what was thrown).

    So far, the above is just common exception handling. What we do is setup SIGINT to die with a special message. The equivalent in Java might be throwing a Thread Interrupted Exception.

    Please note that eval {} is not the same as eval "" and does not have the associated performance penalty.

    Hope this helps.

    Ted

      That will work nicely. Thanks, Ted!

      --Solo
      --
      You said you wanted to be around when I made a mistake; well, this could be it, sweetheart.