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][])

2018-04-15 15:44:36

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.

2018-04-15 19:05:09
Thanks for reminding me, this is actually a bug. Not that you can call methods on objects, but the object slicing in assigments should be prevented at runtime at least. 2018-04-16 06:51:21

@Araq

I give you inc for that. I never liked in C++, to tell you the truth.

2018-04-16 12:25:21