Methods

Procedures always use static dispatch. Methods use dynamic dispatch. For dynamic dispatch to work on an object it should be a reference type.

  1. type
  2. Expression = ref object of RootObj ## abstract base class for an expression
  3. Literal = ref object of Expression
  4. x: int
  5. PlusExpr = ref object of Expression
  6. a, b: Expression
  7. method eval(e: Expression): int {.base.} =
  8. # override this base method
  9. raise newException(CatchableError, "Method without implementation override")
  10. method eval(e: Literal): int = return e.x
  11. method eval(e: PlusExpr): int =
  12. # watch out: relies on dynamic binding
  13. result = eval(e.a) + eval(e.b)
  14. proc newLit(x: int): Literal =
  15. new(result)
  16. result.x = x
  17. proc newPlus(a, b: Expression): PlusExpr =
  18. new(result)
  19. result.a = a
  20. result.b = b
  21. echo eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4)))

In the example the constructors newLit and newPlus are procs because they should use static binding, but eval is a method because it requires dynamic binding.

As can be seen in the example, base methods have to be annotated with the base pragma. The base pragma also acts as a reminder for the programmer that a base method m is used as the foundation to determine all the effects that a call to m might cause.

Note: Compile-time execution is not (yet) supported for methods.

Note: Starting from Nim 0.20, generic methods are deprecated.