[Xotcl] Re: class methods

Gustaf Neumann neumann@wu-wien.ac.at
Wed, 25 Apr 2001 23:27:53 +0200


On Wednesday 25 April 2001 20:51, Artur Trzewik wrote:
> Halo
>
> The problem is more complicated than I have expected.
> It is true, proc are not good for this purposes.
> Classproc are very good idea but it would complicate the model.
>
> It is really a program style not to use class methods.
> If you come from C++ or Java (brr...) you will seldom use it.
> Smalltalk-programmers will miss it (there are many smalltalk based
> languages) A main usage is individual instance creation
> (such as Factory Patterns in C++ or type based polymorphismus)
> for example
>
> MyClass createFromXML "...xml string"
> MyClass createFromFooObject   myObject
>
> C++ programmers will write
>
> class MyClass {
> public:
>      MyClass(XMLNode node);
>      MyClass(FooClass myObject);
> };

 i would recommend to use "-methods" to tag the type; at the
 place, where you create instances of myclass, you will most probably
 know the kind of argument you are passing:
 
 Class MyClass
 MyClass instproc xml value { ;# convert xml value to internal rep
    ...
 }
 MyClass instproc obj value { ;# convert obj to internal rep
    ...
 }
 ...
 MyClass o1 -xml "...xml string"
 MyClass o2 -obj myObject


> > InheritClassProc instproc unknown {m args} {
> >   foreach c [[self] info heritage] {
> >     if {[info command ${c}::$m] != ""} {return [eval $c $m $args]}
> >   }
> >   next
> > }
> > Class instmixin InheritClassProc
>
> The solution do not do what I expect
> See this example. It demostrate how inheritable class method can be used
>
> Class TkWidget
> TkWidget proc testMe {} {
>    set toplevel [toplevel [Object autoname .toplevel]]
>    set inst [[self] create [Object autoname twidget] ${toplevel}.test]
>    pack $toplevel.test
>    return $inst
> }
> Class TkText -superclass TkWidget
> TkText instproc init {win} {
>      text $win
> }
> Class TkEntry -superclass TkWidget
> TkEntry instproc  init {win} {
>      puts "window $win"
>      entry $win
> }
> TkEntry testMe

 i see; what you want is not delegation to the class, where the 
 proc is defined (in this case the call to [self] in testMe would
 return "TkWidget"), but you want to evaluate the method testMe in the
 context of the calling class ([self] in testMe will return "TkEntry")

 Fortunately, we have a questionable feature in xotcl, which allows this
 currently, but notice that you have limited interception capabilities.
 it is possible to call a proc directly, bypassing the xotcl dispatcher.
##################################################################
Class InheritClassProc
InheritClassProc instproc unknown {m args} {
  foreach c [[self] info heritage] {
    if {[info command ${c}::$m] != ""} {
      return [eval ${c}::$m $args]
    }
  }
  next
}
Class instmixin InheritClassProc
###################################################################

 a casual reader will hardly notice the difference, but instead of calling
 '$c $m $args', a call to '${c}::$m $args' is performed.

 if i look at your program, the main reason for using the class proc seems
 to be to call "pack" **after** init without the need to write it into
 TkEntry or TkText. You can also use filters or an instmixin to achieve the
 same behavior:

==========================================================================
Class TkPacker
TkPacker instproc init args {
  set r [next]
  pack [[self] set name]
  return $r
}

Class TkWidget -instmixin TkPacker
TkWidget instproc init {} {
  [self] instvar toplevel
  set toplevel [toplevel [Object autoname .toplevel]]
  [self] set name ${toplevel}.[string trimleft [self] :]
}
Class TkText -superclass TkWidget
TkText instproc init {win} {
  next
  text [[self] set name]
}
Class TkEntry -superclass TkWidget
TkEntry instproc init {} {
  next
  entry [[self] set name]
}
TkEntry a
==========================================================================

 This version has the advantage that you get more predictable widet names.


> I will try to use metaclasses for my problems.
> It can be good to take a look on other new objectbased languages
> ruby, self, python.
> How do these languages handle class methods?


 this is not an easy question; the language of this list which is closest
 to XOTcl is ruby, which has a single construct named "def" to define a 
 proc or instproc (in xotcl terms). within a class definition, def Classname.methodname
 defines a class method. there is no word about inheritence of class procs in the
 documentation.

 self is quite different, since self does not have classes, but traits and mixins,
 which provide a bundle of methods through specially marked "parent" slots. since
 there are not classes, class methods can't be defined. As i see it, one needs 
 can define two slots for traits, one defined as a parent slot (which will provide
 methods for the "instances", and another slot for a separate object, that can be
 reached via delegation, which will have the counterpart of a proc. Two objects can 
 share a trait, therefore it is possible to define something like inherited class procs 
 by "manually" assigning the appropriate slot to all involved objects. This is like defining
 per object mixins to all effected classes. therefore, the short answer is no, there
 is no direct language support for this behavior.
 
 python has a rather week oo support. it has no distinction between instproc and proc,
 all methods are defined by "def". python has no class methods. the trick to achieve
 a similar behavior in python is to define a "module" and to define in the module
 a function outside the scope of a class. Therefore: there is no way get inheritance.

 hope this helps
-gustaf