Tcl Source Code

View Ticket
Login
Ticket UUID: 2898722
Title: [namespace path] + command resolution inconsistencies
Type: Bug Version: obsolete: 8.5.7
Submitter: bharder Created on: 2009-11-16 22:24:59
Subsystem: 21. [namespace] Assigned To: dkf
Priority: 8 Severity: Minor
Status: Closed Last Modified: 2013-09-24 12:04:38
Resolution: Fixed Closed By: dkf
    Closed on: 2013-09-24 12:04:38
Description:
Interpretter seems "slow" to realize that a [proc] is available in current namespace  that will satisfy a call for that command. Example is attached in test. Bug is manifested as bad/delayed interaction between [namespace path] and definition/call of a proc within a namespace.
User Comments: dkf added on 2011-09-21 15:00:41:
I don't know. Maybe. :-)
Removed the constraint

dgp added on 2011-09-20 21:16:43:
When I force it to run, I see test namespace-51.17
pass on the current trunk.  Has this bug been fixed?

dkf added on 2010-01-10 23:54:01:
Committed test namespace-51.17 to HEAD which characterizes the issue. Note that it is constrained to not normally execute; it's going to be tricky to fix, so no sense holding a release up for it...

dkf added on 2010-01-10 20:26:37:
Every namespace has a hash from (qualifier-free) command name to command implementation. What it doesn't do is have a mapping from everything visible due to the installed resolvers to implementation; that would be moderately expensive to compute and isn't the way that resolvers work anyway. Hash tables are also not very fast (not given that command lookup is a major hotspot in most Tcl code).

ferrieux added on 2010-01-10 19:16:11:
Sorry, "command name", not "procname".
Mea maxima culpa, beat me up until dawn, but please please answer...

dkf added on 2010-01-10 01:12:32:
I can't see why you're fixated on procedures.

ferrieux added on 2010-01-09 23:43:20:
Donal, can you comment on the idea of  a hashtable keyed on the procname (tail) ?

dkf added on 2010-01-09 22:49:37:
Distilled down to a single test that hits at least one of the bugs in this area, and hits it reliably. (Because the original report looked like it involves literal sharing, it's not entirely trivial to trigger on an entirely predictable basis.)

dkf added on 2010-01-09 21:25:36:

File Added - 358306: nsbug.tcl

ferrieux added on 2010-01-09 05:45:01:
Sorry, assigning to me is an exaggeration, I'm way above my usual flight level.
Passing on to oxygen-tank-equipped dkf (see my last comment: statistics in TclOO etc)

msofer added on 2009-12-11 07:05:52:
alex - can you take this one over? You seem to be way ahead of me :P

ferrieux added on 2009-11-18 07:27:21:
For the record, a summary of a chat with Miguel:

Mig first dichotomizes into two strategies:
 (a) on first alert, nuke all refs
 (b) look more closely and nuke only those that deserve it
Then he argues that (a) is probably faster+better, since [proc]/[rename] are not done at time-critical runtime; (b) is costlier.

However, as an afterthought to this discussion, I wonder about the feasibility of (a) short of nuking _all_ refs in the interp. Indeed, the concerned refs are not isolated by namespace, they can come from many namespaces (all those who have the current one in their path, plus extra ones with fully qualified procnames aiming directly at us). So unless we nuke all refs in the interp, (a) is identical to (b).

Another approach would be to keep an interpreter-wide hashtable of refs; keyed on the tail of the procname (baz in ::foo::bar::baz). In that case, TclResetShadowed simplifies enormously. However I'm a bit uneasy about what happens to method creation/destruction in TclOO, where the rate of degeneracy on the key (name tail) is high...

ferrieux added on 2009-11-18 05:57:28:
Closing in. It appears TclResetShadowedCmdRefs doesn't take into account the relatively new [namespace path].

ferrieux added on 2009-11-18 05:30:27:
One fascinating thing in this : if you replace

puts "mycmd"

with

puts "abcdef"

or even

puts "mycmd " ;# <- note the extra space

then the effect disappears. So I suspect this is all related to shimmering of the mycmd literal between a cmdName and a String (when output to stdout with some nontrivial encoding). The shimmering explains why *after* executing the ::fu variant, the ::fu::bar gets activated. It doesn't explain though why the ::fu is called instead of the ::fu::bar after redefinition. To be continued.

ferrieux added on 2009-11-17 14:28:25:
Renamed. "Slow" means a perf problem -- this is a semantic bug.

mpc_janssen added on 2009-11-17 05:47:24:
For completeness (and to not require a tcltest script download)
Seems likely that something with caching (implies epoch??) is at fault here. The following simple interactive session demonstrates this:

 % namespace eval ::fu { proc mycmd {} { puts "mycmd" }}
% namespace eval ::fu::bar { namespace path ::fu; mycmd }
mycmd
% namespace eval ::fu::bar { proc mycmd {} { puts "fubar mycmd"}; mycmd }
mycmd
% namespace eval ::fu::bar { mycmd}
fubar mycmd
% namespace eval ::fu::bar { proc mycmd {} { puts "fubar mycmd"}; mycmd }
mycmd
% namespace eval ::fu::bar { mycmd}
fubar mycmd
% namespace eval ::fu::bar { proc mycmd {} { puts "fubar mycmd"}; mycmd }
mycmd

It seems that calling mycmd when it is still only defined in namespace ::fu is a necessary prerequisite to see this behaviour.

dgp added on 2009-11-17 05:27:58:
Likely an epoch check problem
within the "cmdName" Tcl_ObjType.

bharder added on 2009-11-17 05:24:59:

File Added - 351180: nsbug.tcl

Attachments: