PRINT-OBJECTでfortune — #:g1

Posted 2011-05-24 13:04:00 GMT

closure-htmlなどでは、オブジェクトの印字で、#.(foo ... #|comment|#)のようなものが返ってくるのですが、どういう仕掛けでリードマクロがはいったものを返してくるんだろうと不思議に思っていました。
Twitterでつぶやいていたら、print-objectでやってるんじゃないか、とのアドバイスをもらい、早速試してみたのですが、なるほど印字表現を工夫するだけで同様のことができます。
良く良く考えてみれば、#<... >もリーダーマクロです。
ということで、記念にどうでも良い機能を盛り込んだものを作成。インスタンスが評価されるたびにfortuneが実行されます。
もちろんオブジェクトの実体は印字表現とは別個のものなので変数にも普通に格納できます。

(ql:quickload :kmrcl)

(defclass foo () ())

(defmethod print-object ((obj foo) stream) (format stream "#| ~A |#~%#.(make-instance 'foo)" (kl:string-trim-whitespace (kl:command-output "/usr/games/fortune"))))

(defvar *foo* (make-instance 'foo))

*foo* => #| It is a wise father that knows his own child. -- William Shakespeare, "The Merchant of Venice" |# #.(make-instance 'foo) => #| A man was reading The Canterbury Tales one Saturday morning, when his wife asked "What have you got there?" Replied he, "Just my cup and Chaucer." |# #.(make-instance 'foo) => #| Try to get all of your posthumous medals in advance. |# #.(make-instance 'foo)


comments powered by Disqus