Hello,
I'm beginning with nim and can't seem to find the proper way to handle the "constructors" of inherited objects. Let me explain:
Let's say I make a Thing ref object, with a newThing proc that initializes various fields, sets up stuff, etc.
Now I make a OtherThing ref object of Thing, and a newOtherThing proc to do other initializations.
I would like to be able to apply the set of instructions from newThing on the OtherThing object (which should be possible, since it is inheriting from Thing after all), but I cannot find a way other than to repeat all the code from newThing into newOtherThing.
Is there a proper way to do it? I am struggling a little with juggling around with ref objects, object conversion, etc, and so I'm probably missing the elegant way to do it, so I thought I'd ask away.
Thanks in advance!
Not sure about the proper way, but here is a way:
type
ThingObj = object of RootObj
x: int
Thing = ref ThingObj
OtherThingObj = object of ThingObj
y: float
OtherThing = ref OtherThingObj
proc init(t: var ThingObj, x: int) =
t.x = x
proc newThing(x: int): Thing =
new(result)
init(result[], x)
proc init(t: var OtherThingObj, x: int, y: float) =
init(t, x)
t.y = y
proc newOtherThing(x: int, y: float): OtherThing =
new(result)
init(result[], x, y)
proc main() =
let a = newThing(3)
echo a[]
let b = newOtherThing(3, 3.14)
echo b[]
main() If I understood your problem correctly, you can use type conversion to the base type and call its initializer function within the inherited type initializer.
I believe behind the scenes the inherited type holds a pointer to the base, so this translates to just calling the corresponding proc for the base type in the c generated code.
Check it out:
type
Base = ref object of RootObj
first: int
second: float
Inherited = ref object of Base
third: string
proc init(o: Base) =
o.first = 42
o.second = 99.9
proc init(i: Inherited) =
Base(i).init
i.third = "test"
var obj = Base()
obj.init()
var obj2 = Inherited()
obj2.init()
echo $obj[]
echo $obj2[] I may have misunderstood.
type
ThingObj = ref object of RootObj
x: int
OtherThingObj = ref object of ThingObj
y: float
proc initThingObj(x: int): ThingObj =
ThingObj(x: x)
proc initOtherThingObj(x: int, y: float): OtherThingObj =
OtherThingObj(x: x, y: y)
when isMainModule:
let a = initThingObj(3)
echo a[]
let b = initOtherThingObj(3, 4)
echo b[]