在Racket中设置断点?

时间:2016-07-14 15:14:42

标签: debugging scheme racket

将Emacs / geiser与Racket(不是DrRacket)一起使用,如何设置断点然后逐步执行代码,在断点处暂停?例如,我有这段代码:

(define (powerset4 lst)
  (if (null? lst)
      '(())
      (append-map (lambda (x)
                    (begin
                      (fprintf (current-output-port) "~s ~s ~s\n" x lst x)
                      (list x (cons (car lst) x))))
                  (powerset4 (cdr lst)))))

我希望在begin序列内停下来看看发生了什么以及值是什么。不依赖于你自己的printf技巧也是很好的,即跟踪某些参数也是如此。再次,我在Emacs并使用Geiser。实际上,如果我能用它们做得更好,我会转向Guile或Chicken(Geiser语言)。

1 个答案:

答案 0 :(得分:2)

正如@ben rudgers所提到的,有一种debug语言(和库)似乎可以很好地满足您的需求。我还没有使用过其他调试库,因为"不稳定"警告有些令人反感。

这是一个示例test.rkt文件,改编自您的程序:

#lang racket

(require debug/repl)

(define (powerset4 lst)
  (if (null? lst)
      '(())
      (append-map (lambda (x)
                    (begin
                      (list x (cons (car lst) x))
                      (debug-repl) ;; this is the breakpoint that will enter a REPL
                      ))
                  (powerset4 (cdr lst)))))

(powerset4 '(1 2 3))

当我C-c C-a将文件加载到Geiser时,我接到一个REPL,表明我已进入调试器。然后我可以检查当前范围内的值,看看发生了什么。

Welcome to Racket v6.6.
racket@> ,enter "/Users/my_username/test.rkt"
-racket@test.rkt> x
'()
-racket@test.rkt> lst
'(3)
-racket@test.rkt> 

奇怪的是,(至少对我而言)当Geiser尝试auto-complete lst变量时,REPL挂起并且杀死REPL的racket进程导致Emacs也挂起。不完全确定这是什么,但这似乎除了那之外还好。