Tcl:如何从其他名称空间调用proc,同时还从其名称空间向proc传递变量?

时间:2019-03-01 22:15:33

标签: scope namespaces tcl

我定义了两个脚本:第一个脚本在第二个脚本中调用proc。第二个脚本定义了名称空间fooSpace,在fooValue中定义了变量fooSpace,并在myProc中定义了过程fooSpace

在我的第一个脚本中,我想使用参数myValue来调用我的proc。我希望我的程序测试myValue中是否以fooSpace的形式存在fooValue。如果是这样,该函数将使用fooValue做一些事情。

如果我理解正确,upvar会引用调用者的名称空间,在我看来,该名称空间与函数的名称空间不同。但是我也不认为我可以在我的proc中执行variable $myvalue,对吧?如何获得我的proc以使用fooSpace中定义的变量?

下面的代码返回“无法读取$ fooSpace”

这是我的第一个脚本(位于alpha.tcl中)的样子:

source bravo.tcl
namespace import fooSpace::myProc

# call the fuction
myProc apples

这是我的第二个脚本(位于bravo.tcl中)的样子:

namespace eval fooSpace {
    namespace export myProc
    set apples "Apples are 3 for a dollar"

    proc myProc {myValue} {
        upvar $fooSpace::$myValue fruit
        if {[info exists fruit] == 1} {
            puts "$fruit"
        } else {
            puts "we don't have any $fruit today"
        } 
    }
}

2 个答案:

答案 0 :(得分:2)

您可以使用namespace upvar做您想做的事情,namespace upvar $fooSpace $myValue fruit 旨在查看另一个命名空间中的变量:

upvar

或者,您可以使用fooSpace来完成此操作,但是随后需要停止对${…}变量名的替换,使其不再包含名称空间分隔符(否则您最终会用该名称空间中的空名称,该名称可能不存在)。这样的报价控制是通过upvar ${fooSpace}::$myValue fruit 完成的:

${fooSpace}::${myValue}

(您也可以使用namespace upvar,解析后它们的工作原理都一样。)

尽管如此,我还是建议您使用onSuccess:效率更高,因为它根本不需要重新解析变量名。

答案 1 :(得分:0)

  

如何获取proc以使用fooSpace中定义的变量?

您对upvar的使用是虚假的,您会错过级别参数#0

upvar "#0" [namespace current]::$myValue fruit

此外,$fooSpace不是引用名称空间fooSpace,而是该名称的proc-local变量(因此出现can't read "fooSpace": no such variable错误);因此:

[namespace current]::$myValue

变成

::fooSpace::$myValue
  

但是我也不认为我可以在proc中执行$ myvalue变量

这取决于是否要使用链接变量fruit,否,variable命令不会为您提供。但是您当然可以引用这样的命名空间变量:

 variable $myValue

次要建议:myValue最好用myVarmyVarName来命名,因为该参数表示(命名空间)变量 names (不是这些变量存储的值)