this is part of a longer meditation, but I want to keep it short:
I want to be able to catch error-objects thrown with die and I want to have an easy syntax:
the JS model is reproducible 1-to-1 with Try::Tiny it's even easier because Perl's $_ is automatically set to JS's e
from try...catch#conditional_catch-blocks
try { myroutine(); // may throw three types of exceptions } catch (e) { if (e instanceof TypeError) { // statements to handle TypeError exceptions } else if (e instanceof RangeError) { // statements to handle RangeError exceptions } else if (e instanceof EvalError) { // statements to handle EvalError exceptions } else { // statements to handle any unspecified exceptions logMyErrors(e); // pass exception object to error handler } }
But in most cases the final else will just do die $_ to propagate the error to higher call levels, hence it's boilerplate.
Python has a model for this by providing a condition after the 'catch', if non is matched the error is raised again.
from https://pythonbasics.org/try-except/
try: # your code here except FileNotFoundError: # handle exception except IsADirectoryError: # handle exception except: # * # all other types of exceptions print('Should reach here')
(* the last except must be removed to automatically raise the error again)
So ideally one could define in Perl a prototype for catch (COND) { CODE } where the (COND) part is optional. Alas that's not possible in Perl, even with mandatory (COND) (otherwise experiments with syntax extension were easy)
Three workarounds come into mind
try { # your code here } catch { only { FileNotFoundError }; # ° # handle exception } catch { only { IsADirectoryError }; # handle exception } catch { # * # all other types of exceptions }; print('Should reach here')
(* again, if the simple catch is removed the error is automatically thrown again die $_ )
( ° the COND is either a boolean expression or a constant resp. object representing an error-class. Since an error-class is blessed into a type like "ErrorClass" this can be tested by only ... hence a shorthand for $_->isa(FileNotFoundError) ... not sure if Python has the same flexibility ;)
try { # your code here } catch { FileNotFoundError } sub { # handle exception }, catch { IsADirectoryError } sub { # handle exception }, catch { # * # all other types of exceptions }; print('Should reach here')
UPDATE: added commas, plz see here why.
with sub _ (&;@){ return @_ }
try { # your code here } catch { FileNotFoundError }_ { # handle exception } catch { IsADirectoryError }_ { # handle exception } catch { # * # all other types of exceptions }; print('Should reach here')
This variant could help implementing a future built-in syntax catch () {} by parsing {...}_ as (...)
Like that module authors wanting to be backwards compatible to older versions could keep writing {...}_ without loosing the full performance of newer versions.
And new syntax for compound statements could be experimentally implemented and tested.
I wanted to keep it short and didn't show much implementation detail. I'm more interested in comments regarding the interface... or probably I'm missing a good CPAN module already?
comments? suggestions?
Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery
In reply to conditional catch-blocks 'try {} catch(COND) { }' by LanX
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |