如果我想在运行时选择性地需要一个模块,我可以使用 [ 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)