2011-07-29 7 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

そうすることが実際に可能です。トレースは関数 - 名前空間内の関数を探します。したがって、値と関数を混在させないように注意してください。

(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関数を参照してください)。もちろん

あなたがしたいすべてがfoo-3が呼び出される印刷何か出ている場合、あなたは常にFOOでラムダフォーム内のprint文を入れることができます...

+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