is supposed to build, run and produce output as shown in the last box on the page.
Instead, I get this:
$ make nim compile --run --verbosity:0 t2.nim Hint: t2 [Processing] t2.nim(185, 7) template/generic instantiation from here t2.nim(189, 40) Error: undeclared identifier: 'this' make: *** [Makefile:5: build_and_run] Error 1 2 $
In general how stable/usable is nim metaprogramming? I'm interested in using it to automatically generate database backing for types in a new project.
Thanks, Britton
You can make the oop_macro work with the following changes:
Change
result =
if exported:
# mark `typeName` with an asterisk
quote do:
type `typeName`* = ref object of `baseName`
else:
quote do:
type `typeName` = ref object of `baseName`
to
if exported:
result =
quote do:
type `typeName`* = ref object of `baseName`
else:
result =
quote do:
type `typeName` = ref object of `baseName`
I'm not sure if this used to work because right now in Nim, you can't assign the result of an if ... else expression to a variable.
And change:
node.params.insert(1, newIdentDefs(ident("self"), typeName))
to
node.params.insert(1, newIdentDefs(ident("this"), typeName))
You'll notice in the code at the bottom:
class Animal of RootObj:
var name: string
var age: int
method vocalize: string {.base.} = "..." # use `base` pragma to annonate base methods
method age_human_yrs: int {.base.} = this.age # `this` is injected
proc `$`: string = "animal:" & this.name & ":" & $this.age
class Dog of Animal:
method vocalize: string = "woof"
method age_human_yrs: int = this.age * 7
proc `$`: string = "dog:" & this.name & ":" & $this.age
class Cat of Animal:
method vocalize: string = "meow"
proc `$`: string = "cat:" & this.name & ":" & $this.age
class Rabbit of Animal:
proc newRabbit(name: string, age: int) = # the constructor doesn't need a return type
result = Rabbit(name: name, age: age)
method vocalize: string = "meep"
proc `$`: string = "rabbit:" & this.name & ":" & $this.age
the references are all to "this". But the author used "self" in the macro definition. Either this code never worked, or the author rewrote it with a typo. Either way, simple fix!
I'm not sure if this used to work because right now in Nim, you can't assign the result of an if ... else expression to a variable.
Of course you can, if is an expression in Nim (as well as in many other languages)
Maybe you won't even need macros, because you can get done a lot already with generics and iterators on object members.
I've been poking through the nim docs a lot but haven't run into a discussion of this approach?