需要 Racket 中模块未提供的标识符
Require identifiers not provided by a module in Racket
假设我有一些文件 a.rkt
:
#lang racket
(define a 12)
我现在想写一些测试用例,使用需要 a.rkt
:
的文件 b.rkt
#lang racket
(require "a.rkt")
a
有什么方法可以让我 b.rkt
识别 a.rkt
中定义的标识符,而不必从第一个文件中 provide
它? (理想情况下根本不必更改第一个文件。)
我在 the documentation for require/provide 中没有立即看到任何内容。
您可以在 b.rkt
中使用 require/expose
来访问 a.rkt
中的绑定。 b.rkt
看起来像这样:
#lang racket
(require rackunit)
(require/expose "a.rkt" (a))
a
正如 Leif 所提到的,RackUnit 的 require/expose
将 允许在其他模块中使用未提供的标识符,但 its own documentation 不保证非常有力的保证:
Note that require/expose
can be a bit fragile, especially when mixed with compiled code. Use at your own risk!
另一种方法是使用 submodules,它可以有效地提供一种认可的方式来导出私有 API 以用于测试或其他方式。
例如,假设一个模块实现了一个函数来测试字符串是否包含单个单词:
#lang racket
(provide word?)
(define (word? str)
(not (ormap space? (string->list str))))
(define (space? c)
(eq? c #\space))
(这也许不是最现实的例子,但请耐心等待。)
测试 space?
函数以确保其正常工作可能很有用,但它可能不应该是 public 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))
这是一种更安全的方法,可以在不将标识符暴露给所有消费者的情况下从模块中暴露标识符。
假设我有一些文件 a.rkt
:
#lang racket
(define a 12)
我现在想写一些测试用例,使用需要 a.rkt
:
b.rkt
#lang racket
(require "a.rkt")
a
有什么方法可以让我 b.rkt
识别 a.rkt
中定义的标识符,而不必从第一个文件中 provide
它? (理想情况下根本不必更改第一个文件。)
我在 the documentation for require/provide 中没有立即看到任何内容。
您可以在 b.rkt
中使用 require/expose
来访问 a.rkt
中的绑定。 b.rkt
看起来像这样:
#lang racket
(require rackunit)
(require/expose "a.rkt" (a))
a
正如 Leif 所提到的,RackUnit 的 require/expose
将 允许在其他模块中使用未提供的标识符,但 its own documentation 不保证非常有力的保证:
Note that
require/expose
can be a bit fragile, especially when mixed with compiled code. Use at your own risk!
另一种方法是使用 submodules,它可以有效地提供一种认可的方式来导出私有 API 以用于测试或其他方式。
例如,假设一个模块实现了一个函数来测试字符串是否包含单个单词:
#lang racket
(provide word?)
(define (word? str)
(not (ormap space? (string->list str))))
(define (space? c)
(eq? c #\space))
(这也许不是最现实的例子,但请耐心等待。)
测试 space?
函数以确保其正常工作可能很有用,但它可能不应该是 public 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))
这是一种更安全的方法,可以在不将标识符暴露给所有消费者的情况下从模块中暴露标识符。