Re: A simple debugging macro
- From: "fairchild.anthony@xxxxxxxxx" <fairchild.anthony@xxxxxxxxx>
- Date: Thu, 29 Nov 2007 23:16:14 -0800 (PST)
On Nov 29, 8:52 pm, "fairchild.anth...@xxxxxxxxx"
<fairchild.anth...@xxxxxxxxx> wrote:
On Nov 29, 8:31 pm, Rainer Joswig <jos...@xxxxxxx> wrote:
In article
<23a2fa9f-68ea-48f4-939a-a4bc04051...@xxxxxxxxxxxxxxxxxxxxxxxxxxxx>,
"fairchild.anth...@xxxxxxxxx" <fairchild.anth...@xxxxxxxxx> wrote:
Hello all,
I wrote this simple macro a while back and I've found it to be
extremely useful for old-fashioned trace style debugging. Maybe
others will find it useful as well. Thoughts or criticism are
welcome. Perhaps others have similar macros or other methods of doing
this that are better.
This is the macro:
(eval-when (:compile-toplevel :load-toplevel :execute)
(defvar *debug* t)
(defmacro print-vars (&rest vars)
"Prints variables listed in vars to *trace-output*. The first
argument can be a string which will be printed directly."
(when *debug*
You have to recompile client code to switch tracing on or off.
That was the intent of the macro, to allow the user to completely
compile-out the trace statements while leaving them in the code (thus
requiring a recompile of everything). I actually don't use this
feature, so I'll take it out. I usually just remove the PRINT-VARS
after I'm done debugging.
`(progn (format *trace-output* "TRACE: ")
,(when (stringp (first vars))
Why just the first arg? Allow strings in all positions.
This is a very good suggestion, I'll change the macro to handle it.
`(format *trace-output* "~A " ,(pop vars)))
FORMAT obsession. Inserting a string in a string and printing that.
Good point. I use used FORMAT because I was printing the string
followed by a space. Perhaps I should use WRITE-STRING followed by
PRINC?
,@(loop for var in vars
collect `(format *trace-output* "~A=~S "
',var ,var))
(format *trace-output* "~%" )
FORMAT obsession. TERPRI.
Excellent, this is exactly what I was looking for, good criticism. My
inexperience is showing ;-)
Thanks for your input. I'll rewrite it and post an update
(finish-output *trace-output*)))))
This is how you use it:
CL-USER 46 > (let ((a 10))
(print-vars "before fib loop" a)
(loop for n from 1 to a
for x = 1 then y
and y = 1 then (+ x y)
do (print-vars n x y))
(print-vars "after fib loop" (* a a)))
TRACE: before fib loop A=10
TRACE: N=1 X=1 Y=1
TRACE: N=2 X=1 Y=2
TRACE: N=3 X=2 Y=3
TRACE: N=4 X=3 Y=5
TRACE: N=5 X=5 Y=8
TRACE: N=6 X=8 Y=13
TRACE: N=7 X=13 Y=21
TRACE: N=8 X=21 Y=34
TRACE: N=9 X=34 Y=55
TRACE: N=10 X=55 Y=89
TRACE: after fib loop (* A A)=100
NIL
Regards,
Anthony
--http://lispm.dyndns.org/
Ok, here's the new macro:
(defmacro print-vars (&rest vars)
"Prints variables listed in vars to *trace-output*. If a string
is passed, it will be printed directly."
`(progn (write-string "TRACE: " *trace-output*)
,@(loop for var in vars
collect (if (stringp var)
`(progn (write-string ,var)(write-string "
"))
`(format *trace-output* "~A=~S "
',var ,var)))
(terpri *trace-output*)
(finish-output *trace-output*)))
Much smaller and cleaner now with your help.
And here's the new usage code:
CL-USER> (let ((a 10))
(print-vars "before fib loop" a "more stuff here")
(loop for n from 1 to a
for x = 1 then y
and y = 1 then (+ x y)
do (print-vars n x y "in loop!"))
(print-vars "after fib loop" (* a a)))
TRACE: before fib loop A=10 more stuff here
TRACE: N=1 X=1 Y=1 in loop!
TRACE: N=2 X=1 Y=2 in loop!
TRACE: N=3 X=2 Y=3 in loop!
TRACE: N=4 X=3 Y=5 in loop!
TRACE: N=5 X=5 Y=8 in loop!
TRACE: N=6 X=8 Y=13 in loop!
TRACE: N=7 X=13 Y=21 in loop!
TRACE: N=8 X=21 Y=34 in loop!
TRACE: N=9 X=34 Y=55 in loop!
TRACE: N=10 X=55 Y=89 in loop!
TRACE: after fib loop (* A A)=100
Here's a macroexpand:
CL-USER> (pprint (macroexpand-1 '(print-vars "before" a b c "after")))
(PROGN
(WRITE-STRING "TRACE: " *TRACE-OUTPUT*)
(PROGN (WRITE-STRING "before") (WRITE-STRING " "))
(FORMAT *TRACE-OUTPUT* "~A=~S " 'A A)
(FORMAT *TRACE-OUTPUT* "~A=~S " 'B B)
(FORMAT *TRACE-OUTPUT* "~A=~S " 'C C)
(PROGN (WRITE-STRING "after") (WRITE-STRING " "))
(TERPRI *TRACE-OUTPUT*)
(FINISH-OUTPUT *TRACE-OUTPUT*))
; No value
Thanks again! Now I'm off to look at kenny's suggestions.
Anthony
.
- Follow-Ups:
- Re: A simple debugging macro
- From: Ken Tilton
- Re: A simple debugging macro
- References:
- A simple debugging macro
- From: fairchild.anthony@xxxxxxxxx
- Re: A simple debugging macro
- From: Rainer Joswig
- Re: A simple debugging macro
- From: fairchild.anthony@xxxxxxxxx
- A simple debugging macro
- Prev by Date: Re: Newbie-solved a problem in ANSI common lisp
- Next by Date: Re: Reasons to choose CLISP over other free implementations
- Previous by thread: Re: A simple debugging macro
- Next by thread: Re: A simple debugging macro
- Index(es):