El sistema de errores de Factor tiene tres piezas: throw para señalar un error, recover para gestionar uno y ERROR: para definir tu propio tipo de error.
throwthrow (en kernel) lanza un error. El argumento puede ser cualquier valor, ya sea un string, un número o una tupla, y se convierte en el error que puedes inspeccionar después:
! DOCTEST: SKIP
"file not found" throw
throw no devuelve el control; se omite el resto de la palabra actual.
recoverrecover (en continuations) es el try/catch de Factor. Recibe una quotation de intento y una quotation de recuperación:
recover ( try recovery -- )
Si try termina sin lanzar nada, se ignora recovery. Si try lanza un error, el error se coloca en la pila y se ejecuta recovery:
[ "boom" throw ] [ drop "caught" ] recover .
! => "caught"
[ "ok" ] [ drop "never runs" ] recover .
! => "ok"
when, de kernel, es el complemento natural: solo ejecuta una quotation cuando la parte superior de la pila es verdadera:
: check-positive ( n -- )
0 < [ "negative!" throw ] when ;
ERROR:ERROR: define una clase de tupla y una palabra que construye una instancia nueva y la lanza:
! DOCTEST: SKIP
ERROR: not-found path ;
"/missing" not-found
! throws T{ not-found { path "/missing" } }
Un error sin ranuras es simplemente ERROR: name ;: llamar a name lanza una instancia vacía. Las tuplas definidas con ERROR: incluyen un predicado de clase name? que puedes usar para comprobar si un error capturado era de ese tipo.
Un error capturado no es más que una tupla, así que cada ranura de ERROR: viene con el mismo lector slot>> generado automáticamente que cualquier otra tupla.
! DOCTEST: SKIP
{
T{ not-found { path "/a" } }
T{ not-found { path "/b" } }
}
[ path>> ] map . ! => { "/a" "/b" }
Elena, la nueva responsable de calidad de una fábrica de periódicos, te pide que escribas un pequeño programa para vigilar la sala de producción.
Define una clase de tupla de error machine-error con la palabra de análisis
ERROR:. No necesita slots.
machine-error ! throws a fresh machine-error
Define check-humidity. Toma una lectura de humedad de la pila y lanza con
throw la cadena "humidity too high" cuando la lectura es estrictamente
mayor que 70. En caso contrario, no devuelve nada.
50 check-humidity ! returns nothing
80 check-humidity ! throws "humidity too high"
Define check-temperature. Toma una lectura de temperatura y lanza con
throw la cadena "temperature too high" cuando la lectura es estrictamente
mayor que 500. En caso contrario, no devuelve nada.
400 check-temperature ! returns nothing
600 check-temperature ! throws "temperature too high"
Define monitor para que tome una humedad y una temperatura de la pila y
ejecute ambas comprobaciones. Si alguna de las comprobaciones lanza un error,
monitor debe lanzar en su lugar un machine-error nuevo. Si ambas pasan,
monitor no devuelve nada.
50 400 monitor ! returns nothing
80 400 monitor ! throws a machine-error
50 600 monitor ! throws a machine-error
Define monitor-batch para que tome un array de lecturas
{ humidity temperature } y devuelva cuántas de ellas fallarían (es decir,
cuántas harían que monitor lanzara un error).
{ { 50 400 } { 80 400 } { 50 600 } { 60 200 } } monitor-batch .
! => 2
Regístrate en Exercism para aprender y dominar Factor con 47 conceptos163 ejercicios y mentoría humana real, todo gratis.