Still looking for an official explanation for the operations of [eval] (and other stuff I posted), but here's another one. The code follows:
package require XOTcl 1.3 namespace import xotcl::*
Class Foo -parameter doors
Foo instproc init {req} { puts $req }
Object ob
set newOb [Foo new -childof ob hello -doors 4] puts "Doors: [$newOb doors]"
$newOb proc doStuff {} { puts "class: [self class]" set newOb [[self class] new -childof [self] whatevah -doors 3] puts "Doors: [$newOb doors]" }
$newOb doStuff
#$newOb eval { # doStuff #}
This version correctly states that the class for [self class] is an empty string. However, if I comment out the "eval" version and use it instead, [self class] gives me "::xotcl::Object".
Hi again,
well the problem here is the same as before. "eval" passes the control to the Tcl eval command implementation. That is, all what is called inside an "eval" in an object's namespace bypasses the XOTcl dispatcher. So the callstack entries are not correct. also filters/mixins do not work here. You should always use the XOTcl invocation syntax "objName methodName args", like:
$newOb eval { $newOb doStuff }
I would like to make it impossible to call doStuff directly here, as in the example below, but this would require changes to the Tcl core or has a performance impact; so we chose to live with the problem that procs can be called directly via the namespace
Uwe
Kristoffer Lawson wrote:
Still looking for an official explanation for the operations of [eval] (and other stuff I posted), but here's another one. The code follows:
package require XOTcl 1.3 namespace import xotcl::*
Class Foo -parameter doors
Foo instproc init {req} { puts $req }
Object ob
set newOb [Foo new -childof ob hello -doors 4] puts "Doors: [$newOb doors]"
$newOb proc doStuff {} { puts "class: [self class]" set newOb [[self class] new -childof [self] whatevah -doors 3] puts "Doors: [$newOb doors]" }
$newOb doStuff
#$newOb eval { # doStuff #}
This version correctly states that the class for [self class] is an empty string. However, if I comment out the "eval" version and use it instead, [self class] gives me "::xotcl::Object".
/ http://www.fishpool.com/~setok/
Xotcl mailing list - Xotcl@alice.wu-wien.ac.at http://alice.wu-wien.ac.at/mailman/listinfo/xotcl
On Mon, 6 Sep 2004, Uwe Zdun wrote:
I would like to make it impossible to call doStuff directly here, as in the example below, but this would require changes to the Tcl core or has a performance impact; so we chose to live with the problem that procs can be called directly via the namespace
That's fine, just so I know that's not the intended use. Though I still think it may be interesting to have a method that would allow access to methods and everything in that fashion, but that may not be feasible.
Dear all, i just returned from vacation and i am slowly digging through my mail.
That's fine, just so I know that's not the intended use. Though I still think it may be interesting to have a method that would allow access to methods and everything in that fashion, but that may not be feasible.
the method eval is defined in predefined.xotcl through instforward.
# provide some Tcl-commands as methods for Objects foreach cmd {array append lappend trace eval} { ::xotcl::Object instforward $cmd -objscope }
the option -objscope means, that the instvars of the object are in the current scope of evaluation and can be reached without any prefix. one can do
~/scripts> Object o ::o ~/scripts> o set x 1 1 ~/scripts> o incr x 2 ~/scripts> o eval regexp b abc y 1 ~/scripts> o info vars x y ~/scripts> o set y b
See the documentation of 1.3 for more details about the forwarding stuff
accessing methods in general only through the namspace is not possible, since we have procs+instprocs (of several classes) with the same name. you certainly can call a proc of the object via the eval method
~/scripts> o proc x {} {puts hu} ~/scripts> o eval x hu
but not instprocs. The following explanation is only for advanced readers: <techyspeak> in XOTcl, instprocs are defined as Tcl-procs within class-specific namespaces. Therefore we can have a method with the same name in various classes, which are linked via the next-path.
the class specific namespace for the methods of ::xotcl::Object is ::xotcl::classes::xotcl::Object. you can see the instprocs of ::xotcl::Object via:
~/scripts>info procs ::xotcl::classes::xotcl::Object::*
If one defines a method in a class ~/scripts> Object instproc y {} {puts ho-[self]} it shows up there as well ~/scripts> info procs ::xotcl::classes::xotcl::Object::y ::xotcl::classes::xotcl::Object::y
if for some reason, one has to call the instproc directly, one could use the forwarder
~/scripts> Object instproc y {} {puts ho-[self]} ~/scripts> o eval y ho-::o
or e.g. the approach in "Itcl in XOTcl" http://mini.net/tcl/10975 where itcl methods are called just by their names (i have somewhere a slightly faster version using "interp alias"). </techyspeak>
I would not recommend this for the general usage, since - as uwe pointed out - this is bypassing the xotcl dispatcher an can lead to unexpected behavior (it is a defined behavior, but different from the variant without eval).
hope, this helps, -gustaf
On Tue, 14 Sep 2004, Gustaf Neumann wrote:
I would not recommend this for the general usage, since
- as uwe pointed out - this is bypassing the xotcl dispatcher
an can lead to unexpected behavior (it is a defined behavior, but different from the variant without eval).
Yes, I let go of that assumption and implementation. It may be good to mention in the documentation that the eval really is intended for fields only (although it doesn't state anything about methods anyway, I was just playing around).
Anyway, thanks for the response.