def f(a, b=0, **kw): print kw f(1, 2, x=10, y=20)kw is the dictionary and is accessible in usual way (item existent checking, getting and so on). Argument b can be skipped and is optional too.
For Tcl it's easy to write procedure for processing keyword arguments (like getopt):
proc getargs {argsName kwArgsName arguments} {
# like getopt for proc/method, ex:
# 1) argsName may be ""|{} - to avoid positional args saving
# 2) if no value of keyword argument, then it's value will be "Y"
upvar 1 $kwArgsName kwargs
set posargs {}
proc isKw opt {
return [expr {"-" eq [string index $opt 0]}]
}
proc setPosArg opt {
upvar 1 posargs posargs
lappend posargs $opt
}
proc setKwArg {name val} {
set ret "@NOMORE"; # used or not $val, it's possible positional opt
if {$name ne ""} {
upvar 1 kwargs kwargs
set defaultValue [lindex [array get kwargs $name] end]
if {$defaultValue in {"Y" "N"}} {
if {$val eq ""} {
set val "Y"
} elseif {$val ni {"Y" "N"}} {
set ret $val
set val "Y"
}
}
set kwargs($name) $val
}
return $ret
}
set kw ""
set state OPT; # OPT|VAL|END
lappend arguments "@EOO"
foreach opt $arguments {
switch -- $state {
OPT {
if {$opt eq "@EOO"} {
set state END
} elseif {[isKw $opt]} {
set kw $opt
set state VAL
} else {
setPosArg $opt
}
}
VAL {
if {$opt eq "@EOO"} {
setKwArg $kw ""
set state END
} elseif {[isKw $opt]} {
setKwArg $kw ""
set kw $opt
} else {
set maybePos [setKwArg $kw $opt]
if {$maybePos ne "@NOMORE"} { setPosArg $maybePos }
set state OPT
}
}
END { break; }
}
}
if {$argsName ne ""} {
upvar 1 $argsName _posargs
set _posargs $posargs
}
}
Here is the example how to use:set args {}; # positional args
array set kw {-a 1 -b 2}; # default kw-args
set inputArgs {-a 20 -c 30 zzz -q -v xxx yyy}
getargs args kw $inputArgs
puts "Args:\n $args"
puts "KW Args:"
foreach {k v} [array get kw] {
puts " $k = $v"
}
If positional arguments are not needed, use "" or {} instead of its' variable name. If some keyword options has no value (it's flag only!), set it's default value ("Y" or "N") to kwArgsName (kw array is example), so getargs will not interpret the next word as option value. But it's possible to has value if it is "Y" or "N": someCommand -someFlag or someCommand -someFlag N