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

pseudo-class inheritance at a price ?

 [1/7] from: phil:hayes:cnutarch at: 7-Oct-2001 14:25


Chris, What about this scenario.... How would you transmit an object over an IP connection and be able to type it? i.e. parent class A -> child class B parent class A -> child class C C: class-C-object-instance clientfd: open tcp://localhost:9999 insert clientfd C( ? ) <- or perhaps use a refinement C/insert clientfd close clientfd serverfd: open tcp://:9999 listen: first serverfd wait listen obj: copy first listen <- or perhaps use a refinement obj/copy listen clsoe first listen close serverfd No answers here but something that would definitely entyice me to use the class methods!

 [2/7] from: chrismorency:videotron:ca at: 7-Oct-2001 23:14


Hi Phil,
> What about this scenario.... > How would you transmit an object over an IP connection and be able to type
<<quoted lines omitted: 14>>
> No answers here but something that would definitely entyice me to use the > class methods!
Hmm, I have to admit that I haven't been thinking about object over ip connection. However, since class are still object! and object-instance are object! too (in the rebol sense), I would expect to serve both class and object through a connection... Best, Chris

 [3/7] from: chrismorency:videotron:ca at: 7-Oct-2001 23:14


Hi Christian,
> some months ago I worked an a similiar project, you can find my > code at the bottom of this mail. It's not very complete, but it > may inspire you in a way or two :)
Thanks very much for the code, I will certainly look at it. However, my implantation is almost complete...
> I don't believe this to be a big problem. There are other > dialects in REBOL differing from "native" REBOL style and > syntax, e.g. the dialects used for PARSE and VID.
Agreed.
> > 1. new class would be define like this : > > make-class 'class-name [ ... ]
<<quoted lines omitted: 5>>
> Having a special functions for deriving classes eases reading code a lot, > allowing for having 'class and 'superclass on the same line of code:
<code snip>
> What do you think?
Actually I had implemented the construct with and without refinements, but thought it might be easier for developers to use the refinements... I personnally prefer without. I'll change that ;)
> > 2. Object would be instanciated as : > > new-object-name: class-name/new
<<quoted lines omitted: 5>>
> REBOL has it's own garbage collector, do we really need > constructors and deconstructors?
Actually, a constructors might be useful to automatically assigned values to properties... as for the deconstructors, it would'nt be necessary..
> > 4. Within class declaration, methods would be define like this : > > method-name: func [value !refinement ref-value] [ ... ]
<<quoted lines omitted: 8>>
> rename your FUNC to METHOD, making the difference somewhat more obvious? > Just a thought, so.
Unfortunately, I really can't use refinements as they are currently being defined... I would have to change some implementation in my library, and some of the code of object instance really really redundant... which I try to minimize. Your idea of a METHOD is great... I'll look at it ;)
> Not beeing a REBOL guru in any way you eventually may find some > suggestions in my code :)
I'll look at it with interest. Best, Chris

 [4/7] from: jasonic:nomadics at: 8-Oct-2001 7:21


It be waaay offbase, but you may want to peek at Pyro - Python Remote Objects. Not as a suggestion to use Python instead of Rebol, but simply good progamming by an original programmer: http://pyro.sourceforge.net/ ./Jason

 [5/7] from: chrismorency:videotron:ca at: 7-Oct-2001 4:59


Hi, As I mentioned in another post earlier, I've been working for the past three weeks on a pseudo class inheritance library for Rebol/Core. This would enable rebol developers to use class to define object or class inheritance. Why ? The current implementation of object "inheritance" under rebol is done by a way of cloning (ie copying everything) from one object to the other. Hmm and ? What I've been working on enable small objects (in term of memory and method code) to refer big class (with a lot of method code). But ? However, my implementation would require some diversions from the way we actually code objects in rebol ! I would like to ask to those interested in such a library if these diversions would be inappropriate to their coding style, taste, etc... rebol source code = [ ... ] 1. new class would be define like this : make-class 'class-name [ ... ] Inherited class would be define like this : make-class/from 'class-name [ ... ] super-class-name [ ... ] would look similar to the code we currently use in make object! [ ... ] 2. Object would be instanciated as : new-object-name: class-name/new I'm thinking about adding an automatic initiation method that would be call when instanciating an object ! What about a destroy method... 3. Type validation would be send as : object-name/type-of class-name 4. Within class declaration, methods would be define like this : method-name: func [value !refinement ref-value] [ ... ] However, during execution, refinement would be use as usual : method-name "a value" mathod-name/refinement "a value" "a ref-value" 5. Class within class would be declared as such make-class 'class-name [ sub-class-within-class-name: sub-class ] where sub-class would be previously declared. Upon creation of a new-object/new, all sub-objects would have new instance of sub-class by sending new to these sub-class. 6. Extremely specific use of self/method or self/value within class-method-declaration. self/method or self/property would refer to the instance method or property... self method or self property would refer to the class method or property... 7. Specific calling of super-class within methods... 8. Current Reserved words : [class, super, self, new, type-of] I've spent a lot of time on this, I hope some people are intersted in this kind of library... otherwise I may return to my other project ;) Note : the library has not been tested enough for a public release. also, it would requires some testing by people working daily with objects in rebol, mainly rebol gurus who could tell me if everything I'm doing is proper or not ;) and how it could be better... or if a guru would like to take up the project and make it better ! I'm open to suggestion ! Best, Chris

 [6/7] from: christian:ensel:gmx at: 7-Oct-2001 12:19


