Search code examples
bindrebolscopingrebol2

How to bind local context block to global context in Rebol2?


As I understand it, you are supposed to be able to bind any block to any context. In particular you can bind a global context block to a local context:

>> a: context [
    print: does [rebol/words/print "yeah!"]
    f: func[b] [do bind b 'print]
]

>> a/f [print "hello"]
yeah!
== "hello"

So it must be possible to bind a local context block to the global context too? But my attempts were unsuccessful:

>> b: context [
    b: [print "hello"]
    print: does [rebol/words/print "yeah!"]
    f: func[] [do bind b 'system]
]

>> b/b
== [print "hello"]

>> do b/b
yeah!
== "hello"

>> b/f
hello

>> do b/b
hello

It seems I made it but:

>> equal? bind? 'system bind? in b 'b
== false

>> same? bind? in b 'f bind? in b 'b
== true

What is my error here?


Solution

  • You are binding the words in the block assigned to b/b, you aren't binding the word b itself.

    >> equal? bind? 'system bind? in b 'b
    == false
    

    This compares two objects, the first is the one that 'system is bound to, and the second is the one that in b 'b is bound to (the top-level b object).

    The thing is that blocks aren't really bound, the words in the block are bound. The blocks themselves don't have any bindings, not even as a concept. Also, the block that is assigned to b/b is just a value that happens to be assigned to b/b, it's not the word 'b.

    This comparison should work:

    >> equal? bind? 'system bind? first get in b 'b
    == true
    

    What you are comparing with this is the binding of the first word in the block assigned to b/b, which is that print that you bound earlier. That word is what you changed the binding of in b/f.