世界一短い(かもしれない)オブジェクト指向フレームワーク「nekoduck」
- 発表資料。要Firefox(他のブラウザでは試してない)。1024×768ピクセル固定。F11キー(全画面表示)推奨
- http://practical-scheme.net/wiliki/wiliki.cgi?Scheme%3A%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E8%A1%A8%E7%8F%BEのCLOS風ではない方のOOをできるだけ素朴に実装しようと思って30分くらいででっちあげたプログラム。かなり手抜き
●ソースコード (define (object parent . methods) (lambda (method-name . params) (if (null? parent) (let ((root-value (assoc method-name methods))) (if root-value ((cadr root-value) params) 'not_found)) (let ((my-value (assoc method-name methods))) (if my-value ((cadr my-value) params) (parent method-name))))))
●使い方 (define オブジェクト名 (let ((フィールド1 初期値1) (フィールド2 初期値2) …)) (object 親オブジェクト名 `(メソッド1 ,処理1) `(メソッド2 ,処理2) …))))
- ルートオブジェクトの場合は親オブジェクトとして空リストを指定
- 外からフィールドにアクセスするにはアクセサを用意する
- 継承の例は発表資料を参照
●オブジェクトの例(カウンタ) (define counter (let ((c 0)) (object '() `(up ,(lambda (p) (set! c (+ c 1)))) `(plus ,(lambda (p) (set! c (+ c (car p))))) `(show ,(lambda (p) c)))))
(counter 'show) 0 (counter 'up) 1 (counter 'plus 5) 6
【追記】
よく見たら親オブジェクトにメソッドの引数渡してなかった。ダメすぎ
引数を一つに限定して、複数の引数を渡したいときはリストを渡すようにすればOKか。コードは略
【2010-03-20追記】
親オブジェクトにメソッドの引数を渡すのはapplyでいいのに気付いた。なんでわからなかったんだろう
(define (object parent . methods) (lambda (method-name . params) (if (null? parent) (let ((root-value (assoc method-name methods))) (if root-value ((cadr root-value) params) 'not_found)) (let ((my-value (assoc method-name methods))) (if my-value ((cadr my-value) params) (apply parent method-name params))))))
ついでに、カウンターのplusも任意の個数の引数を取れた方がいいよね
(define counter (let ((c 0)) (object '() `(up ,(lambda (p) (set! c (+ c 1)))) `(plus ,(lambda (p) (set! c (apply + c p)))) `(show ,(lambda (p) c)))))