Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

strange behaviour with package and namespace

42 views
Skip to first unread message

pd

unread,
Feb 6, 2024, 5:53:35 PMFeb 6
to
I'm trying the diagram implementation listed in [1] which provides an example and a link to a package file.

I've downloaded the package file (diagram.tcl) and copied the example in a tcl file (test_diagram.tcl)

I have a problem using the package diagram. But after loading successfully the package:

% lappend auto_path .
C:/Users/... .
% package require BWidget
1.9.13
% package require diagram
1

but I cannot use it because it doesn't find any command, for example:

% ::diagram::create_diagram
invalid command name "::diagram::create_diagram"

even when the namespace exits:

% namespace exists diagram
1

The namespace defined in package export all symbols (namespace export *) so I've tried to import them all and try to run the procs withou success:

% namespace import diagram::*
% create_diagram
invalid command name "create_diagram"

I was expecting to execute procs in a namespace when you fully qualified it, but it doesn't work in this case.

What is really strange is it seems to be using a different diagram namespace because if I query for its vars and procs I get:

% info vars ::diagram::*
::diagram::Snit_typemethodInfo ::diagram::Snit_info ::diagram::Snit_optionInfo ::diagram::Snit_methodInfo
% info procs ::diagram::*
::diagram::Snit_methodreset ::diagram::Snit_destructor ::diagram::Snit_constructor ::diagram::Snit_typeconstructor ::diagram::Snit_instanceVars

which seems to be related with Snit and not with the package I have loaded (which defines a diagram namespace with vars like data, minimap_ratio or autoscrolling and procs like create_scroll_minimap, find_port_point_circle or create_diagram)

Any idea about what's happening? maybe is a problem with another package loaded? maybe BWidget?

regards

saitology9

unread,
Feb 6, 2024, 8:10:15 PMFeb 6
to
On 2/6/2024 5:53 PM, pd wrote:
> I'm trying the diagram implementation listed in [1] which provides an example and a link to a package file.
>
> I've downloaded the package file (diagram.tcl) and copied the example in a tcl file (test_diagram.tcl)
>
> I have a problem using the package diagram. But after loading successfully the package:
>
> % lappend auto_path .
> C:/Users/... .
> % package require BWidget
> 1.9.13
> % package require diagram
> 1
>
> but I cannot use it because it doesn't find any command, for example:
>
> % ::diagram::create_diagram
> invalid command name "::diagram::create_diagram"


I am not familiar with this code but you should be able to get this to
run with the following changes:

1) In the file "diagram.tcl", move the statement "package provide ..."
from the top to the bottom of the file.

2) In the "test_diagram.tcl" file, change all instances of
"diagram::xyz" to "::diagram::xyz".


pd

unread,
Feb 7, 2024, 4:10:33 PMFeb 7
to
El martes, 6 de febrero de 2024 a las 23:53:35 UTC+1, pd escribió:
>
> I have a problem using the package diagram. But after loading successfully the package:
>
> % lappend auto_path .
> C:/Users/... .
> % package require BWidget
> 1.9.13
> % package require diagram
> 1
>
> but I cannot use it because it doesn't find any command, for example:
>
> % ::diagram::create_diagram
> invalid command name "::diagram::create_diagram"
>
> even when the namespace exits:
>
> % namespace exists diagram
> 1
>
> What is really strange is it seems to be using a different diagram namespace because if I query for its vars and procs I get:
>
> % info vars ::diagram::*
> ::diagram::Snit_typemethodInfo ::diagram::Snit_info ::diagram::Snit_optionInfo ::diagram::Snit_methodInfo
> % info procs ::diagram::*
> ::diagram::Snit_methodreset ::diagram::Snit_destructor ::diagram::Snit_constructor ::diagram::Snit_typeconstructor ::diagram::Snit_instanceVars
>

I managed to solve the problem, apparently the package was loaded right but it's an illusion, really the package that was loaded with

% package require diagram

is the tcllib diagram package which happens to be also version 1.0 and also defines a diagram namespace, for this reason all procs and vars in the namespace are so strange, they are from tcllib diagram rather than diagram.tcl

I solved it making the diagram.tcl a module (pm) rather than a package, so I can better control which one is loading.

This issue makes me to realize about the problem of name collision between packages, I think it should be managed but don't know how because there's no proper mechanism , maybe a hierarchy name similar to java packages.

Also I have another problem with tcllib package (I've played with it after this problem) but I'll discuss it in another post.


pd

unread,
Feb 7, 2024, 4:14:38 PMFeb 7
to
El miércoles, 7 de febrero de 2024 a las 2:10:15 UTC+1, saitology9 escribió:

> I am not familiar with this code but you should be able to get this to
> run with the following changes:
>
> 1) In the file "diagram.tcl", move the statement "package provide ..."
> from the top to the bottom of the file.
>
> 2) In the "test_diagram.tcl" file, change all instances of
> "diagram::xyz" to "::diagram::xyz".

thanks for the ideas, I solved it another way but your reply made me think about...

Is it important where you put the "package provide" in the source file? I supposed it is mainly declarative, independently of where it comes

I also thought ::X::y and X::y to be analogous, like an alias... but maybe X::y is relative to current namespace rather than relative to root namespace and thus ::X::y is not the same of X::y

Rich

unread,
Feb 8, 2024, 2:14:54 PMFeb 8
to
pd <euke...@gmail.com> wrote:
> I also thought ::X::y and X::y to be analogous, like an alias...

No, those two are not analogous.

> but maybe X::y is relative to current namespace

It is. So X::y will only resolve to ::X::y provided you do not have a
sub X namespace in your current namespace.

> rather than relative to root namespace and thus ::X::y is not the
> same of X::y

No, those two are not identical. X::y just ends up finding ::X::y
because of the namespace name lookup rules, and then only when you
don't have an X namespace below where you are.

If you have this

::X

Then in ::X just Y will look for ::Y as part of the name resolution.

But if you have this:

::X::Y

Then when in ::X, just Y will find ::X::Y and not ::Y (even if you also
have a ::Y).

Harald Oehlmann

unread,
Feb 9, 2024, 2:43:25 AMFeb 9
to
May I also underline, that the name resolution changed in 9.0.
9.0 does not try any more to resolve in the global namespace without
prefixed "::". So, in 9.0 it will "X::y" will only work from the global
namespace, "::X::y" will work from any namespace.

Harald
0 new messages