# Next Metamethod For Index Table

## Rewriting `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
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
```

### Example usage

```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
```
will give a result of:
```a  111
b  222
c  333
d  444
```