Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will code after eval(die "some error message") continue to be executed?

Tags:

die

perl

eval

I know that in java language ,if an exception is catched successfully ,the code after the try-catch-clause will still run.In perl ,it uses eval to catch exception.So ,I write two simple programs to test it.

testEval1.pl:

 $exp = '$i = 3; die "error message"; $k = $i + $j';

push ( @program, '$i = 3; die "error message"; $k = $i + $j');
 $rtn =eval($exp);
    if ( ! defined ( $rtn))
    {
       print "Exception: " , $@,"\n";
    }
    else
    {
       print $rtn,"\n";
    }

output of testEval1.pl:

code continue to run after die!
Exception: error message at (eval 1) line 1.

testEval2.pl

$baseDir = "/home/wuchang/newStore1";
my $eval_rtn = eval(opendir(BASEDIR,$baseDir) or die "dir doesn't exist!\n");
print "code continue to run after die!\n";
if(!defined($eval_rtn)){
print $@;
}
 else
    {
       print $rtn,"\n";
    }

output of testEval2.pl:

dir doesn't exist!

you can see that in the two code examples , the code block of eval both has die expressions.But in testEval1.pl,the code after eval can be excuted,while in testEval2.pl,it's not! So ,my question is ,what's the difference ? What can I do to make the program continue to run even if a "dir doesn't exist" exception happeded ?

thank you.

like image 743
wuchang Avatar asked Mar 21 '23 11:03

wuchang


2 Answers

You're evaling result of

opendir(BASEDIR,$baseDir) or die "dir doesn't exist!\n"

code. If it would succeed that would be equivalent of eval(1).

What you want is eval BLOCK:

my $eval_rtn = eval{ opendir(BASEDIR,$baseDir) or die "dir doesn't exist!\n" };

Check perldoc -f eval for difference between eval EXPR and eval BLOCK

like image 52
mpapec Avatar answered Apr 06 '23 04:04

mpapec


To answer your question title:

Will code after eval(die “some error message”) continue to be executed?

The answer is "No". But please read on, because this is not a problem, but a misunderstanding about the Perl syntax involved.

The line:

my $eval_rtn = eval( opendir(BASEDIR,$baseDir) or die "dir doesn't exist!\n" );

Does not get as far as running the eval. The syntax you have used with (..) brackets takes a scalar value, and before the eval does anything at all, it is waiting for the opendir...or die expression to return a string (which will then be evaluated). To make it equivalent to your other example, you could make the param a string:

my $eval_rtn = eval( q{opendir(BASEDIR,$baseDir) or die "dir doesn't exist!\n"} );

You could also use the block form instead:

my $eval_rtn = eval { opendir(BASEDIR,$baseDir) or die "dir doesn't exist!\n"; };

I would recommend using the block form where possible, it is usually easier to debug, and in your case better matches the exception handling semantics that you want to achieve.

like image 30
Neil Slater Avatar answered Apr 06 '23 04:04

Neil Slater