条件要求并定义调试

时间:2015-11-29 12:46:56

标签: racket

我想在我的代码中打开和关闭调试,所以我试图在我的模块顶部做这样的事情......

(define DEBUGGING #f)
(if DEBUGGING
    (require unstable/debug)
    (define (debug x) void))

但是我不能在条件内requiredefine。我已经快速查看了dynamic-require,但无法弄清楚如何解决问题。

4 个答案:

答案 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 debugrequire 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")))