lua-users home
lua-l archive

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

This is all behaving as expected.

1. Your table contains only nil entries. The length must be zero.

2. n[3] is non-nil and n[4] is nil, thus 3 is a valid boundary and a correct return value for the length; as n[1] is nil, 0 would be a correct length as well - both are valid. Relying on either is relying on undefined, implementation-specific behavior. LuaJIT and PUC Lua are likely to differ.

3. table.insert(n, x) without the pos argument is equivalent to n[#n + 1] = x. As you've seen #n can be either 0 or 3, so this will set x at either the first index or the last index. If the first case happened, the length of the table may be either 1 or 3. If the second case happens, 0 remains a valid length, and 4 is another valid length. This is what you're observing: You're getting 0 for the length.

Yes, this behavior is odd. You should always make sure that your tables have no "holes" (nil values from 1 to #table) in the list part when working with table.[insert|remove|concat], ipairs etc. to get reliable behavior. Otherwise multiple valid lengths exist, yielding possibly "unexpected" results.

I've tested your example with LuaJIT, which returns 4 as length (also valid) after the insert:

$ luajit 
LuaJIT 2.1.0-beta3 -- Copyright (C) 2005-2017 Mike Pall. 
JIT: ON SSE2 SSE3 SSE4.1 AMD BMI2 fold cse dce fwd dse narrow loop abc sink fuse 
> n = {nil, nil, nil} 
> print(#n) 
> n = {nil, nil, 1} 
> print(#n) 
> table.insert(n, 1) 
> print(#n)  

See for details.

On 19.05.22 21:23, the lemons wrote:
On Thu May 19, 2022 at 1:57 PM CDT, Sean Conner wrote:
It was thus said that the Great Mason Bogue once stated:
Lua 5.4.3  Copyright (C) 1994-2021, PUC-Rio
t = {1, nil, 3}
  That's assuming you define the metatable as:

mt =
    -- blah blah


    -- blah blah

And yes, under Lua 5.4.3, #mt is indeed 3.
as an aside, I consider this to be somewhat strange behavior.

 > n = {nil,nil,nil}
 > #n
 > n = {nil,nil,1}
 > #n
 > table.insert(n,1)
 > #n

I understand why this happens, but shouldn't #n be 0 in both cases?