Hello all,
Small feature request: could XOTcl be made to automatically [namespace import] the ::xotcl::* commands into every object it creates? I'm trying to write a package using XOTcl, and so don't want to import XOTcl into the global namespace. As Tcl's command resolution rules are current namespace then global namespace only, I can't just import it into my package namespace, as all objects (which are sub-namespaces, AIUI) would skip the containing namespace when resolving. So, I have two options:
1) Fully qualify everything - lots of xotcl::my, xotcl::self etc everywhere 2) Import xotcl namespace manually into each object namespace.
2 is better than 1, but is still a bit of a pain to remember to do, and I seem to remember trying it and it not always working (I could be wrong about that).
So, my feature request would be that all Objects [namespace import] the xotcl namespace automatically.[1]
Cheers,
Neil.
[1] [namespace import] is actually quite expensive as it creates commands in each namespace which forward on to the originals. Possibly if XOTcl is already hooked in to Tcl's resolver APIs for method dispatch/inheritance, then the xotcl namespace could just be added as a final search path (after xotcl::Object).
On Monday 24 May 2004 22:57, Neil Madden wrote:
Hello all,
Small feature request: could XOTcl be made to automatically [namespace import] the ::xotcl::* commands into every object it creates? ...
- Fully qualify everything - lots of xotcl::my, xotcl::self etc
everywhere 2) Import xotcl namespace manually into each object namespace.
or 3) do a gobal namespace import.
2 is better than 1, but is still a bit of a pain to remember to do, and I seem to remember trying it and it not always working (I could be wrong about that).
(2) does not help too much, since xotcl is "namespace transparent", which means that it simply keeps the current namespace. This means that if you do a "namespace eval xxx {o m}" the method is evaled in the namespace xxx (and not o}.
As a sidenote: not every xotcl obj creates a namespace, since tcl namspaces are quite large in memory. Namespaces are only created when an object has child objects or procs. You can measure the difference on your system (the following works for linux, ps might be different on other OSes)
============================================== ::xotcl::Class Mem -instproc init {} { set r [exec ps -xv | fgrep [pid]] ::xotcl::my set m [lindex $r 6] }
set n 1000 Mem m1
set ts [time {for {set i 0} {$i<$n} {incr i} { ::xotcl::Object create a$i}}] Mem m2 set mem1 [expr {([m2 set m]-[m1 set m])*1024/$n}]
set ts [time {for {set i 0} {$i<$n} {incr i} { ::xotcl::Object create b$i -requireNamespace}}] Mem m3 set mem2 [expr {([m3 set m]-[m2 set m])*1024/$n}]
puts "consumption/obj without ns: $mem1, with ns: $mem2" ==============================================
So, my feature request would be that all Objects [namespace import] the xotcl namespace automatically.[1]
we had something like this in earlier versions of xotcl, but it was quite a pain, where it was quite easy to run into inifine loops, since procs of objects were resolved without the object name. To be on the safe side, every reference to a gobal tcl command had to be prefixed by a :: (eg: ::set x 1), otherwise an "obj proc set .." was overruling the tcl command. Note that we have multiple command sets in xotcl, not only in the procs, but in the instprocs of classes (superclasses, mixins) as well.
you can do the following as other alternatives: a) you can import the xotcl commands into your components workspace, and do a namespace eval there b) you can eval the object in the ::xotcl namespace
here are such code snipplets: ================================== namespace eval myns { namespace import ::xotcl::*
Class MyClass MyClass instproc test {} { puts stderr "in [xotcl::self] current namespace [namespace current]" puts "unprefixed: [self] [self class]" } MyClass o
}
puts ========= namespace eval myns { o test }
puts ========= namespace eval xotcl {myns::o test} puts =========
==================================
if you have a component with a slim interface, you can simply do a namespace eval once on the top calling level, this does not cost much performance.
... and, you can write a global unknown handler, but that is not better than importing xotcl (or at least self+my) globally, what still looks like the best option to me.
-gustaf
Thanks for the reply. Comments below.
On 25 May 2004, at 09:43, Gustaf Neumann wrote:
On Monday 24 May 2004 22:57, Neil Madden wrote:
Hello all,
Small feature request: could XOTcl be made to automatically [namespace import] the ::xotcl::* commands into every object it creates? ...
- Fully qualify everything - lots of xotcl::my, xotcl::self etc
everywhere 2) Import xotcl namespace manually into each object namespace.
or 3) do a gobal namespace import.
That's generally not considered good style when writing a package - the global namespace is "owned" by the application author, and so packages shouldn't put stuff there unless explicitly asked.
2 is better than 1, but is still a bit of a pain to remember to do, and I seem to remember trying it and it not always working (I could be wrong about that).
(2) does not help too much, since xotcl is "namespace transparent", which means that it simply keeps the current namespace. This means that if you do a "namespace eval xxx {o m}" the method is evaled in the namespace xxx (and not o}.
OK. That's good to know. But this namespace transparency does not extend all the way. For instance:
package require XOTcl namespace eval foo { proc bar {} { puts "ns = [namespace current]" } xotcl::Class Bar Bar instproc foo {} { puts "ns = [namespace current]" } Bar a } foo::bar ;# prints "ns = ::foo" foo::a foo ;# prints "ns = ::"
I would expect that any object I create in a namespace will always be evaluated in that namespace, as is the case for procs. Given the namespace transparency you describe above, this would solve all my problems.
<snip memory usage discussion>
So, my feature request would be that all Objects [namespace import] the xotcl namespace automatically.[1]
we had something like this in earlier versions of xotcl, but it was quite a pain, where it was quite easy to run into inifine loops, since procs of objects were resolved without the object name. To be on the safe side, every reference to a gobal tcl command had to be prefixed by a :: (eg: ::set x 1), otherwise an "obj proc set .." was overruling the tcl command.
I'm not sure what you mean here. I wasn't suggesting that methods should be able to be called without passing a message to self, just that "my", "self" etc should be imported into each object.
Note that we have multiple command sets in xotcl, not only in the procs, but in the instprocs of classes (superclasses, mixins) as well.
you can do the following as other alternatives: a) you can import the xotcl commands into your components workspace, and do a namespace eval there b) you can eval the object in the ::xotcl namespace
Neither of these alternatives are particularly appealing, as they require the consumer of my package to know to do this, and it would clutter up their code quite a bit. I suppose I could write a wrapper proc for each object:
xotcl::Class MyClass -superclass xotcl::Class MyClass instproc create {name args} { eval [linsert $args 0 next ${name}_] uplevel 1 [list proc $name {args} "uplevel 1 [linsert $args 0 ${name}_]"] }
But this still feels like something XOTcl should be doing for me.
... and, you can write a global unknown handler, but that is not better than importing xotcl (or at least self+my) globally, what still looks like the best option to me.
In 8.5 (hopefully) my [namespace unknown] TIP (181) will get in, so you could do this per-namespace. But it is still a hack. For now, I will import into my package namespace, and use wrapper procs.
Neil.
Hello,
Have had a chance to set up the actiweb framework and now trying out the examples;-) This is really good stuff....
Going through the readme, one would expect that I should be able access the plain text interface via http://...path..:8091/c1, via a browser but I get an error, in the browser.. (the counter2.xotcl example)
"invocation error: Object 'c1' unknown
Status Code 404: *Not Found* Resource Name: c1"
and in the shell ::receiver::error ::ErrorMgr->invocationError ::receiver::start.html {Object 'c1' unknown} {}
I would have expected that a text representation would have been returned via .../c1 ...web-c1 returns the html facade as expected...
Is this because we dont export to the receiver class, or am I missing something else?
regards,
nicolas boretos
On Thursday 27 May 2004 09:55, Nicolas Boretos wrote:
Hello,
Have had a chance to set up the actiweb framework and now trying out the examples;-) This is really good stuff....
thanks.
... {Object 'c1' unknown} {}
I would have expected that a text representation would have been returned via .../c1 ...web-c1 returns the html facade as expected...
The example is meant as an example, where the counter objects are accessed through a facade only.
Is this because we dont export to the receiver class, or am I missing something else?
correct. only "exported" objects can be called via HTTP, and only the exported procs of the exported objects can be called. This can be done via a the following magic lines:
# export the object receiver exportObjs c1 # provide behavior to (a) export procs, (b) a stragey for sending back the result # and (c) a persistency berhavior c1 mixin {WebObject Send=PlainString Persistent=Eager} # export the method increment c1 exportProcs increment
best regards -gustaf neumann