私がやろうとしていること:simple-error
別のエラーでの機能が必要です。私はこれらの理由でこれが欲しいです:
の別の句でそれを処理できるようにするため
handler-case
。メッセージ文字列を何度も指定しないようにするため。
エラーが発生したときにデバッガーを呼び出す。
これはデフォルトでは自然に発生せず、この問題に十分な注意を払っていないので、ちょっと戸惑っていますが、これは明らかにそれがどのように機能するかです...私ができることは、後で処理できるエラーを通知することですhandler-case
またはを使用handler-bind
しますが、これは悪いことです。関数がスローされるかどうかを常に覚えているわけではなく、スローされたときに処理するのを忘れると、関数は何も起こらなかったかのように早く戻ります。しかし、の使用を再開するとsimple-error
、コードは次のようになります。
...
(signal "Container ~S has no key ~S~&" :container foo :key bar)
...
(signal "Container ~S has no key ~S~&" :container foo :key baz)
...
など、至る所で:/もちろん、メッセージテキストを保存するための変数を専用にしたり、短くするためのマクロを使用したりすることもできますが、これは実際には役に立ちません。解決するのではなく、実際の混乱を隠すだけだからです。問題。
これまでにできること:
(define-condition missing-key (condition)
((key :initarg :key
:accessor key-of)
(container :initarg :container
:accessor container-of))
(:documentation
"An error rised when a KEY is not in the CONTAINER"
:report
#'(lambda (condition stream)
(unless *print-escape*
(format stream "~&Container ~S has no key ~S"
(container-of condition)
(key-of condition))))))
(handler-bind
((missing-key
#'(lambda (condition)
(invoke-debugger condition))))
(signal 'missing-key :key 'foo :container 'bar))
ただし、エラーが通知されると、レポート関数が呼び出されることはなく、代わりに一般的なメッセージが出力されます。Condition MISSING-KEY was signalled.
編集:
sdsの回答のおかげで、これは私が今持っているものです:
(define-condition missing-key (error)
((key :initarg :key
:accessor key-of)
(container :initarg :container
:accessor container-of))
(:documentation
"An error rised when a KEY is not in the CONTAINER")
(:report
(lambda (condition stream)
(format stream "Container ~S has no key ~S"
(container-of condition)
(key-of condition)))))
(defmacro signal-missing-key (container key)
`(let ((*break-on-signals*
(cond
((null *break-on-signals*) 'missing-key)
((consp *break-on-signals*)
(list 'or 'missing-key (cdr *break-on-signals*)))
(t (list 'or *break-on-signals* 'missing-key)))))
(signal 'missing-key :key ,container :container ,key)))
より多くの引数をに渡すことで、おそらくより一般的にすることができますsignal
が、これは最初にやりたかったことを実行するので、同じことを行うためのより良い方法がない限り、おそらくこれを使用します。