CLOSオブジェクトのシリアライズ
これ便利。
(define-class <serializable> () ()) (define-method write-object [(x <serializable>) out] (let* ([class (class-of x)] [serializable-slots (filter (^s (get-keyword :init-keyword (cdr s) #f)) (class-slots class))] [slot-names (map car serializable-slots)] [init-kws (filter-map (^s (get-keyword :init-keyword (cdr s))) serializable-slots)]) (apply (pa$ format out (str "#,(serializable ~A " (apply str (separate " ~A " init-kws)) " ~A)") (class-name class)) (map (compose show (cut slot-ref x <>)) slot-names)))) (define-reader-ctor 'serializable (lambda [class . xs] (apply (pa$ make (eval class (interaction-environment))) xs))) ;;gaucheのコード ;;※carrotのutil.scmに依存
<serializable>
クラスのサブクラスのインスタンスをread
で読み戻せる文字列として吐ける。CLOSだから多重継承できるしmixinみたいに使えばいい。
Carrotの各パーツを分割して一つ一つを独立のシェルスクリプトとして動くようにしたんだけど、そのときに便利だった。
cat examples/prelude.nadeko | carrot-read | carrot-type | carrot-compile to-js > main.js
とか
carrot-read | carrot-type | carrot-compile to-carrot-vm | carrot-vm
って風に使えるようになった。