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

Private Object Function

 [1/19] from: coussement::c::itc::mil::be at: 15-Jan-2001 10:52


Hi REBOLS, I would like to make an object function private to this object. That is:
>> o: make object! [
[ value: make integer! 1 [ ; some privatization code ... [ add-one: does [value: value + 1] [ get-value: does [add-one [ print value] [ ]
>> o/get-value
2
>> o/add-one
here I should get something like... ** Script Error: Invalid path value: add-one. ** Where: o/add-one Any idea ? Of course the principle could be extended to the privatization of variables... Thx a lot, Best Regards, chr==

 [2/19] from: rebol:techscribe at: 15-Jan-2001 11:16


Hi Christophe, I think your description is incomplete. By privatization do you mean 1. that functions within the object should/should not have access to the privatized function? 2. If 1, then that limits how hidden the hidden function is. Recall that REBOL functions are editable during runtime. This means that I can use any function that accesses the hidden function as an entry point into the hidden function. I.e. o: make object! [ hidden-func: does [] exposed-func: does [hidden-func] ] exposed-hidden-func: get first second get in o 'exposed-func 3. Should the function have access to other functions and words defined in the context of the object? 4. Should the object be serializable including hidden functions? 5. Should descendants have access to hidden functions? Without clarifying these questions I can see a long thread of rejected proposals. Take Care, Elan CRS - Psy Sel/SPO, COUSSEMENT Christophe, CPN wrote:

 [3/19] from: g:santilli:tiscalinet:it at: 15-Jan-2001 20:39


Hello COUSSEMENT Christoph! On 15-Gen-01, you wrote: CC>>> o/add-one CC> here I should get something like... CC> ** Script Error: Invalid path value: add-one. CC> ** Where: o/add-one The most recent /Core experimental allows you to write: o: make object! [ ; public get-value: none ; private make object! [ value: make integer! 1 add-one: does [value: value + 1] set 'get-value does [ add-one print value ] ] ] or: o: make object! [ ; public get-value: none ; private use [value add-one] [ value: make integer! 1 add-one: does [value: value + 1] get-value: does [ add-one print value ] ] ] Regards, Gabriele. -- Gabriele Santilli <[giesse--writeme--com]> - Amigan - REBOL programmer Amiga Group Italia sez. L'Aquila -- http://www.amyresource.it/AGI/

 [4/19] from: rebol:techscribe at: 15-Jan-2001 13:13


Hi Gabriele, how is this any ifferent from what you can do with the current stable version (2.3)? The questions, however, remain. a) The protection can be circumvented, in as much as I can use get-value's body to access add-one as well as value. b) The object o cannot be serialized together with the hidden words. BTW, Christoph, what are you trying to accomplish? Take Care, Elan I can still access "private" Gabriele Santilli wrote:

 [5/19] from: coussement:c:itc:mil:be at: 16-Jan-2001 9:34


> Hi Christophe, > I think your description is incomplete. By privatization do you mean
<<quoted lines omitted: 9>>
> ] > exposed-hidden-func: get first second get in o 'exposed-func
[ok, I can also use this]
> 3. Should the function have access to other functions and words defined > in the context of the object?
[yes, it should]
> 4. Should the object be serializable including hidden functions?
[I do not understand 'serializable' ?]
> 5. Should descendants have access to hidden functions?
[yes they should. Although it should be interressant to me to have a mean to control this: some sort of 'protected function' which is known to the ancestor, but not to the child objects...]
> Without clarifying these questions I can see a long thread of rejected > proposals.
[the 'private function' I meant is the opposite of a 'public function'. That is, a private function is a function only known and accessible from within the context of the object. A public one is part of the public interface of the object and is therefore accessible from outside the object, by another object from exemple]

 [6/19] from: coussement:c:itc:mil:be at: 16-Jan-2001 9:49


> Hi Gabriele, > how is this any ifferent from what you can do with the current stable
<<quoted lines omitted: 4>>
> b) The object o cannot be serialized together with the hidden words. > BTW, Christoph, what are you trying to accomplish?
[In the context of the project I'm working on I would like to implement a coherent OODBMS - which I announce in the list sometime ago. For this I need to restrict the access to the object's internal implementation. I should be able to determine which methods can be accessed from the outside, which not, which should be inherited or not. The solution should also be applicable for protecting object's properties. Regards, chr==]

 [7/19] from: coussement:c:itc:mil:be at: 16-Jan-2001 9:56


> Hello COUSSEMENT Christoph! > On 15-Gen-01, you wrote:
<<quoted lines omitted: 30>>
> ] > ]
[thanks for answering ! it works fine to me, but it does not simplify and clarify the writing of the code, in that way that the body of the 'public function' must be found back into the 'private' part, due to the runtime binding... Anyway, it's my best solution for now ;-) best regards, chr== ]

 [8/19] from: rebol:techscribe at: 16-Jan-2001 1:56


Hi Christophe,
> > 4. Should the object be serializable including hidden functions? > [I do not understand 'serializable' ?]
By "serializable" I mean that: If I have the object (including its private components) loaded in memory, should I be able to write the object including its private components to a file? Or is it sufficient if I only write the public components of the object to a file? I.e. o: make object! [something: none] write %filename.ext mold o will write this object to a file. If I add private components to this object, and I want to write the object to a file, should the private components be written along with the object? Or should the object be written without the private components, which means that when the object is subsequently loaded from this file, it will not include the private components.
> > 5. Should descendants have access to hidden functions? > [yes they should. Although it should be interressant to me to have a > mean to control this: some sort of 'protected function' which is known to > the ancestor, but not to the child objects...]
Is this "protected" function in addition to the private function? If not, then I don't see how descendants can access the hidden function, if this hidden function is not known to descendants.
> That is, a private function is a function only known and accessible > from within the context of the object. A public one is part of the public > interface of the object and is therefore accessible from outside the object, > by another object from exemple]
Basically, my question is, to what degree do you want to enforce this? Is it a) more an organizational principle to help you as a programmer organize your code; b) you don't want the private functions/words to show up in the block returned by first object, but if a non-member function absolutely wants to, then it will will be able to also access hidden words ... c) Under no circumstances must a non-member function be able to access private components? That's, basically what I'm asking Take Care, Elan

 [9/19] from: rebol:techscribe at: 16-Jan-2001 2:00


Hi Christophe,
> I would like to > implement a coherent OODBMS - which I announce in the list sometime ago.
I just checked my REBOL folder, and I don't appear to have that one. Could you send me the email you are referring to offlist? It may help me understand where you are heading with this. If it's to be an OODBMS then my guess is that you won't be served with a solution that prevents you from storing the private components of an object together with the object? Take Care, Elan

 [10/19] from: coussement:c:itc:mil:be at: 16-Jan-2001 16:07


Elan:
> > > 4. Should the object be serializable including hidden functions? > > [I do not understand 'serializable' ?]
<<quoted lines omitted: 4>>
> o: make object! [something: none] > write %filename.ext mold o
[thanks, I didn't know this one. I used 'save to keep the object structure intact...]
> will write this object to a file. > If I add private components to this object, and I want to write the > object to a file, should the private components be written along with > the object? Or should the object be written without the private > components, which means that when the object is subsequently loaded from > this file, it will not include the private components.
[In the specific context of my try for OODBMS development, the persistence of the DBobject should indeed request to be written down INCLUDING the private methods, because those should contain some business intelligence needed to access/handle the contained data]
> > > > > 5. Should descendants have access to hidden functions?
<<quoted lines omitted: 6>>
> not, then I don't see how descendants can access the hidden function, if > this hidden function is not known to descendants.
[you're right ! methods would be classified in three exclusives classes: public, private and protected Sample use of them could be: - public access : the method can be called from any script in the application. - private access : the method can be called only from scripts in the object for which the function was declared (including the sub-objects); the method cannot be called from descendant of the object. - protected access : the method can be called only from scripts for the object for which the function was declared, and its descendant. !!! ATTENTION !!! After studying some more documentation I collected, I've noticed that I interverted the meaning of the concept 'private' and 'protected' : that's why the definitions above doesn't mach anymore what I previously said. Sorry for the inconvenient. ]
> > That is, a private function is a function only known and > accessible
<<quoted lines omitted: 13>>
> c) Under no circumstances must a non-member function be able to access > private components?
[as I see the implementation for now, my meaning of it is to enforce the protection of the object's contain by keeping the protected/private part out-of-bound for the context from which the object is called. That is, using your words, your point c). Creating highly encapsulated objects organize for sure the code, but more important allows you to completely control any modification and access to properties and methods, which is important in the process of creating waterproof applications... ]
> That's, basically what I'm asking
[I hope you'll find my answers satisfying.]
> Take Care,
[Thank you for caring ;-)) ]
> Elan
[ Best regards, chr== ]

 [11/19] from: coussement:c:itc:mil:be at: 16-Jan-2001 16:13


> > I would like to > > implement a coherent OODBMS - which I announce in the list sometime ago. > > I just checked my REBOL folder, and I don't appear to have that one.
[it was just my answer to a question of Mr. Gabriele Santilli, where he ask if anyone was interrested in building a DB system. I just mentionned my interess foran OODBMS ]
> Could you send me the email you are referring to offlist? It may help me > understand where you are heading with this. If it's to be an OODBMS then > my guess is that you won't be served with a solution that prevents you > from storing the private components of an object together with the > object?
[right again ! for further details, please refer to my answer to your other mail of today]
> Take Care,
[U2 :-) ]
> Elan
[best regards, chr== ]

 [12/19] from: g:santilli:tiscalinet:it at: 16-Jan-2001 19:36


