Shammer's Philosophy

My private adversaria

コンディション超入門

Common Lisp のサイトではないが、Common Lisp 入門Lisp の例外機構について説明があった。
どうやら、例外というものをさらに進化させたコンディションなるものが使用されているようだ。

とりあえず with-open-file マクロで試す。意図的に存在するファイルへの Output Stream を開いてみる。

? (with-open-file (f "exist-file.txt" :direction :output :if-exists :error)
    (format f "This is a test.~%"))
> Error: File exists : "exist-file.txt"
> While executing: CCL::MAKE-FILE-STREAM, in process listener(1).
> Type :POP to abort, :R for a list of available restarts.
> Type :? for other options.

これは、Error というコンディションを補足すればいい、ということだろうか。
まずは、Lisp の例外処理超入門 - Shammerismでもやった catch を使用してみる。

? (catch 'Error
    (with-open-file (f "~/exist-file.txt" :direction :output :if-exists :error)
      (format f "This is a test.~%")))
> Error: File exists : "~/exist-file.txt"
> While executing: CCL::MAKE-FILE-STREAM, in process listener(1).
> Type :POP to abort, :R for a list of available restarts.
> Type :? for other options.

なんか何も変わっていないような、、、
上記サイトの例にならって handler-case を使用してみる。

? (handler-case (with-open-file (f "~/test.txt" :direction :output :if-exists :error)
                  (format f "This is a test.~%"))
    (error (c) c))
#<CCL::SIMPLE-FILE-ERROR #x3020007561ED>
?

おお!なんか変わったぞ!
(error (c) c)というのは、通知されたコンディション(発生した Exception)をそのまま返すだけの意味らしいから、
with-open-file で発生した例外は simple-file-error という名前ということか。
ともあれ、この handler-case というのが Java で言うところの try に相当するやつで、
後に好きなだけ、というか必要なだけ発生する可能性のあるコンディションを書くことができる、
ということになるのか。少し理解できた気がする。