オブジェクトを文字列に書き出す

twittering-modeのデバッグで、Lispオブジェクトを文字列で書き出せると便利だなーと思って作ったelispschemeだとwriteがあったりするんだけど、elispは探してもみつからなかったので自作した。

Lisp interaction modeだとC-jでeval-printできるけど、それでは要素の多いリスト(load-pathとか)は完全に印字できないので、そういうときに便利。

(defun inspect-object (obj)
  (cond
   ((stringp obj) (format "\"%s\"" obj))
   ((symbolp obj) (format "%s" obj))
   ((integerp obj) (format "%d" obj))
   ((floatp obj) (format "%f" obj))
   ((listp obj)
    (let ((ret nil))
      (while obj
	(if (atom obj)
	    (progn (setq ret `(,(inspect-object obj) "." ,@ret))
		   (setq obj nil))
	  (setq ret (cons (inspect-object (car obj)) ret))
	  (setq obj (cdr obj))))
      (concat "(" (mapconcat #'identity (reverse ret) " ") ")")))
   ((arrayp obj)
    (concat "[" (mapconcat #'inspect-object obj " ") "]"))
   (t (error "Unknown type object!"))))


id:masa_edw から prin1 と prin1-to-string というのを教えてもらった。再発明していた。



lisp-interaction-mode の C-j(eval-print-last-sexp)したときの出力は eval-expression-print-length と eval-expression-print-level で コントロールされるようなので、これらを設定してやるといいみたい。eval-print-last-sexp のときの print-length、print-level はこれらの変数で上書きされるようだ。

print - odz buffer

つまりはlisp-interaction-modeで省略されるのはeval-expression-print-* があるせいだからなのか。ふむふむ。引用したエントリの方法だと確かにできました。with-output-to-stringってelispにもあったんですね。勉強になります。


あれ、今ためしてみたら(print load-path) C-j でもlisp-interaction-modeで全部表示できた(その下に戻り値の省略されたリストが挿入された)。さっきは戻り値のほうを見てたから、うまくいってないように勘違いしたのかもしれますん。