is a block a block?
[1/3] from: riachtchenko:docutec at: 29-Nov-2000 12:41
Hi,
now, what is going on here
>> foreach obj b [
[ probe obj
[ ]
make object! [
name: "mascha"
]
make object! [
name: "mascha"
]
>> probe b/1/name
mascha
== "mascha"
>>probe first b
make object! [
name: "mascha"
]
>> probe first b/name
** Script Error: Invalid path value: name.
** Where: probe first b/name
>>
and now:
>> type? [acc_1 acc_2]
== block!
>> type? b
== block!
>> length? [acc_1 acc_2]
== 2
>> length? b
== 2
>>
but:
>> foreach obj [acc_1 acc_2] [
[ probe obj/name
[ ]
** Script Error: Cannot use path on word! value.
** Where: probe obj/name
but (the same!)
>> foreach obj b[
[ probe obj/name
[ ]
mascha
mascha
== "mascha"
>>?
thanks
Alex
[2/3] from: lmecir:mbox:vol:cz at: 29-Nov-2000 18:14
Hi Sascha,
instead of:
probe first b/name
, which tries to find the first element of the B/name path (incorrect) you
could do:
1)
c: first b
probe c/name
2)
probe do-path [first b /name]
, where Do-path is as follows:
do-path: function [
{
A referentially transparent way
to invoke a path.
Usage:
do-path [something /r1 /r2 ... /end-path a1 a2 ...]
/end-path can be omitted, if no args are supplied.
Values between Something and /end-path are ignored,
if they don't evaluate to refinements or integers.
}
[throw]
blk [block!]
] [something path ref] [
set/any [something blk] do/next blk
path: make path! reduce [
either word? get/any 'something [something] ['something]
]
until [
any [
empty? blk
(
set/any [ref blk] do/next blk
if any [
refinement? get/any 'ref
integer? get/any 'ref
] [
not if /end-path <> ref [
insert tail :path either refinement? ref [
to word! ref
] [
ref
]
]
]
)
]
]
do head insert/only copy blk :path
]
Ladislav
[3/3] from: brett::codeconscious::com at: 30-Nov-2000 17:21
> >>probe obj_1
> make object! [
<<quoted lines omitted: 6>>
> ** Where: probe obj/name
> ooops
This is just one block with two words in it. These words happen to have
values, but remember in Rebol (check the guide) the block is not evaluated
immediately. The block is only evaluated when a function processes it. For
example,
>> obj_1: make object! [
[ name: "mascha"
[ ]
>> obj_2: make object! [
[ name: "mascha2"
[ ]
>>
>> foreach obj reduce [ obj_1 obj_2 ] [ print obj/name]
mascha
mascha2
What did reduce do just then? It took a block with two words in it,
individually evaluated each of the words and returned the results in a new
block. Each word evaluted to the object it refers to. So you end up with a
block of two objects which is then given to the foreach function.
> >>b: []
> >>insert b obj_1
> >>insert b obj_1
...
> >>foreach obj b[
> [ probe obj/name
> [ ]
> "mascha"
> "mascha"
> == "mascha"
So here you gave foreach a block that contains two objects (not two words).
This is different from before because of the way you constructed the block
b. First you made a block and inserted the objects into it - guaranteeing
that the block contained the actual objects.
> since also
> >> equal? [obj_1 obj_1] b
> == false
Yes, a block of two words is not the same as a block of two objects.
> but
> >> equal? length? [obj_1 obj_1] length? b
> == true
The lengths of each happen to be the same, that is 2.
This is like asking
>> equal? length? ["the price" "of fish"] 2
== true
> >> equal? type? [obj_1 obj_1] type? b
> == true
Yup, they are both blocks - two different blocks - but definitely two
blocks. Again, the words here are simply being treated as literally the
words obj_1 and obj_2. These two words in this case have not been evaluated.
>> type? [obj_1 obj_2]
== block!
>> type? []
== block!
>> type? [a block full of words with no value]
== block!
>> length? [ a block of length x of meaningless words]
== 8
>> length? [ a block of length 8 of meaningless words]
== 8
Another way of saying this is that
[obj_1 obj_2] is a block of two words. The first word is obj_1, the
second is obj_2.
Nothing more is said. It doesn't matter that you have defined obj_1 and
obj_2 to have values earlier. These values are not accessed until you
evaluate the words (find their value/meaning) by using a function.
Now look at this
two-object-block: reduce [obj_1 obj_2]
This says reduce the block of words to a block of values by evaluting each
word. When done, set the word "two-object-block" to refer to this new block
of values (objects).
So then these work:
>> get in first two-object-block 'name
== "mascha"
>> two-object-block/2/name
== "mascha2"
Hope it helps.
Brett.
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted