Version 3 of shorthand dict set

Updated 2014-05-20 03:09:41 by AMG

Syntax sugar for "dict set" and "dict get".

rename set _set

proc set {args} {
    if {[llength $args] <= 2} {
        uplevel [list _set {*}$args]
    } else {
        uplevel [list dict set {*}$args]
    }
}

proc get {dict args} {
    uplevel dict get [list $dict] $args
}

This over-loads plain-old "set" to allow "set dict_var key... $value" as shorthand for "dict set dict_var key... $value". Normal "set" behaviour is retained.

"get" is there too for symmetry.

Some may see this as heresy, but I think it makes dictionary-heavy scripts more readable :)


AMG: Avoiding [uplevel] which is slightly more dangerous than [eval]:

rename set _set
proc set {varName args} {
    upvar 1 $varName var
    if {[llength $args] <= 1} {
        _set var {*}$args
    } else {
        dict set var {*}$args
    }
}
interp alias {} get {} dict get

Also, because no caller variables are being accessed, there's no reason to use [uplevel] in your [get] command. I used [interp alias] to create an alias, since renaming (actually, partial application of command prefixes) is all that's happening. It's also possible to write: proc get {dict args} {dict get $dict {*}$args}.

One problem I have with this code is that the error message always complains about "var", never the original variable name. Sorry about that.

A more fundamental and philosophical problem is the asymmetry between variable [set] and dictionary [dict set]. Variable [set] can be used to read a value without changing it, but dictionary [dict set] must always set the value.