lua-users home
lua-l archive

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


On 1 April 2011 14:10, Jan Behrens <public@magnetkern.de> wrote:
>> On Fri, Apr 1, 2011 at 08:58, Julien Duminil <julien.duminil@ubisoft.com> wrote:
>> > But I was wondering if __len and __newindex are enough to easily emulate
>> > all four of these options, as you can't detect adding some "holes" in
>> > your table. So here is my question: would it be interesting to add a
>> > __delindex or __remindex metamethod called when an existing table
>> > index/key is setted to nil?
>
> On Friday 01 April 2011 17:28:57 HyperHacker wrote:
>> __newindex is called even if the value being set is nil. The problem
>> is that __newindex isn't called if the key already exists (presumably
>> for optimization). So you need to use __index and __newindex to proxy
>> all accesses to a hidden table somewhere so that you can catch those
>> nil assignments. Then you're free to handle "holes" however you like.
>
>
> One way to do it is this one:
>
> do
> Âlocal data = setmetatable({}, {__mode = "k"}) Â-- ephemeron table since Lua 5.2
> Âlocal mt = {
> Â Â__index = function(t, k)
> Â Â Âreturn data[t][k]
> Â Âend,
> Â Â__newindex = function(t, k, v)
> Â Â Âif v == nil then
> Â Â Â Âprint("NOTICE: Deleted key " .. tostring(k) .. " in (proxy) table " .. tostring(t))
> Â Â Âend
> Â Â Âdata[t][k] = v
> Â Âend,
> Â Â-- TODO: add __len, __pairs, __ipairs as needed (needs Lua 5.2)
> Â}
> Âfunction makeproxy(t) Â-- NOTE: don't mix with undocumented function "newproxy"
> Â Âlocal proxy = setmetatable({}, mt)
> Â Âdata[proxy] = {}
> Â Âfor k, v in pairs(t) do
> Â Â Âdata[proxy][k] = v
> Â Âend
> Â Âreturn proxy
> Âend
> end
>
>
> The results are as follows:
>
> Lua 5.1.4 ÂCopyright (C) 1994-2008 Lua.org, PUC-Rio
>> t = makeproxy{"Hello", "World"}
>> t[1] = nil
> NOTICE: Deleted key 1 in (proxy) table table: 0x800e12a00
>
>
> If I understand correctly, there are two problems with this
> approach in Lua 5.1, which will BOTH be solved in Lua 5.2:
>
> a) Lua 5.1 supports no ephemeron tables, which means that
> Â t[1] = t; t = nil would cause a memory leak, as there are
> Â remaining references to t in the proxied table.
> b) The metamethod __len does not work for tables and the
> Â metamethods __pairs and __ipairs do not exist in Lua 5.1.

What about next(t)?

    henk