another gotcha
[1/4] from: pat665:ifrance at: 2-Dec-2001 12:04
Hi all,
Here is another gotcha from rebol I found as I was cleaning up some of my code. This
cleaning job was motivated by the following section of the "view user's guide".
[...
13.3. Avoiding Variable Collisions
For large scripts that have a lot of position and face variables, it may become difficult
to manage all of the names and keep them from interfering with each other. A simple solution
to this problem is to define pages within objects that have the required variables defined
locally to the objects. For instance here is an address book form that keeps all of its
variables local:
...]
Sounds like a good idea because I had a lot of stuff in my layout. My first attempt was
like this :
Rebol []
o-win: make object! [
page: layout [
banner "Gotcha !"
zone: banner "rebol"
]
]
o-win/page/zone/text: "right"
show o-win/page/zone
view center-face o-win/page
The result was this :
** Script Error: Invalid path value: zone
** Where: do-boot
** Near: o-win/page/zone/text: "right"
My second attempt was like this, and it works, and I was not happy with it because what
is the point of making an object if it works that way too!
Rebol []
o-win: make object! [
page: layout [
banner "Gotcha !"
zone: banner "rebol"
]
]
zone/text: "oops"
show zone
view center-face o-win/page
I thought that making an object would protect "zone" from being modified from the outside.
Thanks to Ladislav, I understand that it was time to re-read the documentation to search
for the little tiny detail I must have missed.
And I found it, "zone" needed a declaration like this :
o-win: make object! [
zone: none
page: layout [
banner "Gotcha !"
zone: banner "rebol"
]
]
After that, direct access to zone produce an error (as expected)
** Script Error: zone has no value
** Where: do-boot
** Near: zone/text: "oops"
So the final attemp (that was successful) was :
Rebol []
o-win: make object! [
zone: none
page: layout [
banner "Gotcha !"
zone: banner "rebol"
]
]
o-win/zone/text: "right"
show o-win/zone
view center-face o-win/page
But finally the big question is why-why-why ?
As I perceive it (in my case perceive is more appropriate than understand) the page's
zone needs a holder (the "zone: none") in the object. I have tried to make an explicit
holder instead and it works too :
Rebol []
o-win: make object! [
explicit-holder: none
page: layout [
banner "Gotcha !"
zone: banner "rebol"
do [explicit-holder: get 'zone]
]
]
o-win/explicit-holder/text: "foo"
show o-win/explicit-holder
view center-face o-win/page
Has anyone a good explanation for this ?
[2/4] from: lmecir:mbox:vol:cz at: 2-Dec-2001 18:12
Hi Patrick,
to understand what is going on, you can either look at the MAKE OBJECT!
description in http://www.sweb.cz/LMecir/contexts.html) or just realize how
the SPEC argument is used by the MAKE native to create objects:
The SPEC block (but not its subblocks!) is searched through and all
Set-words are collected. That list is used to create a new object from. That
is why if you don't include the ZONE: Set-word to the SPEC block, you will
not have it included to the created object as a local word.
<<Patrick>>
(...)
As I perceive it (in my case perceive is more appropriate than understand)
the page's zone needs a holder (the "zone: none") in the object. I have
tried to make an explicit holder instead and it works too :
Rebol []
o-win: make object! [
explicit-holder: none
page: layout [
banner "Gotcha !"
zone: banner "rebol"
do [explicit-holder: get 'zone]
]
]
o-win/explicit-holder/text: "foo"
show o-win/explicit-holder
view center-face o-win/page
Has anyone a good explanation for this ?
(...)
<</Patrick>>
The success depends on what you want to achieve. I would call this a
disaster, because you didn't make 'zone local at the cost of more
complicated code.
Cheers
Ladislav
[3/4] from: rebol665::ifrance::com at: 2-Dec-2001 19:23
Hi Ladislav,
I had read your contexts.html before, and more than once. Who has not ? ;-).
However it's difficult to understand all this concept theoretecally. I am
more a practical person and it is often when confronted to a problem that
theory comes to help. From where I come, these two "declarations" of zone
looks like a redondancy.
So if I understand correctly, unless "declared" in the main specs body, all
my object set-words will be global. Is it right ? BTW, is there an explicit
way to do that, like the word /local in a function declaration ?
Finally I don't know what to think of your <<I would call this a disaster>>
. It has affected me some way.
Regards
Patrick
[4/4] from: lmecir:mbox:vol:cz at: 3-Dec-2001 9:09
Hi Patrick,
<<Patrick>>
(...) From where I come, these two "declarations" of zone
looks like a redondancy.
<</Patrick>>
Yes, right, it really looks strange, especially for beginners. Experienced
users may have some objections too, as I tried to describe in my Rep
http://www.sweb.cz/LMecir/rep.html ).
<<Patrick>>
(...) So if I understand correctly, unless "declared" in the main specs
body, all
my object set-words will be global. Is it right ? BTW, is there an explicit
way to do that, like the word /local in a function declaration ?
<</Patrick>>
There is an explicit way how to do it. The most natural way currently is to
use the word in the SPEC block as you have found out like (spec: [word1:
word2: none etc.]) , although you can write even your own Make-object
function using a totally different specification method. As an example see
my Make-object function in %highfun.r (I didn't use a different way of local
words specification though) or the Sim-make-object function, that show how
you can write your own function creating an object.
<<Patrick>>
(...)Finally I don't know what to think of your <<I would call this a
disaster>>
. It has affected me some way.
Regards
Patrick
<</Patrick>>
Wrong choice of a word, sorry. (I am not a native speaker). What I wanted to
tell was, that:
1) You have found a working solution
2) You have followed the documentation and produced a non-working solution
as you described (it doesn't look as your fault to me)
3) You repaired the sub 2) solution correctly using the [zone: none ...] in
the Spec block. Perfect.
4) You used a more complicated solution hiding its disadvantage that 'zone
would be global in this case. That is a trouble (a "disaster"), but it again
doesn't look as your fault to me, because you probably didn't have much of a
chance to find this in the documentation.
Sorry for offending words, I will try to improve my skills to be more
appropriate in the future.
Regards
Ladislav