TCL命名空间中的变量
我有一个关于 TCL 命名空间中的变量的问题。
我有两个.tcl文件,a.tcl,b.tcl,我在这两个文件中定义相同的全局变量,例如:
a.tcl
variable same "hello1"
b.tcl
variable same "hello2"
proc use {} {
puts same
}
,但在b.tcl中,我尝试定义一个proc来使用变量“same
”,是否存在冲突? proc use() 中使用的是哪一个?
I have a question about variables in namespace of TCL.
I have two .tcl files, a.tcl, b.tcl, I define the same global variable in these two files, for example:
a.tcl
variable same "hello1"
b.tcl
variable same "hello2"
proc use {} {
puts same
}
but in b.tcl, I try to define a proc to use the variable "same
", is it a conflicts? which same is used in proc use()?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
从您的问题(以及对 Donal 的评论)看来,您认为文件与名称空间有关。这种想法是不正确的。
a.tcl
b.tcl
c.tcl
d.tcl
这个故事的寓意是代码所在的文件与命名空间或其他任何东西无关。对于位于单独命名空间中的命令或变量,必须将其显式放置在其中。
It appears from your question (and comments to Donal) that you believe that files have anything to do with namespaces. This thought is incorrect.
a.tcl
b.tcl
c.tcl
d.tcl
The moral of the story being that the file that code is in is irrelevant, to namespaces or anything else. For a command or variable to be in a separate namespace, it must explicitly be placed in there.
use
过程将与same
变量位于相同的命名空间中(代码所在的文件与其创建命令和变量的命名空间 100% 正交)。 但是,use
的主体默认情况下无法访问命名空间的变量,因为默认情况下所有过程声明的变量都是局部变量。这意味着要访问same
,您应该将其带入variable
的范围,可能不带值初始化参数:您还可以使用完全限定名称直接变量,但这往往会更慢(尤其是在循环中)。
在你问之前,我希望上面的代码会导致
use
打印“hello1”或“hello2”,具体取决于a.tcl和b.tcl的顺序是来源
d。任何命名空间都必须通过命名空间 eval ::someNsName { ...script... } 显式完成。您可能会将这样的内容放在每个脚本文件的其余内容中。编写过度依赖源文件顺序的代码通常被认为是不好的形式,主要是因为它往往更难以调试......The
use
procedure will be in the same namespace as thesame
variable (which file the code is in is 100% orthogonal to which namespace it creates commands and variables in). However, the body ofuse
will not have access to the variables of the namespace by default because all procedure-declared variables are local variables by default. This means that to get access tosame
, you should bring it into scope withvariable
, probably without the value-initialization argument:You could also use the fully-qualified name of the variable directly, but that tends to be slower (especially in a loop).
Before you ask, I'd expect the above code to cause
use
to print either “hello1” or “hello2”, depending on which order a.tcl and b.tcl aresource
d. Any namespacing has to be done explicitly through anamespace eval ::someNsName { ...script... }
. You'd probably put such a thing around the rest of the contents of each of your script files. It's usually considered bad form to write code that depends excessively on the order you source files, mostly because it tends to be quite a lot more difficult to debug…暂时忘记这两个文件。假设您只有一个文件,内容为:
这应该会导致一个错误,提示诸如
$x
未定义之类的内容。为什么?因为 Tcl 与 C 不同,不会将任何您不要求的内容导入到函数中。让我再说一遍:tcl procs 不会看到您不告诉它看到的全局或命名空间变量。因此,要导入全局变量,传统方法是使用 global 命令:
这应该可行。
当然,对于命名空间,
global
这个词没有意义,因此创建variable
命令是为了允许命名空间中定义的进程查看命名空间变量:还有另一种方法导入全局和命名空间变量,无需显式使用
global
或variable
:只需指定完整的命名空间。全局命名空间只是::
因此以下内容也有效:当然:
Forget about the two files for a moment. Lets assume you just have a single file and the content is:
This should result in an error that says something like
$x
is undefined. Why? Because Tcl, unlike C, doesn't import anything into a function that you don't ask it to. Let me say that again: tcl procs doesn't see global or namespace variables that you don't tell it to see.So, to import global variables the traditional way is to use the
global
command:this should work.
With namespaces of course the word
global
doesn't make sense so thevariable
command was created to allow procs defined in a namespace to see namespaced variables:There is also another way to import global and namespaced variables without explicitly using either
global
orvariable
: just specify the full namespace. The global namespace is simply::
so the following also works:and of course: