[REBOL] Re: Passing word in a block as an argument
From: carl::cybercraft::co::nz at: 10-Feb-2003 19:26
On 10-Feb-03, Tim Johnson wrote:
> * Tim Johnson <[tim--johnsons-web--com]> [030209 18:23]:
>> Hello Rebols:
>> I'd like to be able to initialize a block of words,
>> pass that block to a function and then get the values
>> in the words by referencing the names of the words.
>>
>> Here's an example of what I'm trying to do, just doesn't
>> work: :-(
>> rebol[]
>> test: func[e[block!]][
>> ?? e
>> print get 'a
>> ]
>> blk: [1 2 3 4 5 6 7 8 9 10 11 12]
>> cols: [a b c d]
>> foreach :cols blk[
>> ?? a ?? b ?? c ?? d
>> test cols
>> ]
>> ; and here's the <sigh>results</sigh>:
>>>> do %test.r
>> Script: "Untitled" (none)
>> a: 1
>> b: 2
>> c: 3
>> d: 4
>> e: [a b c d]
>> ** Script Error: a has no value
>> ** Where: test
>> ** Near: print get 'a
>>
>> So: how do I get the values of a,b,c and d?
> I'm sort of answering my own question here,
> but it raises another. 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?
It's a binding, context problem. foreach words are local to the
foreach block, so your test function doesn't know about them when
it's called. With your fix above though, you're making a, b, c & d
global words, so test does know of them.
I don't know the correct solution to get the foreach approach to work,
but it'll use bind I assume...
>> ? bind
USAGE:
BIND words known-word /copy
DESCRIPTION:
Binds words to a specified context.
BIND is a native value.
ARGUMENTS:
words -- A block of words or single word. (Type: block word)
known-word -- A sample word from the target context. (Type: word)
REFINEMENTS:
/copy -- Deep copies block before binding it.
Online docs and examples here...
http://www.rebol.com/docs/words/wbind.html
Despite having success with bind occasionally, I've never really got
the hang of it, so I'll leave others to attempt a proper
explanation. Their solution may look something like this...
foreach :cols blk[
?? a ?? b ?? c ?? d
bind something something
test cols
]
or it may not... ;-)
Hopefully this puts you on the right track, anyway.
--
Carl Read