I was just thinking about how I can prevent a call of destroy from within a proc, because for callbacks we do not want destroy calls for parameters owned by GTK.
But it seems that this tests does not generate a destroy call for proc parameter at all?
type
O {.bycopy.} = object
i: int
proc new(o: var O) =
echo "new called"
proc `=destroy`*(s: var O) =
echo "=destroy called"
proc `=sink`*(a: var O; b: O) =
echo "=sink called"
proc createO: O =
result.i = 7
proc p(o: O) =
echo "working with o"
echo o.i
proc main =
var
o: O = createO()
p(o)
echo o.i
main()
$ ./h
=sink called
working with o
0
0
=destroy called
I have added the bycopy pragma, but that makes no difference. There is only one destroy call, and that is for the o var in main. When I add a local var of type O to proc p() we get another destroy call as expected.
I can rewrite it this way:
O {.bycopy.} = object
i: int
proc new(o: var O) =
echo "new called"
proc `=destroy`*(s: var O) =
echo "=destroy called"
proc `=sink`*(a: var O; b: O) =
echo "=sink called"
a.i = b.i
proc createO: O =
result.i = 7
proc p(o: sink O) =
echo "working with o"
echo o.i
proc main =
var
o: O = createO()
p(o)
echo o.i
main()
nim
$ ./h
=sink called
working with o
7
7
=destroy called
So p() has a sink parameter. But should not the echo after call of p() force a copy, so that we get two destroys?
Maybe now I understand: Proc parameters are unmutable in Nim, so there is no reason to destroy the copy. Only when inside the proc we have var myVal = myprocPar then we get a new mutable instance, which is destroyed.
And my feeling is that = proc is never used for passing parameters to procs, but only for direct assignment.