It is often needed to determine whether the execution of some given
code raised some particular exception. A possibility is to use a
try-catch
statement like in the following example, a
pretty-printer in an union type:
method _print = void: { try print "#<%u32d>", simple_value; catch if E_elem { print "%v\n", complex_value; } }
This works as intended, but it is somewhat verbose and not that easy
to read for anyone not accustomed to the idiom. It is better to use
the exception predicate operator, ?!
, that has two forms:
exp ?! exception { [statements...] } ?! exception
In the first form, the expression exp is executed. If the
execution raises the exception exception then the result of the
predicate is 1
(true), otherwise it is 0
(false). The
value of the expression is discarded.
In the second form, the compound statement passed as the first operand
is executed. If the exception exception is raised, then the
result of the predicate is 0
(false), otherwise it is 1
(true).
Using exception predicates the pretty-printer above can be written in a much more readable way:
method _print = void: { if (simple_value ?! E_elem) print "%v\n", complex_value; else print "#<%u32d>", simple_value; }
Or, alternatively (and slightly more efficiently):
method _print = void: { ({ print "<%u32d>", simple_value; } ?! E_elem) && print "%v\n", complex_value; }