[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: absence of a __hash metamethod
- From: Colin <share-lua@...>
- Date: Mon, 19 Nov 2007 20:52:38 +0100
> Hm, this, and the suggestion of using the index/newindex metamethods does
> not work for me either because I want the mechanism to work by default,
> however it gave me the following idea:
> How about a flag on every userdata object that switches between the current
> pointer-based hashing for tables, and one that uses the actual userdata (of
> which the address and length is known) i.e. one could use the same hashing
> as for strings, and memcmp() for the equality check)?
Seems to work fine, in my case I didn't even bother to include the flag and
just made the thing compulsory for all userdata objects (because in my case
a userdata object is either immutable or double-indirect, i.e. the userdata
is a boost::shared_ptr<> to the actual, mutable, data...); changelog:
- Extract the hash method from luaS_newlstr() as luaS_hash().
- Change the order of struct Udata::uv's members so that the metatable comes
it seems natural to me to include the metatable pointer in the to-be-hashed
data, but to exclude the env pointer (because I don't know what that's for,
and I don't set ever set it) and the length (arbitrary decision, might as
well include it).
- Create wrapper functions that, given a "const Udata *", return the pointer
and length of the to-be-hashed data, respectively.
- Change luaO_rawequalobj() to compare the lengths and, if equal, the to-be-
hashed data of userdata objects, rather than just comparing the pointers.
- Change mainposition() to use the new luaS_hash() function to get a hash
for userdata objects.
This might be too special-purpose to even consider for inclusion in Lua proper,
but perhaps it can serve as a starting point for further discussion, or there's
somebody with the same special case as I have that can use this idea...
...unless somebody points out that there's a problem with this approach that I
have so far missed (my changes compile, and a simple test case works, but that's