Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

Passing word in a block as an argument

 [1/7] from: tim:johnsons-web at: 9-Feb-2003 17:53


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? TIA -- Tim Johnson <[tim--johnsons-web--com]> http://www.alaska-internet-solutions.com http://www.johnsons-web.com

 [2/7] from: tim:johnsons-web at: 9-Feb-2003 18:35


* Tim Johnson <[tim--johnsons-web--com]> [030209 18:23]:
> Hello Rebols: > I'd like to be able to initialize a block of words,
<<quoted lines omitted: 25>>
> ** 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? -- Tim Johnson <[tim--johnsons-web--com]> http://www.alaska-internet-solutions.com http://www.johnsons-web.com

 [3/7] from: al:bri:xtra at: 10-Feb-2003 17:26


Tim wrote:
> So: how do I get the values of a,b,c and d? >> 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]
>> map blk func cols [print [a b c d]]
1 2 3 4 5 6 7 8 9 10 11 12 Use 'map. :) Andrew Martin ICQ: 26227169 http://valley.150m.com/

 [4/7] from: greggirwin:mindspring at: 9-Feb-2003 21:55


Hi Tim, TJ> I'd like to be able to initialize a block of words, TJ> pass that block to a function and then get the values TJ> in the words by referencing the names of the words. The words are bound to the context of the FOREACH block so your other code can't see them. If you just declare them at the top of your script, so they're global, it will prevent the error. E.g. a: b: c: d: none But it still isn't looking at the values for the words as bound to the FOREACH loop. If you define your function inside your loop, it will work, but that's probably not what you want to do. :) E.g. blk: [1 2 3 4 5 6 7 8 9 10 11 12] cols: [a b c d] foreach :cols blk [ test: func [e[block!]] [ ?? e print get 'a ] ?? a ?? b ?? c ?? d test bind cols 'self ] Beyond that, my poor tired brain isn't aware of a simple solution for binding to the loop context. I'm sure someone else will chime in and show us both how easy it is. :) -- Gregg

 [5/7] 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[
<<quoted lines omitted: 3>>
> ] > ; 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-

 [6/7] 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:
<<quoted lines omitted: 37>>
> ] > ; 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

 [7/7] from: al:bri:xtra at: 10-Feb-2003 19:49


Tim wrote:
> So: how do I get the values of a,b,c and d?
I get a sense of Deja Vu here. I'm sure that we answered this question some months ago? :-/ Andrew Martin ICQ: 26227169 http://valley.150m.com/

Notes
  • Quoted lines have been omitted from some messages.
    View the message alone to see the lines that have been omitted