Hello Elan! On 15-Gen-01, you wrote: E> how is this any ifferent from what you can do with the current E> stable version (2.3)? That makes 2.3 (and all the versions before latest experimental) crash after a recycle. E> The questions, however, remain. a) The protection can be E> circumvented, in as much as I can use get-value's body to E> access add-one as well as value. b) The object o cannot be E> serialized together with the hidden words. This is true. But it is not a problem usually. You're not trying to protect secret code, you're just trying to avoid accidental use of a word meant to be private; this is useful for team projects, or to separate interface from implementation. Regards, Gabriele. -- Gabriele Santilli <[giesse--writeme--com]> - Amigan - REBOL programmer Amiga Group Italia sez. L'Aquila -- http://www.amyresource.it/AGI/

 [13/19] from: rebol:techscribe at: 16-Jan-2001 21:54


Hi Gabriele, you're right (just tried it). I thought it had already been repaired in 2.3? Must've been the later experimental versions. Thanks, Elan

 [14/19] from: coussement:c:itc:mil:be at: 17-Jan-2001 10:40


> 1. I think the DBMS I developed in my REBOL book (REBOL The Official > Guide) may be a starting point (chapters 15-18). It's not the "last > word" in developing a dbms under REBOL, but it does provide some > thoughts and examples that may be useful for you. I think the Object > Navigator might come in handy.
[I already read it. Great book. it taught me REBOL...]
> You appear to follow the Object Pascal (Delphi) conventions.
[IMHO those are just general conventions within OO analysis and development. For sure I didn't find them out !]
> > - private access : the method can be called only from scripts in > the > > object for which the function was declared (including the sub-objects); > the > > method cannot be called from descendant of the object. > > Hidden objects or contexts are not protected from descendants.
[Do you mean by this it shouldn't be possible to implement it in REBOL ?]
>  > See what I wrote above. If you enforce c) then you cannot use REBOL's > default functions for saving an object from outside of the object. The > serialization functions included IN objects can - of course - make use > of write and save.
[It's the way I already followed. I will couple this approach with subobject or 'use for enforcing privacy.]
> Note that - as demonstrated - it is possible to get at the hidden > stuff, if you go out of your way to do so.
[the meaning of all this is to protect code from accidental use, not to enforce paranoia ! So I think your approach is all OK ...]
> The solution IMHO is to implement your own objects and supporting > function in which you enforce private/protected/public rules. As long as > your code does not use REBOL's built-in functions to violate these > rules, you're fine, provided you don't mind the extra overhead.
[Thanks a lot for your good advises ! BTW is there anybody interested by the results I will get ? I do not want to spam the list with uninteresting stuff... Best Regards, chr== ]

 [15/19] from: al:bri:xtra at: 17-Jan-2001 23:33


> BTW is there anybody interested by the results I will get ? I do not want
to spam the list with uninteresting stuff... I'm interested. Andrew Martin Oo Look Rebool... ICQ: 26227169 http://members.nbci.com/AndrewMartin/

 [16/19] from: rebol:techscribe at: 17-Jan-2001 11:43


Hi Christophe,
> > Hidden objects or contexts are not protected from descendants. > [Do you mean by this it shouldn't be possible to implement it in > REBOL ?]
No, I mean that using REBOL's default inheritance mechanism, i.e.
>> o: make object! [foo: none make object! [bar: does ["I'm hidden"] set 'foo does [bar] ] ] >> p: make o [foobar: "I'm p"]
p will have inherited foo as a functions that successfully calls bar just like o does. This leads to the following situation. Given:
>> o: make object! [
foo: none set-bar: none make object! [ bar: none set 'foo does [bar] set 'set-bar func [value] [ bar: value ] ] ]
>> p: make o [] >> o/set-bar "I was set by o." >> print ["o/foo" mold o/foo]
o/foo "I was set by o."
>> print ["p/foo" mold p/foo]
p/foo "I was set by o."
>> p/set-bar "I was set by p." >> print ["o/foo" mold o/foo]
o/foo "I was set by p."
>> print ["p/foo" mold p/foo]
p/foo "I was set by p." Note that - unlike your requirements for private values - p and o share o's private value bar. REBOL's inheritance mechanism acts in a protected way with respect to children's access to hidden object properties. This means that you should really implement your own custom object mechanism, let's call it class mechanism to separate it from REBOL's objects, which may be built on top of objects. class!: make object! [ private: none published: none public: none ] some-class: class class! [ private [ pa: none pb: none ] published [ ua: none ub: none ] public [ la: none lb: none ] ] class: func [ spec [block!] /local new-class] [ set [_ private-block _ published-block _ public-block] spec return make object! [ private: make object! private-block published: make object! published-block public: make object! public-block ] ] some-child: clone some-class clone: func [parent [object!] /local result] [ ; has to be written. I don't have the time right now. ; what takes a little more time is that you must account ; for possible complex structures such as classes embedded ;in a class, or blocks of objects/classes embedded ... ; If nothing useful pops up on the mailing list perhaps I'll implement something this evening ]
> BTW is there anybody interested by the results I will get ? I do not > want to spam the list with uninteresting stuff...
Well, as you've guessed by now, I'd even be interested in contributing some code. I think it'd be an interesting ongoing public project. Take Care, Elan

 [17/19] from: rebol:techscribe at: 17-Jan-2001 22:43


I was really in a hurry when I wrote this stuff. The class function I included was untested and incorrect. The corrected version is: class: func [ default! [object!] spec [block!] ] [ set [_ private-block _ published-block _ public-block] spec return make default! [ if private-block [private: make object! private-block] if published-block [published: make object! published-block] if public-block [public: make object! public-block] ] ] A better version is: class: func [[catch] default! [object!] spec [block!] /local class-spec] [ class-spec: make block! 6 foreach [section definition] spec [ either block? definition [ insert class-spec compose/deep [ (to set-word! section) make object! [(definition)] ] ][ throw make error! join {Expected definition of type block!. Received } [mold definition " of type " mold type? definition " instead."] ] ] return make default! class-spec ] The second version is more flexible in that it permits spec blocks that exclude any or all of the exposure signifiers (public, published, or private), the declarations may occur in any order, and it catches incorrect definitions. Hope this helps, Elan

 [18/19] from: rebol:techscribe at: 16-Jan-2001 14:26


Hi Christophe, 1. I think the DBMS I developed in my REBOL book (REBOL The Official Guide) may be a starting point (chapters 15-18). It's not the "last word" in developing a dbms under REBOL, but it does provide some thoughts and examples that may be useful for you. I think the Object Navigator might come in handy. 2.
> [In the specific context of my try for OODBMS development, the > persistence of the DBobject should indeed request to be written down > INCLUDING the private methods, because those should contain some business > intelligence needed to access/handle the contained data]
You want strictly enforced privacy, and you want the ability to save objects including their private componenets. From the point of view of privacy enforcement REBOL's built-in storage functions (write, save) are non-members that are prohibited from accessing the private components. If they are prevented from accessing the private components, how should they be able to save these private components, unless they are used from within member functions? The OODBMSs I am aware of use two strategies to save objects: a) Each object includes serialization functions used to store the object. Since the serialization functions are members of the object, they do have access to private object conponents. This can be implemented in REBOL. b) The OODBMS uses runtime system information (RTTI) to invade the privacy of the object and automatically determine the components and component types of an object. This can also be implemented in REBOL.
> [you're right ! methods would be classified in three exclusives > classes: public, private and protected
You appear to follow the Object Pascal (Delphi) conventions.
> Sample use of them could be: > - public access : the method can be called from any script in the > application.
This is supported in REBOL using paths, or GETting a value IN an object (i.e. get in object 'word).
> - private access : the method can be called only from scripts in the > object for which the function was declared (including the sub-objects); the > method cannot be called from descendant of the object.
Hidden objects or contexts are not protected from descendants. 
> - protected access : the method can be called only from scripts for > the object for which the function was declared, and its descendant.
Hidden objects or contexts are exposed to descendants.
> > c) Under no circumstances must a non-member function be able to access > > private components? > [as I see the implementation for now, my meaning of it is to enforce > the protection of the object's contain by keeping the protected/private part > out-of-bound for the context from which the object is called. That is, using > your words, your point c).
See what I wrote above. If you enforce c) then you cannot use REBOL's default functions for saving an object from outside of the object. The serialization functions included IN objects can - of course - make use of write and save. Example:
>> o: make object! [
e: none save-me: func [filename] [write/append filename mold self] make object! [ h: does [print "I'm hidden."] set 'e does [h] append second save-me [write/append mold self] ] ]
>> probe o
make object! [ e: func [] [h] save-me: func [filename][write/append filename mold self write/append filename mold self] ] save-me looks like its saving self twice. These are two different selfs. The first self is bound in the context of the public object, the second self is bound int the object used to hide the h function. I.e. the second self evaluates to the "hidden" object. We can see that by retrieving the body of the save-me function: get second in o 'save-me, and then getting and displaying the two self words, using get second ... and get fourth ... respectively, to get the value associated with the second word (self), and the fourth word (self) in the block:
>> print mold get second second get in o 'save-me
make object! [ e: func [][h] save-me: func [filename][write/append filename mold self write/append filename mold self] ]
>> print mold get fourth second get in o 'save-me
make object! [ h: func [][print "I'm hidden."] ] Note that - as demonstrated - it is possible to get at the hidden stuff, if you go out of your way to do so. The solution IMHO is to implement your own objects and supporting function in which you enforce private/protected/public rules. As long as your code does not use REBOL's built-in functions to violate these rules, you're fine, provided you don't mind the extra overhead. Take Care, Elan

 [19/19] from: coussement:c:itc:mil:be at: 22-Jan-2001 8:57


> I was really in a hurry when I wrote this stuff. The class function I > included was untested and incorrect. The corrected version is:
<<quoted lines omitted: 28>>
> incorrect definitions. > Hope this helps,
[Thanks, Elan, for this contribution. I will try to publish on a regular base the results I get. I will try to find a way to bypass the standard REBOL inheritence mechanism so I can implement private functions. BTW, I went to your site this sunday. Great look ! I like the letter type you use ;-) Kind Regards, chr== ]

Notes
  • Quoted lines have been omitted from some messages.
    View the message alone to see the lines that have been omitted