Ticket UUID: | 560297 | |||
Title: | [namespace forget] matches by name only | |||
Type: | Bug | Version: | obsolete: 8.4a4 | |
Submitter: | msofer | Created on: | 2002-05-24 20:18:14 | |
Subsystem: | 21. [namespace] | Assigned To: | dgp | |
Priority: | 8 | Severity: | ||
Status: | Closed | Last Modified: | 2004-09-09 22:44:51 | |
Resolution: | Fixed | Closed By: | dgp | |
Closed on: | 2004-09-09 15:44:51 | |||
Description: |
As documented in [Bug #559268], the behaviour of [namespace forget] is somewhat surprising: (1) it may forget a command imported from a different namespace % namespace eval src0 {proc a {} {puts 0}} % namespace eval src0 {namespace export a} % namespace eval src1 {proc a {} {puts 1}} % namespace eval tst {namespace import ::src0::a} % tst::a 0 % namespace eval tst {namespace forget ::src1::a} % tst::a invalid command name "tst::a" (2) it fails to forget an imported command if it was renamed % namespace eval src {proc a {} {puts 1}} % namespace eval src {namespace export a} % namespace eval dst {namespace import ::src::a} % namespace eval dst {rename a b} % dst::b 1 % namespace eval dst {namespace forget ::src::a} % dst::b 1 | |||
User Comments: |
dgp added on 2004-09-09 22:44:51:
Logged In: YES user_id=80530 Patch -3 committed along with some new tests. commit to HEAD and 8.4 branch. dgp added on 2004-09-01 00:07:07: File Added - 99875: 560297-3.patch Logged In: YES user_id=80530 New patch implements option 3) no more failed tests. dgp added on 2004-08-31 23:18:22: Logged In: YES user_id=80530 the failing test raises the question of how to forget import chains. % namespace eval origin { namespace export cmd proc cmd args {} } % namespace eval link { namespace export cmd namespace import origin::cmd } % namespace eval unrelated { namespace export cmd proc cmd args {} } % namespace eval my namespace import ::link::cmd At this point, in an unpatched Tcl, any of the following commands in namespace "my" will forget my::cmd : namespace forget ::origin::cmd namespace forget ::link:::cmd namespace forget ::unrelated::cmd The last is case (1) in the bug report. After the attached patch is applied, only namespace forget ::origin::cmd will work. The test fails because it would expect that namespace forget ::link::cmd would also work, and that has some intuitive appeal as well, as that is really the command that was imported. So we have some options how to deal with the links in an import chain: 1) forget based only on the origin. - what the patch does 2) forget based only on the first link - closer in intuition to being the inverse of a [namespace import] 3) Both 1) and 2) - allow forgetting by either 1st or last 4) forget based on any link in the chain at all Advantage of 1) is that it means [namespace forget [namespace origin $cmd]] is always a reliable operation. Advantage of including 2) as well is that there will be no failing tests, and it's more intuitive So, I think I like 3) Should probably be said that this whole realm is likely best avoided by using [namespace forget $simpleName] whenever possible. dgp added on 2004-08-31 22:36:23: File Added - 99853: 560297.patch dgp added on 2004-08-31 22:36:21: Logged In: YES user_id=80530 here's a patch that implements the outline posted before. One wrinkle: namespace-old-9.14 fails. NOTE: Patch 1019718 is included in the attached patch. dgp added on 2004-08-31 20:28:51: Logged In: YES user_id=80530 Refinement of the definition: An "imported command" is any for which [namespace which -command $cmd] and [namespace origin $cmd] produce different results. dgp added on 2004-08-28 05:08:27: Logged In: YES user_id=80530 It is the function of [namespace forget] to delete imported command(s) from the current namespace of the interp, based on pattern arguments. An "imported command" is any for which {$cmd ne [namespace origin $cmd]}. Simple patterns (no namespace separator) should match against simple names of imported commands and delete those that match. This means problem (3) isn't really a problem at all. Whether the imported command got into the current namespace via [namespace import] or [rename] shouldn't really matter. For namespace qualified patterns, the apparent intent is to control deletion of import command based on where they point to. Based on that, is seems the correct behavior is to loop over the imported commands in the current namespace, determine the [namespace origin] of each, and match that against the qualified pattern. That algoritthm would correct problems (1) and (2). msofer added on 2002-05-25 04:15:40: Logged In: YES user_id=148712 Kevin Kenny spotted another problem: (3) it may remove a command that was *not* imported into the current namespace: % namespace eval src {proc a {} {puts 1}} % namespace eval src {namespace export a} % namespace eval dst {namespace import ::src::a} % namespace eval dst1 {} % namespace eval dst {rename a ::dst1::b} % dst1::b 1 % namespace eval dst1 {namespace forget b} % dst1::b invalid command name "dst1::b" |