Shammer's Philosophy

My private adversaria

別パッケージのコンディションを使用する

目的

Lispのパッケージで可読性が・・・ - Shammerismで、同一パッケージのソースコードを複数ファイルに分割可能とわかった。次のステップとしてアプリ・システム全体で独自のコンディションを使用してみる。個々の処理ごとに発生する可能性のあるコンディションは定められているが、システムの階層が深くなるにつれて個々のコンディションを処理できるようにしていても可読性が悪くなる。なので、発生したコンディションはなるべく発生直後に処理して、その後は独自のコンディションでRootCauseに相当するコンディションを投げる、そうすることでそれぞれのコンディション発生箇所で一つのコンディションだけを処理すればよいようにしたい。

Sample

condition.lisp
(defpackage "MY"
  (:use "COMMON-LISP" "CCL" "COMMON-LISP-USER")
  (:export "MY-EXCEPTION" "GET-ERROR-MESSAGE"))

(in-package "MY")

(define-condition my-exception (error)
  ((text :initarg :text :reader get-error-message))
  (:report (lambda (condition stream)
             (format stream "~S.~%" (get-error-message condition)))))
main.lisp
(load "condition.lisp")

(defpackage "MAIN"
  (:use "COMMON-LISP" "CCL" "COMMON-LISP-USER" "MY"))

(in-package "MAIN")

(format t "Start!~%")
(handler-case
    (error (make-condition 'MY-EXCEPTION :text "This is a test condition"))
  (my-exception (e)
    (format t "Got an my-exception, error message is ~A.~%" (get-error-message e))))

(quit)
実行結果
 $ ccl64 -l main.lisp 
Start!
Got an my-exception, error message is This is a test condition.
$ 

最初は、condition.lispでget-error-messageをexportするのを忘れて、main.lisp 実行のタイミングで

Undefined function GET-ERROR-MESSAGE called with arguments (#<MY-EXCEPTION #x302000DB8FAD>)

となってしまった。このexportを忘れないようにしたい。