All is in the title.
type
Fruit = object of RootObj
name*: string
Apple = object of Fruit
Pear = object of Fruit
method eat(f: Fruit) {.base.} =
raise newException(Exception, "PURE VIRTUAL CALL")
method eat(f: Apple) =
echo "fruity"
method eat(f: Pear) =
echo "juicy"
let basket = [Apple(name:"a"), Pear(name:"b")]
eat(basket[0])
I assume the compiler infers an element type of Fruit for the array (common denominator type?), each element gets "object sliced", and it results in that everything is a fruit. When you do C++, this behavior is among the hardships you expect to be facing. But I'd assume Nim promises safe coding checks, at least it could output a warning "object get sliced here" ?
This works:
type
Fruit = object of RootObj
name*: string
Apple = object of Fruit
Pear = object of Fruit
method eat(f: Fruit) {.base.} =
raise newException(Exception, "PURE VIRTUAL CALL")
method eat(f: Apple) =
echo "fruity"
method eat(f: Pear) =
echo "juicy"
let basket = [new Apple, new Pear]
eat(basket[0][])
For dynamic dispatch to work on an object it should be a reference type as well.
it's intentionally this way(see: https://nim-lang.org/docs/manual.html#multi-methods ).
But it would probably be better, if there was a warning when you call a method on a non-ref object.
@Araq
I give you inc for that. :D I never liked in C++, to tell you the truth.