__index is supposed to be able to provide a value in response of a key, but not to enumerate all the keys. The key set is not even supposed to be ordered nor finite.
However, what I can't understand is: why there aren't any metamethods __pairs and __ipairs?
The penalty would be very low (outside the loop), and it would help a lot with "magic" objects, be it fancy tables or userdata. I seem to remember that the "for...in" construct and the (i)pairs iterators are pretty new in Lua design, maybe it's just been overlooked?
Anyway, it's very easy to fix:
rawpairs, rawipairs = pairs, ipairs
function pairs(t)
local mt=getmetatable(t)
return (mt and mt.__pairs or rawpairs)(t)
end
function ipairs(t)
local mt=getmetatable(t)
return (mt and mt.__ipairs or rawipairs)(t)
end