Search code examples
lualua-tablelexical-scope

How to have function as field value in a lua table, when the function is declared at a later point?


I have the following scenario in which the position of code shall not change. How to modify this code to fix the error without moving the function and table variable. I am a Lua newbie, just 4 days

function a()
  print("function a");
end

ftable = {
  ["a"] = a,
  ["b"] = b
};

function b()
  print("function b");
end

ftable["a"](); -- prints 'function a' 
ftable["b"](); -- attempt to call field 'b' (a nil value)

Update : Using the following mechanism its possible to do this.

function a()
  print("function a");
end

ftable = {
  ["a"] = a,
  ["b"] = "b"
};

function b()
  print("function b");
end

ftable["a"](); -- prints 'function a' 
_G[ftable["b"]](); 

Solution

  • Lua's table declaration and function definition (and function calling syntax) is very flexible. You can use the field key as an identifier instead of the index syntax, provided that the key is a string and is also a valid identifier ({ a = a } and ftable.a()). This seems to be the case with your a and b keys. You can also make the field assignment with the function definition statement (function ftable.b…).

    function a()
      print("function a")
    end
    
    ftable = {
      a = a
    }
    
    function ftable.b()
      print("function b")
    end
    
    ftable.a() -- prints 'function a' 
    ftable.b() -- prints 'function b' 
    

    Of course, you could also move "function a" down and code it like "function b". that would leave ftable = { } at the top.

    One difference from your code. The global variable b is no longer set to the function. In most cases, this would be considered an advantage.

    I would also like to re-iterate what @lhf said,

    There are no declarations in Lua, only definitions.

    A function definition (in the general case) is an expression. When evaluated, it produces a function value. Various types of statements can assign the value to a variable or field, as does function ftable.b()….