[英]Differing behavior between debug and REPL mode in Dr. Racket: modifying a constant
I am trying to code my own unit-test library in scheme. 我正在尝试在方案中编写自己的单元测试库。 So far, I have the following code in the definition window: 到目前为止,我在定义窗口中有以下代码:
#lang scheme
(define all-tests '())
(define-syntax make-tests
(syntax-rules (->)
[(_ test-name function (args ... -> result) ...)
(begin
(define test-name
(list function (list (list args ...) ...) (list result ...)))
(set! all-tests (cons test-name all-tests)))]))
Using Dr. Racket, when I submit the following code into the REPL: 使用Dr. Racket,当我将以下代码提交到REPL时:
> (make-tests tests + (1 2 -> 3))
set!: assignment disallowed;
cannot modify a constant
constant: all-tests
However when I tried to debug it in Dr. Racket: 但是,当我尝试在Dr. Racket中调试它时:
(debug)> (make-tests tests + (1 2 -> 3))
(debug)> tests
(#<procedure:+> ((1 2)) (3))
(debug)> all-tests
((#<procedure:+> ((1 2)) (3)))
So, for some reason, in Dr. Racket v6.1, my code works in debug mode, but does not work when using the REPL. 因此,出于某种原因,在Dr. Racket v6.1中,我的代码在调试模式下工作,但在使用REPL时不起作用。 What is going on, and how can I debug my code? 发生了什么,我该如何调试我的代码?
Based on the comment on this previous answer : If a module doesn't mutate a binding you cannot mutate it from outside the module. 基于对前一个答案的评论:如果模块没有改变绑定,则不能从模块外部改变它。 Running code in the REPL is not the same as running code in the module. 在REPL中运行代码与在模块中运行代码不同。 A racket source in Racket language is a module and #lang scheme
is not Scheme but synonym for #lang racket
. Racket语言中的球拍源是一个模块,# #lang scheme
不是Scheme,而是#lang racket
同义词。
So to get the behaviour you would like you can replace (define all-tests '())
with: 因此,要获得您希望可以替换的行为(define all-tests '())
:
(define all-tests #f)
(set! all-tests '()) ; quick fix that makes all-test mutable
And it will work. 它会奏效。 You may dig deeper into racket documentation about it too. 您也可以深入了解有关它的球拍文档 。
You can Un-check the option Enforce constant definition
In the choose language menu in DrRacket In the Dynamic properties box. 您可以取消选中“ Enforce constant definition
”选项在“DrRacket”的“选择语言”菜单中的“动态属性”框中。
And as a note to your macro. 并作为你的宏的一个注释。 Why do you specify a name for the test? 为什么要为测试指定名称? The name is not placed in the list, and aside from defining it to cons it to all-tests
it is never used. 该名称不会放在列表中,除了定义它以使其适用于all-tests
它永远不会被使用。 You can use a let instead. 您可以改用let。 Unless of course your are going to do something with tests
later. 当然,除非您稍后会对tests
做些什么。
(define-syntax make-tests
(syntax-rules (->)
[(_ function (args ... -> result) ...)
(let
((test (list function (list (list args ...) ...) (list result ...))))
(set! all-tests (cons test all-tests)))]))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.