This is a proposal on how to extend the notation of args in the definition of proc. It is a request for comments, no implementation is available now.
Numbered as above...
Allow extended syntax of args: This special parameter name comes as a list...
Assume an extension to subst:
proc mysubst {{args -nobackslashes -nocommands -novariables -nocomplain {-uplevel 0} -inplace string1 {string2 {}} args}} { # the above notation is backward compatible ("default values" of args are currently ignored). # a redirection of proc could generate the following code: set -nobackslashes false set -nocommands false set -novariables false set -nocomplain false set -uplevel 0 set -inplace false set string2 {} for {set i 0} {$i < 7} {incr i} { # 7 is the max number of switches plus their values set c [lindex $args $i] if {$c in {-uplevel}} { # 1. switches with default values set $c [lindex $args [incr i]] } elseif {$c in {-nobackslashes -nocommands -novariables -nocomplain -inplace}} { # 2. boolean switches set $c true } else { if {$c eq {--}} {incr i} break } } incr i -1 ;# or do not incr in the first line below (which is harder to generate)? # 3. required (consider errors!) set string1 [lindex $args [incr i]] # 4. optional if {[llength $args] > [incr i]} {set string2 [lindex $args $i]} # more of the above line can be nested in the then-branch... # 5. unnamed set args [lrange $args $i end] unset i c # end of generated code - body below # relative levels are offset by one catch {incr -uplevel} # having both string and args is just to demonstrate the possibilities - use args only if {{} eq $string2} {set args $string1} {set args [list $string1 $string2 {*}$args]} # TODO implement # something like the following - use catch if -nocomplain and return unmodified # also, if -inplace use upvar 1 and modify the values; plus consider a loop for args... # return [uplevel ${-uplevel} [list ::subst {*}$forward_switches $string]] # demo output foreach var {-nobackslashes -nocommands -novariables -nocomplain -uplevel -inplace string1 string2 args} { puts "$var is {[set $var]}" } }
set x 14 set y {$x} set z {[expr $x * 3]} subst -nocomplain -inplace x y z