Prev: Is it possible to specify in TclOO classes a kinds of operators? (e.g. == or "eq")
Next: Making a Scrollable Widget
From: MartinLemburg on 15 Feb 2010 09:47 Hello, I've took the following example from the wiki page http://wiki.tcl.tk/18440: % info patchlevel 8.6b1.1 % package require TclOO 0.6.1 % oo::class create foo { constructor {} {next; puts foo} } ::foo % oo::class create bar { constructor {} {next; puts bar} } ::bar % oo::class create foobar { superclass foo bar; constructor {} {next; puts foobar}} ::foobar % oo::class create geek {constructor {} {next; puts geek}} ::geek % oo::class create mongrel {superclass foobar geek; constructor {} {next; puts mongrel}} ::mongrel % [mongrel new] destroy no next constructor implementation % set errorInfo no next constructor implementation while executing "next" (class "::geek" constructor line 1) invoked from within "next" (class "::bar" constructor line 1) invoked from within "next" (class "::foo" constructor line 1) invoked from within "next" (class "::foobar" constructor line 1) invoked from within "next" (class "::mongrel" constructor line 1) invoked from within "mongrel new" Removing the "next" calls in the non-inheriting classes lead to the following result: % oo::class create foo { constructor {} {puts foo} } ::foo % oo::class create bar { constructor {} {puts bar} } ::bar % oo::class create geek {constructor {} {puts geek}} ::geek % oo::class create foobar { superclass foo bar; constructor {} {next; puts foobar}} ::foobar % oo::class create mongrel {superclass foobar geek; constructor {} {next; puts mongrel}} ::mongrel % [mongrel new] destroy foo foobar mongrel The result is unexpected for me. I expected something like: % [mongrel new] destroy foo bar foobar geek mongrel So I miss the calls to the constructors of the classes "bar" and "geek", which are always the 2nd super classes in the classes "foobar" and "mongrel". Is the chain of invocation via next broken? Or do I miss something? ----- The reason I tested this is, that I wanted to have super classes with constructors with different count of arguments and I looked for a way to achieve the call of this super class constructors - with no success. ----- Any hints or suggestions? Thanks in advance, Martin
From: APN on 15 Feb 2010 11:01 http://sourceforge.net/tracker/?func=detail&aid=2952145&group_id=10894&atid=110894 /Ashok On Feb 15, 7:47 pm, "MartinLemburg(a)Siemens-PLM" <martin.lemburg.siemens-...(a)gmx.net> wrote: > Hello, > > I've took the following example from the wiki pagehttp://wiki.tcl.tk/18440: > > % info patchlevel > 8.6b1.1 > % package require TclOO > 0.6.1 > % oo::class create foo { constructor {} {next; puts foo} } > ::foo > % oo::class create bar { constructor {} {next; puts bar} } > ::bar > % oo::class create foobar { superclass foo bar; constructor {} > {next; puts foobar}} > ::foobar > % oo::class create geek {constructor {} {next; puts geek}} > ::geek > % oo::class create mongrel {superclass foobar geek; constructor {} > {next; puts mongrel}} > ::mongrel > % [mongrel new] destroy > no next constructor implementation > % set errorInfo > no next constructor implementation > while executing > "next" > (class "::geek" constructor line 1) > invoked from within > "next" > (class "::bar" constructor line 1) > invoked from within > "next" > (class "::foo" constructor line 1) > invoked from within > "next" > (class "::foobar" constructor line 1) > invoked from within > "next" > (class "::mongrel" constructor line 1) > invoked from within > "mongrel new" > > Removing the "next" calls in the non-inheriting classes lead to the > following result: > % oo::class create foo { constructor {} {puts foo} } > ::foo > % oo::class create bar { constructor {} {puts bar} } > ::bar > % oo::class create geek {constructor {} {puts geek}} > ::geek > % oo::class create foobar { superclass foo bar; constructor {} > {next; puts foobar}} > ::foobar > % oo::class create mongrel {superclass foobar geek; constructor {} > {next; puts mongrel}} > ::mongrel > % [mongrel new] destroy > foo > foobar > mongrel > > The result is unexpected for me. I expected something like: > % [mongrel new] destroy > foo > bar > foobar > geek > mongrel > > So I miss the calls to the constructors of the classes "bar" and > "geek", which are always the 2nd super classes in the classes "foobar" > and "mongrel". > > Is the chain of invocation via next broken? Or do I miss something? > > ----- > > The reason I tested this is, that I wanted to have super classes with > constructors with different count of arguments and I looked for a way > to achieve the call of this super class constructors - with no > success. > > ----- > > Any hints or suggestions? > > Thanks in advance, > > Martin
From: Donal K. Fellows on 15 Feb 2010 11:25 On 15 Feb, 14:47, "MartinLemburg(a)Siemens-PLM" <martin.lemburg.siemens-...(a)gmx.net> wrote: > I've took the following example from the wiki page http://wiki.tcl.tk/18440: > > % info patchlevel > 8.6b1.1 > % package require TclOO > 0.6.1 You're using an old version of the code there. If you're not going to use 8.6b1 itself (or 8.6b2, but that doesn't exist yet) then you should make sure you're up to date with the HEAD. Indeed, the tip of TclOO has been known as 0.6.2 since the end of November. > So I miss the calls to the constructors of the classes "bar" and > "geek", which are always the 2nd super classes in the classes "foobar" > and "mongrel". > > Is the chain of invocation via next broken? Or do I miss something? I suspect this relates to the fix for Bug 1998244. What to do about it (if anything) I don't know yet. > The reason I tested this is, that I wanted to have super classes with > constructors with different count of arguments and I looked for a way > to achieve the call of this super class constructors - with no > success. You're talking about having a class that derives from two independent classes? In an ontological sense, that's a bit dodgy; if the two classes don't know about each other, how can they possibly pass the right arguments to each other's constructor? There's got to be some shared context for it to even make sense, and that's probably best done through a common superclass. (In that case, you can use option- value pairs as arguments, have each of the "independent" classes strip out the arguments it understands and pass the rest on, and have the common superclass moan about any that get through that it doesn't handle itself.) If this isn't a suitable solution, please provide more information about the real situation that needs this sort of technique. Be prepared to have me ask why delegating to a contained object is an insufficient scheme, but if you've got a real case, I'd love to hear it. I've never encountered a real one that made sense. Donal.
From: MartinLemburg on 16 Feb 2010 02:55 Hi Donal, thanks for your detailed answer! First - where could I get a binary distribution of the most current version? I ask, because I usually build starpacks using the base-kits from the most current ActiveTcl distribution. I have no "build" environment for tcl sources, so I'm not able to fetch something from a CVS or SVN repository and to build it on my own. Second - I changed my coding, so my second "base" class is now used via aggregation. I working on a Microsoft RC file parser rebuilding the structures found there using Tk (BWidget) widgets and tcl msgcats. Some of the RC file structures are not only resources but widget( collection)s, too. So I thought to make a "union" of both base classes Resource and Widget - that's all. I can live with the changes, but I would have thought it would be "easy" to use multiple inheritance and hoped it would be possible - without tricks - to invoke constructors or methods from base class(es) more easier and more transparent. In C++ I often use "_super::.+" or "${BaseClass}::.+", which does not ASAIK open a new stack frame and allows to delegate to base class methods with a specified set of arguments, while TclOO's next has IMHO a "intransparent" call chain. It is not clear which method will called first - especially with multiple inheritance, multiple mixins. And this call sequence is not guaranteed to be "stable". And the called methods are not to be specified. So I can't delegate to two or more base class constructors with different sets of arguments without doing tricks like using "option" sets - you mentioned this. Why not introducing this C++ like call delegation? Introducing a command "super" standing next to "self" and "next" would be that problematic. And if there are more than one super/base class, than a "[$ {BaseClass}::(constructor|\w+) .+]" usage should be allowed. Third - is there a good introduction or tutorial in using TclOO? I don't mean the wiki pages, nor I want to study sources. Or ... is it possible to upgrade the TclOO man pages to contain an introduction into the capabilities and the philosophy (e.g. mixin's) additional to the normal "syntax" explanations? Thanks and best regards, Martin On 15 Feb., 17:25, "Donal K. Fellows" <donal.k.fell...(a)manchester.ac.uk> wrote: > On 15 Feb, 14:47, "MartinLemburg(a)Siemens-PLM" > > <martin.lemburg.siemens-...(a)gmx.net> wrote: > > I've took the following example from the wiki pagehttp://wiki.tcl.tk/18440: > > > % info patchlevel > > 8.6b1.1 > > % package require TclOO > > 0.6.1 > > You're using an old version of the code there. If you're not going to > use 8.6b1 itself (or 8.6b2, but that doesn't exist yet) then you > should make sure you're up to date with the HEAD. Indeed, the tip of > TclOO has been known as 0.6.2 since the end of November. > > > So I miss the calls to the constructors of the classes "bar" and > > "geek", which are always the 2nd super classes in the classes "foobar" > > and "mongrel". > > > Is the chain of invocation via next broken? Or do I miss something? > > I suspect this relates to the fix for Bug 1998244. What to do about it > (if anything) I don't know yet. > > > The reason I tested this is, that I wanted to have super classes with > > constructors with different count of arguments and I looked for a way > > to achieve the call of this super class constructors - with no > > success. > > You're talking about having a class that derives from two independent > classes? In an ontological sense, that's a bit dodgy; if the two > classes don't know about each other, how can they possibly pass the > right arguments to each other's constructor? There's got to be some > shared context for it to even make sense, and that's probably best > done through a common superclass. (In that case, you can use option- > value pairs as arguments, have each of the "independent" classes strip > out the arguments it understands and pass the rest on, and have the > common superclass moan about any that get through that it doesn't > handle itself.) > > If this isn't a suitable solution, please provide more information > about the real situation that needs this sort of technique. Be > prepared to have me ask why delegating to a contained object is an > insufficient scheme, but if you've got a real case, I'd love to hear > it. I've never encountered a real one that made sense. > > Donal.
From: Donal K. Fellows on 16 Feb 2010 04:53
On 16 Feb, 07:55, "MartinLemburg(a)Siemens-PLM" <martin.lemburg.siemens-...(a)gmx.net> wrote: > First - where could I get a binary distribution of the most current > version? > > I ask, because I usually build starpacks using the base-kits from the > most current ActiveTcl distribution. The current version of TclOO for Tcl 8.5 in the ActiveState teapot is up to date (apart from one small but nasty issue with destructor execution which is unfixable because it required a small change to Tcl to provide the necessary hook). Make sure you're using version 0.6.2. (And I'm getting very close to taking on doing release management myself just so that we can get Tcl 8.6b2 out the door, and I utterly *hate* doing release management!) > In C++ I often use "_super::.+" or "${BaseClass}::.+", which does not > ASAIK open a new stack frame and allows to delegate to base class > methods with a specified set of arguments, while TclOO's next has IMHO > a "intransparent" call chain. I understand. The problem is that I really want to have unified semantics for constructors and other methods, and that means a single system for traversing the call chain. (There's also no unified syntax for naming methods, but that's of lesser concern.) Where there is no unified way of handling a variable number of arguments, that makes doing constructors quite difficult. OTOH, I want to be able to support positional arguments anyway (it helps a lot with simpler uses) and putting a magical default "consume all arguments and don't complain" constructor in oo::object just covers up real problems. It's tricky. The itcl package that's built on top of TclOO *does* permit the sort of superclass implementation selection that you're talking about. > It is not clear which method will called first - especially with > multiple inheritance, multiple mixins. And this call sequence is not > guaranteed to be "stable". And the called methods are not to be > specified. All I can guarantee is that if class B inherits from class A, then A's implementation of the method/constructor will be further along the linearized chain of implementations than B's. Anything else just gets too complicated! > Why not introducing this C++ like call delegation? Principally, because I suspect that those cases where people demand it are actually cases where inheritance is being misused. Inheritance is not for modeling rôles (that's what mixins are for) so where you've got multiple inheritance you really need to be thinking in terms of a class that is naturally a specialization of both its superclasses. I've yet to see a satisfying example of this, and I (probably) won't do anything about this until someone demonstrates a proper motivating example. So far, the only concrete example that anyone's tried involved widget classes, and that turned out to be an abuse because the child class was really not very much like one of the parent classes in that a dialog widget isn't subject to normal geometry management rules, etc. > Third - is there a good introduction or tutorial in using TclOO? Not yet. I understand that Clif Flynt is working on an update to his book and he's threatened to pester me for help with writing the chapter(s?) on TclOO. > Or ... is it possible to upgrade the TclOO man pages to contain an > introduction into the capabilities and the philosophy (e.g. mixin's) > additional to the normal "syntax" explanations? Yes, it's very possible. But I'm too close to the implementation (and have too much training in object theory too) to see what tutorial material needs to be there. I need people to propose material, to tell me what they don't understand, to help me grasp the detail of what to add. Help me help you! Donal. |