Mi sembra di ricordare che non è sicuro fidarsi del valore di [email protected]
dopo un eval
. Qualcosa su un gestore di segnale che ha la possibilità di impostare [email protected]
prima di vederlo o qualcosa del genere. Sono anche troppo stanco e pigro in questo momento per rintracciare la vera ragione. Quindi, perché non è sicuro affidarsi a [email protected]
?
risposta
Il Try::Tiny
perldoc ha la discussione 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ì, penso che sia quello che stavo ricordando. –
Non devi più giocare a quei giochi folli. – tchrist
Il Try::Tiny docs ha una buona lista di carenze eval
/[email protected]
. Penso che potresti riferirti alla sezione Localizing [email protected] silently masks errors qui.
[email protected]
ha gli stessi problemi che ogni variabile globale è: quando qualcos'altro imposta, è resettato attraverso l'intero programma. Qualsiasi eval
potrebbe impostare [email protected]
. Anche se non vedi uno eval
nelle vicinanze, non sai chi potrebbe chiamarne uno (subroutine, variabili legate e così via).
- 1. LocationManager.isProviderEnabled (LocationManager.NETWORK_PROVIDER) non è affidabile, perché?
- 2. In_irq() è affidabile?
- 3. Quanto è affidabile current_kernel_time()?
- 4. Quanto è affidabile __destruct?
- 5. È! Document.cookie affidabile?
- 6. MongoDB è affidabile?
- 7. "AndroidAnnotaions" è affidabile?
- 8. Quanto è affidabile HTTP_REFERER?
- 9. Win32 SetForegroundWindow non affidabile
- 10. Process.Start ("IExplore.exe"); <- È affidabile?
- 11. Quanto è affidabile l'installazione avanzata?
- 12. Perché l'attributo onload dell'elemento link non è affidabile per i browser azionari Android?
- 13. L'appChecker Linux Standard Base (LSB) è affidabile?
- 14. L'ubicazione del progetto non è affidabile Errore in Visual Studio
- 15. L'avvio dell'app con strumenti iOS non è affidabile
- 16. emacs vagabondo su una connessione non affidabile
- 17. Montaggio sshfs su connessione non affidabile
- 18. Quanto è affidabile FileSystemWatcher in .netFramwork 4?
- 19. DOM Window scarica evento, è affidabile?
- 20. La proprietà .value di HTMLSelectElement è affidabile
- 21. Is Request.ServerVariables ["REMOTE_ADDR"] è abbastanza affidabile?
- 22. Quanto è affidabile Heroku per un'app sensibile?
- 23. "Jint - Javascript Interpreter for .NET" è affidabile?
- 24. Firebase onDisconnect non affidabile al 100% ora?
- 25. Affidabile "mouseenter" senza jQuery
- 26. $ _SERVER ["SCRIPT_URL"]: quando è presente in modo affidabile?
- 27. Perché Log di Windows Azure non viene registrato in modo affidabile?
- 28. Certificato VeriSign di classe 3 non considerato affidabile da Windows?
- 29. C# affidabile MouseMove (hop)
- 30. TCP vs Affidabile UDP
Vedere anche 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 come Perl 5.14, [Questo è stato corretto.] (http://perldoc.perl.org/perl5140delta.html#Exception-Handling) –