Il sistema di gestione degli errori di Factor è composto da tre parti: throw per lanciare un errore, recover per gestirne uno e ERROR: per definire un tipo di errore personalizzato.
throwthrow (in kernel) lancia un errore. L'argomento può essere un valore qualsiasi, una stringa, un numero o una tupla, e diventa l'errore che potrai esaminare in seguito:
! DOCTEST: SKIP
"file not found" throw
throw non restituisce nulla: il resto della parola corrente viene saltato.
recoverrecover (in continuations) è il try/catch di Factor. Prende una quotation di prova e una quotation di recupero:
recover ( try recovery -- )
Se try termina senza lanciare un errore, recovery viene ignorata. Se try lancia un errore, l'errore viene inserito nello stack e recovery viene eseguita:
[ "boom" throw ] [ drop "caught" ] recover .
! => "caught"
[ "ok" ] [ drop "never runs" ] recover .
! => "ok"
when di kernel è il compagno naturale: esegue una quotation solo quando l'elemento in cima allo stack è vero:
: check-positive ( n -- )
0 < [ "negative!" throw ] when ;
ERROR:ERROR: definisce una classe di tuple e una parola che ne costruisce una nuova istanza e la lancia:
! DOCTEST: SKIP
ERROR: not-found path ;
"/missing" not-found
! throws T{ not-found { path "/missing" } }
Un errore senza slot è semplicemente ERROR: name ;: chiamare name lancia un'istanza vuota. Le tuple definite con ERROR: hanno un predicato di classe name? che puoi usare per verificare se un errore catturato era di quel tipo.
Un errore catturato è solo una tupla, quindi ogni slot di ERROR: ha lo stesso lettore slot>> generato automaticamente di qualsiasi altra tupla.
! DOCTEST: SKIP
{
T{ not-found { path "/a" } }
T{ not-found { path "/b" } }
}
[ path>> ] map . ! => { "/a" "/b" }
Elena, la nuova responsabile qualità di una fabbrica di giornali, ti chiede di scrivere un piccolo programma per monitorare la sala di produzione.
Definisci una classe di tuple di errore machine-error usando la parola di
parsing ERROR:. Non servono slot.
machine-error ! throws a fresh machine-error
Definisci check-humidity. Prende dallo stack una lettura di umidità e, quando
la lettura è strettamente maggiore di 70, con throw lancia la stringa
"humidity too high". Negli altri casi non restituisce nulla.
50 check-humidity ! returns nothing
80 check-humidity ! throws "humidity too high"
Definisci check-temperature. Prende una lettura di temperatura e, quando la
lettura è strettamente maggiore di 500, con throw lancia la stringa
"temperature too high". Negli altri casi non restituisce nulla.
400 check-temperature ! returns nothing
600 check-temperature ! throws "temperature too high"
Definisci monitor in modo che prelevi dallo stack un'umidità e una temperatura
ed esegua entrambi i controlli. Se uno dei due controlli lancia un errore,
monitor deve invece lanciare un nuovo machine-error. Se entrambi passano,
monitor non restituisce nulla.
50 400 monitor ! returns nothing
80 400 monitor ! throws a machine-error
50 600 monitor ! throws a machine-error
Definisci monitor-batch in modo che prelevi un array di letture
{ humidity temperature } e restituisca quante di esse fallirebbero (cioè
quante farebbero lanciare un errore a monitor).
{ { 50 400 } { 80 400 } { 50 600 } { 60 200 } } monitor-batch .
! => 2
Iscriviti a Exercism per imparare e padroneggiare Factor con 47 concetti163 esercizi e il mentoring di persone reali, tutto gratis.