[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: userdata as table keys
- From: "Erik Cassel" <erik@...>
- Date: Mon, 8 Jan 2007 12:09:49 -0800
This is a new(?) riff on an old topic:
http://lua-users.org/lists/lua-l/2005-06/msg00108.html
http://lua-users.org/lists/lua-l/2006-04/msg00474.html
Has there been any more thought on implementing a __hash metamethod?
--------------------------------------------------------------
a = getObject(3)
b = getObject(3)
t = {}
t[a] = 12
print(a == b) -- this prints "true"
print(t[a]) -- this prints "12"
print(t[b]) -- this prints "nil" !!!
a and b are userdata values. Under the hood these userdata point the same
C++ object, so I want to treat them as "equal". The table lookup doesn't
work as expected, because it doesn't call the __eq metamethod I defined.
I'm troubled by this apparent inconsistency. Lua doesn't treat UserData
values like other values. Arguably, Lua shouldn't define an __eq metamethod
without also providing a __hash metamethod. Alternately, table lookup
should conservatively do an O(n) lookup when it encounters a key with an
__eq metamethod.
I've thought of one workaround to the problem: The first time a UserData is
created for a C++ object, copy a weak reference to it in the registry. The
next time C++ is asked to return the same object, lookup that weak reference
in the registry and return the same userdata. This gets pretty messy - I'll
have to do special garbage collecting of these registry entries.
-Erik