lua-users home
lua-l archive

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


I installed Lua 5.2 rc2 to try out the new features, and I was very 
pleased with the improvements over 5.1. However, I did find 
something that looks like an oversight in the table library when I 
tried the __len metamethod on a proxy table. 

In the reference manual, at the start of section "6.5 - Table 
Manipulation", we have:

> Remember that, whenever an operation needs the length of a 
> table,  the table should be a proper sequence or have a __len 
> metamethod

The function descriptions also imply that using the table library with 
proxy tables will work. For example, the table.unpack definition 
mentions that it is equivalent to "return list[i], list[i+1], ..., list[j]", and 
that "By default, i is 1 and j is #list". 

The other functions are described with similar wording.

However, a quick test reveals that it doesn't quite work:

t = { 1, 2, 3 }
proxy = setmetatable({}, { 
  __index = t,
  __newindex = t,
  __len = function() return #t end

print(#proxy) --> prints 3, as expected

print(table.unpack(proxy)) --> prints "nil nil nil", but I expected "1 2 3" as per the manual

The problem is that all functions from the table library honor the 
__len metamethod, but not __index or __newindex. They use 
luaL_len to query the length of the sequence, but lua_rawgeti 
and lua_rawseti to access its elements. This isn't a showstopper, 
but it doesn't look like a logical or useful behaviour.

For more consistency, lua_gettable and lua_settable should be 
used to access the elements (great for proxy tables), or lua_rawlen 
should be used to get the list length (same behaviour as Lua 5.1). In 
the latter case, the manual should be updated to reflect the fact that 
the raw length of the sequence is used in the table library.