Search code examples
if-statementlua

Lua : attempt to index a nil value; avoiding errors in conditionals


Let's say I have a giant table, something like:

test.test[1].testing.test.test_test

The table isn't guaranteed to exist. Neither are the tables containing it. I would like to just be able to do:

if test.test[1].testing.test.test_test then
   print("it exits!")
end

But of course, this would give me an "Attempt to index ? (a nil value)" error if any of the indices aren't yet defined. So many times, I'll end up doing something like this:

if test then
   if test.test then
      if test.test[1] then
         if test.test[1].testing then -- and so on

Is there a better, less-tedious way to accomplish this?


Solution

  • You can write a function that takes a list of keys to look up and does whatever action you want if it finds the entry. Here's an example:

    function forindices(f, table, indices)
      local entry = table
    
      for _,idx in ipairs(indices) do
        if type(entry) == 'table' and entry[idx] then
          entry = entry[idx]
        else
          entry = nil
          break
        end
      end
    
      if entry then
        f()
      end
    end
    
    test = {test = {{testing = {test = {test_test = 5}}}}}
    
    -- prints "it exists"
    forindices(function () print("it exists") end,
               test,
               {"test", 1, "testing", "test", "test_test"})
    
    -- doesn't print
    forindices(function () print("it exists") end,
               test,
               {"test", 1, "nope", "test", "test_test"})
    

    As an aside, the functional programming concept that solves this kind of problem is the Maybe monad. You could probably solve this with a Lua implementation of monads, though it wouldn't be very nice since there's no syntactic sugar for it.