Me parece recordar que no es seguro confiar en el valor de [email protected]
después de eval
. Algo sobre un manejador de señal que tiene la oportunidad de establecer [email protected]
antes de verlo o algo así. También estoy muy cansado y flojo ahora mismo para rastrear la verdadera razón. Entonces, ¿por qué no es seguro confiar en [email protected]
?
Respuesta
El Try::Tiny
perldoc tiene la discusión definitiva del problema con [email protected]
:
There are a number of issues with eval.
Clobbering [email protected]
When you run an eval block and it succeeds, [email protected] will be cleared, potentially clobbering an error that is currently being caught.
This causes action at a distance, clearing previous errors your caller may have not yet handled.
[email protected] must be properly localized before invoking eval in order to avoid this issue.
More specifically, [email protected] is clobbered at the beginning of the eval, which also makes it impossible to capture the previous error before you die (for instance when making exception objects with error stacks).
For this reason try will actually set [email protected] to its previous value (before the localization) in the beginning of the eval block.
Localizing [email protected] silently masks errors
Inside an eval block die behaves sort of like:
sub die { [email protected] = $_[0]; return_undef_from_eval(); }
This means that if you were polite and localized [email protected] you can't die in that scope, or your error will be discarded (printing "Something's wrong" instead).
The workaround is very ugly:
my $error = do { local [email protected]; eval { ... }; [email protected]; }; ... die $error;
[email protected] might not be a true value
This code is wrong:
if ([email protected]) { ... }
because due to the previous caveats it may have been unset.
[email protected] could also be an overloaded error object that evaluates to false, but that's asking for trouble anyway.
The classic failure mode is:
sub Object::DESTROY { eval { ... } } eval { my $obj = Object->new; die "foo"; }; if ([email protected]) { }
In this case since Object::DESTROY is not localizing [email protected] but still uses eval, it will set [email protected] to "".
The destructor is called when the stack is unwound, after die sets [email protected] to "foo at Foo.pm line 42\n", so by the time if ([email protected]) is evaluated it has been cleared by eval in the destructor.
The workaround for this is even uglier than the previous ones. Even though we can't save the value of [email protected] from code that doesn't localize, we can at least be sure the eval was aborted due to an error:
my $failed = not eval { ... return 1; };
This is because an eval that caught a die will always return a false value.
Sí, creo que eso es lo que estaba recordando. –
Ya no tiene que jugar esos juegos locos. – tchrist
La Try::Tiny docs tiene una muy buena lista de deficiencias eval
/[email protected]
. Creo que podría estar refiriéndose a la sección Localizing [email protected] silently masks errors allí.
[email protected]
tiene los mismos problemas que cada variable global tiene: cuando se establece otra cosa, pone a cero en todo el programa. Cualquier eval
puede establecer [email protected]
. Incluso si no ve un eval
cerca, no sabe a quién más podría llamarle uno (subrutinas, variables vinculadas, etc.).
- 1. ¿Por qué Java Future.get (timeout) no es confiable?
- 2. ¿Qué tan confiable es HtmlUnitDriver?
- 3. ¿Qué tan confiable es HTTP_HOST?
- 4. ¿Qué tan confiable es __destruct?
- 5. ¿Qué tan confiable es current_kernel_time()?
- 6. ¿Qué tan confiable es HTTP_REFERER?
- 7. ¿Por qué Windows Azure Diagnostics no registra de manera confiable?
- 8. Código GPGPU no confiable (OpenCL, etc.): ¿es seguro? ¿Qué riesgos?
- 9. ¿Qué tan seguro es "git" con una conexión no confiable?
- 10. qué tan confiable es css3 pie
- 11. ¿Qué tan confiable es el instalador avanzado?
- 12. ¿Es MongoDB confiable?
- 13. ¿Es! Document.cookie confiable?
- 14. ¿Es window.opener confiable?
- 15. ¿Qué tan confiable es el FileSystemWatcher en .netFramwork 4?
- 16. ¿Qué tan confiable es la propiedad MaxLength de TextBox-Control?
- 17. soporte de broswer para canvas.toDataUrl y qué tan confiable es
- 18. ¿Por qué el ESTADO DE LA MESA DE MUESTRA de innodb es tan poco confiable?
- 19. ¿Qué tan confiable es Heroku para una aplicación sensible?
- 20. ¿Qué tan confiable es detectar dispositivos móviles por resolución de pantalla?
- 21. iMacros es bueno pero no confiable. ¿Hay alguna alternativa?
- 22. ¿Por qué no puedo capturar de manera confiable un evento de mouseout?
- 23. Estrategia de deserialización no confiable
- 24. Si $ _SERVER ['HTTP_REFERER'] no es confiable, ¿qué usaré para garantizar la integridad de la aplicación web?
- 25. Process.Start ("IExplore.exe"); <- ¿Es esto confiable?
- 26. Por qué un iterador (.Net) no sería confiable en este código
- 27. ¿Es Request.ServerVariables ["REMOTE_ADDR"] lo suficientemente confiable?
- 28. ¿Por qué la volatilidad no es suficiente?
- 29. ¿Por qué jQuery.parseJSON no es una función?
- 30. ¿Por qué esta recursión NO es infinita?
Véase también http://stackoverflow.com/questions/503189/is-object-oriented-exception-handling-in-perl-worth-it, http://stackoverflow.com/questions/2165161/whats -broken -about-exceptions-in-perl, http://stackoverflow.com/questions/2439966/do-you-use-an-exception-class-in-your-perl-programs-why-or-why-not – Ether
Nota que como Perl 5.14, [Esto ha sido corregido.] (http://perldoc.perl.org/perl5140delta.html#Exception-Handling) –