type boolPointer = ptr bool stringPointer = ptr string Node = ref object of RootObj Values* : Table[string, pointer] Map : Table[string, string] proc `[]`(parser : ArgParser, key : string): bool|string = if parser.Values.hasKey(key): if parser.Values[key] is boolPointer: result = cast[ptr bool](parser.Values[key])[] elif parser.Values[key] is stringPointer: result = cast[ptr string](parser.Values[key])[]
But this doesn't compile: Error: type mismatch: got <string> but expected 'bool'
The error takes place on the second cast and I tried using generics and the any keyword for the return type and it is still failing... Any ideas?
Hm, are you sure you need pointers? Usually references are better (as references are tracked by the garbage collector).
Also, runtime type data doesn't work like this. The is operator works at compile time. What I think you want to do is this:
type
NodeValueKind = enum
nvString
nvBool
NodeValue = ref object
case kind: NodeValueKind
of nvString:
stringValue: string
of nvBool:
boolValue: bool
Node = ref object of RootObj
Values* : Table[string, NodeValue]
Map : Table[string, string]
proc `[]`(parser : ArgParser, key : string): NodeValue =
if parser.Values.hasKey(key):
return parser.Values[key]
Unlike languages such as Python or Go, Nim doesn't rely on runtime-type-information all that much. There is a module for run-time-type information, but it's somewhat advanced... and unsafe.
THANK YOU that has helped a lot! now I am having issues using []= on the Values table...
But I appreciate it :)
Barely anything at all, in fact I decided to run a little experiment:
[peter /tmp ] $ cat test.nim
import json
var x = newJArray()
for i in 0..10_000_000:
x.add newJString("Hello world")
x.add newJBool(true)
[peter /tmp ] $ cat test2.nim
type
NodeValueKind = enum
nvString
nvBool
NodeValue = ref object
case kind: NodeValueKind
of nvString:
stringValue: string
of nvBool:
boolValue: bool
var x: seq[NodeValue]
for i in 0..10_000_000:
x.add NodeValue(kind: nvString, stringValue: "Hello world")
x.add NodeValue(kind: nvBool, boolValue: true)
[peter /tmp ] $ time ./test
./test 0.67s user 0.36s system 99% cpu 1.037 total
[peter /tmp ] $ time ./test
./test 0.69s user 0.31s system 99% cpu 1.004 total
[peter /tmp ] $ time ./test
./test 0.65s user 0.36s system 99% cpu 1.009 total
[peter /tmp ] $ time ./test2
./test2 0.74s user 0.30s system 99% cpu 1.038 total
[peter /tmp ] $ time ./test2
./test2 0.74s user 0.30s system 99% cpu 1.038 total
[peter /tmp ] $ time ./test2
./test2 0.73s user 0.31s system 99% cpu 1.038 total
Both examples are compiled with 0.19.4 and the -d:release switch. Not entirely sure why the JSON version appears to be faster, but as far as performance goes I would say it's pretty good.