gpt4 book ai didi

namespaces - tcl 切换命名空间和 proc 参数

转载 作者:行者123 更新时间:2023-12-04 16:53:26 28 4
gpt4 key购买 nike

我有一个小问题,目前无法解释。我创建了一个简约的代码片段来显示我的问题或缺乏了解 tcl namespace 的工作原理。

所以我有文件 test.tcl:

namespace eval test {
proc print {file_name} {
namespace inscope ::test2 {
printFileName $::test::file_name
}
}
}

namespace eval test2 {
proc printFileName {file_name} {
puts $file_name
}
}

比我使用 tclsh 并运行:
source test.tcl
test::print test.dat

返回:
can't read "::test::file_name": no such variable

为什么 test::print 的参数不应该在::test 名称范围内?
我有一个简单的解决方法 设置::测试::文件名$文件名之前 命名空间范围内 {} .

但我不满意,因为我在这里错过了一些东西。

我不能只是跑 ::test2::printFileName $file_name 因为我的现实世界代码更复杂,并且不只运行一个命令,所以它提供了一个命令列表,这些命令都在不同的命名空间中。

最佳答案

局部变量不是命名空间变量。特别是,即使使用变量链接(基础机制 upvarglobalvariable 等),形式参数变量也绝不是命名空间变量。这就是变量的映射方式,因为这样做非常快;过程入口代码是Tcl的实现代码中 HitTest 门的部分之一,所以我们努力保持尽可能快的速度。

但一切都没有丢失!

您可以很容易地将值复制到命名空间变量,甚至可以使用跟踪和 upvar 做一些技巧。使它看起来像可以从该内部作用域写回局部变量。 (您可能必须使用 info level 在堆栈中搜索备份写入的位置,这将非常困惑,但它会起作用。)

但是我要做的是发出命令来提供值(并可能允许在必要时回写)。我认为它更干净一些。

namespace eval test {
proc print {file_name} {
proc ::test2::file_name {} [list return $file_name]
namespace eval ::test2 {
printFileName [file_name]
}
}
}

namespace eval test2 {
proc printFileName {file_name} {
puts $file_name
}
}

您可以通过使用 namespace path 使这更优雅。这样您就不必每次调用时都构建一个全新的过程。 interp alias也可以提供帮助(如果您熟悉函数式编程中的这类事情,这是进行参数柯里化(Currying)的好方法)。

关于namespaces - tcl 切换命名空间和 proc 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27844855/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com