El sistema de errores de Factor tiene tres partes: throw para lanzar un error, recover para manejar uno, y ERROR: para definir tu propio tipo de error.
throwthrow (en kernel) lanza un error. El argumento puede ser cualquier valor (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 resto de la palabra actual se omite.
recoverrecover (en continuations) es el try/catch de Factor. Recibe una cita try y una cita recovery:
recover ( try recovery -- )
Si try termina sin lanzar un error, recovery se ignora. 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 compañero natural: ejecuta una cita solo 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 slots es simplemente ERROR: name ;: llamar a name lanza una instancia vacía. Las tuplas definidas con ERROR: llevan un predicado de clase name? que puedes usar para comprobar si un error capturado era de ese tipo.
Un error capturado es simplemente una tupla, así que cada slot de ERROR: viene con el mismo lector slot>> autogenerado que cualquier otra tupla.
! DOCTEST: SKIP
{
T{ not-found { path "/a" } }
T{ not-found { path "/b" } }
}
[ path>> ] map . ! => { "/a" "/b" }
Elena, la nueva gerente de calidad de una fábrica de periódicos, te pide que escribas un pequeño programa para monitorear la sala de producción.
Define una clase de tupla de error machine-error usando 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 hace throw del string "humidity too high" cuando la lectura es estrictamente mayor que 70. De lo 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 hace throw del string "temperature too high" cuando la lectura es estrictamente mayor que 500. De lo 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 verificaciones. Si alguna de las verificaciones hace throw, monitor debe hacer throw de un machine-error nuevo en su lugar. 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 haga throw).
{ { 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.