I'd still go with the one @shirleyquirk posted. That version will only do it 
for tables, and not arbitrary values, saving you from the issue that the C++ 
code had. Compare this:
    
    
    proc `[]`[A, B, C](t: var Table[A, Table[B, C]], key: A): var Table[B, C] =
      t.mgetOrPut(key, initTable[B, C]())
    
    var nested: Table[string, Table[string, Table[string, int]]]
    
    nested["this"]["works"]["fine"] = 42
    #echo nested["this"]["doesn't"]["work"] # Will throw an exception about the 
key not being found
    
    
    Run

To this, which has similar behaviour to the C++ version which silently inserts 
keys:
    
    
    var nested: Table[string, Table[string, Table[string, int]]]
    
    nested["this"]["works"]["fine"] = 42
    discard nested["now"]["this"]["works"]     # Adds a default int to the key
    echo nested["now"]["this"].len             # Now there is something in the 
"this" table
    echo nested["now"]["this"].hasKey("works") # And the works key have been 
silenly added
    echo nested["now"]["this"]["works"]        # With the default value of an 
int, which is 0
    
    
    Run

The first version will still shadow-add table entries to the subtables if you 
do something like `echo nested["a"]["couple"]["keys"]`, but you could always 
also create a procedure like:
    
    
    proc hasKey[A, B, C](t: Table[A, Table[B, C], k: A): bool = t.hasKey(k) and 
t[k].len != 0
    
    
    Run

To make `hasKey` behave a bit more like "has key with useful data".

Reply via email to