<source-trap> class implements traps that are attached to a
precise source code expression, as read by the reader, and which fire
each time that that expression is evaluated. These traps use a low
level Guile feature which can mark individual expressions for
trapping, and are relatively efficient. But it can be tricky to get
at the source expression in the first place, and these traps are
liable to become irrelevant if the procedure containing the expression
is reevaluated; these issues are discussed further below.
(display "Enter an expression: ") (let ((x (read))) (install-trap (make <source-trap> #:expression x #:behaviour (list trace-trap trace-at-exit))) (primitive-eval x)) -| Enter an expression: (+ 1 2 3 4 5 6) | 3: (+ 1 2 3 4 5 6) | 3: =>21 21
The key point here is that the expression specified by the
#:expression option must be exactly (i.e.
what is going to be evaluated later. It doesn't work, for example, to
#:expression '(+ x 3), with the expectation that the trap
will fire whenever evaluating any expression
(+ x 3).
trap-here macro can be used in source code to create and
install a source trap correctly. Take for example the factorial
function defined in the
(ice-9 debugging example-fns) module:
(define (fact1 n) (if (= n 0) 1 (* n (fact1 (- n 1)))))
To set a source trap on a particular expression — let's say the
(= n 0) — edit the code so that the expression is
enclosed in a
trap-here macro call like this:
(define (fact1 n) (if (trap-here (= n 0) #:behaviour debug-trap) 1 (* n (fact1 (- n 1)))))
Install a source trap with options trap-options on expression, then return with the whole call transformed to
Note that if the
trap-here incantation is removed, and
fact1 then redefined by reloading its source file, the effect
of the source trap is lost, because the text “(= n 0)” is read again
from scratch and becomes a new expression
(= n 0) which does
not have the “trap here” mark on it.
If the semantics and setting of source traps seem unwieldy, location traps may meet your need more closely; these are described in the following subsubsection.