rebol - R3 如何使用脚本头的 Needs 字段?对命名空间有什么影响吗?

标签 rebol rebol3

我想知道 R3 在处理脚本头的 Needs 字段时的行为,以及它对单词绑定(bind)有什么影响。

背景。我目前正在尝试将一些 R2 脚本移植到 R3 以学习 R3。在 R2 中,脚本 header 的 Needs 字段本质上只是文档,尽管我将它与自定义函数一起使用来引用使我的脚本运行所需的脚本。

R3 似乎调用了 Needs 引用的脚本本身,但绑定(bind)似乎与执行其他脚本不同。

例如当 %test-parent.r 是:

REBOL [
    title: {test parent}
    needs: [%test-child.r]
]

parent: now
?? parent
?? child

%test-child 是:

REBOL [
    title: {test child}
]

child: now
?? child

R3 Alpha(Saphiron build 22-Feb-2013/11:09:25)返回:

>> do %test-parent.r
Script: "test parent" Version: none Date: none
child: 9-May-2013/22:51:52+10:00
parent: 9-May-2013/22:51:52+10:00
** Script error: child has no value
** Where: get ajoin case ?? catch either either -apply- do
** Near: get :name

我不明白为什么 test-parent 不能访问 %test-child.r 设置的 Child

如果我从 test-parent.r header 中删除 Needs 字段,而是向 DO %test-child.r 中插入一行,那么就不会出现错误,并且脚本会按预期执行。

最佳答案

啊,您遇到了 Rebol 3 的政策“照您说的去做,它无法读懂您的想法”。 R3 的 Needs header 是其模块系统的一部分,因此您使用 Needs 加载的任何内容实际上都是作为模块导入的,即使它没有这样声明也是如此。

使用Needs 加载脚本是一种将它们视为模块的快速方法,即使原作者没有这样声明它们。模块在定义它们的词的地方有自己的上下文。将脚本作为模块加载是使用不太整洁的脚本的好方法,它会将单词泄漏到共享脚本上下文中。就像您的 %test-child.r 脚本一样,它将单词 child 泄漏到脚本上下文中,如果您不希望这种情况发生怎么办?使用 Needsimport 加载它,这将立即清理它。

如果您希望将脚本视为脚本,请使用do 来运行它。常规脚本使用(大部分)共享上下文,因此当您执行 脚本时,它会在与您调用它的脚本相同的上下文中产生影响。这就是 child: now 语句影响父脚本中的 child 的原因。有时这就是您想要做的,这就是为什么我们如此努力地使脚本在 R3 中以这种方式工作。

如果您打算使用Needsimport 加载您自己的脚本,您不妨将它们制成模块并导出您想要的内容,如下所示:

REBOL [
    type: module
    title: {test child}
    exports: [child]
]

child: now
?? child

和以前一样,如果您要使用 Needsimport,您甚至不必包含 type: module ,但如果您使用 do 运行您的模块,它会有所帮助。 R3 假定如果您将模块声明为模块,那么您将其编写为模块并依赖于它以这种方式工作,即使它是通过 do 调用的。至少,声明一个 type header 比根本不声明一个 type header 更强大,所以它在冲突的“do what you say”情况下优先。

在这里查看有关模块系统如何工作的更多详细信息:How are words bound within a Rebol module?

关于rebol - R3 如何使用脚本头的 Needs 字段?对命名空间有什么影响吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16462904/

相关文章:

rebol - 使用代码块中隐含的对象字段

rebol - 当可能有嵌入 block 时如何使用load/next/error?

event-handling - 我应该使用事件处理程序还是 Actor 来为游戏添加键盘控件

rebol3 - 是否可以在 Rebol 中通过引用传递参数?

console - 如何清除 Rebol 控制台?

rebol - REBOL 对象的类型声明

dll - 从 rebol 调用时从 dll 函数返回的指针

url-routing - Rebol 3 方案中的用户/密码

rebol - 使用 Rebol 将二进制数据打印到 stdout

rebol - 捕获所有 Rebol VID 错误的有趣方法