Version 4 of lset forward compatibility

Updated 2005-01-12 04:19:06

Originated by Tom Wilkason on comp.lang.tcl.

Modifications by DGP.

  if {[package vcompare [package provide Tcl] 8.4] < 0} {
      proc tcl::K {a b} {return $a}
      proc lset {listName index val} {
          upvar $listName list
          set list [lreplace [tcl::K $list [set list {}]] $index $index $val]
      }
  } ;# end if

KPV Does anybody have a version that works with multiple indices?

MG Nov 12 2004 - Does this work?

  proc lset2 {listName args} {
     if { [llength $args] == "0" } {
          error "wrong # args: should be \"lset2 listVar index ?index...? value\""
        }
     upvar $listName list
     if { [llength $args] == "1" || ([llength $args] == "2" && [llength [lindex $args 0]] == "0") } {
          set list [lindex $args [expr {[llength $args]=="1"?0:1}]]
          return $list;
        }
     set val [lindex $args end]
     foreach x [lrange $args 0 end-1] {
             set list [lreplace $list $x $x $val]
            }
     return $list;
   }

LIO I couldn't seem to get the above to work correctly. I wrote a recursive version, the only difference to the actual lset (that I can think of) is it will not take the indeces as a single list (although it would be easy to add that in).

  if {[package vcompare [package provide Tcl] 8.4] < 0} {
      proc tcl::K {a b} {return $a}
      proc lset_r {list args val} {
          if { [llength $args] == "0" } {
              return $val
          } else {
              return [lreplace $list [lindex $args 0] [lindex $args 0] [lset_r [lindex $list [lindex $args 0]] [lrange $args 1 end] $val]]
          }
      }
      proc lset {listName args} {
          if { [llength $args] == "0" } {
              error "wrong # args: should be \"lset varName ?index...? newValue\""
          }
          upvar $listName list
          set list [lset_r [tcl::K $list [set list {}]] [lrange $args 0 end-1] [lindex $args end]]
      }
  }