pairs/ipairs metamethods

A related problem with Lua objects that want to control their table-like behaviour is that pairs/ipairs work directly with a table's raw contents. In Lua 5.2, an object can fully support both kinds of array iteration:

for i =1,#obj do ... end  -- can override __len
for i,o in ipairs(obj) do .. end  -- can override __ipairs

A more concrete example shows an array proxy object:

local array = {}
local ipairs = ipairs
do
  local _ENV = array
  function __len(t)
       return #t.store
  end
  function __newindex(t,i,val)
       t.store[i] = val
  end
  function __index(t,i)
       return t.store[i]
  end
  function __ipairs(t)
       return ipairs(t.store)
  end
end

This object will now behave like a regular Lua array-like table:

t = new_array()
t[1] = 10
t[2] = 20
print(#t)
for i,v in ipairs(t) do print(i, v) end
=>
2
1       10
2       20

To be precise, it acts as a proxy for the underlying object in store (which might in fact be userdata).

Array proxies are not as useful as they could be, since the functions in table generally work on raw Lua tables. For instance, table.concat does not respect __len or __ipairs.