[REBOL] Re: Embedded Object and Scope - again...
From: gjones05:mail:orion at: 10-May-2001 18:07
From: "CRS - Psy Sel/SPO, COUSSEMENT Christophe, CPN" > Hi list:
<snip> I tried the following:
> <snip>
>
> ancestor-object: make object! [
>
> global-obj-prop: make integer! 0
>
> init: func [
> val [integer!]
> ][
> global-obj-prop: make integer! val
> ]
>
> embedded-object: make object! [
> print-global-obj-prop: does [print global-obj-prop]
> ]
> ]
>
> </snip>
>
> Ok, so I tried:
>
> >> ancestor-object/init 10
> == 10
> >> ancestor-object/embedded-object/print-global-obj-prop
> 10
>
> No problem here :-)
>
> >> descendant-object: make ancestor-object []
> >> descendant-object/init 20
> == 20
> >> descendant-object/embedded-object/print-global-obj-prop
> 10
>
> Ouch, not what I thought... Let's check... In the "Official Guide", pg
348,
> I found:
>
> <quote>
> "The ancestor object and the descendant object share the same embedded
> object."
> </quote>
>
> OK, so I tried something else:
>
> >> descendant-object: make ancestor-object
[descendant-embedded-object: make
> embedded-object []]
> >> descendant-object/init 20
> == 20
> >> descendant-object/descendant-embedded-object/print-global-obj-prop
> 10
>
> Again, not what I thought ... I was awaiting 20 !!! ;-(
>
> Here are my questions:
>
> 1. Why did RT choose for such implementation ? What are the advantages
?
> 2. Why did my last try not work - it was -IMHO- logical I should get a
> result of 20 ..., as I instanciated the embedded object within the
> instanciation of the ancestor object.
> 2. How can I get my descendant-embedded-object to retrieve the
property of
> it's container, the descendant-object ?
>
> Thx for answering :-))
>
> chr==
Hi, Christophe,
CC> Why did RT choose for such implementation ? What are the advantages
?
A social-anthropology professor once warned us students against asking
why
questions -- the answers tend to be too grounded in philosophical
tautologies. I evidently didn't learn my lesson, because I still ask
them 20+ years later. ;-)
I suspect that this behavior is partially a legacy of the way in which
RT assigns values in memory. I can't think of a really good advantage,
mainly because any argument that I come up with fails the principle of
least surprise. The path notation suggests that something is being
pointed to that really isn't!
CC> Why did my last try not work - it was -IMHO- logical I should get a
result of 20 ..., as I instanciated the embedded object within the
instanciation of the ancestor object.
If you will probe the object created by the last try, you will see that
it contains two objects: the original embedded object and a new
descendant embedded object. As far as I can tell, this demonstrates
that making a descendant object does not really instantiate a unique
instance of embedded objects. However, it does create new instances of
the embedded word values, like global-obj-prop. Through the original
series of examples, you create an object, then you create an object
derived from the original object. The global-obj-prop is unique in each
of these objects, but the embedded object only exists in the original
object creation. This is the reason that Anton's suggestion provided a
nice work around to the problem.
What I suspect that you are looking for is the way to create new words
in the context of the newly made object. See the next section for "the
way".
CC> How can I get my descendant-embedded-object to retrieve the property
of
it's container, the descendant-object ?
Luke, use The Force,
or at least the 'context. I believe that
'context may be the solution to your problem.
>> ? context
USAGE:
CONTEXT blk
DESCRIPTION:
Defines a unique (underived) object.
CONTEXT is a function value.
ARGUMENTS:
blk -- Object variables and values. (Type: block)
Now, back to your example. Now, the ancestor sets up a unique context
for the property. Creating a new descendant object will create a new
context for this property.:
ancestor-object: make object! [
global-obj-prop: context [the-obj-val: 0]
init: func [
val [integer!]
][
global-obj-prop/the-obj-val: make integer! val
]
embedded-object: make object! [
print-global-obj-prop: does [print
global-obj-prop/the-obj-val]
]
]
ancestor-object/init 10 ;yields == 10
ancestor-object/embedded-object/print-global-obj-prop ;yields 10
; Christophe is happy so far. Now for the moment of truth ...
descendant-object: make ancestor-object []
descendant-object/init 20 ; yields == 20
descendant-object/embedded-object/print-global-obj-prop ;yields 20
; now Christophe is very, very happy!
I'm not saying that this all makes total sense to me, but once I began
to understand how the code is represented in memory, I began to
understand how to deal with the problem that you laid out. I hope that
this is of some benefit.
--Scott Jones