我想在我的代码中打开和关闭调试,所以我试图在我的模块顶部做这样的事情......
(define DEBUGGING #f)
(if DEBUGGING
(require unstable/debug)
(define (debug x) void))
但是我不能在条件内require
或define
。我已经快速查看了dynamic-require
,但无法弄清楚如何解决问题。
答案 0 :(得分:3)
首先将DEBUGGING
定义为在扩展时使用的变量,而非运行时间:
(define-for-syntax DEBUGGING #f)
然后创建一个宏,如
(define-syntax (if-debug stx)
(let ((dat (syntax->datum stx)))
(if DEBUGGING
(datum->syntax stx (cadr dat))
(datum->syntax stx (caddr dat)))))
最后用作
(if-debug
(require unstable/debug)
(define (debug x) void))
答案 1 :(得分:2)
uselpa的回答有正确的想法。这是使用syntax-case
的相同构思的替代实现,它是(IMHO)更易读的,具有稍好的错误检查(例如,如果传递了无关的子表单):
(define-syntax (if-debug stx)
(syntax-case stx ()
((_ debug-expr non-debug-expr)
(if DEBUGGING
#'debug-expr
#'non-debug-expr))))
答案 2 :(得分:0)
我喜欢uselpa的答案,特别是克里斯'细化。我自己也用过这种方法。但老实说:这些天我会做的只是提供两种表达方式,并取消我当时想要的替代方案:
;; (require unstable/debug)
(define (debug x) (void))
或:
(require unstable/debug)
;; (define (debug x) (void))
不可否认,这个"宏通过评论"不是运行时选择 - 但宏观答案都不是。
虽然技术含量低,但它的优势在于只有两行清晰明显的代码。
如果它被复制到多个源文件中,我特别喜欢这个。
我可能更喜欢这个,即使它被provide
s debug
和require
d文件放在一个文件中。
答案 3 :(得分:0)
谢谢大家,我在一个简单的脚本中成功地使用了这些答案,并希望分享这些内容。您实际上可以使用任何形式而不是布尔DEBUG,实际上不需要更改代码。我不想每次都在多个脚本上更改/注释掉多行,这个解决方案让我可以在drracket上运行并使用repl或从shell运行(通过向命令添加第一个arg):
; @echo off
; "C:\Program Files\Racket\racket.exe" "%~f0" %*
; exit /b
#lang racket
(define-for-syntax args (current-command-line-arguments))
(define-for-syntax PROTOTYPING (or
(= (vector-length args) 0)
(equal? (vector-ref args 0) "local")))
(define-syntax (if-prototyping stx)
(syntax-case stx ()
((_ debug-expr non-debug-expr)
(if PROTOTYPING
#'debug-expr
#'non-debug-expr))))
(if-prototyping
(require (file "C:/file1.rkt"))
(file "C:/util1.rkt""))
(require (file "C:/file2.rkt"))
(file "C:/util2.rkt")))