R3如何使用脚本标题的Needs字段?命名空间有什么影响吗?

时间:2013-05-09 13:25:21

标签: rebol rebol3

我想知道R3在处理脚本标题的Needs字段时的行为以及它对字绑定有什么影响。

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

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

例如,当%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中插入一行,则没有错误,脚本按预期执行。

1 个答案:

答案 0 :(得分:2)

啊,你已经遇到了Rebol 3的政策,按照你说的做,它无法读懂你的想法"。 R3的Needs标头是其模块系统的一部分,因此您使用Needs加载的任何内容实际上都是作为模块导入的,即使它未被声明为此类。

使用Needs加载脚本是将它们视为模块的快速方法,即使在原始作者没有声明它们的情况下也是如此。模块在定义单词时会得到自己的上下文。将脚本作为模块加载是一种很好的方法,可以使用不整齐的脚本,将单词泄漏到共享脚本上下文中。与您的%test-child.r脚本一样,它会将单词child泄漏到脚本上下文中,如果您不希望这种情况发生,该怎么办?加载Needsimport,然后将其清理干净。

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

如果您要使用Needsimport加载自己的脚本,您可以制作模块并导出您想要的内容,如下所示:

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

child: now
?? child

与以前一样,如果您打算使用type: moduleNeeds,您甚至不必包含import,但这样做有助于您使用do运行您的模块。 R3假设如果您将模块声明为模块,则将其编写为模块,即使使用do调用模块也依赖于模块。至少,声明一个type标题是一个比没有声明type标题更强的声明,所以它优先于冲突"做你说的"情况。

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