将方括号传递给上层 TCL
pass square brace to uplevel TCL
我有一个代码,我在其中传递了一个要由 TCl uplevel #0 评估的列表。
如果我给它一个使用花括号来包裹方括号的代码,它会很好用,例如:
uplevel #0 { puts [ info vars CCK_* ] }
我使用列表时无法接受,即:
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)。例如:
if { [ getpoint $elem ] == $pointy }
当 [ getpoint $elem ]
要在uplevel中求值时,但pointy实际上是在调用proc中定义和设置的,因此我不能为它使用花括号,在调用uplevel之前会有求值,并且它只会得到一个数字。
谢谢,
组装脚本(或命令序列)以提交给上层等不一定使用 list
最好地实现。例如,具有嵌套评估的脚本就是这种情况。
你的问题措辞对我来说不是很清楚(所以我可能解释不正确),但你可能想考虑使用 [subst]
或 [string map]
来达到你的目的?
观看:
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
assembles 要通过 [concat]
ing 参数评估的脚本。就像提供一个 [concat]
'ed 的论点一样。您不会在此处使用 list
来 assemble 整个脚本,而是保护程序集下的脚本组件(请参阅 bar-robust
)。此处的保护意味着复杂值在脚本组装期间保持其原始含义(例如,包含空格的匹配模式:CCK _*
)。
我的建议是 运行 分两步编写代码。首先,运行 方括号中的代码,然后在第二次调用中使用该代码的结果。当然,因为你只是在做一个 puts
,所以没有必要 运行 通过 uplevel
:
set result [uplevel #0 [list info vars CCK_*]
puts $result
如果使用 puts
是为了说明目的,那么我认为调用 uplevel
两次的一般想法仍然有效:运行 方括号中的代码作为一个独特的步骤,然后将其与您的其他代码结合以获得最终结果。
您只能使用 list
命令来构建 单一无替换 命令。它专门为您引用所有内容来执行此操作,并且 puts [info vars CCK_*]
是一个复合命令。有几种解决方法,但您应该仔细考虑您真正在做什么:
我引用 #0
只是为了突出显示。
只有 uplevel
需要它
puts [uplevel "#0" [list info vars CCK_*]]
或者在这种情况下:
puts [uplevel "#0" {info vars CCK_*}]
将化合物包裹在 eval
中
您可以像这样发送任意内容,但我不确定您为什么这样做:
uplevel "#0" [list eval { puts [ info vars CCK_* ] }]
发送 Lambda 术语
uplevel "#0" [list apply {{} {
set vars [uplevel 1 {info vars CCK_*}]
puts $vars
}}]
它在这里不是很有用,但是当你想从当前范围发送任意附加值时,它会变成 superb:
set value "this is a {complex string with \[some bits\] that might} make $tcl choke"
uplevel "#0" [list apply {{value} {
set vars [uplevel 1 {info vars CCK_*}]
puts $value
puts $vars
puts $value
}} $value]
我有一个代码,我在其中传递了一个要由 TCl uplevel #0 评估的列表。 如果我给它一个使用花括号来包裹方括号的代码,它会很好用,例如:
uplevel #0 { puts [ info vars CCK_* ] }
我使用列表时无法接受,即:
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)。例如:
if { [ getpoint $elem ] == $pointy }
当 [ getpoint $elem ]
要在uplevel中求值时,但pointy实际上是在调用proc中定义和设置的,因此我不能为它使用花括号,在调用uplevel之前会有求值,并且它只会得到一个数字。
谢谢,
组装脚本(或命令序列)以提交给上层等不一定使用 list
最好地实现。例如,具有嵌套评估的脚本就是这种情况。
你的问题措辞对我来说不是很清楚(所以我可能解释不正确),但你可能想考虑使用 [subst]
或 [string map]
来达到你的目的?
观看:
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
assembles 要通过 [concat]
ing 参数评估的脚本。就像提供一个 [concat]
'ed 的论点一样。您不会在此处使用 list
来 assemble 整个脚本,而是保护程序集下的脚本组件(请参阅 bar-robust
)。此处的保护意味着复杂值在脚本组装期间保持其原始含义(例如,包含空格的匹配模式:CCK _*
)。
我的建议是 运行 分两步编写代码。首先,运行 方括号中的代码,然后在第二次调用中使用该代码的结果。当然,因为你只是在做一个 puts
,所以没有必要 运行 通过 uplevel
:
set result [uplevel #0 [list info vars CCK_*]
puts $result
如果使用 puts
是为了说明目的,那么我认为调用 uplevel
两次的一般想法仍然有效:运行 方括号中的代码作为一个独特的步骤,然后将其与您的其他代码结合以获得最终结果。
您只能使用 list
命令来构建 单一无替换 命令。它专门为您引用所有内容来执行此操作,并且 puts [info vars CCK_*]
是一个复合命令。有几种解决方法,但您应该仔细考虑您真正在做什么:
我引用 #0
只是为了突出显示。
只有 uplevel
需要它
puts [uplevel "#0" [list info vars CCK_*]]
或者在这种情况下:
puts [uplevel "#0" {info vars CCK_*}]
将化合物包裹在 eval
中
您可以像这样发送任意内容,但我不确定您为什么这样做:
uplevel "#0" [list eval { puts [ info vars CCK_* ] }]
发送 Lambda 术语
uplevel "#0" [list apply {{} {
set vars [uplevel 1 {info vars CCK_*}]
puts $vars
}}]
它在这里不是很有用,但是当你想从当前范围发送任意附加值时,它会变成 superb:
set value "this is a {complex string with \[some bits\] that might} make $tcl choke"
uplevel "#0" [list apply {{value} {
set vars [uplevel 1 {info vars CCK_*}]
puts $value
puts $vars
puts $value
}} $value]