如何将包的内容加载到当前命名空间而不是全局命名空间?
假设我有以下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
}
但是,这似乎不起作用,因为默认情况下将包加载到全局名称空间中。
答案 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这样的对象系统。它们的设计更多是为了解决这个问题。剔除大量相同(或有微小变化)的东西的问题。