Is it possible to exit in 1 command, from two levels of nesting? That is, let us say I have this code:
foreach l { 1 2 3 4 } {
foreach k { 3 4 5 6 } {
if { $k > 4 } {
break2
} else {
puts "$k $l"
}
}
What that I would like to see output is:
1 3
1 4
The question is, how can one code the break2 (if possible)?.
I do not know of such "feature" in any language, other than wrapping this in a proc, and using return to stop the proc, which is more of a hack than proper language construct
Thanks.
It's not possible to do it directly; the break machinery doesn't have anything to trace up to anything other than the nearest looping context.
The easiest way of handling this is to use try in 8.6 and a custom exception code (i.e., any value from 5 upwards).
foreach a {b c} {
puts "a=$a; to show that this is not stopping the outermost loop"
try {
foreach l { 1 2 3 4 } {
foreach k { 3 4 5 6 } {
if { $k > 4 } {
# Generating a custom exception code is a bit messy
return -level 0 -code 5
}
puts "$k $l"
}
}
} on 5 {} {
# Do nothing here; we've broken out
}
}
Running that gives this output:
a=b; to show that this is not stopping the outermost loop 3 1 4 1 a=c; to show that this is not stopping the outermost loop 3 1 4 1
But it's pretty messy to do this; the best approach is typically to refactor your code so that you can just return ordinarily to end the loop. Using apply might make this easier:
foreach a {b c} {
puts "a=$a; to show that this is not stopping the outermost loop"
apply {{} {
foreach l { 1 2 3 4 } {
foreach k { 3 4 5 6 } {
if { $k > 4 } {
return
}
puts "$k $l"
}
}
}}
}
The downside of using apply is that it is a different variable context and has quite a bit more overhead (because of all the stack frame management). Still, the variable context thing can be worked around using upvar if you're careful.
It's possible in Tcl ≥ 8.5:
foreach l { 1 2 3 4 } {
foreach k { 3 4 5 6 } {
if {$k > 4} {
return -code break -level 2
} else {
puts "$k $l"
}
}
}
That return -code break -level 2 works like "make the enclosing command two levels up the stack return as if it has called break".
The return command manual page.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With