Is this the expected output with mget?
(if so how do I do multiple operations with a table entry without suffering multiple lookups)
Thanks
type
astruct = object
a: int
b: int
var table = initTable[string, astruct]()
table["entry"] = astruct()
echo table["entry"]
table.mget("entry").a = 1 ## (a: 1, b: 0)
var s = table.mget("entry")
s.a = 2
echo table["entry"] ## --> (a: 1, b: 0)
I get the same behavior (after adding "import tables" to get it to compile).
As a workaround for your tables use case, this works for me:
var s: ptr astruct = addr table.mget("entry")
s.a = 1
s.b = 2
echo table["entry"] ## --> (a: 1, b: 2)
Hopefully that can get you moving again. You should be careful to not use such ptrs after the memory may have been invalidated by the table resizing itself, such as after inserting another item.
This same surprising behavior also happens with the simpler example:
proc foo(x: var int): var int = result = x
var y = 1
var s = foo(y)
inc(s)
assert y == 2 # fails
In the generated C code for both examples, the assignment through 'var s' sets an s_TEMPNUM = *LOCn (a struct copy in C for the object type case which could be expensive for large objects). The code correctly updates s_TEMPNUM or s_TEMPNUM.a to be 2. The generated code never struct copies/writes the location back via a *LOCn assignment, though.
Well I guess I'm still finding my feet with nim but it was surprising to me; returning a var seems a special case of var.
I guess thinking in python then I expected a naming assignment. And thinking in C I wouldn't have done the copy.
Obviously though nim is nim.
Updating the manual would be helpful, also the docs for tables.nim.
Thanks to you both!