Breaking parent loop in tcl

不打扰是莪最后的温柔 提交于 2019-12-12 18:14:16

问题


I have a for loop in a while loop. I have a condition to break the while in the for loop.

Here is the code :

while {[gets $thefile line] >= 0} {
   for {set i 1} {$i<$count_table} {incr i} {
   if { [regexp "pattern_$i" $line] } {
      for {set break_lines 1} {$break_lines<$nb_lines} {incr break_lines} {
         if {[gets $thefile line_$break_lines] < 0} break
      }
   }
   #some other process to do
}

I want to skip $nb_lines in the file parsed to do other thing further. Here the break, breaks the for loop, so it doesn't work.

Can the for loop make the while loop broken ? But the break is just for 1 (or more) lines, i want to continue to parse the file after the break to process line further

Thanks


回答1:


The break command (and continue too) doesn't do multi-level loop exit. IMO, the simplest workaround is to just refactor the code so you can return to exit the outer loop. However, if you can't do that, then you can use something like this instead (for 8.5 and later):

proc magictrap {code body} {
    if {$code <= 4} {error "bad magic code"}; # Lower values reserved for Tcl
    if {[catch {uplevel 1 $body} msg opt] == $code} return
    return -options $opt $msg
}
proc magicthrow code {return -code $code "doesn't matter what this is"}

while {[gets $thefile line] >= 0} {
   magictrap 5 {
      for {set i 1} {$i<$count_table} {incr i} {
         if { [regexp "pattern_$i" $line] } {
            for {set break_lines 1} {$break_lines<$nb_lines} {incr break_lines} {
               if {[gets $thefile line_$break_lines] < 0} {magicthrow 5}
            }
         }
      }
   }
   #some other process to do
}

The 5 isn't very special (it's just a custom result code; Tcl reserves 0–4, but leaves the others alone) but you need to pick a value for yourself so that it doesn't overlap with any other uses in your program. (It is mostly possible to redo the code so it works with 8.4 and before too, but it's quite a bit more complex to rethrow an exception there.)

Be aware that custom exception codes are a “deep magic” part of Tcl. Please use ordinary refactoring instead if you can.




回答2:


Perhaps obvious, but you can use an additional variable (go_on) to break the while:

while {[gets $thefile line] >= 0} {
  set go_on 1
  for {set i 1} {$i<$count_table && $go_on} {incr i} {
    if { [regexp "pattern_$i" $line] } {
      for {set break_lines 1} {$break_lines<$nb_lines && $go_on} {incr break_lines} {
        if {[gets $thefile line_$break_lines] < 0} { set go_on 0 }
      }
     }
   }
   #some other process to do
}


来源:https://stackoverflow.com/questions/11523432/breaking-parent-loop-in-tcl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!