2011-07-29 104 views
7

追溯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 ???) 
+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 
+0

謝謝!我一直在通過http://www.gnu.org/s/emacs/manual/html_node/elisp/Symbol-Components.html#Symbol-Components,http://www.dreamsongs.com/Separation.html和CLTL。現在我對此有了一個很好的感覺。關於這個值得參考的命名空間的任何其他資源? – user869081

3

我不認爲這是可能的:據我所知,跟蹤宏通常的工作原理是通過調用原來還打印出跟蹤位的包裝在一個給定的符號替換功能。

如果您對(複雜的)實現細節感興趣,SBCL代碼位於src/code/ntrace.lisp(您可能需要查看trace-1函數)。

當然,如果你想要做的就是打印出來的東西時富-3被調用時,你總是可以把打印語句foo中的拉姆達表單內...

+1

是否有關於閉包的基礎知識,使得爲它們編寫追蹤函數變得不可能? – user869081

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