What I'm proposing here is that the OP can solve his underlying problem, which is overloading symbols by qualifying them. He proposes to sub-values as a qualifying mechanism, but has encountered a problem with that approach when associations are involved.
My counter proposal is that using context qualified symbols will provide a simple and elegant way to do everything the OP wants to do with sub-values, including adding a new key-value pair to an association with Set (where sub-values failed)
In a comment now removed from the question, the OP objected to use of the context construct because writing Begin-End frames was "so 20th century". However, a symbol can always be used as a context qualifier without writing and evaluating Begin
and End
frames. To illustrate this I will give a rather contrived example where the context debug`
is used to control some debugging output.
Global variables. I define these just to show they are not be affected by changes to debug`clicks
and debug`on
,
clicks = 0; on = 42;
Commands to turn debugging on and off.
debugOn := (debug`clicks = 0; debug`on = True)
debugOff := debug`on = False
Start debugging and show values of interest.
debugOn;
Dynamic @ Row[{clicks, on, debug`clicks, debug`on}, " "]
0 42 0 True
Now here is the contrived example of code with an embedded debugging variable that can be turned on off. When debugging is on, the changes in the variable can observed dynamically.
DynamicModule[{colors = {Red, Blue}},
Row[
{Button["Change Color",
If[debug`on, debug`clicks++]; colors = Reverse @ colors],
Dynamic @ Graphics[{colors[[1]], Disk[]}]}, Spacer[10]]]
Evaluate the above code and click on the button five times. You would see the disk alternate between red and blue and the monitored variables would become
0 42 5 True
Note that the global variables are unaffected.
Now evaluate
debugOff
The row of monitored variables becomes
0 42 5 False
and clicking on the button still changes the color of the disk but no longer affects the monitored variables.
Also, and perhaps most important to the OP, there is no problem with associations.
debug`assoc = <|"a" -> 10|>;
debug`assoc["b"] = 20;
debug`assoc
<|"a" -> 10, "b" -> 20|>