Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search

[REBOL] Re: Embedded Object and Scope yet again...

From: larry:ecotope at: 10-May-2001 23:10

Hi Joel You have been coming up with some fun examples lately. Maybe I can throw a little light on the topic. First the effect in your example is also obtained with this code: ob1: make object! [ a: 1 init: func [n [integer!]] [a: n] set 'ob11 make object! [ b: 10 init: func [n [integer!]] [b: n] wot: func [] [a + b] ] ] All of your tests below give the same result as when using the do [] construct. The form above is the poor man's module capability (until the real thing comes along in REBOL/Core 3). Carl, myself, and many others often use this construction. In fact, much of VID is written using this mechanism. For example, if you do source LAYOUT, you will find that layout calls a number of functions like TRACK, EXPAND-SPECS, DO-FACETS, GROW-FACETS, etc. which are not defined globally. This works because LAYOUT was defined in the VID object, but it was defined using SET as above and thus exported to the global context. This is very useful because it allows you to export a few interface functions for the object to the global context, while at the same time being able to reference all of the words in the "parent" object. At the same time, the global context is shielded from the many named data-structures, layouts, sub-objects, styles, helper functions, etc. which are included in the parent object. So how does all this work? There are others who can surely give a better explanation than I can, but I will make a few comments. There are stages in object creation, and in one of the early stages the object spec block is scanned for all first-level set-words. A context for the object is created with these words bound to it. After this stage, the code in the object spec is executed, in exactly the same way as a block of code in the global context. The only difference is that those words which occurred in the spec-block as set-words are bound to the objects context. Any code can appear and will be executed. For example:
>> x: 21 ob: make object! [ a: 52 print [a x]]
52 21 This feature is also very handy. I often wrap a whole script this way: REBOL [] ctx-my-script [ .... all of the script code just as it was when its words were in the global context ] end ctx-my-script The global context is protected from all of the set-words used in the script. There are some extra precautions when using vid which I will skip here. There are a couple of facts about "embedded" objects which are good to know: 1) Sub-objects which are defined with a set-word in the parent object are treated differently than other datatypes when the object is cloned. Sub-objects are not cloned, the pointer (which what a word really references) still points to the original sub-object. Other datatypes are copied into the cloned object. . 2) Sub-objects exported with your do [] construct or by using SET are not really "embedded", the words which reference them are global, but the words contained in their definition blocks are bound to the context of the object in which they are created. To me it is similar to this example:
>> b: [] repeat j 3 [use [x][x: j append b 'x]]
== [x x x]
>> b
== [x x x]
>> reduce b
== [1 2 3] The word b is in the global context, it's value is a block which contains the words x, x, and x each of them created in a different unnamed context. You can do much the same thing in LISP, Scheme or other symbolic programming languages. Your conclusion can be extended to state that it is often misleading to apply the concepts of object-oriented programming in trying to understand REBOL. REBOL's objects do not support the key concepts of OO. They are primarily name-spaces, and have their own distinctive properties relating to the underlying symbolic language. They are one-of-kind objects, sometimes called objects by prototype in the books. Perhaps others will contribute further insights or corrections. (Carl, Jeff, Holger, Gabriele, Ladislav?) -Larry