[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Enumerating Inherited Properties
- From: "Peter Hill" <corwin@...>
- Date: Sat, 8 Mar 2003 23:39:13 +0800
Peter Hill:
> Hmm, I notice that my new version (which I actually bothered to test this
> time!) happens to meet that condition, though I was not actively aiming
> for it :-).
Wim Couwenberg:
> I figured.
I presume you mean about not actively aiming for it (since that is where it
doesn't fully work).
> Try your example on this:
> t = {a=11}
> setmetatable(t,{__index={a=44}, __next=tnext})
>
> That'll keep Lua busy for a while. :-)
You have great insight! Either you've thought about this a lot, or you're
just smarter than I. :-O
Because I wasn't aiming to handle duplicated key entries I didn't test that.
And I was too slack, letting the first test fall through to the nil-case
loop. Bad move.
So, how about this version? Am I there yet?
function tnext(t,o)
local i,v
if o then
-- 'o' is not nil (it is a real existing key).
-- Locate the key's table.
local r = t
while not rawget(r,o) do
local m = getmetatable(r)
r = m and m.__index
assert(type(r)=="table", "Key not in table")
end
-- Grab the next non-shadowed index
local s
i = o -- Start with the current index.
repeat
-- Get next real (non-nil) index.
i,v = next(r,i)
while (i==nil) do
local m = getmetatable(r)
r = m and m.__index
if (r==nil) then return nil,nil end -- None left.
assert(type(r)=="table", "__index must be table or nil")
i,v = next(r)
end
-- Find the next index's level.
s = t
while not rawget(s,i) do
local m = getmetatable(s)
s = m and m.__index
end
-- If match then not shadowed, else repeat.
until (r==s)
-- Return it.
return i,v
else
-- 'o' is nil, so want the first real key. Scan each table in
-- turn until we find one (or give up if all are empty).
while t do
i,v = next(t)
if i then break end
local m = getmetatable(t)
t = m and m.__index
assert(t==nil or type(t)=="table", "__index must be table or nil")
end
return i,v
end
end
*cheers*
Peter Hill.