Thanks Gabiele - glad to know it is at least technically possible (within limits)
Sunanda
This there anyy clever, quick, way to turn these two blocks into a single object? names: [field1 field2 field3] values: ["a" "b" "C"]
I've already done it the long way around: blk: copy [] for nn 1 length? names 1 [append blk reduce [to-set-word names/:nn values/:nn]] probe make object! blk
Endo
I wrote a build-object function does that, not more quicker/clever though
build-object: funct [names values] [ o: copy [] parse compose names [some [set name [word! | set-word!] (append o to-set-word name) | skip]] set/pad words-of o: context append o none compose values o ]
probe build-object names values
== make object! [ field1: "a" field2: "b" field3: "C" ]
My more general version is a bit longer, but works without values, word! or set-word!s:
build-object: func [ "Builds an object from a block" names [block!] "Words or word/value pairs" /values val [block!] "Initial values" /local o name value ][ o: copy [] o: either values [ parse compose names [some [set name [word! | set-word!] (append o to-set-word name) | skip]] set/pad reflect o: context append o none 'words compose val o ] [ if any [ parse compose names [some [set name [word! | set-word!] (append o reduce [to-set-word name none])]] parse compose names [some [set name [word! | set-word!] set value any-type! (append o reduce [to-set-word name :value])]] ] [context o] ] o ]
build-object [a b c] build-object [a 1 b "2"] build-object [a: 1 b 2] build-object [a: 1 b 'c] build-object/values [a: b] [c 1] x: 1 build-object/values [a: b] [c (x)]
if you can add an extra word to your names, there is another way to do it:
>> names: [self field1 field2 field3] == [self field1 field2 field3] >> values: [#[none] "a" "b" "C"] == [none "a" "b" "C"] >> names: use names reduce [names] == [self field1 field2 field3] >> set names values == [none "a" "b" "C"] >> object: bound? first names >> object/self: object >> probe object make object! [ field1: "a" field2: "b" field3: "C" ]
Up to you to decide if it's better or worse. :)
Endo
More clever award goes to ChirtianE, more interesting award goes to Gabriele :)
Sunanda
Thanks guys: lots of good ideas - as usual!
Gregg
change-each: func [ [throw] "Change each value in the series by applying a function to it" 'word [word!] "Word or block of words to set each time (will be local)" series [series!] "The series to traverse" body [block!] "Block to evaluate. Return value to change current item to." /local do-body ][ do-body: func reduce [[throw] word] body forall series [change/only series do-body series/1] ; The newer FORALL doesn't return the series at the tail like the old one ; did, but it will return the result of the block, which is CHANGE's result, ; so we need to explicitly return the series here. series ]
o: context append change-each name names [to set-word! name] none set o values print mold o
Not sure what I was thinking. Should use MAP, not CHANGE-EACH.
R2 has MAP-EACH, so use that instead, so 'names isn't changed.
Then the entire solution is:
o: context append map-each name names [to set-word! name] none
A MAP func would make it a little shorter, but R2 doesn't have one by default.
Marco
Nice addition to my "-each"s functions Gregg!
GiuseppeC
Could someone explain the difference between open/direct/lines/no-wait and open/direct/lines ?
The only one I have found is that if I read a client port with probe COPY/part WAIT PORT 1 I get NONE Otherwise COPY/part PORT 1 I get []
But it should be more complex, I know I am missing something.
GiuseppeC
Forget my request: I have spent the whole day on REPL for TCP ports. It was interesting and intense but I have cleared many doubts and answered to questions.