Hi all,
May I know how to dynamically call a function in Corona?
I would like to call a function like this…
display[i] ( )
Is it possible to do that?
Best Regards,
John
Hi all,
May I know how to dynamically call a function in Corona?
I would like to call a function like this…
display[i] ( )
Is it possible to do that?
Best Regards,
John
I’m not sure if this is what you are after, but I found a similar question (“lua call function from a string with function name”) answered here:
http://stackoverflow.com/questions/1791234/lua-call-function-from-a-string-with-function-name
Hi. Unfortunately, you cannot use the Lua loadstring() and loadfile() functions because they are disabled. Why? Because Apple does not allow dynamic code execution. i.e. No real-time scripting.
That said, there is always a way. I’ll give you a partial solution and let you take it from there…
local functions = {} -- First arg is 'reference' to function or the name of that function, the second argument tells the parser whether to expect a value in return -- -- Note: I don't actually use the 'hasReturn' flag, but I did it this way to show you a way of adding 'details' about individual functions you can use later. -- functions["print"] = { cmdRef = "print", hasReturn = false } functions["create circle"] = { cmdRef = display.newCircle, hasReturn = true } functions["set fill last"] = { cmdRef = "setFillColor" , hasReturn = false } local function commandParser( commands ) local lastRet = {} local last local retVal local cmd local args local cmdRef local hasReturn = false for i = 1, #commands do cmd = commands[i].cmd args = commands[i].args cmdRef = functions[cmd].cmdRef hasReturn = functions[cmd].hasReturn last = lastRet[#lastRet] -- May be nil print( "-------------------------------------------" ) print( i, cmd, unpack(args), cmdRef, hasReturn ) retVal = nil -- Print Handler -- if( cmd == "print" ) then cmdRef = \_G[cmdRef] -- Get the print function out of the globals table retVal = cmdRef( unpack( args ) ) elseif( cmd == "create circle" ) then retVal = cmdRef( unpack( args ) ) elseif( cmd == "set fill last" ) then cmdRef = last[cmdRef] -- Get a reference to 'setFillColor' off of the last object we created retVal = cmdRef( last, unpack( args ) ) -- Call setFillColor like a function and pass last object as first argument end -- Store return value if found if(retVal) then lastRet[#lastRet] = retVal end end end -- =================================================================== -- === NOW LET'S USE THE ABOVE 'PARSER' -- =================================================================== local tableOfCommands = {} -- cmd - command to execute -- args - arguments to pass to command -- tableOfCommands[1] = { cmd = "print", args = { "hello", "this is a", "test", 0xed15c001 } } tableOfCommands[2] = { cmd = "create circle", args = { 100, 100, 20 } } tableOfCommands[3] = { cmd = "set fill last", args = { 255, 0, 0 } } tableOfCommands[4] = { cmd = "create circle", args = { 200, 150, 25 } } tableOfCommands[5] = { cmd = "set fill last", args = { 255, 0, 255 } } commandParser( tableOfCommands )
The above code ‘dynamically’ parses a table of ‘commands’ and executes them, giving this result:

