Tcl `阵列nextelement`--can';当searchId无效时,无法捕获错误
我已经并且正在做一个练习来实现Tcl `阵列nextelement`--can';当searchId无效时,无法捕获错误,tcl,Tcl,我已经并且正在做一个练习来实现数组foreach(是的,我知道) 我正在使用数组startsearch/more/nextelement/donesearch。我现在试图捕获在搜索过程中添加或删除数组元素时抛出的错误:我发现我无法在代码中捕获该错误,但我可以在交互式会话中捕获它 下面是一个互动会话: % array set Y {foo bar baz qux} % set sid [array startsearch Y] s-1-Y % set key [array nextelement
数组foreach
(是的,我知道)
我正在使用数组startsearch/more/nextelement/donesearch。我现在试图捕获在搜索过程中添加或删除数组元素时抛出的错误:我发现我无法在代码中捕获该错误,但我可以在交互式会话中捕获它
下面是一个互动会话:
% array set Y {foo bar baz qux}
% set sid [array startsearch Y]
s-1-Y
% set key [array nextelement Y $sid]
foo
% set Y(hello) world
world
% try {
set key [array nextelement Y $sid]
} trap {TCL LOOKUP} {msg e} {puts "$sid has been invalidated\n$e"}
s-1-Y has been invalidated
-code 1 -level 0 -errorstack {INNER {invokeStk1 ::tcl::array::nextelement Y s-1-Y}} -errorcode {TCL LOOKUP ARRAYSEARCH s-1-Y} -errorinfo {couldn't find search "s-1-Y"
while executing
"array nextelement Y $sid"
("try" body line 1)} -errorline 1
%
一切都好。我们可以看到,在我添加了一个数组元素之后,当一个活动搜索正在进行时,searchId无效:错误代码以{TCL LOOKUP ARRAYSEARCH}
现在,我将其包装在一个proc中,并安排在启动交互式tclsh时对其进行源代码获取(有关详细信息,请参阅)。这是我的数组foreach
过程的主体:
% info body ::monkeypatches::array_foreach
if {[llength $vars] != 2} {
error {array foreach: "vars" must be a 2 element list}
}
lassign $vars keyVar valueVar
# Using the complicated `upvar 1 $arrayName $arrayName` so that any
# error messages propagate up with the user's array name
upvar 1 $arrayName $arrayName $keyVar key $valueVar value
set sid [array startsearch $arrayName]
while {[array anymore $arrayName $sid]} {
# This doesn't seem to be able to catch the error when the user
# tries to modify the array during a search. Hmm.
try {
set key [array nextelement $arrayName $sid]
} trap {TCL LOOKUP ARRAYSEARCH} {"" e} {
return -options $e "detected attempt to modify the array while iterating"
}
set value [set "${arrayName}($key)"]
uplevel 1 $body
}
array donesearch $arrayName $sid
return
当我重现捕捉错误的步骤时,我发现我的try
没有捕捉到错误:
% array set Y {foo bar baz qux}
% array foreach {key val} Y {set Y(hello) world}
couldn't find search "s-1-Y"
将特定的trap
子句替换为通用的on error
没有帮助。使用catch
而不是也不能尝试
我不明白为什么这个进程不能捕获错误。有什么想法吗?如果您查看错误跟踪,您会发现错误并非来自您预期的地方。(为了本测试的目的,我创建了一个名为array\u foreach
的过程。)
您已经在阵列nextelement
上设置了陷阱,但不再在阵列上设置陷阱,这是实际检测问题(并抛出问题)的地方
我想您最好将循环更改为:
while true {
try {
if {![array anymore $arrayName $sid]} {
break
}
set key [array nextelement $arrayName $sid]
set value [set ${arrayName}($key)]
} trap {TCL LOOKUP ARRAYSEARCH} {"" e} {
return -options $e "detected attempt to modify the array while iterating"
}
uplevel 1 $body
}
哦。谢谢你,多纳尔。
while true {
try {
if {![array anymore $arrayName $sid]} {
break
}
set key [array nextelement $arrayName $sid]
set value [set ${arrayName}($key)]
} trap {TCL LOOKUP ARRAYSEARCH} {"" e} {
return -options $e "detected attempt to modify the array while iterating"
}
uplevel 1 $body
}