Re: How to chain prodecure calls that mutate a reference object ?
I know this code isn't meant to be used, but the given answers for `var Child` were wrong to the point where I have to respond. We want the variable `self.child` not `child`. No need for templates or anything type Child* = object value: int Parent* = object child: Child proc set_value*(self: var Child, value: int): var Child {.discardable.} = self.value = value self proc get_child*(self: var Parent): var Child = self.child = Child() self.child var parent = Parent() parent.get_child().set_value(10) echo parent.child.value # 10 Run Again, this isn't idiomatic code, just had to point it out.
Re: How to chain prodecure calls that mutate a reference object ?
Polluting your APIs in order to support "chaining" is a bad idea. Wait for [https://github.com/nim-lang/Nim/pull/13092](https://github.com/nim-lang/Nim/pull/13092) instead please.
Re: How to chain prodecure calls that mutate a reference object ?
working solution all in one snippet type Child* = ref object value: int Parent* = ref object child: Child proc set_value*(self: var Child, value: int): var Child {.discardable.} = self.value = value return self proc return_child(child : var Child) : var Child {.discardable.} = child template get_child*(self : var Parent) : Child = var child = Child() self.child = child return_child(child) var parent = Parent() parent.get_child().set_value(10) Run However I would use @mratsim's solution instead unless you are using objects instead of ref objects.
Re: How to chain prodecure calls that mutate a reference object ?
Hey ! Thanks you for the quick answers ! As @solo989, just returning var Child like in the snippets below does not work has it triggers a compile error. proc set_value*(self: var Child, value: int): var Child {.discardable.} = self.value = value return self proc get_child*(self: var Parent): var Child {.discardable.} = var child = Child() self.child = child return child # Raises: # Error: 'child' escapes its stack frame; context: 'child'; see https://nim-lang.org/docs/var_t_return.html Run Finally, @mratsim solutions works fine and make perfect sens :)
Re: How to chain prodecure calls that mutate a reference object ?
you are returning value, not reference. change return type to var Child
Re: How to chain prodecure calls that mutate a reference object ?
You don't need `var` in any of those procs because you are using ref objects and you are modifying the memory pointed to by the reference, not the reference itself. i.e. this compiles type Child* = ref object value: int Parent* = ref object child: Child proc set_value*(self: Child, value: int): Child {.discardable.} = self.value = value return self proc get_child*(self: Parent): Child {.discardable.} = let child = Child() self.child = child return child let parent = Parent() parent.get_child().set_value(10) Run
Re: How to chain prodecure calls that mutate a reference object ?
get_child returns a Child, not a var Child
Re: How to chain prodecure calls that mutate a reference object ?
You need to make the return value var as well. proc set_value*(self: var Child, value: int): var Child {.discardable.} = self.value = value return self proc get_child*(self: var Parent): var Child {.discardable.} = var child = Child() self.child = child return child Run However then var child escapes it's stack frame so I would normally make it a template instead. template get_child*(self : var Parent) : Child {.discardable.} = var child = Child() self.child = child child Run But the template doesn't work with discardable so combine both proc return_child(child : var Child) : var Child {.discardable.} = child template get_child*(self : var Parent) : Child = var child = Child() self.child = child return_child(child) Run