The table of commands was created statically in this case, but there is no reason why it could not be assembled on the fly.
Again, I’ll leave this to your imagination,…
PS - I love the fact that the forums support code formatting, but the wonky thing always adds extra carriage returns… OK. Fixed, now the code should look more legible.
PPS - If this solution works for you, please mark this thread as solved.
Going back to the original post, though, if the goal is to make a function call like
[lua]
displayi
[/lua]
such that the function that gets called varies depending on what ‘i’ is, then you should just make ‘display’ a table and the items in the table the functions you want to call. You can make the keys to the table anything you like – integers (like an array) and strings are of course the most common.
Actually, we shouldn’t name the table ‘display’, since that’s the name of a Corona library – a pretty important one too :-) – but give it some other name and it would be fine.
Note: If you want to grab the sample instead of cutting and pasing, you can get it here:
https://github.com/roaminggamer/RG_FreeStuff/tree/master/Dynamic%20Code
Hi roaminggamer,
Actually,I would like to create a function array.Is it possible to do that in Corona?
Best Regards,
John
Sure its possible to make an table (array) of references to global functions, but then that is actually what _G is
print("Cool") -- same as \_G["print"]("Cool")
Making a table of methods (functions attached to display objects, etc.) is a little trickier, but also doable.
local methodTable = {} local obj1 = display.newCircle( 10, 10, 10 ) local obj2 = display.newCircle( 30, 30, 10 ) -- Store reference to obj1's setFillColor method. methodTable["setFillColor"] = obj1.setFillColor -- Grabbing reference from table in local variable to make code more legible, -- local func = methodTable["setFillColor"] -- If I recall, this will work: -- -- Use reference to obj1's setFillColor method to set color of obj2 func( obj2, 255, 0, 0 ) -- Above equivalent to this: methodTable["setFillColor"]( obj2, 255, 0, 0 ) -- I've never tried it, but this might work too, assuming display objects all -- share the same implementation for setFillColor() -- local obj3 = display.newRect(50,50,20,20) -- Use reference to obj1's (a circle) setFillColor method to set color of obj3 ( a rect) func( obj3, 255, 0, 0 )
just a reminder making a table named display will likely disable access to the included display.* calls, like creating images.
I’m not sure if this is what you are after, but I found a similar question (“lua call function from a string with function name”) answered here:
http://stackoverflow.com/questions/1791234/lua-call-function-from-a-string-with-function-name
Hi. Unfortunately, you cannot use the Lua loadstring() and loadfile() functions because they are disabled. Why? Because Apple does not allow dynamic code execution. i.e. No real-time scripting.
That said, there is always a way. I’ll give you a partial solution and let you take it from there…
local functions = {} -- First arg is 'reference' to function or the name of that function, the second argument tells the parser whether to expect a value in return -- -- Note: I don't actually use the 'hasReturn' flag, but I did it this way to show you a way of adding 'details' about individual functions you can use later. -- functions["print"] = { cmdRef = "print", hasReturn = false } functions["create circle"] = { cmdRef = display.newCircle, hasReturn = true } functions["set fill last"] = { cmdRef = "setFillColor" , hasReturn = false } local function commandParser( commands ) local lastRet = {} local last local retVal local cmd local args local cmdRef local hasReturn = false for i = 1, #commands do cmd = commands[i].cmd args = commands[i].args cmdRef = functions[cmd].cmdRef hasReturn = functions[cmd].hasReturn last = lastRet[#lastRet] -- May be nil print( "-------------------------------------------" ) print( i, cmd, unpack(args), cmdRef, hasReturn ) retVal = nil -- Print Handler -- if( cmd == "print" ) then cmdRef = \_G[cmdRef] -- Get the print function out of the globals table retVal = cmdRef( unpack( args ) ) elseif( cmd == "create circle" ) then retVal = cmdRef( unpack( args ) ) elseif( cmd == "set fill last" ) then cmdRef = last[cmdRef] -- Get a reference to 'setFillColor' off of the last object we created retVal = cmdRef( last, unpack( args ) ) -- Call setFillColor like a function and pass last object as first argument end -- Store return value if found if(retVal) then lastRet[#lastRet] = retVal end end end -- =================================================================== -- === NOW LET'S USE THE ABOVE 'PARSER' -- =================================================================== local tableOfCommands = {} -- cmd - command to execute -- args - arguments to pass to command -- tableOfCommands[1] = { cmd = "print", args = { "hello", "this is a", "test", 0xed15c001 } } tableOfCommands[2] = { cmd = "create circle", args = { 100, 100, 20 } } tableOfCommands[3] = { cmd = "set fill last", args = { 255, 0, 0 } } tableOfCommands[4] = { cmd = "create circle", args = { 200, 150, 25 } } tableOfCommands[5] = { cmd = "set fill last", args = { 255, 0, 255 } } commandParser( tableOfCommands )
The above code ‘dynamically’ parses a table of ‘commands’ and executes them, giving this result:

The table of commands was created statically in this case, but there is no reason why it could not be assembled on the fly.
Again, I’ll leave this to your imagination,…
PS - I love the fact that the forums support code formatting, but the wonky thing always adds extra carriage returns… OK. Fixed, now the code should look more legible.
PPS - If this solution works for you, please mark this thread as solved.
Going back to the original post, though, if the goal is to make a function call like
[lua]
displayi
[/lua]
such that the function that gets called varies depending on what ‘i’ is, then you should just make ‘display’ a table and the items in the table the functions you want to call. You can make the keys to the table anything you like – integers (like an array) and strings are of course the most common.
Actually, we shouldn’t name the table ‘display’, since that’s the name of a Corona library – a pretty important one too :-) – but give it some other name and it would be fine.
Note: If you want to grab the sample instead of cutting and pasing, you can get it here:
https://github.com/roaminggamer/RG_FreeStuff/tree/master/Dynamic%20Code
Hi roaminggamer,
Actually,I would like to create a function array.Is it possible to do that in Corona?
Best Regards,
John
Sure its possible to make an table (array) of references to global functions, but then that is actually what _G is
print("Cool") -- same as \_G["print"]("Cool")
Making a table of methods (functions attached to display objects, etc.) is a little trickier, but also doable.
local methodTable = {} local obj1 = display.newCircle( 10, 10, 10 ) local obj2 = display.newCircle( 30, 30, 10 ) -- Store reference to obj1's setFillColor method. methodTable["setFillColor"] = obj1.setFillColor -- Grabbing reference from table in local variable to make code more legible, -- local func = methodTable["setFillColor"] -- If I recall, this will work: -- -- Use reference to obj1's setFillColor method to set color of obj2 func( obj2, 255, 0, 0 ) -- Above equivalent to this: methodTable["setFillColor"]( obj2, 255, 0, 0 ) -- I've never tried it, but this might work too, assuming display objects all -- share the same implementation for setFillColor() -- local obj3 = display.newRect(50,50,20,20) -- Use reference to obj1's (a circle) setFillColor method to set color of obj3 ( a rect) func( obj3, 255, 0, 0 )
just a reminder making a table named display will likely disable access to the included display.* calls, like creating images.