¿Se seguirá ejecutando el código después de eval (muere "algún mensaje de error")?

Sé que en el lenguaje java, si una excepción se detecta con éxito, el código después de la cláusula try-catch aún se ejecutará. En perl, usa eval para detectar la excepción. Entonces, escribo dos programas simples para probarlo.

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";
    }

salida de 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";
    }

salida de testEval2.pl:

dir doesn't exist!

puede ver que en los dos ejemplos de código, el bloque de código de eval tiene expresiones die. Pero en testEval1.pl, el código después de eval se puede ejecutar, mientras que en testEval2.pl, ¡no es así! Entonces, mi pregunta es, ¿cuál es la diferencia? ¿Qué puedo hacer para que el programa continúe ejecutándose incluso si ocurre una excepción de "dir no existe"?

gracias.

preguntado el 02 de diciembre de 13 a las 08:12

Si quieres algo más similar a Java try-catch sintaxis, echa un vistazo a la Try::Tiny módulo. -

Gracias por su notificación. Es útil. -

2 Respuestas

Estás evaluando el resultado de

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

código. Si tuviera éxito, eso sería equivalente a eval(1).

Lo que quieres es eval BLOCK:

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

Revise perldoc -f evaluación por la diferencia entre eval EXPR y eval BLOCK

Respondido el 02 de diciembre de 13 a las 08:12

Entonces, para $rtn =eval($exp); es el tipo de eval BLOCK o eval EXPR. ¿Puedo concluir que dado que $exp está entre comillas simples, entonces es una especie de eval BLOCK? ¿verdad? - wuchang

@Vico_Wu considere eval con llaves: eval{ .. } como eval BLOCK, y todo lo demás como eval EXPR. - mpapec

Para responder al título de su pregunta:

¿Se seguirá ejecutando el código después de eval (muere "algún mensaje de error")?

La respuesta es no". Pero siga leyendo, porque esto no es un problema, sino un malentendido sobre la sintaxis de Perl involucrada.

La línea:

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

No llega tan lejos como para ejecutar el eval. La sintaxis que ha utilizado con (..) corchetes toma un valor escalar, y antes de que eval no hace nada en absoluto, está esperando el opendir...or die expresión para devolver una cadena (que luego será evaluada). Para que sea equivalente a su otro ejemplo, podría convertir el parámetro en una cadena:

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

También podría usar el formulario de bloque en su lugar:

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

Recomendaría usar el formulario de bloque siempre que sea posible, generalmente es más fácil de depurar y, en su caso, se adapta mejor a la semántica de manejo de excepciones que desea lograr.

Respondido el 02 de diciembre de 13 a las 11:12

Entonces, para la expresión eval( opendir(BASEDIR,$baseDir) o die "dir is not exist!\n" );, ¿eval solo obtiene una cadena como parámetro y, por lo tanto, funciona igual que eval(1)? - wuchang

@Vico_Wu: Sí. A pesar de opendir devolverá algo que no sea 1 si tiene éxito, ese es el problema básico. - Neil Slater

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.