Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Stopping execution of an eval statement

by slloyd (Hermit)
on Jul 23, 2005 at 14:02 UTC ( #477474=perlquestion: print w/replies, xml ) Need Help??

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

Is there a way to stop the execution of an eval statement during execution without killing the main program?
use strict; $SIG{INT}=\&stopEvaluate; $SIG{HUP}=\&stopEvaluate; my $x=0; my $evalstatement=qq| for(my \$x=0;\$x<25;\$x++){ print "line \$x\n"; sleep(\$x); } return "statement Done"; |; evaluate($evalstatement); print "Done\n"; exit; sub evaluate{ my $perl=shift || return; print "evaluate\n$perl\n\n"; my $rtn=eval($perl); if($@){return $@;} return $rtn; } sub stopEvaluate{ print "stopping eval..."; #Can I call something to stop the eval. return; }

Replies are listed 'Best First'.
Re: Stopping execution of an eval statement
by dave_the_m (Monsignor) on Jul 23, 2005 at 15:39 UTC
    No need to set a flag, just die in the handler:
    sub long { 1 while 1 } $SIG{INT} = sub { die "got int\n" }; eval {long}; print "got err: $@\n" if $@; __END__ $ ./perl /tmp/p got err: got int $

    Dave.

      If i die in the handler, then the whole script would stop processing,not just the eval statement, right? I only want to kill executing the eval statement, not the entire script.
        If i die in the handler, then the whole script would stop processing,not just the eval statement, right?
        Wrong.

        die inside an eval is a common idiom to have exception handling in Perl (see eval for examples, BTW). If you look at the example by dave_the_m, you'll see that the line after eval {long}; is printed - probably after the user has hit CTRL-C.

        Flavio
        perl -ple'$_=reverse' <<<ti.xittelop@oivalf

        Don't fool yourself.
Re: Stopping execution of an eval statement
by davidrw (Prior) on Jul 23, 2005 at 14:56 UTC
    I guess your stopEvalutate sub could set a global flag, and the for look in the evalstatement could check for it:
    for(my \$x=0;\$x<25;\$x++){ return "Statement aborted" if $stop_requested; ... }
    Perhaps fork'ing would be better approach so that you could just kill off the children?
Re: Stopping execution of an eval statement
by kwaping (Priest) on Jul 23, 2005 at 15:03 UTC
    Dang, davidrw beat me to it...
    #!/usr/bin/perl use strict; use warnings; $|++; use vars qw($go); $SIG{'INT'} = 'stop_counting'; $go = 1; my $code = q|my $x = 0; while ($go) { print"$x\n"; $x++; }|; eval($code); print "done counting!\n"; print $@ if ($@); sub stop_counting { $go = 0; print "\n\nstopping eval...\n"; } exit;
Your evaluate() routine does not work.
by schwern (Scribe) on Jul 24, 2005 at 21:16 UTC

    While this isn't what you asked, your evaluate() routine only works in this case by accident of positioning. When it eval's your code, it can only see the lexical $x because the evaluate() subroutine happens to be in the same scope as the original declaration. If you moved the evaluate() subroutine above $x's declaration or out of scope entirely (say, into a library file) things break.

    #!/usr/bin/perl -w use strict; sub evaluate{ my $perl=shift || return; print "evaluate\n$perl\n\n"; my $rtn=eval($perl); if($@){return $@;} return $rtn; } my $x=42; my $evalstatement=q| $x; |; print evaluate($evalstatement);
    evaluate $x; Global symbol "$x" requires explicit package name at (eval 1) line 2.

    For lexical purposes the code is executed at the point eval() is run, not where evaluate() is called. You can't safely use lexicals in code eval'd somewhere else which means you can't safely have a subroutine which takes any ol code as an argument and eval's it.

    Also your eval code would be a lot simpler with q{}.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (3)
As of 2022-05-18 19:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Do you prefer to work remotely?



    Results (71 votes). Check out past polls.

    Notices?