#1889 [namespace forget] matches by name only

obsolete: 8.4a4
closed-fixed
8
2004-09-09
2002-05-24
No

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

Discussion

  • miguel sofer

    miguel sofer - 2002-05-24

    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"

     
  • Don Porter

    Don Porter - 2003-10-02
    • priority: 5 --> 8
     
  • Don Porter

    Don Porter - 2003-11-13
    • milestone: --> obsolete: 8.4a4
     
  • Don Porter

    Don Porter - 2004-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).

     
  • Don Porter

    Don Porter - 2004-08-31

    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.

     
  • Don Porter

    Don Porter - 2004-08-31

    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.

     
  • Don Porter

    Don Porter - 2004-08-31
     
  • Don Porter

    Don Porter - 2004-08-31

    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.

     
  • Don Porter

    Don Porter - 2004-08-31
     
  • Don Porter

    Don Porter - 2004-08-31

    Logged In: YES
    user_id=80530

    New patch implements
    option 3)

    no more failed tests.

     
  • Don Porter

    Don Porter - 2004-09-09
    • assigned_to: msofer --> dgp
    • status: open --> closed-fixed
     
  • Don Porter

    Don Porter - 2004-09-09

    Logged In: YES
    user_id=80530

    Patch -3 committed along with some
    new tests. commit to HEAD and 8.4 branch.

     

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks