Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2009-02-02

「format の痒いのに手が届かないところ」に挑戦!

| 03:49 | 「format の痒いのに手が届かないところ」に挑戦! - わだばLisperになる を含むブックマーク はてなブックマーク - 「format の痒いのに手が届かないところ」に挑戦! - わだばLisperになる

少しブログのトラックバックやコメント機能を活用してみようということで、これからは積極的にトラックバックをしてみることにしました。

今回は、kozimaさんの

を読んでいて、kozimaさんよりナイスな解決法を思い付ける気は全然しませんが、これは面白いと思ったので自分でも色々考えてみました。

まずは、フォーマットストリングではなくてS式だったら良いのでは、というのを受けて関数にしてみたらどうかというところ

fletで

(flet ((format-items (stream arg list)
         (format stream "<ul>~%")
         (dolist (item list)
           (format stream "~VT<li>~A</li>~%" arg item))
         (format stream "</ul>")))
  (format nil #'format-items 3 '(aaa bbb ccc)))
;=>
"<ul>
   <li>AAA</li>
   <li>BBB</li>
   <li>CCC</li>
</ul>
"

formatに直にlambdaを渡す

(format nil (lambda (str n args)
              (format str "<ul>~%")
              (dolist (item args)
                (format str "~VT<li>~A</li>~%" n item))
              (format str "</ul>"))
        3 '(aaa bbb ccc))

やはりいまいちですね。

まったくすっきりする気配がありません。

メソッドにしたらどうか

(defmethod format-ul-method (str n args)
  (dolist (item args)
    (format str "~VT<li>~A</li>~%" n item)))

(defmethod format-ul-method :around (str n args)
  (format str "<ul>~%")
  (call-next-method)
  (format str "</ul>"))

(format nil #'format-ul-method 3 '(aaa bbb ccc))

完全にあさっての方向に進んでしまいましたね。

あさってついでに

(defmethod format-ul-method :around (str n args)
  (format str "<ul>~%~/CALL-NEXT-METHOD/</ul>"))

とかできると面白いかなと思いました。

大域定義にcall-next-methodが存在するかどうかは、処理系依存らしいので、もしかしたらできてしまう処理系もあるのかもしれません。

まとめ

全然まとまってないのですが、やはりformatの~//指示子がローカル関数も対象になると便利かなと思いました。