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

[REBOL] Re: Back to the Advanced Port stuff again

From: rebol:techscribe at: 11-Jan-2001 22:30

Hi Paul, To make this a little more interesting for you, I've included code that shows you how you can add the words associated with the ports to the block, instead of adding the ports themself, so that all ports will be contained in wait-ports like your irc-open-port. I understand that is what was troubling you? you wrote:
> Actually, the waitports is defined as an empty block at the begining of the > script: > > waitports: [] > then later... > waitports: [irc-open-port]
Do you use the first definition (waitports: []) for any purpose before it is defined as waitports: [irc-open-port]? If not, note that the first definition does not accomplish anything. I assume that at a later point in time you add ports to wait-ports using the insert or the append function. 1. waitports: [] What happens here is that you are associating the word waitports with an empty literal block. If you want you can now begin to insert or append stuff to the block, (or remove and search for appended stuff) and so on. This literal block will survive as long as the word waitports (or a different word) are associated with it, or if it is referenced from within a function, an object, or a block, as long as that function, block ... is being referenced by a word (chain of references), or itself is referenced in a block ... which in turn is referenced by a word. As soon as all "live" references to the literal block are consumed by the garbage collector (unset 'waitports, for instance) the literal block will be garbage collected. 2. waitports: [irc-open-port] a) Now the empty literal block in 1 is no longer bound by waitports, and it will be garbage-collected (unless there was a previous step in which the block became associated with some other live value, such as a difference word, or "live" block ...). The literal block that you just abandoned will be garbage- collected and with it all its contents, with exception of stuff that additionally associated with (or bound to) some other surviving value ...) b) waitports is now assigned to a block that contains a word. Note that nothing happens with the word irc-open-port in the block. Most notably it is not automatically replaced by its value. Therefore, if you probe the block, the word irc-open-port will be reported as the contents of the block and not the value that irc-open-port is bound to. If you subsequently add other ports to the block using insert or append, the values (and not the words) will be added. A simple example:
>> a: 1 ;- Step 1 >> b: 2 ;- Step 2 >> c: [a] ;- Step 3 >> append c b ;- Step 4
The block in step 3 "protects" the word a that it contains. The word is not replaced by its value, and the block assigned to c contains the word a. Note that a does not even have to have been associated with a value. x: [y] will work, even if y was not previously associated with any value. What happens in step 4? The function append is evaluated. This function expects two arguments, a series type, and some other value. REBOL looks at the input stream and designates the two tokens following append as appends arguments. REBOL determins that c is a block, it replaces the word c by its value, namely the block, and determines that the block c fulfills append's requirement for a series type value as its first argument. REBOL needs a second argument for append, and finds the word b. This word (like c) is replaced by its value (namely 2) and the integer 2 is passed to append as its second argument. The resulting block c is
>> c
== [a 2] The a that was already "packaged" in the block was never evaluated, and therefore it continues to exist as an unevaluated word. The word b never reached the block, because it was replaced by its value, 2, before it was passed to append which inserted 2 (and not b) in the tail of block c. Therefore the value associated with b, namely 2, is the second element of the block c. The same thing is probably happening in your case. When you associate waitports with the block [irc-open-port] the word irc-open-port is not evaluated, i.e., it is not replaced by its value, and therefore it the first element of the block. I think it's understood by now. So, what do you do in order to have a block waitports which uniformly contains either ports, or words that evaluate to ports? 1. ... uniformly contains ports:
>> waitports: [] >> insert waitports irc-open-port
In this example irc-open-port is evaluated and its value (the port-object) will be inserted, not the word itself. Another option:
>> waitports: reduce [irc-open-port]
The reduce function returns a block in which the word irc-open-port has been replaced by its value. 2. ... uniformly contains WORDS that evaluate to port objects:
>> waitports: [irc-open-port]
Ok, we know by now that the block protects the word irc-open-port, it is not evaluated, and therefore the block associated with waitports is currently
>> waitports
== [irc-open-port] How about the other ports? Simple. Assuming that you are using the string "Paul" which identifies the user Paul as set-word! that will be associated with a port:
>> user: "Paul" >> word: to set-word! join user "s-open-port"
== Pauls-open-port:
>> word make port-object! [ .... ] >> append waitports to word! :word
== []
>> probe waitports
== [irc-open-port Pauls-open-port] Great, now how do you get the port associated with Pauls-open-port? There are different ways:
>> second reduce wait-orts >> get second waitports ;- less compute-intensive if you have a lot of ports >> get waitports/2 >> first find wait-ports 'Pauls-open-port ;- will return the word Pauls-open-port
== Pauls-open-port
>> get first find wait-ports 'Pauls-open-port ;- will get the port associated with Pauls-open-port
But if you don't know that its "Paul" s-open-port? Here:
>> get first find wait-ports to word! join user "s-open-port"
Hope this helps, Elan