¿Cuáles son los escollos comunes asociados con eval
de Perl, que pueden hacer que elija utilizar un módulo como Try::Tiny
?¿Cuáles son los inconvenientes más comunes al usar la evaluación de Perl?
Respuesta
de Perl viene en dos sabores, eval cadena y el bloque eval. La evaluación de cadena invoca al compilador para ejecutar el código fuente. La evaluación de bloque rodea el código ya compilado en un contenedor que detectará la excepción die
. (cadena evalúa captura la excepción die
también, así como cualquier error de compilación).
Try :: Tiny solo se aplica al formulario de bloqueo de eval, pero lo siguiente se aplica a ambos formularios.
Cada vez que llame al eval
, cambiará el valor de [email protected]
. Será ''
si la evaluación tuvo éxito o el error fue capturado por la evaluación.
Esto significa que cada vez que llame a una evaluación, borrará cualquier mensaje de error anterior. Try::Tiny
localiza la variable [email protected]
para usted, de modo que una evaluación exitosa no borre el mensaje de una evaluación fallida anterior.
La otra trampa proviene del uso de [email protected]
como el control para determinar si la evaluación fue exitosa. Un patrón común es:
eval {...};
if ([email protected]) {
# deal with error here
}
Esto se basa en dos supuestos, primero que todo mensaje de error [email protected]
podría contener es un valor verdadero (por lo general es cierto), y que no existe un código entre el bloque eval y la sentencia if.
Visualmente, por supuesto, esto último es cierto, pero si el bloque eval crea un objeto, y ese objeto queda fuera del alcance después de la evaluación, se llamará al método DESTROY
del objeto antes de la instrucción if
. Si DESTROY
pasa a llamar a eval sin localizar [email protected]
y tiene éxito, entonces cuando se ejecuta su instrucción if
, se borrará la variable [email protected]
.
La solución a estos problemas es:
my $return = do {
local [email protected];
my $ret;
eval {$ret = this_could_fail(); 1} or die "eval failed: [email protected]";
$ret
};
romper esa línea separados por línea, el local [email protected]
crea un nuevo [email protected]
para el bloque do
que impide clobbering valores anteriores. my $ret
será el valor de retorno del código evaluado. En el bloque eval, se asigna $ret
, y luego el bloque devuelve 1
. De esta forma, pase lo que pase, si la evaluación tiene éxito, se devolverá verdadera, y si falla devolverá falsa. Depende de usted qué hacer en caso de falla. El código anterior simplemente muere, pero puede usar fácilmente el valor de retorno del bloque eval para decidir ejecutar otro código.
Dado que el conjuro anterior es un poco tedioso, se vuelve propenso a errores.El uso de un módulo como Try::Tiny
lo aísla de esos posibles errores, a costa de unas pocas llamadas a función más por evaluación. Es importante saber cómo usar eval correctamente, porque Try::Tiny
no lo ayudará si tiene que usar una evaluación de cadena.
Solucionado en la versión actual. – tchrist
Corrección pequeña: '$ @' en realidad será una cadena vacía en lugar de undef si no se lanzó ninguna excepción. –
@Grant McLean => gracias, debería haber recordado, porque así es como mi respuesta habitual se ocupa de los errores: 'perl -wE 'dice eval, $ @ while <>' ' –
Los problemas se explican en el Try::Tiny documentation. En pocas palabras, ellos son: eval
Además de las respuestas anteriores, yo añadiría ...
- eval se ve afectada por la acción causando
$SIG{__DIE__}
manejador mundial a distancia. - Es fácil para un principiante confundir
eval BLOCK
yeval STRING
, ya que parecen hacer lo mismo, pero uno es un agujero de seguridad.
Try :: Tiny tiene sus propios escollos, el más grande es que si bien se ve como un bloque, en realidad es una llamada de subrutina. Eso significa esto:
eval {
...blah blah...
return $foo;
};
y esto:
try {
...blah blah...
return $foo;
};
no hacen lo mismo. Estos se presentan en el CAVEATS section of the Try::Tiny docs. Dicho esto, lo recomendaría más de eval
.
¿Estás diciendo que' eval' es * todavía * inusualmente roto en 5.14? ** ¿En serio? ** Sería * extremadamente * decepcionante, porque sé que se trabajó mucho para tratar de hacer que "Try :: Tiny" quede obsoleto al solucionar los errores subyacentes que plagaban a 'eval'.Si ese esfuerzo falló, entonces hay un problema horrible porque 'Try :: Tiny' sigue siendo simplemente un módulo de CPAN, no un núcleo. Si no puede hacer un trabajo real y confiable con el núcleo, entonces esa es una situación inaceptable. – tchrist
@tchrist Olvidó eso. Según lo entiendo, 5.14.0 resolvió una clase de errores relacionados con las interacciones entre $ @ y la destrucción de objetos y generalmente hizo 'eval {...}; if ($ @) {...} 'más confiable. Creo que eso resuelve 2 de las 3 cosas: Try :: Tiny fixes ... y el tercero (un falso $ @) es bastante improbable. Todavía deja los puntos que mencioné. Sería una buena función 5.16 detener el lanzamiento de '$ SIG {__ DIE __}' dentro de una evaluación. Y marque el drama, amigo. – Schwern
Llamar 'eval STRING' a un" problema de seguridad "no es demasiado dramático; ni siquiera es verdad He usado 'eval STRING' desde que apareció por primera vez en Perl2 hace unos veintitrés años, puedo asegurarle que nunca he experimentado ningún supuesto" problema de seguridad "con él. Claro, los programadores tontos pueden hacer cosas tontas con eso, pero esto es cierto para casi cualquier cosa. Si usted existe en un mundo patológicamente paranoico, debe utilizar el modo de contaminación y/o compartimentos de seguridad. En un mundo normal, 'eval STRING' obtiene mucho trabajo útil; ver el programa clásico * rename *. – tchrist
El uso de la función eval en X11 aún podría no mantenerse activo.
El código es como
eval {
@win_arrays = GetWindowsFromPid($pid);
};
El guión será retirado
X Error de solicitudes con error: ...
- 1. ¿Cuáles son los inconvenientes de usar Lucene?
- 2. ¿Cuáles son los inconvenientes de Stackless Python?
- 3. ¿Cuáles son los verdaderos inconvenientes de usar ReaderWriterLock
- 4. ¿Cuáles son los inconvenientes de la compilación de JIT?
- 5. ¿Cuáles son los inconvenientes de utilizar Spring BlazeDS Integration?
- 6. ¿Cuáles son los inconvenientes de utilizar la llamada ajax sincrónica?
- 7. ¿Cuáles son tus optimizaciones sql más comunes?
- 8. ¿Cuáles son los usos comunes de UDP?
- 9. ¿Cuáles son los inconvenientes de configurar enable_nestloop en OFF
- 10. ¿Cuáles son los errores más comunes que se deben evitar al codificar javascript para Internet Explorer?
- 11. ¿Cuáles son los errores comunes de configuración de Magento?
- 12. ¿Cuáles son los patrones de diseño comunes en Cocoa Touch?
- 13. C++: ¿cuáles son las vulnerabilidades más comunes y cómo evitarlas?
- 14. ¿Cuáles son los inconvenientes de usar PHP para crear variables en mi hoja de estilo CSS?
- 15. ¿Cuáles son los principales inconvenientes de usar OpenOffice DB frente a Microsoft Access?
- 16. ¿Cuáles son los inconvenientes de usar una clave primaria compuesta/compuesta?
- 17. ¿Cuáles son los inconvenientes de usar servidores vinculados en SQL Server?
- 18. ¿Cuáles son las convenciones más comunes para usar espacios de nombres en Clojure?
- 19. ¿Cuáles son los patrones de diseño de servicios de Windows más comunes?
- 20. ¿Cuáles son los usos comunes de etiquetar algo más que una confirmación?
- 21. ¿Cuáles son algunos de los esquemas de ramificación/compromiso de vida más comunes de Git?
- 22. ¿Cuáles son las bibliotecas comunes para C?
- 23. ¿Cuáles son los errores más comunes cometidos en el desarrollo de WPF?
- 24. ¿Cuáles son las dificultades más comunes de la sincronización basada en la marca de tiempo?
- 25. ¿Cuáles son los inconvenientes de la replicación de sesión en Tomcat?
- 26. ¿Cuáles son los patrones de diseño más comunes para cualquier aplicación de formularios de Windows?
- 27. ¿Cuáles son los diez permisos más mortales?
- 28. ¿Cuáles son algunos malentendidos comunes sobre TDD?
- 29. ¿Cuáles son las formas más comunes de implementar la limitación de velocidad/solicitud de API web?
- 30. ¿Cuáles son las aplicaciones prácticas de los algoritmos ancestrales comunes más bajos?
posible duplicado de [¿Por qué es '$ @ '¿no es confiable?] (http://stackoverflow.com/questions/3686857/why-is-untrustworthy), [¿Qué hay de malo en las excepciones en Perl?] (http://stackoverflow.com/questions/2165161/) – mob
El único re De todos modos, no usaría el built-in si no está ejecutando una versión actual de Perl. – tchrist
@mob - sí, esa parece ser la misma pregunta. – Hugh