trace

ある言語で,プログラミングを学習する際,hello, world 的なものの次には,
デバッグ方法やら,トレース方法を教えるのがいいのではないかと思う今日この頃ですが,
皆様いかがおすごしでしょうか?


gauche を使用して scheme を勉強しています.で,トレースしたいと.
ドキュメント読んでたら,trace マクロが紹介されていて,

(use ggc.debug.trace)

することで,trace できていたんですが,list? に循環リストを渡して,
トレースすると,行ったきりで帰ってこないので,困っていました.
そこで,Web で調べると,といっても調べているのは,私なのか,Google なのかは微妙ですが,
ま,ほいで,slib (scheme library?) の trace を使ってみようと.
apt-get でインストールして,

(use slib)
(require 'trace)

で,オーケーなはずでした.
ええ,件の,list? に循環リスト渡しても,帰ってきます.
でも,再帰の回数が多いと,途中までしか表示してくれず悲しいです.
で,また,ドキュメント.ありましたよ,奥さん.

 7.5.5 Tracing

(require 'trace)

This feature provides three ways to monitor procedure invocations:

stack

    Pushes the procedure-name when the procedure is called; pops when it returns. 
track

    Pushes the procedure-name and arguments when the procedure is called; pops when it returns. 
trace

    Pushes the procedure-name and prints `CALL procedure-name arg1 …' when the procdure is called; pops and prints `RETN procedure-name value' when the procedure returns. 

Variable: debug:max-count

    If a traced procedure calls itself or untraced procedures which call it, stack, track, and trace will limit the number of stack pushes to debug:max-count. 

うひひ.超意訳すると,変数 debug:max-count で,スタックへの push 回数を制御してると.(要約しすぎ?)

gosh> debug:max-count ;; てか,「debug:」の部分の表記方法をしらんのだが,これはスコープ制御みたいな感じか?
5 ;; なるほど,たしかにございます.
gosh> (define debug:max-count 30)
debug:max-count ;; ま,こんなもんでいいか.で,
gosh> (define fact
	(lambda (n)
	  (if (= n 0)
	      1
	      (* n (fact (- n 1))))))
fact
gosh> (trace fact)
#<closure (debug:trace-procedure debug:trace-procedure)>
gosh> (fact 10)
CALL fact 10
 CALL fact 9
  CALL fact 8
   CALL fact 7
    CALL fact 6
     CALL fact 5
      CALL fact 4
       CALL fact 3
        CALL fact 2
         CALL fact 1
          CALL fact 0
          RETN fact 1
         RETN fact 1
        RETN fact 2
       RETN fact 6
      RETN fact 24
     RETN fact 120
    RETN fact 720
   RETN fact 5040
  RETN fact 40320
 RETN fact 362880
RETN fact 3628800
3628800

キタコレ!!