Next Metamethod For Index Table |
|
next()
for when __index
is a Table
To make a next()
function that matches this indexing method (including the shadowing of higher level keys by lower level ones) you can use the following code...
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
t = {a=111, b=222, c=333} u = {a=123, d=444} setmetatable(t, {__index=u}) for i,v in tnext,t do print(i,v) end
a 111 b 222 c 333 d 444
-- PeterHill