[REBOL] Re: Passing word in a block as an argument
From: joel:neely:fedex at: 9-Feb-2003 23:04
Hi, Tim,
In a nutshell, the difference is that FOREACH creates a new context
for its word (or block of words) argument. Consider this:
>> i: "nobody home"
== "nobody home"
>> foreach i [0 2 4 6 8] [print i]
0
2
4
6
8
>> print i
nobody home
The I that is used inside the FOREACH isn't the same I as was set
and printed outside that expression. Now see below:
Tim Johnson wrote:
> ... I can use forskip with the desired result, as in:
>
> forskip blk length? cols[
> set cols blk
> ?? a ?? b ?? c ?? d
> test cols
> ]
> ; so why is there a difference?
>
Here the body of the loop uses SET to set the words, therefore
making them global, and therefore accessible to TEST, which is
trying to get a global word via 'A . To see this in more detail,
we can change your original code to contain one extra line, as
follows:
>> a: b: c: d: "Global!"
== "Global!"
>> test: func[e[block!]][
[ ?? e
[ print get 'a
[ ]
>> blk: [1 2 3 4 5 6 7 8 9 10 11 12]
== [1 2 3 4 5 6 7 8 9 10 11 12]
>> cols: [a b c d]
== [a b c d]
>> foreach :cols blk[
[ ?? a ?? b ?? c ?? d
[ test cols
[ ]
a: 1
b: 2
c: 3
d: 4
e: [a b c d]
Global!
a: 5
b: 6
c: 7
d: 8
e: [a b c d]
Global!
a: 9
b: 10
c: 11
d: 12
e: [a b c d]
Global!
This shows (clearly, I hope!) that the A B C and D *inside* the
FOREACH loop aren't the same as any global variables that exist
already (and TEST is trying to see a global A as mentioned above).
-jn-