How to capture words related in an external context when creating a new context?

Let's say I have this situation:

;; 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 that I want from an external 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 to do this? Are there circumstances where this may not give me what I expect?

+2
source share
2 answers

this is a good style, especially the second one, which is more flexible, because it allows you to massively use all kinds of uses of external printing without any ambiguity. when using direct binding, an override of the word external-print or a change of context between two calls to make foo [] can occur and, at the end, points to two different bindings.

static character resolution

For completeness, there is a third option that does not require additional words for customization. I don't have the right name for it, feel free to suggest a better title.

This method ignores any string binding problems because you directly use the value function:

 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 for the interesting part: if you SOURCE internal print function:

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

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

This, in fact, is perhaps the closest to what we can get in some form of compilation in pure REBOL. instead of constantly using symbols for extraction and evaluation, we can simply statically resolve them manually using the abbreviation or layout, as in the above.

pros:

It can never be hacked with any advanced and malicious binding code, i.e. even if there are no direct restrictions on PRINT words in ANY and ALL contexts, you still have a direct link to the original function in your body.

minuses:

This is a very static way of coding and not very "Rebolish".

+2
source

 ;; Capture current context into something called outer 

a comment suggests that you think there is some "current context" in Rebol. This is not true. Each word has its own context. So, there are times when your

 outer: self 

The code does not work as you expect. For example, suppose you want to access two variables, 'print and' set. It is possible that words have different "external" contexts. In this case, the trick will certainly not work for at least one of the words, but it may, in fact, not work for both.

+2
source

All Articles