如果我想在运行时可选地要求一个模块,我可以使用 [
现在假设我们想要创建一个名为
dynamic-require
'1。如果我想要引用已安装的包,这种方法非常有效:(dynamic-require 'racket/match 'match)
如果我已经安装了 racket/match
,那么这将需要它并且会评估该库中的 match
绑定。
然而,当我想要引用一个本地未安装的模块时,就会遇到问题。假设我有一个名为 eat.rkt
的模块,它提供了一个函数:bite
:
#lang racket ;; eat.rkt
(provide bite)
(define (bite) "Nom nom")
现在假设我们想要创建一个名为
lunch.rkt
的模块,该模块需要eat.rkt
并调用该函数。此外,假设它们位于同一目录中:#lang racket ;; lunch.rkt
(require "eat.rkt")
(bite) ; => Nom Nom
因为我使用了静态的 require
,所以这很好,但是当我想要进行动态 require
时,这就会出问题:
#lang racket ;; lunch2.rkt
(define bite (dynamic-require "eat.rkt" 'bite)
(bite) ; => Nom Nom
虽然这看起来没问题,但事实证明,dynamic-require
所需的模块并不是基于模块路径要求的,而是根据current-directory
。因此,如果我在定义该模块的目录中运行程序,则可以正常运行,但如果我在另一个目录中则会出现问题:
$ racket lunch2.rkt
"Nom Nom"
$ cd snacks/
$ racket ../lunch2.rkt
; default-load-handler: cannot open module file
显然,如果我知道这个模块的路径,我可以简单地将current-directory
更改为此模块的目录。但是,如果我不知道这个模块的路径,有没有办法获取它?或者更直接地说,是否可能相对于要求的模块路径dynamic-require
一个模块?
define-runtime-module-path-index
,(如果我没记错的话)它也与raco distribute
和其它相关。 - Ryan Culpepperdefine-runtime-module-path-index
非常好用。 也许是在这个问题之后添加的? - soegaard