''[APW] 2007-06-06'' Some time ago I started efforts to reimplement [Itcl] on top of [tclOO] [http://tip.tcl.tk/257]. I started based on [tclOO], using only the [API] functions of [tclOO] and a lot of additonal code in [C]. With that approach I had about 90% of the test suite of Itcl running successfully, but I saw, after all that, I was only using a small part of [tclOO] code. My second approach was implementing a [TMOS]-like [http://www.tcl.tk/cgi-bin/tct/tip/279.html] extension using a lot of code from the [XOTcl] reference implementation and again achieved about 90% of the test suite of Itcl running successfully. I felt that the code was too big and too complicated, partially because of having all these XOTcl features running. Additionally there were some features of Itcl which would have needed a lot of redesign of that code to pass the Itcl test suite. So I decided to come back to the [tclOO] implementation, thinking that it is, after all, the best starting point. This time I changed/extended the [tclOO] code directly so as to be able to use as much as possible of that code, because I had the feeling it has a lot of good implemented features, which I did like to use. I also did like the implementation of the dispatch and [class]/[object] creation mechanism much more than the one in the TMOS implementation. I started implementing [extension]s to tclOO (directly in [tclOO], as the [API] is not enough) to get a lot of features of Itcl to run. This includes a lot of code implemented in [pure-Tcl] on top of [tclOO]. Doing that, I learned a lot more details and "specialities" about Itcl. Currently I have an implementation which is successfully in running about 70% of the Itcl test suite. Having now a better feeling about what is needed for Itcl, I will start to write down the missing tclOO features and my solutions for them, in the hope that there will be some comments (especially from [dkf]). These comments could also include suggestions on how to solve the problem in a different way, without having to modify tclOO. In the following, ''solution'' means that is my current (not always optimal) solution for the problem. In the code examples I am using a meta syntax, not the [Itcl] or [tclOO] syntax, to make the code shorter! Here starts the list; I will add topics as they come up: ---- what: '''[Namespace] names for Itcl''' problem: Itcl expects that the namespace of a class is the same as the class name solution: add an option -withnamespace or a [method] createwithnamespace [DKF]: This is actually a serious problem, since the current design of the system specifically decouples the namespace and the class (i.e. object) name. ---- what: '''calling of [method]s without''' ''my'' '''in front of the method name''' problem: Itcl resolves command calls first within the class hierarchy before using the normal Tcl rules solution: add a [namespace unknown] command as a dispatcher for Itcl methods [DKF]: Good solution. ---- what: '''access to [class] [variable]s''' problem: Itcl has 3 protection levels which guard the access to class variables in the class hierachy. solution: I use the [apply] command for constructing the body parts for the class methods (and [constructor]s and [destructor]s) after the complete class has been parsed and all classes in the hierarchy are known. There is an additional parameter, ''self,'' added automatically to the arguments of the method, and the variables of all the classes in the hierarchy are mapped using namespace upvar. Variables in Itcl have to live in the namespace where they are defined as there might be the same variable name in different classes in the hierarchy even with different protection (private, protected and public). In generating the namespace upvar commands the private variables of inherited classes are skipped. [DKF]: implement the ''self'' variable by prepending each method body with: set self [self] ---- what: '''Itcl rules for calling/traversing the constructors and destructors''' problem: the rules for traversing the constructors/destructors in Itcl are very "special" and cannot be mapped to the model in tclOO. Example: class foo { constructor {args} { puts foo } } class bar { constructor {args} { puts bar } } class foobar { superclass foo bar constructor {args} { puts foobar } } class geek { constructor {args} { puts geek } } class mongrel { superclass foobar geek constructor {args} { puts mongrel } } output: geek bar foo foobar mongrel In other words Itcl walks through the list of superclasses starting at the end based on the definition order. It looks for inherited classes up to the root class and unrolls the built stack. Then for the next class in inheritance, the same is done. solution: new command: "invokeitclconstructors" similar to the [[next]] command in [tclOO] (to be done: add details here) [DKF]: The [next] command, if put ''first'', causes the constructors to be walked in the desired order. % package req TclOO; namespace path oo % class create foo { constructor {} {next; puts foo} } ::foo % class create bar { constructor {} {next; puts bar} } ::bar % class create foobar { superclass foo bar; constructor {} {next; puts foobar}} ::foobar % class create geek {constructor {} {next; puts geek}} ::geek % class create mongrel {superclass foobar geek; constructor {} {next; puts mongrel}} ::mongrel % [mongrel new] destroy geek bar foo foobar mongrel [DKF]: Discussion seems to indicate that there is a deeper problem here, but not one I understand yet. [APW]: I need ''info class superclasses ...'' on a lot of places for Itcl and it returns the class names not in the order the have been defined, so I am calling class create mongrel {superclass geek foobar; constructor {} {next; puts mongrel}} to get the order as expected in Itcl, for the Itcl input: itcl::class mongrel { inherit foobar geek; constructor {} {puts mongrel}} ---- what: '''Itcl special init code script in constructors''' problem: in Itcl constructors it is possible to define an init script, which is invoked directly before the code in the constructor, but after the object is instantiated. Example: the script after the arguments and before the body is the "constructor init code" class foo { constructor {args} { puts foo } } class bar { constructor {args} { puts bar } } class foobar { superclass foo bar constructor {args} { foo::constructor ; # this is the init code which calls the constructor of class foo } { puts foobar } } class geek { constructor {args} { puts geek } } class mongrel { superclass foobar geek constructor {args} { foobar::constructor } { puts mongrel } } output: foo bar foobar geek mongrel solution: add the init code script in building the apply code for the constructors [DKF]: Definitely sounds like you need a custom '''constructor''' command. It might even be easier to not use TclOO constructors at all and instead define your own scheme using multiple methods (this is what you'd have to do if doing [XOTcl] on top of TclOO). ---- what: '''Itcl command [itcl::body]''' problem: In Itcl, there are several ways to partially define a method: protection + name, protection + name + params, protection + name + params + body. That method can be redefined later on, but the params list for the method - if defined in the class definition - has to be compatible. solution: add additional information about method params and status to each method definition in the tclOO internal structures. There is an additional problem in that tclOO cannot handle partially defined methods, the solution to which is adding this functionality. [DKF]: I thought about having abstract methods - early drafts had it in - but in the end I took it out. I reasoned that it would be easier to implement such things on top of a basic core than it would be to figure out how to do it directly. ---- what: '''Itcl info command''' problem: getting the original body of a method when using apply internally solution: save the original body in the tclOO internal structures of a method. In general I am generating a method '''info''' within each class. That is like a class proc in Itcl syntax. It is something like a singleton method and it can be called without an object being instantiated. '''info''' first trys the Itcl specific commands, and if that does not work, it forwards to the ::info command. [DKF]: I think this sort of thing should be fairly simple to hang off the metadata mechanism. ---- what: '''Itcl singelton methods''' problem: In Itcl it is possible to have class methods which are like singletons. They can be called uisng the class or an instantiated object. Nevertheless, if they have protection level ''protected'' they can be only called from within the class namespace. That will not work with the current tclOOCall.c implementation, as it just calls unknown and also if that is a user defined method, there is not enough information available for specific diagnostics. solution: Add some code in AddMethodToCallChain, to do some additional checks and use a class specific call back to report the appropriate error. ---- what: '''Itcl methods calls and protection violation error''' problem: In Itcl it is necessary to generate specific error messages when a protection violation is detected. That will not work with the current tclOOCall.c implementation. solution: Add some code in AddMethodToCallChain, to use a class specific call back in that case, which can be set via a setprotectioncallback command, to report the appropriate error. ---- ---- [APW] I would feel happy if native english speakers could correct the wording and the grammar above where necessary. ''[escargo]'' - I think it might be clearer if instead of mixing bullets and definition lists, the text that is currently part of the bullet was at the beginning of the text after ''problem'' (maybe in bold face or italic to set it off). That's too radical a chance for me to make without checking for other opinions first. I think the list would also take up less space on the page. [APW] You are right, I am also not happy with the layout, but it was the best, which I was able to produce. If someone knows better please go ahead. Have changed a little bit, but don't know a method to get the text behind "problem:" instead of the next line. ''[escargo]'' - I stuck in some horizontal rules to make the ''problem'' - ''solution'' pairs more obvious, but I think the result looks much better. ''[APW]'' Yes indeed! [jcw] - I changed the last example, maybe you like that better - else, just restore it, please :) ''[APW]'' - Thanks [jcw], I have added another tag, maybe that's a better solution to what I had in mind. ---- [[ [Category Discussion] | [Category Itcl] | [Category Object Orientation] ]]