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

Context misery

 [1/8] from: gjones05::mail::orion::org at: 5-Jun-2001 8:58


From: "Joel Neely" ...
> (Without going into deep and > opaque waters, just remember that > there can be *many* words > whose names are spelled the same!)
... snickering out loud! --Scott Jones

 [2/8] from: ptretter:charter at: 5-Jun-2001 10:27


Not sure I know exactly what you want to do but here is my approach I use for assignment of DCC ports in an irc script I made: REBOL [] myfunc: func ["Creates a dynamic variable and sets to a value in /local temp" string [string!] ; string that will contain the new 'word to be assigned /local value temp ][ value: [1 2 3] temp: make set-word! string mold temp :value ]

 [3/8] from: sanghabum:aol at: 5-Jun-2001 12:33


Thanks Joel and all for the various replies, Maybe I'm thinking more like an Imperial stormtrooper than a Rebol, but the Rebol model for contexts and global/local variables seems neither simple nor straightforward, as several previous threads have suggested.
> Unless it is necessary, evaluating strings is generally not > a good practice. Evaluating strings is less efficient than
<<quoted lines omitted: 4>>
> at best, and a potential source of highly subtle bugs at > worst.
Thanks for TFM ref. I'd completely failed to R that part. Sounds like we've both learnt from experience here.
> Why? If you can describe what you're trying to accomplish > here, perhaps some of the old hands can offer some alternatives > that won't be so tricky to deal with. For example...
Well, the moment, has passed. I coded what I wanted in another way--the code involved builds a data update layout dynamically from a CSV file: first row is the field names, subsequent rows the data, and it was generating global variables from the field names. It seems like a good idea at the time. Thanks again, --Colin.

 [4/8] from: carl:rebol at: 5-Jun-2001 10:02


Ah, but what are you really trying to do? From your example, the variable is not really dynamic (because you use exactly the string you pass in for it.) So, just pass the name as a name. myfunc: func [name] [set name copy [1 2 3]] myfunc 'example print example That will allow 'example to be part of any context, including objects and locals to functions. You can also use the shorthand: myfunc: func ['name] [set name copy [1 2 3]] myfunc example print example And, if you need "code" as part of it: myfunc: func [name code] [set name do code] myfunc 'example [1 + 2] print example You get the idea, -Carl

 [5/8] from: sanghabum:aol at: 5-Jun-2001 7:13


Hi there, Could someone with a better grasp of context than me explain why this won't work?---I think the problem is using a local variable in a DO: myfunc: func [BlockName [string!] /local aa bb][ aa: copy [1 2 3] bb: join BlockName ": copy aa" print ["aa is " mold aa] print ["bb is " mold bb] do bb ] When I run it I get:
>> myfunc "myblock"
aa is [1 2 3] bb is "myblock: copy aa" ** Script Error: aa has no value ** Where: myfunc ** Near: myblock: copy aa
>>
All I'm trying to do is create a variable dunamically based on a name passed to a function. Thanks! Colin.

 [6/8] from: joel:neely:fedex at: 5-Jun-2001 7:38


Hi! [Sanghabum--aol--com] wrote:
> Hi there, > Could someone with a better grasp of context than me explain why this won't
<<quoted lines omitted: 15>>
> ** Near: myblock: copy aa > >>
The REBOL/Core Users' Guide says (page 3-11): Unless it is necessary, evaluating strings is generally not a good practice. Evaluating strings is less efficient than evaluating blocks, and the context of words in a string is not known. I strongly recommend taking that advice to heart! Trying to construct source code strings that DO what you want is tricky at best, and a potential source of highly subtle bugs at worst. That said, when you define BB using the expression bb: join BlockName ": copy aa" and then DO that string, REBOL has no idea that you intend for the two-letter token "aa" in the string to indicate the LOCAL word AA in the current function. (Without going into deep and opaque waters, just remember that there can be *many* words whose names are spelled the same!) To get the value that's in your local variable to be the value stored in the (possibly!) new variable named by the BLOCKNAME parameter, you will need to force evaluation of your local AA and then use that result to construct the string. One possible (and possibly clumsy) way to do this is:
>> myfunc: func [BlockName [string!] /local aa bb] [
[ aa: copy [1 2 3] [ bb: rejoin [BlockName ": copy " mold aa] [ print ["aa is " mold aa] [ print ["bb is " mold bb] [ do bb [ ]
>> myfunc "myblock"
aa is [1 2 3] bb is "myblock: copy [1 2 3]" == [1 2 3]
>> myblock
== [1 2 3]
>>
But *please* remember the old joke: "Doc, it hurts when I do this!" "Well, then don't do that!" ;-)
> All I'm trying to do is create a variable dunamically based > on a name passed to a function. >
Why? If you can describe what you're trying to accomplish here, perhaps some of the old hands can offer some alternatives that won't be so tricky to deal with. For example... You can think of REBOL contexts as being like mini-dictionaries that map strings (the word names) to other values. (Now you see why different contexts can have words with the same name!) If you're trying to keep up with some data and you *really* need to associate values with names you can't know in advance, you could build your own "dictionary" as follows: fw: make object! [ storage: copy [] learn: func [ token [string!] value [any-type!] /local where ][ either none? find storage token [ append storage reduce [token value] ][ change/only storage value ] ] fetch: func [token [string!]] [ select storage token ] ]
>> fw/learn "myblock" copy [1 2 3]
== ["myblock" [1 2 3]]
>> fw/learn "yourblock" copy [4 5 6]
== ["myblock" [1 2 3] "yourblock" [4 5 6]]
>> fw/learn "anyblock" [9 8 7]
== ["myblock" [1 2 3] "yourblock" [4 5 6] "anyblock" [9 8 7]]
>> fw/fetch "myblock"
== [1 2 3] This is just a Q&D sample; an obvious improvement is to have LEARN return the VALUE argument as its result to facilitate embedding in larger expressions. Implementing that, and any other improvements, is left as an exercise to the reader! ;-) Hope this helps! -jn- ------------------------------------------------------------ Programming languages: compact, powerful, simple ... Pick any two! joel'dot'neely'at'fedex'dot'com

 [7/8] from: lmecir:mbox:vol:cz at: 5-Jun-2001 15:02


Hi Colin, try this instead: myfunc: function [ BlockName [word!] ] [aa bb] [ aa: copy [1 2 3] bb: reduce [to set-word! BlockName 'copy 'aa] print ["aa is " mold aa] print ["bb is " mold bb] do bb ] Cheers Ladislav

 [8/8] from: sanghabum:aol at: 5-Jun-2001 18:07


Hi Carl,
> Ah, but what are you really trying to do? > From your example, the variable is not really dynamic
<<quoted lines omitted: 3>>
> myfunc 'example > print example
Well, it's dynamic insofar as I don't know what it is when the program starts. It is read as a string from a file. So (the original intention was) it goes into the function as a string, and comes out as a global variable. So I can use your function like this: myfunc to word! FieldName where Fieldname is the string. And that solves the original problem. Thanks! While I've got your attention, can I just say that I really really like this language! Thank you all for creating it.....I think my main problem is trying to run before I can walk, and often running straight into brick walls before donning the right head gear. --Colin.

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