[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Proxying in Lua 5.1 vs Lua 5.2 (Was: Re: Possible bug with the length operator)
- From: Jan Behrens <public@...>
- Date: Fri, 1 Apr 2011 20:10:43 +0200
> 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.
Regards
Jan Behrens