I can get pointer of an object with addr or unsafeAddr, but how can I get a reference to an object? for example, the commented parts
type
MyObjRef = ref MyObj
MyObj = object
var o = MyObj()
# var r: MyObjRef = o
proc p(r: MyObjRef) = discard
# o.p
You simply start with the MyObjRef type. var o = MyObjRef()
You can also copy the object into a ref like so: o[] = otherObj
And finally, maybe your p is wrong and uses r: ref MyObj where it should have used r: var MyObj.
hidden away in the stdlib there's byaddr that emulates an lvalue reference
from the docs:
var s = @[10,11,12]
var a {.byaddr.} = s[0]
a+=100
doAssert s == @[110,11,12]
doAssert a is int
var b {.byaddr.}: int = s[0]
doAssert a.addr == b.addr
That is really very bad advice for unexperienced people, and I think you posted it for the second time. Your to_ref() creates a copy, and that is not what people want most of the time.
Deleted my answer. I didn't realised it creates a copy.
I'm kind of envisaging that {.byaddr.} will go away once views become stable?
e.g. you would be able to do:
var a: var int = s[0] # mutable view
let b: lent int = s[0] # immutable view
a = 5
echo b # prints "5"
doAssert(addr a == addr b)
Personally this whole views feature (including first-class openArray) is my most anticipated feature of the language. I hope it works out because I'm really looking forward to it :)
As far as I know, Nim's reference type always points to heap memory and cannot points to static or stack momery. If you declare an object type outside of procedures, it exists on static momery. If you declare an object type in a procedure, it exists on stack memory.
As long as there is reference to an object exists, that object must not be freed. And when last reference to an object gone, that object must be freed. If an object exists on static or stack memory, you cannot free it in such a way.
{.byaddr.} is just a pointer but it is wrapped with template so that it doesn't looks like a pointer. And it can points to invalid memory. For example, when it points to an element of a seq and you resize the seq, it can become invalid pointer. View type prevents it by detecting modification of that seq and report it as compile error.
I wrote withAliases macro that provides something like view type in different way almost safely and it works with current stable Nim. It creates new scope with aliases you specified and you cannot access local variables outside of that scope as if you called another procedure. So you cannot resize the seq while you are using the alias of that's element as long as you don't make an alias of that seq at same time. A safe nimmer is a happy nimmer and your safety is number one priority at compile time.