Sto implementando un REPL per un interprete Scheme in Haskell e mi piacerebbe gestire alcuni eventi asincroni come UserInterrupt, StackOverflow, HeapOverflow, ecc ... In sostanza, mi piacerebbe fermare il calcolo corrente quando si verifica UserInterrupt e stampare un messaggio adatto quando si verificano StackOverflow e heap overflow, ecc ho implementato in questo modo:Gestione dell'eccezione UserInterrupt in Haskell
repl evaluator = forever $ (do
putStr ">>> " >> hFlush stdout
out <- getLine >>= evaluator
if null out
then return()
else putStrLn out)
`catch`
onUserInterrupt
onUserInterrupt UserInterrupt = putStrLn "\nUserInterruption"
onUserInterrupt e = throw e
main = do
interpreter <- getMyLispInterpreter
handle onAbort (repl $ interpreter "stdin")
putStrLn "Exiting..."
onAbort e = do
let x = show (e :: SomeException)
putStrLn $ "\nAborted: " ++ x
Esso funziona come previsto con una sola eccezione. Se comincio l'interprete e premere Ctrl-Z + Invio, ottengo:
>>> ^Z
Aborted: <stdin>: hGetLine: end of file
Exiting...
Questo è corretto. Ma se comincio l'interprete e premere Ctrl-C seguita da Ctrl-Z + Invio ottengo:
>>>
UserInterruption
>>> ^Z
E si blocca e non posso più usare l'interprete. Tuttavia, se premo di nuovo Ctrl-C, REPL sblocca. Ho cercato molto e non riesco a capirne il motivo. Qualcuno può spiegarmi?
Grazie mille!
Non vedo mai Ctrl-Z essere catturato Il primo Ctrl-C viene catturato, ma il secondo non lo è. Questo è probabilmente lo stesso problema. Potresti cambiare il codice in una prova completa di lavoro? F.e. "return" invece di "interpreter" stdin "" e con le importazioni appropriate aggiunte. –