Version 9 of ranged switch

Updated 2005-12-20 14:23:32 by escargo

coyotes rand mair fheal wrote in the comp.lang.tcl newsgroup:

 proc rangedswitch {index switches} {
     for {set i 0} {$i<[llength $switches]} {incr i} {
         if {[string equal $switches([expr {$i+1}]) ..]} {
             set match [expr {$switches($i)<=$index &&$index<=$switches([expr {$i+2}])}]
             incr i 2
         } else {
             set match [expr {$switches($i)==$index}]
         }
    et cetera

    rangedswitch $i {
        0 {do a}
        2 .. 5 {do b}
    }

* Could someone elaborate on this? It won't work as-is. -- Sy / jrandomhacker.info


RS rather reinvented that wheel, slightly different of course - see the test at end:

 proc rswitch {value body} {
   set go 0
   foreach {cond script} $body {
      if {[regexp {(.+)\.\.(.+)} $cond -> from to]} {
           if {$value >= $from && $value <= $to} {incr go}
      } else {
          if {$value == $cond} {incr go}
      }
      if {$go && $script ne "-"} { #(2)
          uplevel 1 $script
          break
      }
   }
   if {$cond eq "default" && !$go} {uplevel 1 $script} ;#(1)
 }

Testing:

 % foreach i {0 1 2 3 4 5 6 7 8} {puts $i;rswitch $i {1 {puts yes} 2..5 {puts maybe} 6..8 {puts no}}}
 0
 1
 yes
 2
 maybe
 3
 maybe
 4
 maybe
 5
 maybe
 6
 no
 7
 no
 8
 no

Due to polymorphic comparison (numeric or string), this also works:^)

 % foreach i {A K c z 0 7} {
   puts $i;rswitch $i {A..Z {puts upper} a..z {puts lower} 0..9 {puts digit}}
 }
 A
 upper
 K
 upper
 c
 lower
 z
 lower
 0
 digit
 7
 digit

* Ok, that's useful stuff.. but what about multi-digit numbers? -- Sy / jrandomhacker.info

e.g., using:

 rswitch 100 {A..Z {echo upper} a..z {echo lower} 0..999 {echo digit}}

RS Yup, my bug. ".." in regular expressions match any char, so the original version

      if {[regexp (.+)..(.+) $cond -> from to]} {

was over-eager - in 0..99, it matched "0." as from, and "9" as to. Fixed above, so multi-digit numbers work (and added a line for default treatment at #(1)). Another enhancement at #(2) is fall-through treatment (a - b - c ...} just like in switch. Thanks for testing!


Arts and crafts of Tcl-Tk programming | Category Control Structure