2014-03-14-01-Common Lisp のコンディション機構 - project-enigma

2014-03-14-01-Common Lisp のコンディション機構

>> Site top >> weblog >> 月別アーカイブ >> 2014年03月のlog >> 2014-03-14-01-Common Lisp のコンディション機構

最終更新日付:2014/03/14 23:55:00


Common Lisp のコンディション機構

2014 年 03 月 14 日

Common Lisp にはコンディションという仕組みがある。C++ などの例外機構に似ているが、もっと柔軟なものだ。正直これまでおろそかにしてきたが、ここらでちゃんとおさらいしておこうと思った。まぁおおむね『実践 Common Lisp』で学んだことをなぞっているだけなのだが。

 

まず、通知に使うコンディションオブジェクトは condition か、またはその子孫である error から派生する。といっても defclass するのではなく、それに良く似たコンディション専用の define-conditon を使う。スロットについては後回しだ。ここでは、ありきたりな例としてゼロ除算を。

(define-condition divide-by-zero (error) ())

で、コンディションオブジェクトを作成するには make-instance ではなく make-condition を使う。

(make-conditon 'divide-by-zero)

こうやって作らなくても、error にコンディション型(とあればパラメータ)を渡せばコンディションオブジェクトの生成と投入をいっぺんにやってくれるらしい。

(error 'divide-by-zero)

そんなわけで、関数 test-divide を作ってみる。これでゼロ除算が起きるような test-divide 呼び出しをすれば、divide-by-zero が通知される。

(defun test-divide (a b)
  (when (zerop b)
    (error 'divide-by-zero))
  (/ a b))

* (test-divide 10 0)
; => Condition DIVIDE-BY-ZERO was signalled.

上記コードをそのまま実行すると、通知されたコンディションを処理するコードがないのでデバッガに落ちる。それではアレなので、小さなドライバ関数を書いてやろう。これを通して test-divide をコールすると、通知された divide-by-zero は test-driver が処理し、結果として :infinite を返す。

(defun test-driver (a b)
  (handler-case (test-divide a b)
    (divide-by-zero ()
      :infinite)))

* (test-driver 10 0)
;  => :infinite

まだまだ色々あるけれど、何回かに分けて書くとしよう。埋め草には丁度いい。

 

コメント

このページにコメントする

 

このページのタグ

Page tag : Common Lisp

 

 


Copyright(C) 2005-2017 project-enigma.
Generated by CL-PREFAB.