lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]




On 17/07/16 10:47 PM, Tim Hill wrote:

On Jul 17, 2016, at 5:14 AM, Philipp Janda <siffiejoe@gmx.net <mailto:siffiejoe@gmx.net>> wrote:

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.

Which is pretty horrible too…

u = <some userdata with __key>
t = {}
t[u] = “foo”— Lua calls __key here
t[u] = “bar"— Let’s hope __key returns same value every time!
u = nil— Goodbye last reference to u!

So now we have the potential for a userdata to splatter content all over a table by playing tricks with __key. Not good. And a userdata that vanishes even though we have (apparently) stored it as a table key. Not good. And if u doesnt return the same key every time, good luck finding the key in the table, short of enumerating the whole thing.

The point is really this: __key modifies the contract for a table dramatically. It can’t just drop transparently into existing code without the danger of breaking something. (What if __key returns an int when the user has already used int keys for other things?). So anyone using such a userdata MUST be coding specially for it. And if they are doing that, then they can add the necessary metatable logic to the table to check for __key and so add the desired behavior without changing a line of Lua.

Say that to __len, __index, __newindex, __mode and __pairs.


—Tim


--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.