#:g1: sheepleの紹介

Posted 2014-01-22 15:00:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の23日目です。

sheepleとはなにか

 sheepleとは、MOPとマルチメソッドを持つCLOS風なプロトタイプベースのオブジェクト指向システムです。

パッケージ情報

パッケージ名sheeple
Quicklisp
参考サイトIntroduction to Sheeple | sykosomatic
CLiKihttp://cliki.net/sheeple
Quickdocshttp://quickdocs.org/sheeple

インストール方法

(ql:quickload :sheeple)

試してみる

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

 まず、入門的な記事は、tszさんが既に書かれてますので、そちらを参照すると良いかなと思います。

 オブジェクト指向システムの手軽なサンプルにBankAccountというのがあるらしいのでSheepleで書いてみます。

(defproto =bank-account= ()
  ((dollars 0)))

(defmessage deposit (obj n))

(defreply deposit ((obj =bank-account=) (x =number=)) (incf (dollars obj) x))

(defmessage withdraw (obj n))

(defreply withdraw ((obj =bank-account=) (x =number=)) (setf (dollars obj) (max 0 (- (dollars obj) x))))

(defparameter *my-account* (create =bank-account= 'dollars 200)) ;=> *MY-ACCOUNT*

(dollars *my-account*) ;=> 200

(deposit *my-account* 50) ;=> 250

(withdraw *my-account* 100) ;=> 150

(withdraw *my-account* 200) ;=> 0

(dollars *my-account*) ;=> 0

(defproto =stock-account= (=bank-account=)
  ((num-shares 0)
   (price-per-share 30)))

(defreply (setf dollars) ((x =number=) (obj =stock-account=)) (setf (num-shares obj) (/ x (price-per-share obj))) (dollars obj))

(defreply dollars ((obj =stock-account=)) (* (num-shares obj) (price-per-share obj)))

(defparameter *my-stock* (create =stock-account= 'num-shares 10)) ;=> *MY-STOCK*

(dollars *my-stock*) ;=> 300

(setf (dollars *my-stock*) 600) ;=> 600

(deposit *my-stock* 60) ;=> 660

(num-shares *my-stock*) ;=> 22

(withdraw *my-stock* 120) ;=> 540

(num-shares *my-stock*) ;=> 18

という風に、ほぼそのままCLOSという感じにも書けます。

SheepleのMOP

 SheepleはCLOS風にMOPを装備する方向のようです(といっても開発は停滞しているようですが…)。
APIはそれなりに揃っているので、現状でもCLOS MOPと似たようなことは可能です。定番のオブジェクト生成時にインスタンスを勘定するのは下記のように書けます。

(defproto =counted-sheep= (=standard-metaobject=)
    ((counter 0)))

(defproto =kadorto= (=counted-sheep=))

(defreply smop:allocate-object :after ((obj =kadorto=)) (incf (counter obj)))

(defproto =mahaman= () () :metaobject =kadorto=)

実行してみる
(setf (counter =kadorto=) 0)

(dotimes (i 100) (clone =mahaman=))

(counter =counted-sheep=) ;=> 0 (counter =kadorto=) ;=> 100

CLOS MOP風というかクラス風に=counted-sheep=をそのまま使うと=counted-sheep=の中身が書き変わるのでクローンを作成しています。

sheepleの紹介/関連記事等

まとめ

 今回は、sheepleを紹介してみました。
MOP付きのプロトタイプベースのオブジェクト指向システムというのも珍しいと思います。配布ソースにMOPの例は数点付属しているので興味のある方は遊んでみると良いかなというところです。

comments powered by Disqus