O sistema de erros do Factor tem três peças: throw para sinalizar um erro,
recover para tratar de um, e ERROR: para definires o teu próprio tipo de
erro.
throwthrow (em kernel) lança um erro. O argumento pode ser
qualquer valor, uma string, um número ou um tuplo, e torna-se no
erro que podes inspecionar mais tarde:
! DOCTEST: SKIP
"file not found" throw
throw não devolve nada; o resto da word atual é ignorado.
recoverrecover (em continuations) é o try/catch do Factor.
Recebe uma quotation try e uma quotation recovery:
recover ( try recovery -- )
Se a try terminar sem lançar nada, a recovery é ignorada. Se a try
lançar um erro, o erro é colocado na pilha e a recovery é executada:
[ "boom" throw ] [ drop "caught" ] recover .
! => "caught"
[ "ok" ] [ drop "never runs" ] recover .
! => "ok"
O when de kernel é o companheiro natural: só executa uma
quotation quando o topo da pilha é verdadeiro:
: check-positive ( n -- )
0 < [ "negative!" throw ] when ;
ERROR:ERROR: define uma classe de tuplo e uma word que constrói uma
instância nova e a lança:
! DOCTEST: SKIP
ERROR: not-found path ;
"/missing" not-found
! throws T{ not-found { path "/missing" } }
Um erro sem slots é apenas ERROR: name ;: chamar name lança uma
instância vazia. Os tuplos definidos com ERROR: trazem um predicado
de classe name? que podes usar para testar se um erro capturado era
desse tipo.
Um erro capturado é apenas um tuplo, por isso cada slot de ERROR:
vem com o mesmo leitor slot>> gerado automaticamente que qualquer
outro tuplo.
! DOCTEST: SKIP
{
T{ not-found { path "/a" } }
T{ not-found { path "/b" } }
}
[ path>> ] map . ! => { "/a" "/b" }
A Elena, a nova gestora de qualidade de uma fábrica de jornais, pede-te para escreveres um pequeno programa para monitorizar a sala de produção.
Define uma classe de tuplo de erro machine-error com a palavra de análise ERROR:. Não precisa de slots.
machine-error ! throws a fresh machine-error
Define check-humidity. Recebe uma leitura de humidade da pilha e usa throw para lançar a string "humidity too high" quando a leitura for estritamente superior a 70. Caso contrário, não devolve nada.
50 check-humidity ! returns nothing
80 check-humidity ! throws "humidity too high"
Define check-temperature. Recebe uma leitura de temperatura da pilha e usa throw para lançar a string "temperature too high" quando a leitura for estritamente superior a 500. Caso contrário, não devolve nada.
400 check-temperature ! returns nothing
600 check-temperature ! throws "temperature too high"
Define monitor para receber uma humidade e uma temperatura da pilha e executar ambas as verificações. Se alguma das verificações lançar, monitor deve lançar um novo machine-error em vez disso. Se ambas passarem, monitor não devolve nada.
50 400 monitor ! returns nothing
80 400 monitor ! throws a machine-error
50 600 monitor ! throws a machine-error
Define monitor-batch para receber um array de leituras { humidity temperature } e devolver quantas delas iriam falhar (ou seja, quantas fariam com que monitor lançasse).
{ { 50 400 } { 80 400 } { 50 600 } { 60 200 } } monitor-batch .
! => 2
Inscreve-te no Exercism para aprenderes e dominares Factor com 47 conceitos163 exercícios, e mentoria humana real, tudo grátis.