#:g1: cl-abstract-classesの紹介

Posted 2014-10-04 15:00:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の278日目です。

cl-abstract-classesとはなにか

 cl-abstract-classesは、Tim Bradshaw氏作のCommon Lispで抽象クラス、シングルトンクラス、ファイナルクラスを実現するメタクラスのライブラリです。

パッケージ情報

パッケージ名cl-abstract-classes
Quicklisp
Quickdocscl-abstract-classes | Quickdocs
CL Test Grid: ビルド状況cl-abstract-classes | CL Test Grid

インストール方法

(ql:quickload :abstract-classes)

でabstract-classとfinal-classが、

(ql:quickload :singleton-classes)

でsingleton-classが使えます。

試してみる

 どんな関数があるかは、Quickdocsで確認できます。

 使い方は簡単で、まずabstract-classですが、

(defclass lomilwa ()
  ()
  (:metaclass final-class))

(define-final-class lomilwa () ())

(make-instance 'lomilwa) ;=> #<LOMILWA {1014121093}>

(defclass kandi (lomilwa) ()) ;!> Attempting to subclass a final class

こんな感じで使えます。:metaclassを毎度書くのが面倒なので専用の構文も提供されています。実装は、make-instanceで直接abstract-classを生成しようとしたらエラーにするというシンプルなもの。

(defmethod make-instance ((c abstract-class) &rest junk)
  (declare (ignore junk))
  (error "Trying to make an instance of ~A which is an abstract class"
	 (class-name c)))

 次に、final-classですが、

(defclass lomilwa ()
  ()
  (:metaclass final-class))

(define-final-class lomilwa () ())

(make-instance 'lomilwa) ;=> #<LOMILWA {1014121093}>

(defclass kandi (lomilwa) ()) ;!> Attempting to subclass a final class

この実行例で分かるように継承して使うことができません。
実装は、validate-superclassのチェック時でサブクラスの生成を弾くというもの。なるほど。

(defmethod validate-superclass ((class standard-class)
				(superclass final-class))
  (error "Attempting to subclass a final class"))

 そして、singleton-classですが、

(defclass zilwan ()
  ()
  (:metaclass singleton-class))

(eq (make-instance 'zilwan) (make-instance 'zilwan)) ;=> T

こんな感じに使えて、実装は、make-instanceがキャッシュしたものを返すことで唯一性を保証するというものです。

(defmethod make-instance ((class singleton-class)
                          &key)
  (with-slots (instance) class
    (or instance
        (setf instance (call-next-method)))))

まとめ

 今回は、cl-abstract-classesを紹介してみました。
結構昔からウェブサイトで公開されていましたが、いつの間にかQuicklispに含まれるようになっていたんですね。
しかし、このパッケージ名では、final-classとsingleton-classが含まれていることが分からないかも。

comments powered by Disqus