Take a look at this code:
package require XOTcl 1.6 namespace import xotcl::*
Class Foo
Foo instproc hello {} { puts hello }
Foo instproc myfilter {args} { puts "\nme: [self]" ::set targetclass [my info class] puts "targetclass: $targetclass" puts "calledproc: [self calledproc]" ::set r [next] puts "back from next" puts "paramcmds: [$targetclass info instparametercmd]" }
Foo instfilter myfilter
Foo ob ob hello ob foo
So first I have a filter installed which does nothing but print some information, and checks something using the [info] method afterwards. I call an instantiated object with [hello] (an existing method) and again with [foo] (a non-existing method). The latter is when things get interesting. Check the output:
me: ::ob targetclass: ::Foo calledproc: configure back from next paramcmds:
me: ::ob targetclass: ::Foo calledproc: init back from next paramcmds:
me: ::ob targetclass: ::Foo calledproc: hello hello back from next paramcmds:
me: ::ob targetclass: ::Foo calledproc: foo back from next
me: ::alloc ::alloc: unable to dispatch method 'info' while executing "my info class" (procedure "cleanup" line 4) ::alloc ::Foo->myfilter ::Foo ::xotcl::Class->recreate ::Foo ::xotcl::Class->create ::Foo ::xotcl::Class->unknown ::Foo ::xotcl::Class->create ::Foo ::xotcl::Class->unknown ::Foo ::xotcl::Class->create ::Foo ::xotcl::Class->unknown invoked from within "$targetclass info instparametercmd" (procedure "foo" line 9) ::ob ::Foo->myfilter invoked from within "ob foo" (file "filtertest.tcl" line 24)
me: ::alloc targetclass: ::Foo calledproc: destroy back from next paramcmds:
me: ::info targetclass: ::Foo calledproc: destroy back from next paramcmds:
me: ::ob targetclass: ::Foo calledproc: destroy back from next paramcmds:
... So while the [hello] method works as expected, things get totally weird for [foo]. The first thing we notice is that it doesn't jump out at [next] (which should give an error as it does not exist). It continue execution of the filter after [next]. This may or may not be intended, I don't know. The documentation is not clear on this.
More interesting still, we end up with a totally unexpected error. The thing I believe is happening is that, for some reason or other [$targetclass info instparametercmd] is not ending up calling [info] for $targetClass, but creating an object called ::info (and thus overriding the original Tcl command). How [alloc] gets involved in the filter chain too, I am not sure. My guess is that the "unknown method" that resulted from [foo] is being interpreted by the XOTcl $targetclass C implementation as an error that occurred there, and that a new instance called "info" or possibly "alloc" should be created.
This causes major havoc as soon as an unknown method is called. Does the filter code look correct?
This happens with 1.6.2. I had a quick look at CHANGES for later versions and while there was some mention of memory leaks in [info] I wasn't sure if there was anything that would have fixed this.
Any ideas?
Dear Kristoffer,
many things went wrong. It is true, there is a bug in all XOTcl 1.* releases, which is there most likely since many years (8+).
the bug:
- when a filter chain comes to its end without finding the method (e.g. "ob foo"), xotcl records its fact, but this affected as well the method invocations from the filter after the "next".
- The call "$targetclass info ..." was then letal especially with the standard unknown handler of the metaclass: xotcl belived incorrectly that "info" is unknown, and since an "unknown" call on a class (here $targetclass) creates an object, it was creating the object "info" as instance of that class, and the nightmare turned even worse.
I have fixed the bug in 1.6.6, you can obtain it via
git clone git://alice.wu-wien.ac.at/xotcl
best regards -gustaf neumann
Am 29.08.10 03:02, schrieb Kristoffer Lawson:
Take a look at this code:
package require XOTcl 1.6 namespace import xotcl::*
Class Foo
Foo instproc hello {} { puts hello }
Foo instproc myfilter {args} { puts "\nme: [self]" ::set targetclass [my info class] puts "targetclass: $targetclass" puts "calledproc: [self calledproc]" ::set r [next] puts "back from next" puts "paramcmds: [$targetclass info instparametercmd]" }
Foo instfilter myfilter
Foo ob ob hello ob foo
So first I have a filter installed which does nothing but print some information, and checks something using the [info] method afterwards. I call an instantiated object with [hello] (an existing method) and again with [foo] (a non-existing method). The latter is when things get interesting. Check the output:
me: ::ob targetclass: ::Foo calledproc: configure back from next paramcmds:
me: ::ob targetclass: ::Foo calledproc: init back from next paramcmds:
me: ::ob targetclass: ::Foo calledproc: hello hello back from next paramcmds:
me: ::ob targetclass: ::Foo calledproc: foo back from next
me: ::alloc ::alloc: unable to dispatch method 'info' while executing "my info class" (procedure "cleanup" line 4) ::alloc ::Foo->myfilter ::Foo ::xotcl::Class->recreate ::Foo ::xotcl::Class->create ::Foo ::xotcl::Class->unknown ::Foo ::xotcl::Class->create ::Foo ::xotcl::Class->unknown ::Foo ::xotcl::Class->create ::Foo ::xotcl::Class->unknown invoked from within "$targetclass info instparametercmd" (procedure "foo" line 9) ::ob ::Foo->myfilter invoked from within "ob foo" (file "filtertest.tcl" line 24)
me: ::alloc targetclass: ::Foo calledproc: destroy back from next paramcmds:
me: ::info targetclass: ::Foo calledproc: destroy back from next paramcmds:
me: ::ob targetclass: ::Foo calledproc: destroy back from next paramcmds:
... So while the [hello] method works as expected, things get totally weird for [foo]. The first thing we notice is that it doesn't jump out at [next] (which should give an error as it does not exist). It continue execution of the filter after [next]. This may or may not be intended, I don't know. The documentation is not clear on this.
More interesting still, we end up with a totally unexpected error. The thing I believe is happening is that, for some reason or other [$targetclass info instparametercmd] is not ending up calling [info] for $targetClass, but creating an object called ::info (and thus overriding the original Tcl command). How [alloc] gets involved in the filter chain too, I am not sure. My guess is that the "unknown method" that resulted from [foo] is being interpreted by the XOTcl $targetclass C implementation as an error that occurred there, and that a new instance called "info" or possibly "alloc" should be created.
This causes major havoc as soon as an unknown method is called. Does the filter code look correct?
This happens with 1.6.2. I had a quick look at CHANGES for later versions and while there was some mention of memory leaks in [info] I wasn't sure if there was anything that would have fixed this.
Any ideas?
... forgot to mention: You have to return the result of "next" as return of the filter (in the case of your example $r).
all the best -gustaf neumann
Am 29.08.10 13:54, schrieb Gustaf Neumann:
Dear Kristoffer,
many things went wrong. It is true, there is a bug in all XOTcl 1.* releases, which is there most likely since many years (8+).
the bug:
when a filter chain comes to its end without finding the method (e.g. "ob foo"), xotcl records its fact, but this affected as well the method invocations from the filter after the "next".
The call "$targetclass info ..." was then letal especially with the standard unknown handler of the metaclass: xotcl belived incorrectly that "info" is unknown, and since an "unknown" call on a class (here $targetclass) creates an object, it was creating the object "info" as instance of that class, and the nightmare turned even worse.
I have fixed the bug in 1.6.6, you can obtain it via
git clone git://alice.wu-wien.ac.at/xotcl
best regards -gustaf neumann
Am 29.08.10 03:02, schrieb Kristoffer Lawson:
Take a look at this code:
package require XOTcl 1.6 namespace import xotcl::*
Class Foo
Foo instproc hello {} { puts hello }
Foo instproc myfilter {args} { puts "\nme: [self]" ::set targetclass [my info class] puts "targetclass: $targetclass" puts "calledproc: [self calledproc]" ::set r [next] puts "back from next" puts "paramcmds: [$targetclass info instparametercmd]" }
Foo instfilter myfilter
Foo ob ob hello ob foo
So first I have a filter installed which does nothing but print some information, and checks something using the [info] method afterwards. I call an instantiated object with [hello] (an existing method) and again with [foo] (a non-existing method). The latter is when things get interesting. Check the output:
me: ::ob targetclass: ::Foo calledproc: configure back from next paramcmds:
me: ::ob targetclass: ::Foo calledproc: init back from next paramcmds:
me: ::ob targetclass: ::Foo calledproc: hello hello back from next paramcmds:
me: ::ob targetclass: ::Foo calledproc: foo back from next
me: ::alloc ::alloc: unable to dispatch method 'info' while executing "my info class" (procedure "cleanup" line 4) ::alloc ::Foo->myfilter ::Foo ::xotcl::Class->recreate ::Foo ::xotcl::Class->create ::Foo ::xotcl::Class->unknown ::Foo ::xotcl::Class->create ::Foo ::xotcl::Class->unknown ::Foo ::xotcl::Class->create ::Foo ::xotcl::Class->unknown invoked from within "$targetclass info instparametercmd" (procedure "foo" line 9) ::ob ::Foo->myfilter invoked from within "ob foo" (file "filtertest.tcl" line 24)
me: ::alloc targetclass: ::Foo calledproc: destroy back from next paramcmds:
me: ::info targetclass: ::Foo calledproc: destroy back from next paramcmds:
me: ::ob targetclass: ::Foo calledproc: destroy back from next paramcmds:
... So while the [hello] method works as expected, things get totally weird for [foo]. The first thing we notice is that it doesn't jump out at [next] (which should give an error as it does not exist). It continue execution of the filter after [next]. This may or may not be intended, I don't know. The documentation is not clear on this.
More interesting still, we end up with a totally unexpected error. The thing I believe is happening is that, for some reason or other [$targetclass info instparametercmd] is not ending up calling [info] for $targetClass, but creating an object called ::info (and thus overriding the original Tcl command). How [alloc] gets involved in the filter chain too, I am not sure. My guess is that the "unknown method" that resulted from [foo] is being interpreted by the XOTcl $targetclass C implementation as an error that occurred there, and that a new instance called "info" or possibly "alloc" should be created.
This causes major havoc as soon as an unknown method is called. Does the filter code look correct?
This happens with 1.6.2. I had a quick look at CHANGES for later versions and while there was some mention of memory leaks in [info] I wasn't sure if there was anything that would have fixed this.
Any ideas?
On 29 Aug 2010, at 15:09, Gustaf Neumann wrote:
... forgot to mention: You have to return the result of "next" as return of the filter (in the case of your example $r).
Yeah, I do that in my actual code which runs into the bug. Forgot it from the clip I posted here.
I am wondering if it will be possible to somehow implement coroutines in XOTcl? Is it feasible? Would it be worth it?
On 02.09.10 07:28, Victor Mayevski wrote:
I am wondering if it will be possible to somehow implement coroutines in XOTcl? Is it feasible? Would it be worth it?
Sorry for the late answer. With XOTcl 1.6.* there is no special support for coroutines (one can certainly create Tcl-coroutines and use it).
With 2.0 one can write object oriented coroutines. The new regression test contains already the classical number generator example based on coroutines (see below).
-gustaf neumann
========================================================= Test case number-generator {
Object create numbers {
# set instance variable used in coroutine set :delta 2
:public method ++ {} { yield set i 0 while 1 { yield $i incr i ${:delta} } } }
# create coroutine coroutine nextNumber numbers ++ set ::j 0
# use coroutine for {set i 0} {$i < 10} {incr i} { incr ::j [nextNumber] }
# remove coroutine rename nextNumber {}
? {set ::j} 90 }
Thank you Gustaf,
Part of my original question, which still stands, was "would it be worth it?"
It seems that the example you provided can be done with XOTcl alone, no need for coroutine. Is there any case where coroutine would actually give some extra power to XOTcl? Forgive me, I am not a C programmer so the concept of NRE or stackless TCL is a little foggy to me.
----- Original Message ----- From: "Gustaf Neumann" neumann@wu-wien.ac.at To: xotcl@alice.wu-wien.ac.at Sent: Tuesday, September 28, 2010 2:49:06 AM GMT -08:00 US/Canada Pacific Subject: Re: [Xotcl] coroutines
On 02.09.10 07:28, Victor Mayevski wrote:
I am wondering if it will be possible to somehow implement coroutines in XOTcl? Is it feasible? Would it be worth it?
Sorry for the late answer. With XOTcl 1.6.* there is no special support for coroutines (one can certainly create Tcl-coroutines and use it).
With 2.0 one can write object oriented coroutines. The new regression test contains already the classical number generator example based on coroutines (see below).
-gustaf neumann
========================================================= Test case number-generator {
Object create numbers {
# set instance variable used in coroutine set :delta 2
:public method ++ {} { yield set i 0 while 1 { yield $i incr i ${:delta} } } }
# create coroutine coroutine nextNumber numbers ++ set ::j 0
# use coroutine for {set i 0} {$i < 10} {incr i} { incr ::j [nextNumber] }
# remove coroutine rename nextNumber {}
? {set ::j} 90 }
_______________________________________________ Xotcl mailing list Xotcl@alice.wu-wien.ac.at http://alice.wu-wien.ac.at/mailman/listinfo/xotcl
On 29.09.10 19:58, Victor Mayevski wrote:
Thank you Gustaf,
Part of my original question, which still stands, was "would it be worth it?"
It seems that the example you provided can be done with XOTcl alone, no need for coroutine. Is there any case where coroutine would actually give some extra power to XOTcl? Forgive me, I am not a C programmer so the concept of NRE or stackless TCL is a little foggy to me.
In general, everything done with coroutines can be computed as well without it. At the end, coroutines are a question of style. There is hope that for certain classes of problems, coroutines help to reduce complexity for the developer (who has learned how to use coroutines). Typical application areas are generators (i.e. technically speaking infinite loops that are suspended after each result, the generator example) and event driven programs suspending from time to time their execution. While traditionally event driven programs require to split up the logic into small functions (i have to admit to like this), coroutines facilitate a linear programming style.
Coroutines are certainly an interesting concept. Whether or not it is "being worth it" can only be estimated by the eye of the beholder.
-gustaf neumann
On 29 Aug 2010, at 14:54, Gustaf Neumann wrote:
- The call "$targetclass info ..." was then letal especially with the standard unknown handler of the metaclass: xotcl belived incorrectly that "info" is unknown, and since an "unknown" call on a class (here $targetclass) creates an object, it was creating the object "info" as instance of that class, and the nightmare turned even worse.
Ah yes, this confirms my suspicions of what was going on. I'll report this to Apple to try and get them to upgrade the included XOTcl on OS X. I'm trying to keep my own work in sync with what is available on OS X to ease any deployment I might do.