[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Is it safe to unpack { nil, a, b } ?
- From: Dirk Laurie <dirk.laurie@...>
- Date: Mon, 2 Nov 2015 09:35:33 +0200
2015-11-02 8:32 GMT+02:00 Niccolo Medici <niccolomedici@gmail.com>:
> Officially, it's not correct to do "table.unpack{nil, 'something',
> 'another'}" because the nil makes it legitimate for table.unpack() to
> regard the length of the table as 0.
> However, all Lua implementations I've checked (Lua 5.1, 5.2, 5.3, JIT)
> do calculate #{nil,a,b} to be 2, not 0. Let's assuming a and b are
> never nil.
The reason why it works is that when you have a table constructor,
the "array" part of the table is initialized to be large enough to contain
all the keyless elements.
> So I was wondering if this is a special case we can trust to always work.
Unfortunately, no. The documentation of lua_createtable says:
"Parameter narr is a hint for how many elements the table will have as
a sequence; parameter nrec is a hint for how many other elements the
table will have. Lua may use these hints to preallocate memory for the
new table. This pre-allocation is useful for performance when you know
in advance how many elements the table will have."
I.e. it's a hint only. In fact, a Lua implementation does not even need
to have an array part at all.
> Why do I ask this?
>
> Because sometimes I need to wrap one of the system functions. Such
> functions return (nil, errmsg, errcode) on error. So I have the
> following pattern in my code:
>
> local ret = { file:close() }
> -- do something
> return table.unpack(ret)
>
> I know I can rewrite is as:
>
> local ret = table.pack( file:close() )
> -- do something
> return table.unpack(ret, 1, ret.n)
>
> But sometimes I do "ret = { nil, a, b }" explicitly and it'd be
> cumbersome to set the "n" field myself in all places.
In this situation I would write
local success, msg, status = file:close()
-- do something
return success, msg, status