Hi Bob,

A) do works when you only want to load a single object. It's like saying:

do [make object! [word: 'something]]

which - of course - returns a single object, namely the last object (and
here only object) found in the block (returned by load), and not a block
containing all objects that were in the file.

B)
you wrote:
>is there a situation where reduce should not be used?

There are two I can think of right now.

1. When the object contains a literal word, as in:

>> o: make object! [word: 'something]

here 'something is lit-word!

probe o reveals that the lit-word! becomes a word! when we create the object:

>> probe o

make object! [
    word: something
]

We store it and then load it. We now have the following block:

>> o: load %bob-store.dat
== [
    make object! [
        word: something
    ]]

Note that this block contains three elements: the word make, the word
object!, and the block containing the set-word! word and the word something.

So when we reduce this block, we have the same situation as:

>> o: make object! [word: something]

which generates an error as it would with reduce, because the word
something is not defined in this context:

>> o: make object! [word: something]
** Script Error: something has no value.
** Where: word: something

This whole scenario is due to the fact that the original lit-word!
something (i.e. 'something) was reduced to a word when the original object
- the one that we saved - was created. Accordingly, when we saved the
object the word something, originally a lit-word! is saved as a word! and
is no longer usable to create the object.

I don't see how this situation could be avoided, since you can't as a
matter of principle change all words that are assigned to a set-word! into
lit-words when you load the stuff, because it is possible that some of
these words are indeed intended as words. 

This is only a problem if it is possible that your object will include
values that started out as lit-words, before the object was created.

Two work-arounds: 

a) Never use literal words in objects you want to save, instead always
assign literal word in blocks:

>> o: make object! [word: [something] ]
>> save %bob-store.dat o
>> o: reduce load %bob-store.dat
== [
    make object! [
        word: [something]
    ]]
>> type? first o
== object!

b) Or 

If you are certain that - when you load objects from a file - you will not
be using words that should be dereferenced during the act of object
creation, i.e. something can never be intended as anything but 'something,
then you could edit each respective block used in the object creation
before you reduce the stuff, like in this case:

>> o: make object! [word: 'something]
>> save %bob-store.dat o
>> loaded-o: load %bob-store.dat
== [
    make object! [
        word: something
    ]]
>> change back tail third loaded-o ['something]
== [
]
>> print mold loaded-o
[
    make object! [
        word: 'something
    ]]
>> o: reduce loaded-o
== [
    make object! [
        word: something
    ]]
> type? first o
== object!
>> probe first o

make object! [
    word: something
]


2. When you have objects that contain references to objects:

>> p: make object! [q: o]
>> save %bob-store.dat p
>> r: first reduce load %bob-store.dat
>> probe r

make object! [
    q: [
        make object! [
            word: something
        ]]
]

>> probe p

make object! [
    q: [
        make object! [
            word: something
        ]]
]

Looks as though everything is ok. NOT!

Here's the problem:
p, which is the object the word q as a reference to o, does not have its
own copy of o. If you modify o, you automatically modify p's embedded object:

Let's grab the object contained in the block o (remember we loaded it from
the file):

>> o: first o
>> probe o

make object! [
    word: something
]

Ok, now let's change what word is pointing at:

>> o/word: 'something-else
== something-else

and p was changed as well:

>> probe p

make object! [
    q: [
        make object! [
            word: something-else
        ]]
]

in contrast there is no equivalent of p in the loaded scenario r, such that
this equivalent points at the  object referenced by q in r.

In other words, as soon as you save the objects o and p, the relationship
between o and p, namely that p/q is only reference to the object o, and not
a second object, this relationship is lost.

Can't think of anything else right now.

Hope this helps.


;- Elan >> [: - )]

Reply via email to