3

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

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

R3 似乎调用了需要引用的脚本本身,但绑定似乎与执行其他脚本不同。

例如,当 %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 标头中删除 Needs 字段,而是在 DO %test-child.r 中插入一行,则没有错误,并且脚本按预期执行。

4

1 回答 1

2

啊,您遇到了 Rebol 3 的“言出必行”的政策。R3 的Needs标头是其模块系统的一部分,因此您加载的任何内容Needs实际上都是作为模块导入的,即使它没有被声明为这样。

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

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

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

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

child: now
?? child

和以前一样,您甚至不必包含type: module如果您将要使用Needsimport无论如何,但它会有所帮助,以防您使用do. R3 假设如果您将模块声明为模块,那么您将其编写为模块并依赖于它以这种方式工作,即使它被调用do。至少,声明一个type标题是一个比根本不声明标题更强的声明type,所以它在冲突的“按你说的做”的情况下具有优先权。

在此处查看有关模块系统如何工作的更多详细信息:Rebol 模块中的单词是如何绑定的?

于 2013-05-09T15:56:43.590 回答