lua-users home
lua-l archive

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


The behaviour of table.insert and table.delete in Lua 5.2.1 is odd and not
fully documented.

table.remove bounds checks the 'pos' parameter and silently does nothing if
pos is less than 1 or greater than #.

table.insert on the other hand does no bounds checking and will happily
insert element -1, element 100000 etc. sometimes unnecessarily moving
elements.

So, code like this does not produce reasonably expected results:

t = {"salt"}                 -- {[1] = "salt"}
table.insert(t, -10, "test") -- {[-10] = "test"; [2] = "salt"}
table.remove(t, -10)         -- {[-10] = "test"; [2] = "salt"}
table.remove(t, 2)           -- {[-10] = "test"; [2] = "salt"}
table.insert(t, 1000, "over")-- {[-10] = "test"; [2] = "salt"; [1000] =
"over"}
table.remove(t, 1000)        -- {[-10] = "test"; [2] = "salt"; [1000] =
"over"}
table.insert(t, 1000, "big") -- {[-10] = "test"; [2] = "salt"; [1000] =
"big"}

Why has "salt" been moved unnecessarily after the first 'insert'?

Why will 'remove' not remove some elements 'insert' was happy to insert?

Why did the last 'remove' not move the original element 1000 to 1001?

Suggestion:

Use an 'index' rather than 'pos' similar to 'select' in Lua or the C API
stack. So a negative index counts back from -1 = #. After resolving negative
indexes, an index out of the range (1 <= index <= #) for remove, or (1 <=
index <= (# + 1)) for insert, should either cause an error panic or should
saturate the index at 1 or the upper limit.

Or:

table.insert should still insert "outliers", but should not move "main
sequence" elements when it does. table.remove should remove outliers as well
as "main sequence" elements. But inserting an "outlier" which was already
present would still present an anomaly in this scheme.

I like the first suggestion best, with the error panic. At the very least,
table.insert should not move elements unnecessarily.