I don't see the difference between the 2 scripts.
# First script
namespace eval ns1 {
namespace eval ::ns2 {
proc name {} {
puts ok
}
}
}
# Second script
namespace eval ns1 {}
namespace eval ns2 {
proc name {} {
puts ok
}
}
In both cases, calling the name
procedure is the same writing. My example is very simple, but I thought that my first script protected the ns2
namespace and that I could call the name
command only if the ns1
namespace existed.
My apprehension is to have the same namespace ns2
in another package, source... for example.
Both of your scripts create the proc in the ::ns2 namespace. In your first script, you prefixed the ns2 with (::), which means it is created relative to the root namespace (and not relative to the wrapping ns1 namespace), thus essentially ignoring the outer ns1 namespace.
Your second script also creates the proc in the ::ns2 namespace. The first line (namespace eval ns1 {}) does nothing. Because the second line is run in a global context it creates the ns2 namespace as a child of the global namespace i.e. your ns2 is equivalent to ::ns2.
You can confirm this by running it with the full namespace or with info command e.g.
% ::ns2::name
ok
% info command ::ns2::name
::ns2::name
If you want to create your proc in ns2, where ns2 is a child namespace of ns1, just omit the double colon e.g.
namespace eval ns1 {
namespace eval ns2 {
proc name {} {
puts ok
}
}
}
% ::ns1::ns2::name
ok
% info command ::ns1::ns2::name
::ns1::ns2::name
In order to run the name proc, you will need to provide the full namespace either explicitly or in an eval. If you just try to run name, you get a namespace error:
% name
wrong # args: should be "namespace subcommand ?arg ...?"