将包加载到当前名称空间

时间:2017-03-29 18:04:42

标签: tcl

如何将包的内容加载到当前命名空间而不是全局命名空间?

假设我有以下package.tcl

package provide pgkTest 1.0

variable _value ""
proc get_value {} {
  variable _value
  return _value
} 

该软件包列在pkgIndex.tcl中,已找到。现在在我想要做的另一个文件夹的主脚本中:

namespace eval myns1 {
   package require pgkTest 1.0
   package forget pgkTest 
}

namespace eval myns2 {
   package require pgkTest 1.0
   package forget pgkTest 
}

但是,这似乎不起作用,因为默认情况下将包加载到全局名称空间中。

1 个答案:

答案 0 :(得分:1)

您尝试执行的操作无效,因为每个包(由其名称确定)最多只能加载一次到解释器中。相反,该软件包可能应该提供一个命令来设置一个给定的命名空间,其中包含您所追求的功能:

package provide pgkTest 1.0

namespace eval ::pgkTest {}
proc ::pgkTest::setup {{targetNamespace ""}} {
    # If caller doesn't give a namespace, get the caller's namespace
    if {$targetNamespace eq ""} {
        set targetNamespace [uplevel 1 {namespace current}]
    }
    namespace eval $targetNamespace {
        variable _value ""
        proc get_value {} {
          variable _value
          return _value
        } 
    }
}

然后你可以这样做以获得你想要的效果

package require pgkTest 1.0

namespace eval myns1 {
    ::pgkTest::setup
}

namespace eval myns2 {
   ::pgkTest::setup
}

如果你真的做了很多这样的事情,考虑转而使用像TclOO,[incr Tcl]或XOTcl这样的对象系统。它们的设计更多是为了解决这个问题。剔除大量相同(或有微小变化)的东西的问题。