The variable in namespace of TCL
我对TCL命名空间中的变量有疑问。
我有两个.tcl文件a.tcl,b.tcl,我在这两个文件中定义了相同的全局变量,例如:
a.tcl
1 | variable same"hello1" |
b.tcl
1 2 3 4 | variable same"hello2" proc use {} { puts same } |
但是在b.tcl中,我尝试定义一个使用变量"
从您的问题(和对Donal的评论)看来,您认为文件与名称空间有关。这种想法是不正确的。
a.tcl
1 | variable same"hello a" ;# global namespace |
b.tcl
1 2 3 4 5 6 | variable same"hello b" ;# global namespace proc use {} { variable same ;# reads from the global namespace puts $same ;# will puts"hello a" or"hello b" depending on whether ;# a.tcl is sourced after b.tcl or not } |
c.tcl
1 2 3 4 | namespace eval ::not_the_global { variable same"hello c" ;# a different namespace, and a different variable than ;# the one from the previous two files } |
d.tcl
1 2 3 4 5 6 7 | namespace eval ::not_the_global { proc use {} { ;# a different use proc from the one in b.tcl variable same ;# the variable defined in this namespace in c.tcl puts $same ;# will output"hello c" no matter is a.tcl or b.tcl ;# were sourced } } |
故事的寓意是代码所在的文件与名称空间或其他任何内容都不相关。为了使命令或变量位于单独的命名空间中,必须将其显式放置在该命名空间中。
1 2 3 4 | proc use {} { variable same puts $same } |
您也可以直接使用变量的全限定名称,但这往往会变慢(尤其是在循环中)。
在您问之前,我希望上面的代码会导致
暂时忘掉这两个文件。假设您只有一个文件,内容为:
1 2 3 4 5 | variable x hello ;# this is a global variable. proc use {} { puts $x } |
这将导致错误,提示未定义类似
因此,导入全局变量的传统方法是使用
1 2 3 4 5 6 | variable x hello proc use {} { global x ;# import $x into this proc puts $x } |
这应该有效。
当然,对于命名空间,
1 2 3 4 5 6 7 8 | namespace eval foo { variable x hello proc use {} { variable x ;# import $x into this proc puts $x } } |
还有另一种无需显式使用
1 2 3 4 5 | variable x hello proc use {} { puts $::x } |
,当然:
1 2 3 4 5 6 7 | namespace eval foo { variable x hello proc use {} { puts $foo::x } } |