将方形支架传递到上层TCL

将方形支架传递到上层TCL,tcl,stack-trace,procedure,Tcl,Stack Trace,Procedure,我有一个代码,在其中我传递了一个列表以供TCl uplevel#0评估。 如果我给它一个使用花括号来包装方括号的代码,它会工作得很好,例如: uplevel #0 { puts [ info vars CCK_* ] } if { [ getpoint $elem ] == $pointy } 当我使用列表时,我无法接受,即: uplevel #0 [list puts "\[" info vars CCK_* "\]" ] 我得到: wrong # args: should be "pu

我有一个代码,在其中我传递了一个列表以供TCl uplevel#0评估。 如果我给它一个使用花括号来包装方括号的代码,它会工作得很好,例如:

uplevel #0 { puts [ info vars CCK_* ] }
if { [ getpoint $elem ] == $pointy }
当我使用列表时,我无法接受,即:

uplevel #0 [list puts "\[" info vars CCK_* "\]" ]
我得到:

wrong # args: should be "puts ?-nonewline? ?channelId? string"
    while executing
"puts {[} info var CCK_* \]"
    ("uplevel" body line 1)
    invoked from within
"uplevel #0 [ list puts "\[" info var CCK_* "\]" ]"
我需要list命令,因为代码的其他部分需要对变量名求值,这必须在uplevel开始排序之前发生(即,uplevel的输入)。例如:

uplevel #0 { puts [ info vars CCK_* ] }
if { [ getpoint $elem ] == $pointy }
[getpoint$elem]
要在uplevel中求值,但pointy实际上是在调用过程中定义和设置的,因此我不能对它使用大括号,在调用uplevel之前会进行求值,它只会得到一个数字。
谢谢,

组装脚本(或命令序列)提交到uplevel等不一定最好使用
列表
。例如,具有嵌套计算的脚本就是这样

你的问题措辞对我来说并不完全清楚(所以我可能不正确地解释它),但是你可能想考虑使用<代码> [SuST] 或<代码> [String Mult] 为你的目的?< /P> 观察:

set CCK_1 ""

proc foo {someVarName} {
    uplevel "#0" [subst -nocommands {
    if {"$someVarName" in [info vars CCK_*]} {
        puts "Found $someVarName"
    }
   }]
}

foo CCK_1; # prints "Found CCK_1"
foo CCK_2
列表更适合命令序列,无需过多的求值嵌套;对于完整的脚本,最好使用基于
[subst]
[string map]
的脚本模板。注意:
[subst]
[string map]
不要保护替换值,并将它们以文本形式放置在脚本中

更新 这并不是说您的原始代码片段无法正常工作:

set CCK_1 ""
# a) non-robust variant
proc bar {pattern} {
    uplevel "#0" puts "\[info vars $pattern\]"
    # equiv of
    uplevel "#0" [concat puts "\[info vars $pattern\]"]
    # versus
    uplevel "#0" [list puts "\[info vars $pattern\]"]
}

bar CCK_*

set "CCK _1" ""
# b) robust variant
proc bar-robust {pattern} {
    uplevel "#0" puts "\[[list info vars $pattern]\]"
    # equiv of
    uplevel "#0" [concat puts "\[[list info vars $pattern]\]"]
}

bar-robust "CCK _*"
uplevel
汇编脚本,由
[concat]
对其参数进行求值。就像提供一个
[concat]
'ed参数一样。您不会在此处使用
list
来组装整个脚本,而是保护正在组装的脚本组件(请参见
bar-robust
)。此处的保护意味着在脚本组装过程中,复杂值保持其原始含义(例如,包含空格的匹配模式:
CCK.
)。

组装要提交给uplevel等的脚本(或命令序列)不一定最好使用
list
。例如,具有嵌套计算的脚本就是这样

你的问题措辞对我来说并不完全清楚(所以我可能不正确地解释它),但是你可能想考虑使用<代码> [SuST] 或<代码> [String Mult] 为你的目的?< /P> 观察:

