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