デバッグプリント補助マクロ
僕が行うデバッグ(及びプログラムの動作確認)のほとんどは、プリントデバッグだ。
common lispのprint系の出力関数は、引数の値を出力した後(?)そのまま返してくれるので、ある式の値を手軽に知りたいときは、その式を(print exp)といったように出力関数で囲むだけでいい。
(defun add (a b) (+ (print a) ;; aの値は? b)) > (add 5 20) 5 --> 25
ただ、この方法だと、値を知りたい式がころころ変わる場合(デバッグの際には珍しくない)に、print関数のつけはずし-特に閉じ括弧の除去-が面倒だったりする。
なので、そのためのリードマクロを作成してみた。
;; #D expression ;; #nD printed-expression_1 ... printed-expression_n main-expression (set-dispatch-macro-character #\# #\d (lambda (stream ch n) (declare (ignore ch)) `(progn (format t "~&~@{~A~}" ,@(loop repeat (1- (or n 1)) collect (read stream t nil t))) (prin1 ,(read stream t nil t)))))
次のように使う。
;; (defun x*y/3 (x y) (/ #D (* x y) ;; x*yの値は? 3)) > (y*x/3 7 9) 63 --> 21 ;; (defun x*y/3 (x y) (/ #1D"X*Y: "(* x y) ;; x*yの値は? 3)) > (y*x/3 7 9) X*Y: 63 --> 21
簡略化(2009/10/07)
もっと簡単に使えるものも作成。
;; ? exp ;; ? label-string exp (set-macro-character #\? (lambda (stream ch) (declare (ignore ch)) (let ((exp #1=(read stream t nil t))) (if (stringp exp) `(progn (format t "~&~A" ,exp) (prin1 ,#1#)) `(progn (fresh-line) (prin1 ,exp)))))) > ?(+ 1 1) 2 2 > ?"label: "(+ 1 1) label: 2 2