Let's start Scheme

2012-01-26

CLOSの動作チェック

0.3.0に備えてCLOSの動作チェック。組込みでCLOSをサポートするため。でもCL並みに高性能にするべきか悩み中。

とりあえず、Tiny CLOSをベースにしようと考えていたので、サポートしてるmoshで検証。ただ、moshのCLOSってうっかり変なことするとすぐにハングアップするので注意が必要。せめて構文エラーとかそんなメソッドないとか言ってくれればいいのに。
今回はaround、before、after、primaryについてちょっと調べてみた。結論を言うと、完全Aspect指向って感じ。検証コードは以下。
(import (rnrs) (clos core) (clos user))
(define (print . args)
  (for-each display args) (newline))

(define-class <person> () name age)
(define-method initialize ((p <person>) init-args)
  (initialize-direct-slots p <person> init-args))
(define-class <painter> (<person>) pen)
(define-method initialize ((p <painter>) init-args)
  (call-next-method)
  (initialize-direct-slots p <painter> init-args))

(define koch (make <painter> 'name "Koch" 'age 18 'pen "Brush"))
(print (slot-ref koch 'name))
(define-generic paint)

(define-method paint 'arround ((p <person>) colour)
  (print "starting messing up")
  (call-next-method)
  (print "ended messing up"))
(define-method paint 'arround ((p <painter>) colour)
  (print "starting")
  (call-next-method)
  (print "end"))

(define-method paint 'before ((p <person>) colour)
  (print "messing up " colour))
(define-method paint 'before ((p <painter>) colour)
  (print "preparing " colour))
(define-method paint ((p <painter>) colour)
  (print "painting " colour))
(define-method paint 'after ((p <painter>) colour)
  (print "painted " colour))
(define-method paint 'after ((p <person>) colour)
  (print "messed up " colour))
(paint koch 'red)
#|
Output:
Koch
starting
starting messing up
preparing red
messing up red
painting red
messed up red
painted red
ended messing up
end
|#
aroundがarroundになっているのは仕様です。aroundだと動かない・・・そしてmoshが死ぬ。
beforeはprimaryが呼ばれる前で、順番は子から親へ辿る。
afterはprimaryが呼ばれた後で親から子へ辿る。
aroundは見たとおりで、すべての処理の前と後。ただし、call-next-methodを呼ばないと本処理が走らない。また、同じメソッドがあれば、子から親の順で呼ばれる。
aroundはcall-next-methodをコメントアウトしたりすると理解が早い。たとえばのaround内にあるcall-next-methodを消すと、子->親->子で終了する。aroundを指定したら必ずcall-next-methodを呼ばないとえらいことになる。
Java等ですでにAspect指向をやったならあれとほぼ一緒だろう。表面的なことしか見てないけど。

問題は、どうこれを実装するかだな・・・

No comments:

Post a Comment