调试 – 在Racket中设置断点?

使用带有Racket的Emacs / geiser(不是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)))))

我想在开始序列内停下来看看发生了什么以及价值是什么.不依赖于你们的印刷技巧也是很好的,即跟踪某些参数也是如此.再次,我在Emacs并使用Geiser.实际上,如果我能用它们做得更好,我会改用Guile或Chicken(Geiser语言).

最佳答案 正如@ben rudgers所提到的,有一种调试语言(和库)似乎可以很好地满足您的需求.我没有使用其他调试库,因为“不稳定”警告有点令人反感.

这是一个示例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试图自动完成第一个变量时,REPL挂起并且杀死了REPL的racket进程导致Emacs也挂起.不完全确定这是什么,但这似乎除此之外还有效.

点赞