2

假设我有这样的情况:

;; 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"
    ]
]

这是正确的成语,还是有更好的方法?在某些情况下,这可能无法满足我的期望吗?

4

2 回答 2

2

这是一种很好的风格,尤其是第二种风格,它更灵活,因为它可以让您对外部打印的所有用途进行大规模效果,而不会产生任何歧义。使用直接绑定时,可能会重新定义外部打印一词,或者两次调用之间的上下文发生变化,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在任何和所有上下文中都没有直接的词绑定,你仍然可以直接引用你体内的原始函数。

缺点:

它是一种非常静态的编码方式,并且不是很“Rebolish”。

于 2013-05-28T14:43:05.207 回答
2

;; Capture current context into something called outer

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

outer: self

代码无法按预期工作。例如,假设您要访问两个变量,'print 和 'set。单词可能具有不同的“外部”上下文。在这种情况下,这个技巧肯定不会对至少一个单词起作用,但实际上它可能对两个单词都不起作用。

于 2013-05-29T00:26:35.557 回答