Struggling to put function into table. "Missing '(' near new."

I have this code right here, in a file named "hframe.lua".

table.insert(handler.class, framename)
local func = [[
function new(())
print("Hello Stackoverflow!")
end
]] --The function test itself.
local a="table.insert(handler.class."..framename..", "..func..")" --I broke it in two to make things easier for me to read.
print(a) --Read out the variable so I can see what it looks like.
local b=load(a) --Load it up
b() --Nil error. Great.

"framename" is a constant from another file, which is simply declared as "frame". The error is a simple nil error. Upon running b(), it throws a local nil error. With an assert, I've discovered this error.

Error: Thread error (Thread: 0x04c7d2f0)

uicode/hframe.lua:16: [string "table.insert(handler.class.frame, function ne..."]:1: '(' expected near 'new'
stack traceback:
        [C]: in function 'assert'
        uicode/hframe.lua:16: in main chunk
        [C]: in function 'require'
        uicode/handlerthread.lua:165: in main chunk
stack traceback:
        [string "boot.lua"]:777: in function <[string "boot.lua"]:773>
        [C]: in function 'error'
        [string "boot.lua"]:631: in function <[string "boot.lua"]:630>
        [string "boot.lua"]:604: in function <[string "boot.lua"]:594>
        [C]: in function 'xpcall'

I'm not entirely sure WHY it's throwing this error, because clearly I define it as function new(). What I have I done wrong?


Solution 1:

function new() end

is syntactic sugar for

new = function () end

This is an assignment. It does not resolve to a value. Hence you cannot use a function definiton where a value is expected.

In your case the code executed is

table.insert(handler.class.someFrameName,
  function new () print("Hello Stackoverflow!") end
)

The only thing that would make sense for Lua with the function keyword present in a list of expressions is an anonymous function and it expects a ( after function but finds new

You have two options to fix this.

If function new() end is equivalent to new = function () end, function () end must resolve to a function value. So we can create a function value in-place:

table.insert(handler.class.someFrameName,
  function () print("Hello Stackoverflow!") end
)

I'll leave it up to you to impelement this in the string you want to load.

Another option is to define the function first. You can do this both in the string or in the scope of your load call.

function new() print("Hello Stackoverflow")
table.insert(handler.class.someFrameName, new)

Solution 2:

Lua load() function returns nil and the error if it failed to compile code. Since the passed code is invalid, b is nil. Therefore a error is raised when you attempt to call it.

The reason the code is invalid is because when a function declaration is used as an expression, the function name must be omitted, e.g.

table.insert(sometable, function() … end)

Please note that most likely you don’t need to create code dynamically, the following will work:

table.insert(handler.class[framename], function() … end)