Roblox Lua equivalent of table.pack(..)

Aloha,

table.pack(…) is a function available in core Lua [ see documentation here ]

However this is not available in Roblox Lua.

I was just wondering if there was any equivalent method for this?

Thanks

2 Likes
function pack(...)
   return {...}
end

Or just do it in-line, all you need to write is {...}.

It’s pretty pointless for table.pack to exist in Lua to begin with, really, other than API symmetry. (EDIT: apart from some differences between {…} and table.pack(…) that you may or may not ever run into, see below)

9 Likes

The actual implementation is this:

function pack(...)
    return {n = select("#", ...), ...}
end

I know this because I’ve been writing it in almost every module, lately.

Also relevant:


Also, it should be noted that such a function is necessary in order to receive values returned by a function, in addition to the number of returned values. Consider this function:

ReturnVariableValues()

Because there’s no operation to assign an unknown number of values, only one thing can be done to the values at a time:

  • results = select("#", ReturnVariableValues()): gets the amount, but discards the values.
  • results = {ReturnVariableValues()}: gets all the values, but discards the amount.

Thus, a function is required to wrap the values in a ... operator, to be used twice (note the pack implementation above):

  • results = pack(ReturnVariableValues()): gets both the values and the amount

Basically, without a pack function, the variable arguments feature is incomplete.

9 Likes

That’s interesting, I didn’t know it also set “n” in the table. I don’t really understand why they decided to set this in the table itself rather than returning it as a second result of table.pack though (or not at all, there’s # after all and I can’t really think of a situation where it’d be inconvenient to do #t over t.n, but maybe I’m missing something), seems non-intuitive

1 Like
select('#', 1, 2, nil) -- 3
#{1, 2, nil} -- 2

It’s why table.getn exists. Arrays need to store size explicitly to avoid problems with nil elements.

2 Likes

I was confused when I read this because I could’ve sworn this wasn’t the case.

#{1,2,nil,3} -- Prints 4...?
1 Like

Doesn’t # just return the highest index?

print(#{"a", "b", nil, "c"})
--> 4

print(#{"a", "b", nil})
--> 2
3 Likes

It only guarantees to return some index for which the element is not nil but where the next element is (except for 0).

It does e.g. a binary search on the allocated array to find that value (with some shortcuts, like when the last element in the allocated array is not nil and there is no hash part):

> local t = {1, nil, 3} print(#t)
3
> local t = {1} t[3] = 3 print(#t)
1
> print(#{"a", "b", nil, "c"})
4
> print(#{"a", "b", nil, "c", nil}) -- last elem of the array-allocated area is forced to be nil, so here it does binary search
2
> print(#{"a", "b", nil, "c", nil, nil, nil, nil}) -- binary search here too, with other results as the array-allocated area has a different length
4
4 Likes

That seems weirdly overcomplicated.
Still, I don’t really think it’s a common practice for people to measure the length of an array with holes in it.

2 Likes