No registered users in community xowiki
in last 10 minutes
in last 10 minutes
[Xotcl] Re: class methods
From: Gustaf Neumann <neumann_at_wu-wien.ac.at>
Date: 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
Date: 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