2011-07-29 15 views
7

CL'de bir kapağın izlenmesi mümkün mü? Örneğin, aşağıda foo-3'ü izleyebilir miyim? Bunu sanmıyorumBir kapağın izlenmesi

(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

Harika soru! –

cevap

1

Bunu yapmak gerçekten mümkün olmaktadır. Trace, işlev-ad alanındaki işlevlere bakar, bu nedenle değerleri ve işlevleri karıştırmamaya dikkat edin.

(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

Teşekkürler! Http://www.gnu.org/s/emacs/manual/html_node/elisp/Symbol-Components.html#Symbol-Components, http://www.dreamsongs.com/Separation.html ve üzerinde çalışıyorum. CLTL. Şimdi bunun için iyi hissediyorum. Bu konu alanlarına atıfta bulunmaya değecek başka kaynaklar var mıdır? – user869081

3

mümkündür: olarak bildiğim kadarıyla, iz makro genellikle orijinal çağırır ve ayrıca izleme biraz dışarı yazdıran bir sargı ile verilen bir sembole fonksiyonunu değiştirerek çalışır.

(Karmaşık) uygulama ayrıntılarıyla ilgileniyorsanız, SBCL kodu src/code/ntrace.lisp (büyük olasılıkla trace-1 işlevine bakmak isteyebilirsiniz). foo-3 çağrıldığında yapmak istediğiniz tüm yazdırma şeyler ise, her zaman foo içinde lambda form içinde bir yazdırma deyimi koyabilirsiniz Tabii

...

+1

Onlar için bir izleme işlevi yazma imkansız kılan kapanışlar hakkında temel bir şey var mı? – user869081

0

Burada sorun olduğunu düşünüyorum Bu trace, izleme kapanışlarıyla ilgili bir sorun olmak yerine bir işlev adı gerektirir. Yukarıdaki örnekten devam edersek, bir adlandırılmış işlevinden foo-3 diyoruz ve bu izleyebilirsiniz:

(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 
İlgili konular