lua-users home
lua-l archive

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


Hi,

another information that can only be found in section "Changes in the
Libraries" is

  The ipairs iterator now respects metamethods ...

A consequence of this is that the # operator and ipairs have different
notions of the length of a table.

-- A table with three entries.
local t = { 1, 2, 3 }
-- Let's manipulate the "length" of a table
-- using various metamethods.
--
-- We start with the __index metamethod.
print('Manipulate only __index.')
local mt = {
  __index = { [4] = 4 },
}
setmetatable(t, mt)
print('#t = ', #t)-- => 3
print('Iterate using ipairs()')
for i,v in ipairs(t) do-- => 1 ... 4
  print(i, v)
end
-- And we try the __len metamethod.
print('Manipulate only __len.')
local mt = {
  __len = function(t) return 5 end,
}
setmetatable(t, mt)
print('#t = ', #t)-- => 5
print('Iterate using ipairs()')
for i,v in ipairs(t) do-- => 1 ... 3
  print(i, v)
end

While # ignores __index and respects the __len metamethod (since Lua
5.2), ipairs ignores __len and respects __index (since Lua 5.3).  The
fact that iterating over table elements via ipairs and iterating over
table indices 1 to #t are not equal operations has been discussed on
this list before.  But it is neither mentioned in the section describing
ipairs nor in the section describing the # operator.  I think this fact
deserves more visibility in the manual.

Best regards,
Stephan Hennig