How to capture words bound in outer context when c

2019-07-23 14:19发布

Let us say I have a situation like this:

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

I can do this, or if I have more than one thing I want from the outer context I could capture it explicitly:

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

Is this the right idiom, or is there a better way of doing it? Are there circumstances where this might not give me what I expect?

标签: rebol
2条回答
啃猪蹄的小仙女
2楼-- · 2019-07-23 14:40

this is good style, especially the second, which is more flexible as it allows you to mass-effect all uses of the outer print, without any ambiguity. when using direct binding, it may occur that the word outer-print is redefined or the context changes between two calls to make foo [] and in the end, points to two different bindings.

static symbol resolving

For the sake of completeness there is a third alternative which doesn't require any extra words to be setup. I don't have a proper naming for it, feel free to suggest a better title.

This method defies any binding issues down the line because you use the function value directly:

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

Now the interesting part is if you SOURCE the inner print function:

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

see how the native value of print is used directly in the body, instead of a word referring to it.

This is, in fact, probably the closest we can get to some form of compilation in pure REBOL. instead of constantly using symbols to fetch and evaluate, we can simply statically resolve them manually, using reduce or compose as in the above.

pros:

It can never be hi-jacked by some advanced and malicious binding code, i.e. even if there are no direct word bounds to PRINT in ANY and ALL contexts, you still have a direct reference to the original function in your body.

cons:

Its a very static way to code, and isn't very "Rebolish".

查看更多
仙女界的扛把子
3楼-- · 2019-07-23 15:00

The

;; Capture current context into something called outer

comment suggests that you think there is some "current context" in Rebol. That is false. Every word has got its own context. Thus, there are cases when your

outer: self

code doesn't work as you expect. For example, let's suppose that you want to access two variables, 'print and 'set. It is possible for the words to have different "outer" contexts. In that case the trick will be certain to not work for at least one of the words, but it may, in fact, not work for both.

查看更多
登录 后发表回答