Hello Christian Morency, some months ago I worked an a similiar project, you can find my code at the bottom of this mail. It's not very complete, but it may inspire you in a way or two :)
> As I mentioned in another post earlier, I've been working for the past three > weeks on a pseudo class inheritance library for Rebol/Core. This would
<<quoted lines omitted: 7>>
> in such a library if these diversions would be inappropriate to their coding > style, taste, etc...
I don't believe this to be a big problem. There are other dialects in REBOL differing from "native" REBOL style and syntax, e.g. the dialects used for PARSE and VID. And now for some comments:
> 1. new class would be define like this : > make-class 'class-name [ ... ] > > Inherited class would be define like this : > make-class/from 'class-name [ ... ] super-class-name
I for a reason decided against a construct using refinements because this would make reading your code unneccessarily hard: The specification of the superclass as an argument to a refinement leads to code looking like make-class/from 'class-name [ ;... ;... insert hundreds of line of method code here ;... ] super-class-name Having a special functions for deriving classes eases reading code a lot, allowing for having 'class and 'superclass on the same line of code: make-derived-class 'class-name 'superclass-name [ ;... ;... insert hundreds of line of method code here ;... ] What do you think?
> 2. Object would be instanciated as : > new-object-name: class-name/new > > I'm thinking about adding an automatic initiation method > that would be call when instanciating an object ! What > about a destroy method...
Actually, I haven't thought in deep about that, but as long as REBOL has it's own garbage collector, do we really need constructors and deconstructors?
> 4. Within class declaration, methods would be define like this : > method-name: func [value !refinement ref-value] [ ... ] > > However, during execution, refinement would be use as usual : > method-name "a value" > mathod-name/refinement "a value" "a ref-value"
I didn't spend effort to allow for method refinements in my OOP-framework, but IIRC there was a solution to compose function calls with refinements on the mailing list some time ago which shouldn't be to hard to implement. But if your refinement defining syntax differs from FUNC's style why not rename your FUNC to METHOD, making the difference somewhat more obvious? Just a thought, so.
> Note : the library has not been tested enough for a public release. also, it > would requires some testing by people working daily with objects in rebol, > mainly rebol gurus who could tell me if everything I'm doing is proper or > not ;) and how it could be better... or if a guru would like to take up the > project and make it better ! I'm open to suggestion !
Not beeing a REBOL guru in any way you eventually may find some suggestions in my code :) Kind regards, Christian ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> REBOL [ title: "Classes & Instances" name: %class-instances.r author: "Christian 'CHE' Ensel" date: 23-Aug-2001 ] context [ ;======================================= CLASS instance-spec class-spec == ; ------------------------------ class: func [ "Defines a user class object." instance-spec [block!] "Code per instance" class-spec [block!] "Code per class" /local new-class ] ;......................................................................... [ new-class: make object! compose [ super-class: none instance: ( make object! head insert instance-spec compose [class: none] ) (class-spec) ] new-class/instance/class: new-class new-class ] ;------------------------------------------------------------------------- ;=================== DERIVED-CLASS super-class instance-spec class-spec == ; -------------------------------------------------- derived-class: func [ "Derives a user class object from an existing class object." super-class [object!] "Class to inherit from" instance-spec [block!] "Code per instance" class-spec [block!] "Code per class" /local new-class ] ;......................................................................... [ new-class: make super-class compose [ super-class: (super-class) instance: (make super-class/instance instance-spec) (class-spec) ] new-class/instance/class: new-class new-class ] ;------------------------------------------------------------------------- ;========================================= INSTANCE class instance-spec == ; ---------------------------- instance: func [ "Returns an instance object of desired class." class [object!] "Class to belong to" instance-spec [block!] "Instance-specific code" /local new-instance ] ;......................................................................... [ new-instance: make class/instance instance-spec ] ;------------------------------------------------------------------------- ;==================================== DO-METHOD instance message /SUPER == ; --------------------------------- do-method: func [ [catch] "Dispatch a class method, throw error for unknown methods." instance [object!] "Instance" message [block!] {Block containing method word and argument words, if any} /super "Invoke method of super-class." /local method ] ;......................................................................... [ method: in either super [ instance/class/super-class ][ instance/class ] first message if none? method [ throw make error! reduce ['script 'unknown-method first message] ] method: get method do compose [(:method) (instance) (next message)] ] ;------------------------------------------------------------------------- ;============================== TRY-METHOD instance message /ANY /SUPER == ; --------------------------------------- try-method: func [ "Dispatch a method, do nothing for unknown methods." instance [object!] "Instance" message [block!] {Block containing method word and argument words, if any} /super "Invoke method of super-class." /local method ] ;......................................................................... [ method: in either super [ instance/class/super-class ][ instance/class ] first message either none? method [none] [ method: get method do compose [(:method) (instance) (next message)] ] ] ;------------------------------------------------------------------------- ;============================================ IS? class instance /EXACT == ; ------------------------- is?: func [ "Returns TRUE if instance is (indirect) instance of given class." class [object!] "Class" instance [object!] "Instance" /exact "Return TRUE only for direct instances of given class." /local instance-class ] ;......................................................................... [ either exact [ equal? instance/class class ][ instance-class: instance/class forever [ if equal? instance-class class [break/return true] instance-class: instance-class/super-class if none? instance-class [break] ] ] ] ;------------------------------------------------------------------------- ;=============================================================== IMPORT == ; ------ import: func [ "Expose dialect to global context." ] ;......................................................................... [ set bind [ class derived-class instance is? do-method try-method ] in system/words 'context reduce [ :class :derived-class :instance :is? :do-method :try-method ] return ] ;------------------------------------------------------------------------- ;----------------------------------- SYSTEM/ERROR/SCRIPT/UNKNOWN-METHOD -- ; system/error/script: make system/error/script [ unknown-method: ["Method" :arg1 "not declared"] ] ;------------------------------------------------------------------------- ] ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> And here's an example demonstrating the use of the above: ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> REBOL [ title: "Classes & Instances - Example" name: %class-instances-sample.r author: "Christian 'CHE' Ensel" date: 23-Aug-2001 ] do in do %/rebol/scripts/class-instances.r 'import do sample: [ human!: class [ name: none age: none ][ introduce: function [human [object!]] [] [ do-method human [say rejoin ["Hi, I'm " human/name "!"]] do-method human [say rejoin ["I'm " human/age " years old."]] do-method human [say "I'm human."] ] say-to: function [human [object!] whom [object!] what [string!]] [] [ do-method human [ say rejoin [whom/name ", " lowercase/part what 1] ] ] say: function [human [object!] what [string!]] [] [ print rejoin [human/name {: ^-"} what {"}] ] ] man!: derived-class human! [] [ introduce: function [man [object!]] [] [ do-method/super man [introduce] do-method man [say "And I'm a man."] ] ] woman!: derived-class human! [] [ introduce: function [woman [object!]] [][ do-method/super woman [introduce] do-method woman [say "And I'm a woman."] ] bewitch: function [woman [object!] whom [object!]] [][ do-method woman [say-to whom "Eat this!"] ] ] human: instance human! [name: "Nobody"] adam: instance man! [name: "Adam" age: 32] eve: instance woman! [name: "Eve" age: 27] linda: instance woman! [name: "Linda" age: 28] do-method adam [say "Hello, I'm Adam."] prin newline do-method eve [say "Hello, I'm Eve."] prin newline do-method adam [introduce] prin newline do-method eve [bewitch adam] prin newline do-method/super eve [introduce] prin newline try-method adam [bewitch eve] prin newline do-method linda [introduce] prin newline do-method linda [say-to adam "You'd better eat this banana."] prin newline do-method/super linda [say-to adam "You'd better eat this banana."] prin newline if is? human! adam [print "Adam is a human."] ] ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

 [7/7] from: christian:ensel:gmx at: 9-Oct-2001 21:16


Hello Christian,
>> No answers here but something that would definitely entyice me to use the >> class methods! > Hmm, I have to admit that I haven't been thinking about object over ip > connection. However, since class are still object! and object-instance are > object! too (in the rebol sense), I would expect to serve both class and > object through a connection...
Whenever it comes to making OOP objects persistent - and at the very moment I don't see too much of a difference between writing class instances to disk and transferring them over networkobjects - there's the problem of correctly identifing the class a object belongs to. Now, while thinking about that today's evening I've had an idea (don't know if someone had this idea too long before me, at least till now I never heard of it :) Instead of letting Joe User (Joe Developer, to be exact) name it's classes and later watching him running into the problem of names clashing between different developers naming different classes using the same name, why not let the user take care of forgiving _universally_ _unique_ _class_ _names_? This could be achieved very easily if we adopt the model XML uses for namespaces: foo: make object! [ super: none class: http://www.christian-ensel.de/classes/foo.r ... ] bar: make object! [ super: http://www.foobar.com/classes/foo.r class: http://www.foobar.com/classes/bar.r ... ] This also may serve as a solution to the networking problem as well, because everyone who wants to work with such class based objects knows where to get the class definition. Or am I missing something? Regards, Christian (Ensel :)

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