Version 0 of The serial iterator

Updated 2005-04-13 11:57:17

I stumbled across a sweet way to create an autoincrementing variable for use in loops and such. It allows me to write code like:

tclsh8.4 ~/codesource serial.tcl tclsh8.4 ~/codeserial create s tclsh8.4 ~/codeforeach fruit {apples oranges pears banannas} { > puts format {%03d %s} $s $fruit >} 001 apples 002 oranges 003 pears 004 banannas tclsh8.4 ~/code

Anyway, I'm so impressed by my own cleverness, that I need to post it online immediately.


#serial.tcl #Copyright April 13, 2005 - Pierre Coueffin

source subcommands.tcl

proc serial {command args} {

    subcommand $command args {
        create {var {start 1} {step 1}} {
            incr start [expr -1 * $step]

            upvar $var v

            if {[regexp {read {serial trace (-?[0-9]+)}} \
                     [trace info variable v]]} {
                error "The variable $var has already been declared serial."
            }

            set v $start
            trace add variable v read [list serial trace $step]
        }

        array {var vals {step 1}} {
            upvar $var v
            foreach {idx val} $vals {
                set v($idx) [expr $val - $step]
            }
            trace add variable v read [list serial trace $step]
        }

        trace {step var idx _op} {          
            upvar $var v

            if {$idx == {}} {
                incr v $step
            } else {
                incr v($idx) $step
            }
        }

        forget {var} {
            upvar $var v
            trace remove variable v read \
                [list serial trace [serial stepsize v]]
        }

        stepsize {var {newstep {}}} {
            upvar $var v
            if {[llength $newstep] > 0} {
                serial forget v
                serial create v $v $newstep
                return $v
            } else {
                regexp {read {serial trace (-?[0-9]+)}} \
                    [trace info variable v] match step
                return $step
            }
        }

        last {var} {
            upvar $var v
            return [incr v [expr -1 * [serial stepsize v]]]
        }

        default {} {
            error "serial: I don't know how to \"$command\"!"
        }
    }

}