Reputation: 7494
I'm looking for a way to append a string to an existing member of an inner dictionary (Tcl8.5)
dict append
is no good - enables only 1 level of recursion. dict set
and dict get
, but it's pretty ugly. dict with
will help, but it can be disastrous if one of the keys has the same name as the name of the dictionary..
dict set cfg animals mammal cat1 meyaO1
dict set cfg animals mammal cat2 meyaO2
dict set cfg animals mammal cfg bar
# Method 1 (Ugly)
dict set cfg animals mammal cat1 "[dict get $cfg animals mammal cat1]hihi"
puts [dict get $cfg animals mammal cat1]
# Method 2 (Risky)
proc foo {cfg} {
proc dict_append {cfgName} {
upvar $cfgName cfg
dict with cfg animals mammal {
append cat1 "hihi"
}
return $cfg
}
puts [dict_append cfg]
}
foo $cfg
The above code outputs:
meyaO1hihi
missing value to go with key
while executing
"dict with cfg animals mammal {
append cat1 "hihi"
}"
(procedure "dict_append" line 3)
invoked from within
"dict_append cfg"
(procedure "foo" line 9)
invoked from within
"foo $cfg"
(file "basics.tcl" line 20)
Do you know of a neat way which is also safe?
Edit #1, 27 Feb 2014 09:15 UTC:
Responding to @Donal Fellows answer:
What do you mean by "You can't do ... particular format)"?
I think that I can choose whether the key will be formatted or structured... Here's an example:
puts {Structured key:}
dict set cfg animals mammal cat1 meyaO1
dict set cfg animals mammal cat2 meyaO2
dict set cfg animals mammal cfg bar
puts $cfg
unset cfg
puts {Formatted key (NOT structured):}
dict set cfg "animals mammal cat1" meyaO1
dict set cfg "animals mammal cat2" meyaO2
dict set cfg "animals mammal cfg" bar
puts $cfg
The above code outputs:
Structured key:
animals {mammal {cat1 meyaO1 cat2 meyaO2 cfg bar}}
Formatted key (NOT structured):
{animals mammal cat1} meyaO1 {animals mammal cat2} meyaO2 {animals mammal cfg} bar
Upvotes: 1
Views: 321
Reputation: 137717
That's quite deep. You're probably best off going with nested dict update
s.
# Map the value for the 'animals' key as the 'outer' var
dict update cfg animals outer {
# Map the value for the 'mammal' key as the 'inner' var
dict update outer mammal inner {
dict lappend inner cat1 "hihi"
}
}
You can't do something like structured keys like this because dictionaries are designed to allow arbitrary strings as keys (and structured keys won't work with that, because there's no way to tell whether a b c
, or even a.b.c
, is a structured key or a key in a particular format).
The dict with
command is intended for use in situations where the keys are more well-known.
Upvotes: 2