set CCK_1 ""

proc foo {someVarName} {
    uplevel "#0" [subst -nocommands {
    if {"$someVarName" in [info vars CCK_*]} {
        puts "Found $someVarName"
    }
   }]
}

foo CCK_1; # prints "Found CCK_1"
foo CCK_2
列表更适合命令序列,无需过多的求值嵌套;对于完整的脚本,最好使用基于
[subst]
[string map]
的脚本模板。注意:
[subst]
[string map]
不要保护替换值,并将它们以文本形式放置在脚本中

更新 这并不是说您的原始代码片段无法正常工作:

set CCK_1 ""
# a) non-robust variant
proc bar {pattern} {
    uplevel "#0" puts "\[info vars $pattern\]"
    # equiv of
    uplevel "#0" [concat puts "\[info vars $pattern\]"]
    # versus
    uplevel "#0" [list puts "\[info vars $pattern\]"]
}

bar CCK_*

set "CCK _1" ""
# b) robust variant
proc bar-robust {pattern} {
    uplevel "#0" puts "\[[list info vars $pattern]\]"
    # equiv of
    uplevel "#0" [concat puts "\[[list info vars $pattern]\]"]
}

bar-robust "CCK _*"

uplevel
汇编脚本,由
[concat]
对其参数进行求值。就像提供一个
[concat]
'ed参数一样。您不会在此处使用
list
来组装整个脚本,而是保护正在组装的脚本组件(请参见
bar-robust
)。这里的保护意味着在脚本组装过程中,复杂值保持其原始含义(例如,包含空格的匹配模式:
CCK.
)。

我的建议是分两步运行代码。首先,运行方括号中的代码,然后在第二次调用中使用该结果。当然,由于您只执行了一个
put
,因此不需要通过
uplevel

set result [uplevel #0 [list info vars CCK_*]
puts $result

如果使用
put
是为了说明,那么我认为调用
uplevel
两次的一般想法仍然有效:将方括号中的代码作为一个不同的步骤运行,然后将其与其他代码结合以获得最终结果。

我的建议是分两步运行代码。首先,运行方括号中的代码,然后在第二次调用中使用该结果。当然,由于您只执行了一个
put
,因此不需要通过
uplevel

set result [uplevel #0 [list info vars CCK_*]
puts $result

如果使用
put
是为了说明,那么我认为调用
uplevel
两次的一般想法仍然有效:将方括号中的代码作为一个独特的步骤运行,然后将其与其他代码组合以获得最终结果。

您只能使用
list
命令构建单个无替换命令。它引用了专门为您提供的所有信息,而
puts[info vars CCK.*]
是一个复合命令。有几种方法可以解决这个问题,但你应该仔细考虑你真正在做什么:

我引用
#0
只是为了突出显示

只有
uplevel
什么需要它 或者在这种情况下:

puts [uplevel "#0" {info vars CCK_*}]
eval
你可以随意发送这样的东西,但我不知道你为什么这么做:

uplevel "#0" [list eval { puts [ info vars CCK_* ] }]
发送Lambda术语 它在这里不是很有用,但是当您想要从当前作用域发送任意附加值时,它会变得非常出色:


只能使用
list
命令来生成单个无替换命令。它引用了专门为您提供的所有信息,而
puts[info vars CCK.*]
是一个复合命令。有几种方法可以解决这个问题,但你应该仔细考虑你真正在做什么:

我引用
#0
只是为了突出显示

只有
uplevel
什么需要它 或者在这种情况下:

puts [uplevel "#0" {info vars CCK_*}]
eval
你可以随意发送这样的东西,但我不知道你为什么这么做:

uplevel "#0" [list eval { puts [ info vars CCK_* ] }]
发送Lambda术语 它在这里不是很有用,但是当您想要从中发送任意附加值时