I want to create a OOP-style type (i.e. I will have data fields in that "class" and procedures operating on the type in UFCS manner). I not planning to inherit new types from this "class".
So should I declare the "class" with ref:
type
Questions = ref object
what: string
why: string
or should I use direct declaration :
type
Questions = object
what: string
why: string
As said I will have a few procedures operating on this type, like
proc ask(qs: Questions) =
...
Which declaration is recommended? What are the performance implications for the qs.ask() calls?
Thanks heaps for pointers!
Thanks for chiming in! :-)
Excuse the newbie question: What do you mean with "reference semantics"? That the variable is a pointer to the data? So are ref calls faster on large objects (because only the pointer has to be copied into the proc, but the data)?
Aaah, yes, of course! I just realised:
If I want to do something like
proc standard(qs: Questions) =
qs.what = "What's up?"
qs.why = "Why are you here?"
I need
type
Questions = ref object
what: string
why: string
If the signature is var Question it'll work identically for ref object and object
type
Questions = object
what: string
why: string
proc standard(qs: var Questions) =
qs.what = "What's up?"
qs.why = "Why are you here?"
var qs = Questions()
qs.standard()
assert qs == Questions(what: "What's up?", why: "Why are you here?")
Which declaration is recommended?
I tried to explain that in the kids book:
http://ssalewski.de/nimprogramming.html#_references_and_pointers
http://ssalewski.de/nimprogramming.html#_object_orientated_programming_and_inheritance
Conclusion: use references only when you need them.
Any object larger than 3 pointer sizes I believe will be passed by reference instead of value.
It's 3 floats, not 3 pointers.
Yes it's 3 floats, I mistakengly thought it was 3 pointers but somehow the code refers to "float" size, and since Nim float are always 64-bit any objects over 24 bytes is passed by reference in the codegen.
Now I think it would make more sense to use 3 pointer sizes but I don't care enough about 32-bit :p
The links are very comprehensive reading about Nim!
Regarding the ref semantic: I realise, if you want to mimic an OOP style close to languages like Python, the ref object declaration suits better, because all the "class" methods might mutate fields of the "class".
Doesn't seem to be the case:
type Parent = object of RootObj
type Child = object of Parent
method cheers(self: Parent) {.base.} = echo "Parent: hi"
method cheers(self: Child) = echo "Child: hi"
let (p, c) = (Parent(), Child())
p.cheers
c.cheers
var unknown: Parent
# Error unknown = Child()