(break) and (print .. ) scattered about through your code.
After all if MCL has this insanely great Stepper and Inspector and
Documentation tool, surely there should be some more functionality I
can eek out of the trace facility. If not. I might as well use DTRACE from
Touretzky's book, right?
Alas the trace macro in MCL does have a bunch of "Whiz Bang" options. Shamelessly, extracting the Macro description from the MCL documentation.
trace [Macro ]
Syntax trace { spec | spec { option modifier } ) }
Description
The trace macro encapsulates the function or method specified by each spec,
causing the actions specified by the options. When no options are specified,
the default actions print arguments on entry and values on exit.
Invoking (trace) without arguments returns a list of the functions currently
being traced. If no fucntions are currently being traced, (trace) returns
NIL.
Arguments
spec The specification of the function to be traced. This is either
a symbol that is the name of the a function or generic
function, or an expression of the form (setf symbol) , or an
specific metho of a generic function in the form
( :method symbol { qualifiers } (specializer {specializer}*)).
option An option that specifies an action to be performed.
The follwoing options and their modifiers are supported:
:before Specifies the action to be taken before the traced function
is called. The :before keyword must be followed by a
modifier:
:print Prints the name and arguments to the function before
the function is called.
:break Pints the name and arguments to the function and enters
a break loop before the function is called.
You can examine the Stack Backtrace, perform operations
in the Listener, and continue if desired.
lisp-function If the :before option is a function, it is called
before the traced function is called. The
arguments to lisp-function are the name of the
trace function and the arguments passed to the
traced function.
:after Specifies the action to be taken after the traced function
returns. This keyword must be followed by a modifer, which
should be one of the following:
:print Prints the name and the returned values.
:break Prints the name of the function and the returned values,
and enters a break loop. You can examine the Stack
Backtrace, perform operations in the Listener, and
continue if desired.
lisp-function If the :after option is a function, it is called
after the trace function returns. The arguments
are the name of the traced function and the
values returned by the traced function.
:step Specifies whether the traced function shoud be stepped
when it is run. .... [ stuff about *saved-definitions*..]
The :step keyword must be followed by a modifier, which
is either t or a function whose arguments are the
name of the trace function and the arguments passed to
to the traced function. If it is t or if the
function returns non-NIL, then the traced function is
stepped; otherwise it is run without stepping.
Well let's try some of this "Wizardary" out...
fact?
? (defun fact (num )
(declare (notinline fact))
(if (= num 0 )
1
(* num (fact (- num 1 )))))
FACT
? (trace fact)
NIL
Now if you enter (fact 4 ) you'll see the familiar trace of
fact.
? (trace (fact :before :print ))
? (fact 4 )
or
? (trace ( fact :before :break
:after :print ))
? (fact 4 )
or how about
? (defun only-on-odd (func &rest args)
"only break if number is odd"
(if (evenp (car args ))
(format t "~&Calling ~s~%"
(cons func args))
(break "on calling ~s"
(cons func args))))
ONLY-ON-ODD
? (trace (fact :before only-on-odd ))
NIL
? (fact 4 )
Note in the last example the lisp function that :before is using is not
preceeded by #' . The trace macro will append that on for you. However,
for some strange reason I could not get the facility to accpet a lambda
function as the argument ( even though the documentation contains an
example using a lambda function it didn't work... ). Well I guess you
can't have everything.
evenp S-Expression that appears in
only-on-odd above.