[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: table.pack()
- From: Steven Johnson <steve@...>
- Date: Fri, 22 Jan 2010 17:01:50 -0600
> The problem with table.pack is it lacks functionality that is very
> complicated and expensive in pure Lua. Packing values into a new table
> is easy (the common idiom: {n = select("#", ...); ...}). Packing
> values into an existing table is hard. You must iterate over the
> vararg using select which is expensive and ugly. As I've said
> elsewhere, what we really need is table.pack to work on a table passed
> to it and take an index on where to append the values to the array
> (usually, the very beginning). Something like this captures all use
> cases I can think of:
>
> table.pack(t, n, ...)
>
> where the length of t is truncated to length n-1 (luaH_resize?) and
> the variable number of arguments are appended. It may even make sense
> to have an upper bound on where to pack just like table.unpack.
I agree this is useful.
Here's a Lua version with just one select(), though it still has to
evaluate the (diminishing)
vararg on each recursion:
local function Collect (acc, i, count, v1, v2, v3, v4, v5, ...)
if i <= count then
acc[i + 1], acc[i + 2], acc[i + 3], acc[i + 4], acc[i + 5] = v1, v2,
v3, v4, v5
return Collect(acc, i + 5, count, ...)
end
return count, acc
end
--- Collects arguments, including <b>nil</b>s, into an object.
-- @param acc Accumulator object; if <b>nil</b>, a table is supplied.
-- @param ... Arguments to collect.
-- @return Argument count.
-- @return Filled accumulator.
function CollectArgsInto (acc, ...)
local count = select("#", ...)
if acc then
return Collect(acc, 0, count, ...)
else
return count, { ... }
end
end
By adjusting 0 and count passed to the first Collect() it should
accommodate an offset, too.
(5 values seemed to do best during testing.)