lua-users home
lua-l archive

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


Peter Hill:
> An example (in the basic line of the one given by Wim Couwenberg, but
> without the extra 'state' stuff which I'm not sure why it's there) is:
(snip my obviously erroneous code)

Whoops, my code is rather flawed (ok, it's completely wrong)!
This is a more interesting problem than it seemed...
So here is my ammended version.


function tnext(t,o) 
  local i,v
  
  if o then
    -- 'o' is not nil (a real existing key) so locate its table.
    while not rawget(t,o) do
      local m = getmetatable(t)
      t = m and m.__index
      assert(type(t)=="table", "Key not in table")
    end
    -- Grab the next index (if it is a part of this table) and
    -- return it.
    i,v = next(t,o)
    if i then return i,v end
    -- Otherwise, we have run off the end of the table
    -- so look for the 'first' key in subsequent tables.
    local m = getmetatable(t)
    t = m and m.__index
    assert(t==nil or type(t)=="table", "__index must be table or nil")
  end

  -- '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

t = {a=11,b=22,c=33}
setmetatable(t,{__index={d=44,e=55}, __next=tnext})

-- Ideally we then say "for i,v in pairs(t) do print(i,v) end"
-- or the equivalent "for i,v in next,t do print(i,v) end"
-- however, since we don't yet have the "__next" metamethod
-- we can test it with:

for i,v in tnext,t do print(i,v) end

*appologetically*
Peter Hill.