|
Am 17.07.2016 um 10:05 schröbte Sean Conner:
It was thus said that the Great Tim Hill once stated:Where is the synthetic key value stored then? It must be stored in the key+value slot of the table. Where is the userdata stored? In the same place. So now we are storing three items per table slot, not two. Seems to me a significant impact.
The synthetic key is stored as key in the table (or is implicit in the array part). The userdata is not stored at all (unless `__key()` returns it). The synthetic key is used _instead of_ the original userdata.
And yes, a given __key *should* return the same value each time it is called for a given userdata in a given state. But if it doesn’t strange things happen. Strange in that they vastly complicate the table contract. And to what end? I’m not being obtuse here, I just don’t see the bang for the buck.As I present these examples, I'm just not seeing it either, given that a module that wants the behavior of '__key' can just return interned values.
Wrong examples ;-)You want `t[bigint(3)] = x` to be equivalent to `t[3] = x`, but `bigint(3)+bigint(3)` should use custom big integer addition, *not* the built-in Lua integer addition. For `bigint("2^128")` you'll still use an interned userdata so that `t[bigint("2^128")] = 1; print(t[bigint("2^128")])` works as expected (`__key()` would just return the userdata itself in this case).
Another example would be a UTF8String where `#` returns the number of characters not bytes, but which behaves like a regular string when used as a key in a table (and preferably when compared to a regular string via `==`, but that's a different story).
-spc (__key is hard! Let's make rockets!)
It's not hard: Use the result of `getmetatable(x):__key()` instead of `x` itself when doing `t[x]` or `t[x] = y`. But it's only useful under very specific circumstances (i.e. for implementing custom number or string types).
Philipp