Hello!
I've been slowly learning and very much enjoying Nim, I'm going through dom96's book and while messing with the examples I came across an issue. I'm trying to use a CustomObj as key inside a table, so I simply need to define a hash proc for this CustomObj and I should be able to use it as a key inside a table. And it works :
import tables, hashes
type
CustomObj = object
name: string
proc hash(x: CustomObj): Hash =
result = x.name.hash()
result = !$result
var objs = initTable[CustomObj, string]()
objs[CustomObj(name: "A")] = "B"
echo objs
{(name: A): B}
But when I tried the exact same thing inside of a block suddenly it doesn't work anymore and complains that it can't find the new hash proc :
import tables, hashes
block ablock:
type
CustomObj = object
name: string
proc hash(x: CustomObj): Hash =
result = x.name.hash()
result = !$result
var objs = initTable[CustomObj, string]()
objs[CustomObj(name: "A")] = "B"
echo objs
which produces the error:
Hint: used config file '/nim/config/nim.cfg' [Conf]
Hint: system [Processing]
Hint: in [Processing]
Hint: tables [Processing]
Hint: hashes [Processing]
Hint: strutils [Processing]
Hint: parseutils [Processing]
Hint: math [Processing]
Hint: algorithm [Processing]
Hint: etcpriv [Processing]
in.nim(14, 7) template/generic instantiation from here
lib/pure/collections/tableimpl.nim(98, 21) template/generic instantiation from here
lib/pure/collections/tableimpl.nim(53, 14) template/generic instantiation from here
lib/pure/collections/tableimpl.nim(43, 12) Error: type mismatch: got (CustomObj)
but expected one of:
proc hash[T: Ordinal](x: T): Hash
proc hash(x: pointer): Hash
proc hash[T: proc](x: T): Hash
proc hash(x: float): Hash
proc hash[A](x: set[A]): Hash
proc hash[T: tuple](x: T): Hash
proc hash(x: string): Hash
proc hash(x: int): Hash
proc hash[A](aBuf: openArray[A]; sPos, ePos: int): Hash
proc hash(x: int64): Hash
proc hash(x: char): Hash
proc hash(sBuf: string; sPos, ePos: int): Hash
proc hash[A](x: openArray[A]): Hash
I tried it on both 0.17 and devel. I assume I'm simply misunderstanding how blocks work, I thought they were simply creating a new scope?
Cheers!
Joris
EDIT: Edited the title to better reflect the question
Hi,
Thanks! That was exactly my question, is it supposed to bypass the scope rule?
To clarify: by "bypassing scope rules" I meant that code from the tables module somehow knows about the hash proc defined (privately!) in your code. Seems strange to me, but maybe I don't know all the rules.
As for whether the behavior is supposed to be as it is: as I recently learned, the answer to this is likely "It is as it is now, this will all be fixed with VTable types." :)