私は余暇に Common Lisp を学んでいて、条件システムについて質問があります。
Common Lisp でエラーを処理するとき、ハンドラーで error-type を指定して、処理するエラーを決定します。エラーの発生と処理の間に、(restart-case などを使用して) いくつかの再起動を行うことができますが、restart でエラーの種類を指定することはできません。
たとえば、文字列とストリームを受け取り、文字列をストリームに送信し、ストリームからの応答を読み取って返す関数があるとします。メッセージが間違っている場合、ストリームからエラー応答を読み取ったとします。そして、エラーを発生させ、次のような新しいメッセージを要求する再起動をバインドしたい:
(defun process-message (stream raw-message)
(let ((response (get-response stream raw-message)))
(restart-case
(when (response-error-p response)
(error 'message-error :text response))
(change-raw-message (msg)
(process-message stream msg)))))
ここで、メッセージが複雑でsend-command
、いくつかの引数からメッセージを作成してプロセス メッセージを呼び出すことができる別の関数を上位レベルで取得したとします。取得したrecreate-command-message
場合、ユーザーが引数から新しいコマンドを送信できるようにする別の再起動をバインドしたいと思います。'message-error
この再起動は、restart-case の の場所にある可能性がありますがprocess-message
、完全に正しいとprocess-message
は言えません。このような高レベルの関数については知らずsend-command
、戻り値が異なる可能性があるためです。
しかし、ストリームエラー (EOF など) がスローされrecreate-command-message
、ソケットが失敗した場合、recreate-command-message
再起動は超高レベルのsocket-error
ハンドラーで利用可能になり、この再起動は役に立たず、慣用的に間違っています。
これはプログラム設計上の問題であり、そのような問題を回避するようにプログラムを設計する必要がありますか? それとも、再起動をエラー タイプにバインドする方法が見つからないか、条件システムを正しく理解していませんか?
ありがとう。