Hi Fantam

You wrote:
> What a wonderful explanation. Thank you for the insight, Larry.
>
You are welcome!  I realized after my post that there is another important
point about 'bind and contexts which I failed to mention.

I showed you how to bind the words in the code block to the local variable
'member

>> block: ["a" "b" "c"]
>> code: [print member]
>> foreach member block [do bind code 'member]
a
b            ;member in code bound to local var member
c

What I failed to mention is that the use of bind is permanent (until some
other 'bind occurs) so that the after the foreach loop the global block
referenced by 'code remains bound to the local context of foreach.

>> get second code
== "c"

This is a side effect of using 'bind as above, and may not be the desired
effect. It can also lead to a crash when accessing the value of the code
block if there has been a 'recycle or garbage collection which destroys the
local context of the 'foreach function.  The easy way to leave the original
code block unchanged is to copy before the bind.

>> code: [print member]
>> get second code
** Script Error: member has no value.
** Where: get second code

So 'member is bound to the global context but has no value.

>> foreach member block [do bind copy code 'member]
a
b        ;member in COPY of code bound to local var 'member
c
>> get second code
** Script Error: member has no value.
** Where: get second code

The global code block remains unchanged.

In general, it is probably better, when possible, to define code blocks in
the context in which they will be used, as there are further complications
with nested sub-blocks as well as in figuring out how to do the necessary
binding when the functions, function calls, and code blocks are complex. In
addition, when modules are added to REBOL some of our current code relying
on bind may be broken.

Cheers
-Larry


Reply via email to