从具有force选项的命名空间导入proc后,在某些情况下auto_load使用全局命名空间中的proc

时间:2019-02-26 21:41:57

标签: namespaces tcl autoload

我一直在从事一个项目,其中脚本是为单个硬件编写的(例如Type A),并且有很多针对该特定硬件的proc。现在,当我尝试将相同的脚本用于新硬件(例如B型)时,我想到了以下方法, 1.在新名称空间内的新库文件中重新定义所有proc。 2.当主脚本启动时,检查硬件类型。     一种。如果键入A,则什么也不做。来自全局名称空间(旧版)的proc被使用     b。如果类型B是从库到全局名称空间的“名称空间import -force”。

这里的问题是,该项目使用了auto_load,因此当我从新库中导入时,遗留proc尚未处于上下文中。当调用两种硬件都通用的proc时,如果包含该proc的文件还具有为Type B重新定义的另一个proc,则即使我已经完成了此命名空间,该proc也会被全局名称空间proc(传统Type A)覆盖较早地导入部队。

如果很难遵循这些措辞,请参考下面的示例代码及其输出。如果将虚拟proc从TypeB.tcl移到新文件,则没有问题。

[wizard @ work]$ cat main.tcl
#!/usr/bin/tclsh
auto_mkindex ./
set auto_path "$auto_path ./"
namespace import -force TypeB::*
print_name
dummy
print_name

[wizard @ work]$ cat TypeA.tcl

proc print_name { } {
   puts "From the TypeA"
}
proc dummy {} {
   puts "Do nothing"
}

[wizard @ work]$ cat TypeB.tcl
namespace eval TypeB {
   namespace export *

   proc print_name {} {
      puts "From the TypeB"
   }

}


[wizard @ work]$ ./main.tcl
From the TypeB
Do nothing
From the TypeA
[wizard @ work]$

1 个答案:

答案 0 :(得分:0)

考虑auto_mkindex的作用:它将创建一个包含以下内容的tclIndex文件

set auto_index(print_name) [list source [file join $dir TypeA.tcl]]
set auto_index(dummy) [list source [file join $dir TypeA.tcl]]
set auto_index(::TypeB::print_name) [list source [file join $dir TypeB.tcl]]

当您namespace import TypeB::*时,tcl将执行source [file join $dir TypeB.tcl],并将print_name proc拉入全局名称空间。

致电dummy会发生什么? this:source [file join $dir TypeA.tcl]-将dummy proc拉入全局名称空间。但是同时,print_name进程是 redefined

此时,您仍然可以致电TypeB::print_name

您必须执行以下一项操作:

  • 重组代码,
  • 重新执行namespace import TypeB::*
  • 请特别注意呼叫的顺序,例如先呼叫dummy