要求标识不是由Racket中的模块提供的

时间:2015-12-06 20:44:23

标签: scheme racket

假设我有一些文件as.matrix(dist(x))

a.rkt

我现在想要使用需要#lang racket (define a 12) 的文件b.rkt编写一些测试用例:

a.rkt

有没有办法让#lang racket (require "a.rkt") a 能够识别b.rkt中定义的标识符,而不必从第一个文件中a.rkt来识别它? (理想情况下,根本不需要更改第一个文件。)

我在the documentation for require/provide中没有立即看到任何内容。

2 个答案:

答案 0 :(得分:6)

正如Leif所提到的,RackUnit的require/expose 允许在其他模块中使用未提供的标识符,但wrapFunction并未承诺提供非常有力的保证:

  

请注意,require/expose可能有点脆弱,尤其是在与编译代码混合时。使用风险自负!

另一种方法是使用its own documentation,它可以有效地提供一种制裁方式来导出私有API,以便在测试或其他方式中使用。

例如,考虑一个实现函数的模块来测试字符串是否包含单个单词:

#lang racket

(provide word?)

(define (word? str)
  (not (ormap space? (string->list str))))

(define (space? c)
  (eq? c #\space))

(也许这不是最现实的例子,但请耐心等待。)

测试space?函数以确保其有效可能很有用,但它可能不应该是公共API的一部分。要创建一个" escape hatch",可以定义一个导出此绑定的子模块:

(module+ for-testing
  (provide space?))

名称for-testing是任意的 - 它可以是任何东西。无论哪种方式,现在可以要求另一个模块中的子模块访问私有绑定:

#lang racket

(require rackunit
         (submod "a.rkt" for-testing))

(check-true (space? #\space))
(check-false (space? #\a))

这是从模块公开标识符而不将其暴露给所有消费者的更安全的方式。

答案 1 :(得分:5)

您可以使用b.rkt中的require/expose来访问a.rkt中的绑定。 b.rkt看起来像这样:

#lang racket
(require rackunit)
(require/expose "a.rkt" (a))
a