Tcl变量在不同的命名空间中交互,如何修复

Tcl variable interact in different namespace, how to fix

提问人:JoshTitle 提问时间:11/15/2023 最后编辑:mrcalvinJoshTitle 更新时间:11/15/2023 访问量:56

问:

在 tcl 中,我需要获取一些文件,file1、file2、file3,....fileN,我为每个文件创建每个命名空间,但是每个命名空间中设置的 var 会影响其他命名空间的 var

以下是我的代码:

proc source_file { args } {
global i 
  namespace eval NC{$i} {
   uplevel #0 [list source [uplevel 1 {set args}]]
  }
 incr i
}
set i 1
set A 123
source_file file1.tcl
source_file file2.tcl

file1.tcl:

set A 456;
puts $A

文件2.tcl:

puts $A 

我希望 file2.tcl 的 put 会打印 123,但它打印 456,我的代码错误是什么?

命名空间: Tcl

评论

0赞 TrojanName 11/15/2023
缺少“list”命令的右方括号
0赞 Cyan Ogilvie 11/15/2023
需要指出的是,一种更简单的方法是: .虽然我不确定命名空间名称是否符合您的期望,但此示例将创建两个命名空间:和(即大括号只是字符串中的文字字符)namespace eval NC{[incr i]} [list source file1.tcl]; namespace eval NC{[incr i]} [list source file2.tcl]NC{1}NC{2}
0赞 JoshTitle 11/15/2023
Ogilvie,A 是 0 级 var 可以在 NC1 和 NC2 中访问/修改,转义 NC1 和 NC2,A 应保留 456 作为原始 0 级值
0赞 JoshTitle 11/15/2023
我尝试使用命名空间,使用级别方式,但是级别 0 的 A 将在命名空间中修改,甚至转义 nc1 或 nc2

答:

1赞 Donal Fellows 11/15/2023 #1

uplevel #0几乎和做一样;code 参数在全局命名空间中运行。(区别在于他们如何管理堆栈;大多数代码不会关心这种差异。这意味着这两个文件都在同一个命名空间(全局命名空间)中运行。namespace eval ::

在 Tcl 8 中,您需要该文件正确地表示:

variable A 456
puts $A

若要使变量位于正确的命名空间中,需要使用以下命令调用该文件:

uplevel "#0" [list namespace eval $ns [list source $filename]]
# I put #0 in quotes just to defeat the syntax highlighter here

当然,假设您将命名空间和文件名放在正确的局部变量中。


在 Tcl 9 中,分辨率进行了调整。这将在几个地方更多地破坏这段代码,但以修复比它制造的更多的错误的方式......