lua-users home
lua-l archive

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


> >> 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.
> > 
> On 1 April 2011 14:10, Jan Behrens <public@magnetkern.de> wrote:
> > 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.

On Sunday 03 April 2011 02:10:57 Henk Boom wrote:
> What about next(t)?
> 
>     henk

As I know the 'next' function will not honor any __next
metamethod in Lua 5.2, so this will not be possible. Making
'next' to honor a possibly existing metamethod would be a
performance problem anyway, I guess.

Of course you could overwrite 'next' with your own function,
but that won't work for libraries which import the 'next'
function by writing

local next = _G.next

as the reference to the old next function will be copied.
That is why I think introducing __ipairs and __pairs
metamethods is a good decision for Lua 5.2 alpha.


Jan Behrens