Kivételek létrehozása és kiértékelése a tom unitban definiált
objektumokon keresztül történik: Condition
objektumok előidézhetők vagy jelölhetők, és bármilyen objektum dobható (throw
).
A kivételkezelés (szemben a létrehozással) része a nyelvnek. Erre a célra a TOM néhány speciális kifejezést biztosít:
A catch
segítségével tudjuk az eldobott kivételeket elkapni. Felépítése a következő:
catch
egy visszatérési pontot létesít egy throw
hívási vermében. Egy throw egy
meghívása a tag throw
metódusának.
A throw
alapértelmezett implementációja okozza a program
futásának folytatását
ugyanannak a tag
objektumnak a leggyakrabban létesülő catch
-e
után. Nyilvánvalóan, mivel throw
egy
metódus, felül lehet írni. Ezzel vigyázni
kell, mivel az alapértelmezett
szemantika garantálja, hogy a throw
hívásából nincs return.
Normálisan a catch
által visszaadott érték az expression
értéke. Ha egy catch dobódott, a
visszatérési érték throw
–nak
való argumentum értéke. Ha a throw
argumentuma void
,
a catch egyszerűen az
alapértelmezett értékeit adja vissza azoknak az
elemeknek, amiket egyébként
visszaadna. Ha a throw
–nak
void
–tól
különböző argumentumai vannak, hibát jelent, ha a
dobott típus nem
egyezik meg az elkapottal.
A bind
segítségével tudunk kivétel kezelőket definiálni. A felépítése a következő:
Egy bind_expression
beállít egy vagy több kezelőt (handler) minden
kivételre, ami kiváltva vagy
jelölve lett az expression
kiértékélése közben. A bind
visszatérési értéke az az
érték, amivel az expression
visszatér.
Minden handler
egy expression
,
ami akkor hívódik meg, ha a condition
,
vagy egy alkivétel kiváltódik
(vagy jelölődik).
Egy hasznos dolog a kezelő számára,
hogy
bizosítson egy throw
-t
hogy lehetővé tegye a nem-lokális
visszatérést a kivételes
állapotból. Figyelembe kell venni,
hogy a kezelő meghívása a kiváltott kivétel
környezetében történik.
A throw
–nak
szüksége van azonnali return-re ebből a catch
-ből,
hacsak ugyanannak a self
objektumnak egy másik catch-e nincs beállítva
(és aktív) a do_something_difficult
hívása alatt.
A kezelőnek nem szükséges úgy kezelni a
kivételt, hogy egy nem-lokális visszatérést
biztosít. Ha a kezelő nem akarja lekezelni, a
kezelő által
visszaadott értéknek ugyanannak a condition
objektumnak kell lennie,
amit kapott. Ha a kezelő bármilyen más
értéket ad vissza, aminek mindig egy
objektumnak kell lennie, a kezelő kezeltnek ítéli a
kivételt. Ha a kivétel
jelölve volt, a kezelő által visszaadott
érték a signal
által visszaadott érték.
Ha kivétel volt kiváltva, a visszatérési
érték figyelmen kívül lesz hagyva és a
kivételkezelés folytatódik, mintha a kezelő nem
kezelte volna a kivételt.
Az unwind
segítségével tudunk az illetéktelen throw-ok ellen védekezni.
A felépítése a következő:
Egy unwind
kiértékeli a body
–t,
amit a protection
kiértékelése követ. Az unwind
által visszaadott érték a törzsének az
értéke.
Ha a törzs kiértékelése
közben, egy
tag dobódik, korán kilépve ezzel az unwind
környezetéből,
a protection
kifejezés még mindig kiértékelődik. Ha a
kód nem vált ki kivételt vagy dob
bármit, akkor lefutása után az eredeti throw
általi meghívás folytatódik tovább.