Thanks @jrfondren for your thoughtful and complete response. It was certainly
above and beyond the call of duty!.
I tried all of the proposed alternatives and will be updating my production
code code with option #2.
I've include a little _test harness_ in case anyone wants to further play even
more variants.
# How can I change initThing so that it stores in 'list' a *reference* to
'original'
# so that when 'original' is changed, 'list' reflects the change.
# I don't want it to make a copy.
#
# See: https://forum.nim-lang.org/t/11508#74371
template common*(title: string, original, thing: untyped) =
var thing = initThing(original)
proc show(label: string) =
echo "\n", label
echo "Original: ", original.repr
echo "Reference: ", thing.list.repr
echo "\n---", title, "---"
show "Initial:"
original[0] = 666
show "Updated:"
if thing.list[0] != 666:
echo "\nNot a reference!"
when defined BY_VALUE:
# Non reference version:
# - Makes a copy
block:
var original = @[1, 2, 3, 4, 5]
type
Thing = object
list: seq[int]
proc initThing(list: seq[int]): Thing =
result.list = list
common "BY_VALUE", original, thing
when defined BY_REF:
# Warning - fails if original *moves* or is *deleted*
block:
var original: ref seq[int]
new original
# or
# var original = new seq[int]
original[] = @[1, 2, 3, 4, 5]
type
Thing = object
list: ref seq[int]
proc initThing(list: ref seq[int]): Thing =
result.list = list
common "BY_REF", original, thing
when defined BY_POINTER:
block:
var original = @[1, 2, 3, 4, 5]
type
Thing = object
list: ptr seq[int]
proc initThing(list: var seq[int]): Thing =
result.list = list.addr
common "BY_POINTER", original, thing
Run