动态要求一个相对于 Racket 中当前模块路径的模块(或者如何在 Racket 中找到当前模块路径)

Lei*_*sen 5 module racket

如果我想在运行时选择性地需要一个模块,我可以使用 [ dynamic-require' 1。如果我想需要已安装的软件包,这非常有用,例如:

(dynamic-require 'racket/match 'match)
Run Code Online (Sandbox Code Playgroud)

这将(假设我已经racket/match安装)要求racket/match并评估match该库中的绑定。

但是,当我想要需要本地未安装的模块时,我遇到了麻烦。假设我有一个名为 的模块eat.rkt,它提供一个功能bite::

#lang racket ;; eat.rkt
(provide bite)
(define (bite) "Nom nom")
Run Code Online (Sandbox Code Playgroud)

现在假设我们想要创建一个lunch.rkt需要eat.rkt并调用该函数的模块。此外,假设我将它们放在同一目录中:

#lang racket ;; lunch.rkt
(require "eat.rkt")
(bite) ; => Nom Nom
Run Code Online (Sandbox Code Playgroud)

这很好,因为我使用了 static require,但是当我想做一个dynamic-require

#lang racket ;; lunch2.rkt
(define bite (dynamic-require "eat.rkt" 'bite)
(bite) ; => Nom Nom
Run Code Online (Sandbox Code Playgroud)

虽然这看起来没问题,但事实证明,所需的模块dynamic-require不是基于模块的路径所必需的,而是基于current-directory. 因此,如果我在定义模块的目录中运行程序,那很好,但如果我在另一个目录中,一切都会中断:

$ racket lunch2.rkt
"Nom Nom"
$ cd snacks/
$ racket ../lunch2.rkt
; default-load-handler: cannot open module file
Run Code Online (Sandbox Code Playgroud)

current-directory显然,如果我知道该模块的目录在哪里,我可以将其更改为该目录。但是如果我不知道这个模块的路径,有什么办法可以得到它吗?dynamic-require或者,更直接地说,模块是否可以相对于需求的模块路径?

小智 5

define-runtime-path表单定义了一个在运行时可用的路径,并且独立于current-directory. 使用它来定义您想要动态需要的模块的路径,例如:

#lang racket
(require racket/runtime-path)
(define-runtime-path eat "eat.rkt")
(dynamic-require eat 'bite)
Run Code Online (Sandbox Code Playgroud)