[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: The Clear Table Saga
- From: RLake@...
- Date: Mon, 19 May 2003 10:08:39 +0100
> What I'd like to see is tables storing (internally & invisibly) an offset
to
> the first non-nil key. That way starting 'next()' from scratch each time
> will not be prohibitive.
That won't help as much as you think, though. It will solve that particular
problem, but it means that a[k] = nil could take an arbitrary amount of
time (in order to scan the table to update the pointer).
Short of adding zaptable() as an API (which would be easy and maybe a good
idea), I think the best way of solving this particular problem is to use a
proxy table:
This version uses a highly questionable interface in which proxy[nil]
gets/sets
the proxied table. This allows you to not use reserved table keys for
zapping
and iterating, although the code includes those keys. You could delete the
else
clauses from both the __index and __newindex methods and just use the
reserved
keys, or vice versa.
(untested code, sorry)
function ZappableTable(init)
local self = {}
local meta = {}
init = init or {}
function meta:__index(key)
if key == nil then return init
else return init[key]
end
end
function meta:__newindex(key, val)
if key ~= nil then init[key] = val
else init = val or {}
end
end
-- change these names if not appropriate for your application
-- or if you don't like seeing __ all over the place.
-- They are unnecessary if you use the highly questionable
-- "nil key" interface
function self:__zap(new)
init = new or {}
end
function self:__next(key)
return next(init, key)
end
-- This assumes you will not zap during an iteration
function self:__pairs()
return next, init
end
return setmetatable(init, meta)
end
-- functions to exploit the "nil" pseudokey:
function Zap(ztable, new)
ztable[nil] = new
end
function ZapPairs(ztable)
return next, ztable[nil]
end
function ZapNext(ztable, key)
return next(ztable[nil], key)
end