How can I make the following code work?
type
A = object of RootObj
number: int
B[T] = object of T
text: string
proc newB[T](): ref B[T] =
result.new()
result.number = 5
result.text = "Hello World"
proc main() =
var test = newB[A]()
echo "Test:" & $test.number & " " & test.text
main()
The line
B[T] = object of T
gives the error
test.nim(6, 17) Error: inheritance only works with non-final objects
But my "T" is a non-final object
There are two problems here:
One is that at the point of declaration of B[T], the compiler cannot know that T is inheritable.
The other is that it is currently not possible to declare B[T: S] where S is a supertype or a concept that requires inheritance (or rather, it's possible to declare it, but it does not have the desired effect). Note that template mixins (as they're called in C++, and where a type is both a supertype and generic parameter) are not entirely trivial to do.
One workaround here is to declare B[T] as a template instead, e.g.:
type
A = object of RootObj
number: int
template B(T: typedesc): typedesc =
type B = object of T
text: string
B
proc newB[T]: auto =
result = B(T)()
result.number = 5
result.text = "Hello World"
proc main() =
var test = newB[A]()
echo "Test:" & $test.number & " " & test.text
main()
Note that the result of newB[T] also has to be declared as auto, because the type likewise can't be constructed at this point.
An alternative is to parameterize the entire code section (type and affiliated procedures/methods) with a type parameter, e.g.:
type
A = object of RootObj
number: int
template declWithString(B: untyped, T: typedesc): typed =
type
B = object of T
text: string
proc `new B`: ref B =
result.new()
result.number = 5
result.text = "Hello World"
declWithString B, A
proc main() =
var test = newB()
echo "Test:" & $test.number & " " & test.text
main()
Observe how you can construct new identifiers within a template using backquotes.
@Araq: That's just a little bit unfair, don't you think? It's sometimes not clear to new users of a programming language if they are even encountering a bug or just don't yet understand everything. The rational thing to do in this case is to ask.