#:g1: utilities.print-itemsの紹介

Posted 2014-06-14 15:00:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の166日目です。

utilities.print-itemsとはなにか

 utilities.print-itemsは、Jan Moringen氏作のCLOSオブジェクトの印字表現を簡便にカスタマイズするためのユーティリティです。

パッケージ情報

パッケージ名utilities.print-items
Quickdocshttp://quickdocs.org/utilities.print-items
CL Test Grid: ビルド状況utilities.print-items | CL Test Grid

インストール方法

(ql:quickload :utilities.print-items)

試してみる

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

(defclass badi (print-items:print-items-mixin)
  ((a :initarg  :a :reader a)
   (b :initarg  :b :reader b)))

のようなクラスがあったとすれば、

(defmethod print-items:print-items append ((object badi))
  `(,@(when (a object)
        `((:a ,(a object) "[~A]")))
    ,@(when (b object)
        `((:b ,(b object) " (~A)" ((:after :a)))))))

(princ-to-string (make-instance 'badi :a 8 :b 9)) ;=> "#<BADI [8] (9) {1050AA13D3}>"

のような定義を書くことによってインスタンスの印字表現は、スロットの中身を表示してくれるものになります。
使い勝手や仕組みとしては、fare-mopのsimple-print-objectとほぼ同じでmixinさせるというのも同じです。

 print-itemsが何やら複雑な形式になっているのは、継承した時に上位クラスの印字用定義を再利用させるためと思われ、例えば、badiを継承したhamanがa、bに加えて新しくスロットcを追加するものだとすると、

(defclass haman (badi)
  ((c :initarg :c :reader c)))

(defmethod print-items:print-items append ((object haman)) (and (c object) `((:c ,(c object) " {~A}" ((:after :b))))))

のような定義をすれば、追加分の定義だけで済みます。
print-itemsの返り値はリストになっていて、メソッド結合がappendなので上位の結果がリストとしてappendされるようになっているからなのですが、上手いような気もしますし、なんだか難解な気もします。


(print-items:print-items (make-instance 'badi :a 8 :b 9))
;=>  ((:A 8 "[~A]") (:B 9 " (~A)" ((:AFTER :A))))

(print-items:print-items (make-instance 'haman :a 8 :b 9 :c 10))
;=>  ((:C 10 " {~A}" ((:AFTER :B))) (:A 8 "[~A]") (:B 9 " (~A)" ((:AFTER :A))))
(princ-to-string (make-instance 'haman :a 8 :b 9 :c 10)
;=>  #<HAMAN [8] (9) {10} {1052FD1113}>

また謎の(:after :b)等の位置指定ですが、appendメソッド結合の結果だと先頭から追加になるので、そのままの位置関係だとc a bになったりしてしまうので別途指定可能になっているのかなと思われます。

関連

まとめ

 今回は、utilities.print-itemsを紹介してみました。
:berore/:after/:around以外のメソッド結合を上手く使っている例というのは、あまりないのでなかなか貴重な例かもしれません。

comments powered by Disqus