跟踪关闭

时间:2011-07-29 09:46:14

标签: common-lisp

是否有可能在CL中追踪一个闭包?例如,我可以追踪下面的foo-3吗?

(defun foo (n)
    (lambda (i) (incf n i)))
FOO
(setf foo-3 (foo 3))
#<CLOSURE :LAMBDA (I) (INCF N I)>

(funcall foo-3 2)
5
(funcall foo-3 2)
7
(trace ???)

3 个答案:

答案 0 :(得分:3)

我不认为这是可能的:据我所知,跟踪宏通常通过用调用原始的包装器替换给定符号的函数来工作,并打印出跟踪位。

如果您对(复杂)实现细节感兴趣,则SBCL代码位于src/code/ntrace.lisp(您可能希望查看trace-1函数)。

当然,如果你想要做的只是在调用foo-3时打印出来的东西,你总是可以在foo中的lambda表单中放一个print语句......

答案 1 :(得分:1)

确实可以这样做。 Trace在函数命名空间中查找函数,因此请确保不要混合使用值和函数。

(setf (symbol-function 'test)
   (let ((n 0))
    (lambda (x)
     (incf n x))))
=>
#<Interpreted Closure TEST>
(trace test) 
... 
(test 4)
=>
 0[2]: (TEST 4)
 0[2]: returned 4
4
(test 3)
=>
0[2]: (TEST 3)
0[2]: returned 7
7

答案 2 :(得分:0)

我认为这里的问题是trace需要一个函数名,而不是跟踪闭包有问题。继续上面的示例,您可以从命名函数中调用foo-3,并跟踪:

(defun call-foo-3 (i)
   (funcall foo-3 i))
(trace call-foo-3)
(call-foo-3 2)
  0: (CALL-FOO-3 2)
  0: CALL-FOO-3 returned 15