[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Proposal: Constant Tables
- From: Lars Doelle <lars.doelle@...>
- Date: Sat, 13 Aug 2011 19:34:11 +0200
> From: Gregory Bonik <gregory@bonik.org>
> > Practical example:
> > Key1 = { first="John", last="Doe" }
> > Key2 = { first="John", last="Doe" }
> >
> > When using a key like the above for an table, currently Key1
> > and Key2 would identify different entries, i.e. are of no use.
>
> A function like Table.todata in not too hard to implement since you can
> use lua_topointer for tables, userdata, functions and threads.
I looked for such a function, but i did not find it...
I considered using 'tostring(tbl)' but the LUA API is so carefully
not to issue pointers, that i was uncertain how stable they might be.
> Now use intern_table to make keys:
>
> Key1 = intern_table { first="John", last="Doe" }
> Key2 = intern_table { first="John", last="Doe" }
>
> assert(Key1 == Key2)
Right, that's the point.
> Unfortunately, you cannot catch all modifications of tables in registry
> because the semantics of __newindex are so that an assignment t[v] = k
> ignores the metatable if there is already a key v in the table.
Yes, this could only be done by promissing not to change. A constant
table would /guarantee/ this. Perhaps it is so simple, and all what would
be needed is to set a bit in the table suppressing /any/ modifications
including resetting the bit. That would be a rather small and efficient patch.
The remainder could indeed be written in LUA itself, as the module i posted
demonstrates. Though the module is clearly not ideal in many respects,
it is a good proof of concept.
Earlier i searched the wiki and the web for composed keys in LUA but found
nothing. It is hard to understand, how people get along without ...
> Still, you can implement a consistency check function which traverses
> the registry and checks if tables really match their string representations.
>
> Alternatively, you could give up the idea of interned tables and just
> use table_to_string function to produce keys, e.g.
>
> Key1 = table_to_string { first="John", last="Doe" }
Problem with a string representation is, that it can grow exponentially,
when structure sharing comes into play. Try:
Key1 = table_to_string { first="John", last="Doe" }
Key2 = table_to_string { Key1, Key1 }
...
KeyN = table_to_string { Key(N-1), Key(N-1) }
You get a string of O(2^N) length, though having only N tables.
Additionally, one then has the key and the string, which is later
a pain to work with. With something like 'intern_table', the table
remains being the key.
-lars