とりあえず、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をコメントアウトしたりすると理解が早い。たとえば
Java等ですでにAspect指向をやったならあれとほぼ一緒だろう。表面的なことしか見てないけど。
問題は、どうこれを実装するかだな・・・
No comments:
Post a Comment