如何在创建新上下文时捕获在外部上下文中绑定的单词?

时间:2013-05-16 15:50:36

标签: rebol

让我们说我有这样的情况:

;; Capture whatever the print word pointed to into a variable
outer-print: :print

foo: context [
    ;; within foo, override print and implement in terms of outer-print
    print: func [value] [
        outer-print "About to print"
        outer-print value
        outer-print "Done printing"
    ]
]

我可以这样做,或者如果我从外部上下文中有多个我想要的东西,我可以明确地捕获它:

;; Capture current context into something called outer
outer: self

foo: context [
    ;; within foo, override print and implement in terms of outer/print
    print: func [value] [
        outer/print "About to print"
        outer/print value
        outer/print "Done printing"
    ]
]

这是正确的习惯用法,还是有更好的方法?是否有这种情况可能无法满足我的期望?

2 个答案:

答案 0 :(得分:2)

这是一种很好的风格,特别是第二种,它更灵活,因为它允许你大规模地影响外部印花的所有用途,没有任何歧义。当使用直接绑定时,可能会出现重新定义单词outer-print或两次调用make foo []之间的上下文变化,最后指向两个不同的绑定。

静态符号解析

为了完整起见,还有第三种选择,不需要设置任何额外的单词。我没有正确的命名,请随意提出更好的标题。

由于您直接使用 功能,此方法可以解决任何绑定问题:

foo: context compose/deep [
    ;; within foo, override print and implement using native print directly
    print: func [value] [
        (:print) "About to print"
        (:print) value
        (:print) "Done printing"
    ]
]

现在有趣的部分是你SOURCE内部打印功能:

>> p: get in foo 'print   
>> SOURCE P
== p: func [value][native "About to print" native value native "Done printing"]

了解如何直接在正文中使用print的native ,而不是引用它的单词。

事实上,这可能是我们在纯REBOL中获得某种形式的编译的最接近的。而不是经常使用符号来获取和评估,我们可以简单地手动静态解析它们,使用如上所述的reduce或compose。

优点:

它永远不会被一些高级和恶意绑定代码所淹没,即即使在任何和所有上下文中都没有PRINT的直接单词边界,你仍然可以直接引用原始函数。你的身体。

缺点:

它是一种非常静态的编码方式,并不是非常“重生”。

答案 1 :(得分:2)

;; Capture current context into something called outer

评论表明您认为Rebol中存在一些“当前背景”。那是错误的。每个词都有自己的背景。因此,有些情况下你的

outer: self

代码无法正常工作。例如,假设您要访问两个变量'print和'set。单词可能具有不同的“外部”上下文。在这种情况下,诀窍肯定不适用于至少一个单词,但事实上,它可能对两者都不起作用。