Version 5 of dict update

Updated 2016-01-26 09:15:02 by pooryorick

dict update maps values in a dictionary to variables, evaluates a script, and reflects any changes to those variables back into the dictionary.

Synopsis

dict update dictionaryVariable key varName ?key varName ...? body

Description

When body is evaluated, the value of each key in dictionaryVariable is assigned to the corresponding varName. If key doesn't exist in dictionaryVariable, the corresponding varName is not set, and is unset if was set prior to the call to dict update. When the evaluation of body is complete, the values of any varName variables are reflected back into the dictionary, regardless of the exit status of body. If the evaluation of body causes dictionaryVariable to be unset, it is not recreated.

After the evaluation of body, dict update does not unset any varName variables it created, modified, or unset. This can be used to "export" values in a dictionary as variables in the current level, leading to an idiom in which body is empty:

dict update some_data key1 varname1 key2 varname2 {}

Where it is desirable insulate the current level from changes by dict update, use a procedure, lambda, or apply to isolate it.

Examples

HaO 2012-07-20: As I did not understand what it does, I try an example:

Dict update is like a dict set with a proc:

% set d {key1 value1 key2 value2}
key1 value1 key2 value2
% dict update d key1 varKey1 {
    append varKey1 new
  }
value1new
% set d
key1 value1new key2 value2

There might be multiple keys updated simultaneously:

% set d {key1 value1 key2 value2}
key1 value1 key2 value2
% dict update d key1 varKey1 key2 varKey2 {
    append varKey1 new
    append varKey2 new
  }
value2new
% set d
key1 value1new key2 value2new

Keys might be checked for existence and set if they don't exist:

% set d {key1 value1 key2 value2}
key1 value1 key2 value2
% dict update d key3 varKey3 {
    if {![info exists varKey3]} {
       set varKey3 new
    }
  }
new
% set d
key1 value1 key2 value2 key3 new

Keys might be deleted:

% set d {key1 value1 key2 value2}
key1 value1 key2 value2
% dict update d key1 varKey1 {
    unset varKey1
  }
% set d
key2 value2

Application idea by George Petasis on clt:

lappend for sublist:

% set d {key1 {subkey11 value11}}
key1 {subkey11 value11}
% dict update d key1 varKey1 {
    dict lappend varKey1 subkey11 new
  }
subkey11 {value11 new}
% set d
key1 {subkey11 {value11 new}}

Try to put this in a proc:

proc lasubdict {dictname key subkey value} {
    upvar 1 $dictname dictvar
    dict update dictvar $key subdict [list dict lappend subdict $subkey $value]
}
% set d {key1 {subkey11 value11}}
% lasubdict d key1 subkey11 new
subkey11 {value11 new}
% set d
key1 {subkey11 {value11 new}}

Maybe, this is implemented in a more efficient manner with dict with:

proc lasubdict {dictname key subkey value} {
    upvar 1 $dictname dictvar
    dict with dictvar $key [list lappend $subkey $value]
}

Or just dict set:

proc lasubdict {dictname key subkey value} {
    upvar 1 $dictname dictvar
    dict set dictvar $key $subkey [lappend [dict get $dictvar $key $subkey] $value]
}