Search code examples
lualua-table

Iterating over a table and calling a method in lua


I'm trying to iterate over a table of functions, and call each function one by one. I keep getting the 'attempt to access a field/method NIL value. Some of them are obvious, but some of them baffle me.

 tests={}

function tests.test1()
    print("test1 running\n")
end


function tests.test2()
    print("test2 running\n")
end


function tests.test3()
    print("test3 running\n")
end

print(tests)

-- why is tests.i() or tests:i not working?
for i,x in pairs(tests) do
    print("x is")
    print(x)
    print("i is")
    print(i)

    --tests.i()  -- attempt to call field i a NIL value
    --tests.i(tests) -- ditto
    --tests:i() -- attempt to call method i, a NIl value
    --tests:i(tests) -- ditto 
    tests[i]() -- works!

    --tests.x() -- attempt to call field x, a NIl value
    --tests.x(tests) -- ditto
    --tests:x() -- attempt to call method x, a NIL value
    --tests[x]() -- attempt to call field ? a NIl value
end

--all these work
tests.test1(tests)
tests:test1()

tests.test2(tests)
tests:test2()

tests.test3(tests)
tests:test3()

Why is the tests.i() method not working, or tests.i(tests), if it's expecting a 'self' argument, in which case why isn't tests:i() working? The last bit shows all of them working when called outside the loop, which makes it even more difficult to understand.


Solution

  • tests.i() is syntactic sugar for tests["i"](). tests:i() is syntactic sugar for tests["i"](tests).

    In your loop ? for i, x in pairs(tests) do, i is "test1", "test2" and "test3" in the respective loop cycle. So tests[i]() resolves to tests["test1"]() and so forth, which is tests.test1()

    Make sure you understand that tests.i is short for tests["i"], not tests[i]! So in one case you index tests with a string "i" while in the second case you'll index it with the value of the variable i which in your case is one of the keys of tests.

    In a loop like yours the values are functions so you can simply call x intead of calling tests[i] btw.