[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: No ready way to store nil in array as pack does?
- From: Francisco Olarte <folarte@...>
- Date: Wed, 8 Nov 2023 13:46:49 +0100
On Tue, 7 Nov 2023 at 04:56, Родион Горковенко <rodiongork@gmail.com> wrote:
> function behavior, I would like it to return "nil" sometimes (say upon
> reading number when
> no digits were provided).
>
> io.read = function(...)
> res = {}
> for _, typ in ipairs(table.pack(...)) do
> val = someCodeWhichCallsPrompt()
> if typ == '*n' then val = parseNumberWhimsically(val) end
> table.insert(res, val)
> end
> return table.unpack(res)
> end
>
> The difficulty is that if "parseNumberWhimsically" may return "nil",
> it won't be inserted into the table. I don't know whether "table.pack"
> users some complicated magic for this or on contrary I'm missing
> something obvious. Thanks in advance for any hints!
You cannot trust ipairs and #table when doing this kind of stuff, with
nils in the middle. To begin with:
ipairs (t)
Returns three values (an iterator function, the table t, and 0) so
that the construction
for i,v in ipairs(t) do body end
will iterate over the key–value pairs (1,t[1]), (2,t[2]), ..., up to
the first absent index.
So your "input" loop will stop at the first nil.
Also table.insert uses #t as offset, #t is not defined if your "array"
contains nils.
Just iterate with a simple loop:
io.read = function(...)
local res = table.pack(...) -- this leaves length in .n
for i in 1, res.n do
local typ = res[i]
local val = someCodeWhichCallsPrompt()
if typ == '*n' then val = parseNumberWhimsically(val) end
res[i] = val
end
return table.unpack(res, 1, res.n) -- use explicit size.
end
I just reused the res table for everything, but more complex thing can
be made, just put the args in an args.table, and keep a running count
of res table size with a explicit var:
io.read = function(...)
local args = table.pack(...) -- this leaves length in .n
local res = {}, nres=0
for i in 1, args.n do
local arg=args[i]
-- Insert anything, this is just a sample.
if i%2==0 then
res[nres]=nil; nres=nres+1
end
if i%3==0 then
res[nres]=arg; nres=nres+1
end
local val = someCodeWhichCallsPrompt()
if typ == '*n' then val = parseNumberWhimsically(val) end
res[nres] = val ; nres=nres+1
end
return table.unpack(res, 1, nres) -- use explicit size.
end
If I added some forgotten local to make it safer.
I have uses both flavors for doing some stuff. But this code is
untested, check it first.
Francisco Olarte.