Racket:eval、namespace-attach-module 与 namespace-require
Racket: eval, namespace-attach-module vs. namespace-require
假设我有一个模块 "foo.rkt" 导出一个结构 foo,例如
#lang racket (provide foo) (struct foo ())
在另一个模块中,我使用 "foo.rkt" 但我也想将 "struct foo" 的绑定关联到另一个名称空间(出于各种原因我不使用预制件,所以我可以' t 使用命名空间要求)。
我认为我可以按如下方式使用命名空间附加模块:
(define ns (make-base-namespace))
(namespace-attach-module (current-namespace) "foo.rkt" ns)
(eval '(foo) ns)
但这不起作用,因为命名空间映射符号显示 s 未绑定在 ns 中(如果这是查找绑定的唯一位置)。但是它在 REPL 中确实有效。为什么?
我假设问题是避免在 "foo.rkt" 中实例化模块两次,因为这会导致两个不兼容的结构定义。
函数namespace-attach-module
是拼图的一部分,但它只附加
命名空间 ns 的实例化模块 - 即名称 "foo.rkt" 现在与 "foo.rkt" 的正确实例相关联。然而,它并没有使绑定在 ns 中可用——这是 namespace-require
.
的工作
这是一个例子:
文件:"computer.rkt"
#lang racket
(provide (struct-out computer))
(struct computer (name price) #:transparent)
文件:"use-computer.rkt"
#lang racket
(require "computer.rkt") ; instatiate "computer.rkt"
(define ns (make-base-namespace))
(namespace-attach-module (current-namespace) "computer.rkt" ns) ; ns now knows the same instance
(define a-computer
(parameterize ([current-namespace ns])
(namespace-require "computer.rkt")
(eval '(computer "Apple" 2000) ns)))
(computer-name a-computer) ; works, since ns used the same instantiation of "computer.rkt"
运行的结果是:
"Apple"
请注意,删除 namespace-attach-module
行会导致错误:
computer-name: contract violation;
given value instantiates a different structure type with the same name
expected: computer?
given: (computer "Apple" 2000)
由于没有附件,namespace-require
将再次实例化 "computer.rkt",导致开始声明两个不兼容的结构。
假设我有一个模块 "foo.rkt" 导出一个结构 foo,例如
#lang racket (provide foo) (struct foo ())
在另一个模块中,我使用 "foo.rkt" 但我也想将 "struct foo" 的绑定关联到另一个名称空间(出于各种原因我不使用预制件,所以我可以' t 使用命名空间要求)。
我认为我可以按如下方式使用命名空间附加模块:
(define ns (make-base-namespace))
(namespace-attach-module (current-namespace) "foo.rkt" ns)
(eval '(foo) ns)
但这不起作用,因为命名空间映射符号显示 s 未绑定在 ns 中(如果这是查找绑定的唯一位置)。但是它在 REPL 中确实有效。为什么?
我假设问题是避免在 "foo.rkt" 中实例化模块两次,因为这会导致两个不兼容的结构定义。
函数namespace-attach-module
是拼图的一部分,但它只附加
命名空间 ns 的实例化模块 - 即名称 "foo.rkt" 现在与 "foo.rkt" 的正确实例相关联。然而,它并没有使绑定在 ns 中可用——这是 namespace-require
.
这是一个例子:
文件:"computer.rkt"
#lang racket
(provide (struct-out computer))
(struct computer (name price) #:transparent)
文件:"use-computer.rkt"
#lang racket
(require "computer.rkt") ; instatiate "computer.rkt"
(define ns (make-base-namespace))
(namespace-attach-module (current-namespace) "computer.rkt" ns) ; ns now knows the same instance
(define a-computer
(parameterize ([current-namespace ns])
(namespace-require "computer.rkt")
(eval '(computer "Apple" 2000) ns)))
(computer-name a-computer) ; works, since ns used the same instantiation of "computer.rkt"
运行的结果是:
"Apple"
请注意,删除 namespace-attach-module
行会导致错误:
computer-name: contract violation;
given value instantiates a different structure type with the same name
expected: computer?
given: (computer "Apple" 2000)
由于没有附件,namespace-require
将再次实例化 "computer.rkt",导致开始声明两个不兼容的结构。