Nested dictionaries from functions

I was playing around with action code so I could get to know it a little better. I have a question about this function

function nested_dict() {
    var:dictionary nested = {
        nestedk1: "nestedv1";
        nestedk2: "nestedv2";
    };
    var:dictionary dict = {
        nested: nested;
        k1: "v1";
    };
    return dict;
}

I was expecting it to return {nested:{nestedk1: "nestedv1"; nestedk2: "nestedv2";};k1:v1}, but it’s returning {nested:nested;k1:v1}. Did I write it incorrectly? Or are my expectations wrong?

Example tinderbox doc attached.

test-nested-dictionary.tbx (113.4 KB)

var:dictionary dict = {
        nested: nested;
        k1: "v1";
    };

Tinderbox doesn’t do variable interpolation (as Perl did, for example), so this won’t work. You could, however, try:

var:dictionary dict = {
         k1: "v1";
    };
dict["nested"]=nested;

Aha, thank you!

There are also the Dictionary.add() and Dictionary.extend() methods.

Note to self: the above need merging into the general description of working with Dictionary-type data in existing article Dictionary-Type Attributes. In fact, the latter probably needs to be re-factored into a series of more focussed and separately-linkable articles. Using list (List & Set) data likely needs the same re-factoring.

Over v9–v11 dicitionary declaration/access has undergone a fair degree of change. As Tinderbox is fairly liberal in still supporting older (‘legacy’) methods, it can be hard to define a single best practice, not least as one method may avoid an edge case encountered by another method. In contrast, I do try to flag up (and eventually remove reference to) legacy methods in the hope new users will avoid them. But, things like the forum mean there is often old code floating around. Plus, once we learn how to do a thing we become resistive to change if a better method comes along, and so teach old-think to new users.

Also: there is nothing wrong with simply writing the nested dictionary directly:

 var:dictionary nested = {
        nested1: {a:"winter";b:"spring"};
        nested2: "nestedv2";
    };
1 Like

If wanting the use the newer Dictionary-type .add(), this works for me (vDict2 as the second text I tried):

var:dictionary vDict2;
vDict2 = vDict2.add("k1:v1");

var:dictionary vNested;
vNested = vNested.add("nk1: nestedv1").add("nk2: nestedv2");

var:string vString = "Nested:"+vNested;
vDict2 = vDict2.add(vString);

$Text = vDict2;

As action code involves moving in and out of strings, I’d suggest that a key:value pair like this in the original post:

nested: nested;

is courting trouble. Even if the value is actually a named variable, I’d suggest avoiding re-using the same (string) name for objects with different purpose/scope as it avoids hard to diagnose silent fails where we, the user, have shot ourself in the foot by unnecessarily providing code that confuses the code parser.

I’ve updated these articles:

These better integrate the dot operators with the main article and clarify that dot-chaining is possible.