Como o pltscheme captura erros?
-
21-09-2019 - |
Pergunta
Fico impressionado com a função "Erro" no PLTSCHEME. Se eu tiver uma divisão por zero, ela não faz nenhuma outra recursão e sai da pilha de chamadas e me dá um erro.
Existe uma continuação implícita antes de todas as funções? O erro joga fora a pilha de chamadas? Alguém tem alguma idéia sobre isso?
Solução
No esquema PLT, o procedimento erro levanta a exceção EXN: FAIL, que contém uma string de erro. Não há "captura implícita" para todos os define. Veja a seguinte amostra:
;; test.ss
(define (a d)
(printf "~a~n" (/ 10 d)))
(a 0) ;; The interpreter will exit here.
(printf "OK~n")
Execute o script acima da linha de comando e você verá o intérprete existente depois de imprimir algo como
/: division by zero
=== context ===
/home/user/test.ss:1:0: a
Se uma exceção não for tratada no programa de usuário, ele será propagado até o intérprete principal, onde um manipulador padrão lida com ele, ou seja, imprima a exceção e a saída. Em outras palavras, o intérprete apenas diz: "Uma exceção foi levantada e eu não sei como lidar com isso, então estou dizendo". Isso não é muito diferente de como a JVM ou outras exceções da manipulação da máquina virtual.
Para saber mais sobre o mecanismo de manuseio de exceção do esquema PLT, leia sobre com os mão-de-obra e Wind Dinâmico no Manual de idiomas mzscheme. Usando isso, você pode até emular o bloqueio de Java-Catch-Finally.
(define (d a b)
(try
(printf "~a~n" (/ a b))
(catch (lambda (ex)
(printf "Error: ~a" ex)))
(finally
(if (> b -2)
(d a (sub1 b))))))
Aqui está a extensão de sintaxe que tornou possível o acima:
;; try-catch-finally on top of with-handlers and dynamic-wind.
(define-syntax try
(syntax-rules (catch finally)
((_ try-body ... (catch catch-proc))
(with-handlers (((lambda (ex) #t)
(lambda (ex)
(catch-proc ex))))
(begin
try-body ...)))
((_ try-body ... (catch catch-proc) (finally fin-body ...))
(dynamic-wind
(lambda () ())
(lambda ()
(with-handlers (((lambda (ex) #t)
(lambda (ex)
(catch-proc ex))))
(begin
try-body ...)))
(lambda () fin-body ...)))
((_ try-body ... (finally fin-body ...))
(dynamic-wind
(lambda () ())
(lambda () try-body ...)
(lambda () fin-body ...)))))