Forums » Bugs

unpack(t,i,j) does not use i,j parameters

Nov 11, 2023 helix397 link
Summary: unpack(t, i, j) seems to ignore the i and j parameters.

Expected Behavior: From Lua 5.1 docs:

unpack (list [, i [, j]])
Returns the elements from the given table. This function is equivalent to

return list[\i], list[i+1], ···, list[j]

except that the above code can be written only for a fixed number of elements. By default, i is 1 and j is the length of the list, as defined by the length operator.

(source: https://www.lua.org/manual/5.1/manual.html ; ctrl+f "unpack". I inserted a backslash in list[\i] to prevent italic formatting.)

Actual Behavior: unpack(t, i, j) seems to always act like unpack(t).

Example 1: console_print(unpack({1,2,3},2,3)) should print "2 3" but actual output is "1 2 3".

Example 2: console_print(unpack({1,nil,3},1,3)) should print "1 nil 3" but actual output is "1". (On my computer; this example may vary due to nondeterministic behavior of # on sparse lists)

Info: Replicated on latest VO version (1.8.668) with no plugins (just console window) just now (2023-11-11). OS is Windows 10.
Nov 11, 2023 draugath link
Sorry, not related specifically to the bug, but to something mentioned in the report which relates to observed problems.

The length of a table t is defined to be any integer index n such that t[n] is not nil and t[n+1] is nil;
For your second example, the output of 1 is accurate.
Nov 11, 2023 helix397 link
@draugath's definition of the # operator is correct. However, example 2 passes j=3 which means unpack(...) shouldn't use # at all. Because of this, example 2 should still be correct (that "1 nil 3" is the only correct output).
Nov 11, 2023 Luxen link
From the Lua manual you linked:
unpack (list [, i [, j]])
Returns the elements from the given table. This function is equivalent to
return list[ i], list[i+1], ···, list[j]
🚩>>> except that the above code can be written only for a fixed number of elements. By default, i is 1 and j is the length of the list, as defined by the length operator (see §2.5.5).


You missed the second part of the definition there. So, even if you specify an arbitrary length greater than what #table contains, #table is what is being respected. Draugath's correct, unpack will only return your first index.

EDIT: hrmmmm, you're right, never mind.
Nov 11, 2023 helix397 link
By default, i is 1 and j is the length of the list
By default is the key phrase. You can specify j well beyond #t if you like, and those elements will be accessed and not omitted. There is no upper limit to the values of i or j.

I have run this code on a local installation of lua 5.1:

$ lua -e "t={1} t[3]=3 print(#t, unpack(t))"
1 1
$ lua -e "t={1} t[3]=3 print(#t, unpack(t,1,3))"
1 1 nil 3
$ lua -e "t={1} t[3]=3 print(#t, unpack(t,1,5))"
1 1 nil 3 nil nil
$ lua -e "t={1} t[3]=3 print(#t, unpack(t,3,5))"
1 3 nil nil
$ lua -e "t={1} t[3]=3 print(#t, unpack(t,1001,1003))"
1 nil nil nil
$
Nov 11, 2023 draugath link
Sorry, I misunderstood the documentation a little, which was reinforced by historical usage and experience.
Dec 07, 2023 helix397 link
Listed as fixed in 1.8.672 and works now. Thank you!