A question about namespace in Tcl
I have two question about namespace in Tcl.开发者_运维技巧
namespace eval ::dai {
set a 5
set b 10
namespace export *
}
My questions are:
export *
- the export will make some variable inside this namespace can be used in other namespace, but what does thisexport *
mean?Set a 5, should not we use
variable a 5
? are they the same? some tutorials say inside namespace, we should usevariable
, what is the difference betweenvariable
andset
in namespace?
1) As is (supposed to be) logical for Unix users, "*" means "everything available at the moment". It's like when you do rm -f *
in a shell, the shell expands "*" and replaces it with a list of all the files present in the current directory. Actually, as namespace
manual states you can specify more elaborate patters than simple "*". To learn what that "glob-style" thing mentioned there means read about string match
.
2) The question "should not we use..." is incorrect because it depends on what you want to do. If you want to declare a variable located in the namespace, use variable
. If you want to set a variable, use set
, but bevare that if that variable x
is not exist in the namespace yet, Tcl will attempt to find a global variablte with this name, see:
% set x 5
5
% namespace eval foo {
set x 10
}
10
% set x
10
# ^^ observe that the global variable has been assigned
% namespace eval foo {
variable x
set x 20
}
20
% set x
10
# ^^ observe that now `set x 20` found the variable `x` in the namespace and assigned to it
This is explained in the "NAME RESOLUTION" section of the namespace
man page.
Note that this behaviour may appear illogical, but it actually matches that of the procedure scope: if you do set foo bar
in a procedure body, this means setting the local variable unless you stated otherwise using either global
or variable
or by using a fully-qualified name (like ::ns::foo
).
namespace export
only applies to commands (i.e. proc
s) in the namespace: it registers them as being eligible to be imported into another namespace. For example:
% package require textutil
0.7.1
% textutil::splitx abcdefghij {[aeiou]}
{} bcd fgh j
% splitx abcdefghij {[aeiou]}
invalid command name "splitx"
while evaluating {splitx abcdefghij {[aeiou]}}
% namespace import textutil::*
% splitx abcdefghij {[aeiou]}
{} bcd fgh j
精彩评论