Scheme 需要球拍中模块未提供的标识符

Scheme 需要球拍中模块未提供的标识符,scheme,racket,Scheme,Racket,假设我有一些文件a.rkt: #lang racket (define a 12) #lang racket (require "a.rkt") a 现在我想使用需要a.rkt的文件b.rkt编写一些测试用例: #lang racket (define a 12) #lang racket (require "a.rkt") a 是否有任何方法可以让b.rkt识别a.rkt中定义的标识符,而不必从第一个文件中提供它?(理想情况下,无需更改第一个文件。) 我没有立即在中看到任何内容。您可以

假设我有一些文件
a.rkt

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

#lang racket
(define a 12)
#lang racket
(require "a.rkt")
a
是否有任何方法可以让
b.rkt
识别
a.rkt
中定义的标识符,而不必从第一个文件中提供它?(理想情况下,无需更改第一个文件。)

我没有立即在中看到任何内容。

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

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

正如Leif所提到的,RackUnit的
require/expose
将允许在其他模块中使用未提供的标识符,但不保证有很强的保证:

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

另一种方法是使用,它可以有效地提供一种被认可的方式,导出一个私有API用于测试或其他手段

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

#lang racket

(provide word?)

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

(define (space? c)
  (eq? c #\space))
(这也许不是最现实的例子,但请容忍我。)

测试
space?
函数以确保其工作可能很有用,但它可能不应该是公共API的一部分。要创建“转义图案填充”,可以定义导出此绑定的子模块:

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

#lang racket

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

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

这是一种更安全的方式,可以从模块中公开标识符,而不必向所有消费者公开它们。

这是一个自我回答问题的好主意,但您可能希望在问题中添加更多动机。也就是说,澄清这是为了测试,而不是你通常想要做的事情。这是一个好主意,我会改变它。有时,改变原始来源以添加额外的
提供
s是不可行的,例如,不遵守指示的学生。Dan Feltey的测试框架以以下方式使用
require/expose
(和friends):。(与您的答案不矛盾,只描述另一个用例上下文。)