|
As already mentioned linters like Luacheck can help with this problem.Warning 221 Local variable is accessed but never set should save you here.
Alternatively you can use have __index check the key.
local a = setmetatable({}, {__index = function (t, k) if k == nil then error("error table index with nil") end end})
print(a[nil])Am Di., 17. Jan. 2023 um 12:21 Uhr schrieb Aki Tuomi <cmouse@cmouse.fi>:
> On 01/17/2023 1:17 PM EET Marcus Mason <m4gicks@gmail.com> wrote:
>
>
> > Yet, if we do
> >
> > > foo = {}
> > > foo[nil]
> > nil
>
> > it works. Why? This sounds like this should
> > emit error?
>
> The reason this doesn't emit an error is most likely due to the fact that __index can be called. I have used this in the past when I needed to store values including nil (in a set) by using a sentinel value as the key in the __(new)index method. Remember that a table lookup returning nil means the index is not present in the table so this code isn't all that surprising, even though we know nil will never index a table (directly).
>
> If you are worried about mistyped locals not being caught, you can use a module like strict.lua to forbid undefined global access.
> Luacheck also solves this problem by statically analyzing the source code, which for most things is a better alternative to a runtime guard on the environment.
We already have mistyped locals getting caught, it's more about not catching places where the index key is nil for whatever reason, e.g.
some_module.IDX_NAME
not being defined. I recently ran into this exact use-case. We have tables with numeric indexes (because that's how they come from external data source) and we have a module which defines names for these indexes.
Unfortunately accessing some_module.NO_SUCH_IDX returns nil -> accesses the table with nil -> returns nil, which is allowed for some of the fields in the data, leading into severe head scratching.
Aki