lua function as argument in C - lua

I'm going to pass a function to another function which should operate with the passed function. For example:
handler(fun1("foo",2))
handler(fun2(1e-10))
The handler is something like calling the passed function many times.
I'm going to bind handler, fun1, fun2 to C-functions. fun1 and fun2 are going to return some user data with a pointer to some cpp-class so that I can further recover which function was it.
The problem now is that fun1 and fun2 are going to be called before passed to handler. But I don't need this, what I need is the kind of function and its parameters. However, I should be able to call fun1 and fun2 alone without handler:
fun1("bar",3)
fun2(1e-5)
Is it possible to get the context the function is called from?
While typing the question, I realized I could do following
handler(fun1, "foo",2);
handler(fun2, 1e-10);

probably the best way is to pass the function in, with the arguments you want called in a table.
function handler(func, args)
-- do housekeeping here?
...
-- call the function
local ret = func(table.unpack(args))
-- do something with the return value?
end
handler(fun1, {"foo", 2})
handler(fun2, {1e-10})

You can just bind the call to it's arguments in another function and pass that to your handler function:
function handler(func)
-- call func, or store it for later, or whatever
end
handler(function() fun1("foo", 2) end)
handler(function() fun2(1e-10) end)
Now handler doesn't have to worry about storing and unpacking an argument table, it just calls a function.

Related

Lua 5.4 Calling a function declared as a string

I would need to call a function that is declared as a string
i.e local abc = "function x() print('math.sqrt(25)') end"
i've tried load(abc) that gives me no errors but nothing is printed and print(load(abc)) that returns function: 0000000000ebcea0
I've made another tries but nothing seems to suit my case (or probably i'm just bad)
Please read the manual...
If there are no syntactic errors, load returns the compiled chunk as a
function
If you want that function to be called, call it.
local abc = "function x() print('math.sqrt(25)') end"
local loadedFunction = load(abc)
loadedFunction()
or simply
load(abc)()
Of course you should check wether load actually succeeded.
If you want something to happen you probably should also call the function that has been defined by the function you loaded.
load(abc)()
x()

What is happening when you have a function as a parameter?

I'm still ramping up in lua, and I am not quite familiar with this syntax. What is happening when you pass in a function as a parameter like below?
Comm.setRouting(function(url)
for i = 1,4 do
local portIndex = "Path"..i
if url:match(portConfig[portIndex]) ~= nil then
return Comm.slots()[1], Comm.groups()[i]
end
end
end)
The other answers are correct, but it might help you if you wrote your own function that calls another function:
function CallAFunction(func_to_call)
func_to_call()
end
You could pass a named function (an anonymous function assigned to a variable) or an anonymous function written on the fly.
function SayHello()
print("Hello!")
end
--[[
^This is equivalent to:
SayHello = function()
print("Hello!")
end
]]--
CallAFunction(SayHello)
CallAFunction(function()
print("Goodbye!")
end)
output:
Hello!
Goodbye!
and this can be done with parameters
function CallAFunction(func)
func("Bonjour")
end
CallAFunction(function(parameter)
print(parameter)
end)
Here, func is the anonymous function, which accepts 1 parameter parameter.
When you call func("Bonjour") you are passing Bonjour as parameter, like a normal function call.
Here you're passing an argument to setRouting that is an "anonymous function"
Functions are first-class values in Lua and can be stored in local variables, global variables and table fields. Here the function is being passed anonymously on the call stack to the setRouting function.
setRouting would be called a "higher-order function" because it accepts a function as its input.
The following page has some more information about functions in Lua:
https://www.lua.org/pil/6.html
A couple of things are happening in this example:
You're passing a function as a parameter. The callee (e.g. setRouting()) can invoke that function. This is often referred to as a callback function.
You're defining the function itself, on-the-fly. This is an example of an "anonymous function", or a lambda function.

Creating function from available function

I'm trying to do script for game which replaces avalible function with created function. So this is my LUA code:
function ifEmotePlayed(playerName, emoteID)
if emoteID == 0 then
print(playerName.." is dancing!")
end
end
return
function eventEmotePlayed(playerName, emoteID)
end
Exactly thing i want to do is to replace eventEmotePlayed function with ifEmotePlayed function likely
function ifEmotePlayed(playerName, emoteID)
if emoteID==0 then
print(playerName.." is dancing!")
end
end
Instead of
function eventEmotePlayed(playerName, emoteID)
if emoteID==0 then
print(playerName.." is dancing!")
end
end
Does anyone know how to do it?
If you want to rename a function you simply do it like that:
myNewFunctionName = originalFunctionName
Then calling myNewFunctionName() will be identical to calling originalFunctionName() as myNewFunctionName now refers to the same function as originalFunctionName.
In Lua functions are variables.
You could also define a function that calls the original function and pass the parameters like:
function myNewFunction(a,b)
return originalFunction(a,b)
end
But this is obviously not as efficient as you have to do one additional function call.
If you want to replace a function with your own function so the original function will not be executed but yours instead you simply assign your function to the original functions "name" (actually you make the variable that referred to the original function from now on refer to your own function)
function originalFunction(a,b)
return a + b
end
function myOwnFunction(a,b)
return a * b
end
originalFunction = myOwnFunction
Now originalFunction refers to your function and calling originalFunction(a,b) will return the product of a and b instead of the sum. It's the same as in the first example, just the other way around.

Lua: How to call a function prior to it being defined?

What is the syntax to create the function, but then add it's implementation further down in code?
So roughly like this:
Define function doX
Call doX (further down in the code)
doX implemention (i.e. all functions down at the bottom of the file)
You only need to have a variable to reference. local funcName is sufficient for your purposes with one caveat. This will work:
local funcName
function callIt()
print(funcName())
end
function defineIt()
funcName = function() return "My Function" end
end
defineIt()
callIt()
As long as you define it (defineIt) before you call it (callIt), it should work as expected. You can't do something like this though (and this is the caveat):
local funcName
print(funcName())
funcName = function() return "My Function" end
You will get an error: attempt to call local 'funcName' (a nil value).
oh...so there's really no way to call funcName prior to having actually defined the function then? i.e. you still need to make sure defineIt is called before your first call to funcName itself?
I wanted to clarify this point, and I felt that an answer would be the better way than a comment.
Lua is a much simpler language than C or C++. It is built on some simple foundations, with some syntactic sugar to make parts of it easier to swallow.
There is no such thing as a "function definition" in Lua. Functions are first-class objects. They are values in Lua, just like the number 28 or the string literal "foo" are values. A "function definition" simply sets a value (namely, the function) into a variable. Variables can contain any kind of value, including a function value.
All a "function call" is is taking the value from a variable and attempting to call it. If that value is a function, then the function gets called with the given parameters. If that value is not a function (or a table/userdata with a __call metamethod), then you get a runtime error.
You can no more call a function that hasn't been set in a variable yet than you can do this:
local number = nil
local addition = number + 5
number = 20
And expect addition to have 25 in it. That's not going to happen. And thus, for the same reason, you can't do this:
local func = nil
func(50)
func = function() ... end
As Paul pointed out, you can call a function from within another function you define. But you cannot execute the function that calls it until you've filled in that variable with what it needs to contain.
As others have written, you cannot call a function at runtime that has not been assigned prior to the call. You have to understand that:
function myFunc() print('Something') end
Is just a syntax sugar for this:
myFunc = function() print('Something') end
Now, it makes sense that this kind of code would not work the way you want it to:
print(greeter(io.read())) -- attempt to call global 'greeter' (a nil value)
function greeter(name) return 'Hello '..name end
When you use the greeter variable, its value is nil, because its value is set only on the next line.
But if you want to have your "main" program on the top and the functions at the bottom, there is simple way to achieve this: create a "main" function and call it as the last thing on the bottom. By the time the function is called, all the functions will be set to the corresponding global variables:
-- start of program, your main code at the top of source code
function main()
local name = readName()
local message = greeter(name)
print(message)
end
-- define the functions below main, but main is not called yet,
-- so there will be no errors
function readName() io.write('Your name? '); return io.read() end
function greeter(name) return 'Hello, ' .. name end
-- call main here, all the functions have been assigned,
-- so this will run without any problems
main()

Callback to Lua member function

I have a lua "animation variable" which has a callback function used in an animation loop.
local av = AnimationVariable(ticker.Position.Y)
...
av:addCallback( ** animation function goes here **)
Skipping over details, this addCallback function is defined as follows in C++:
void LuaUIAnimationVariable::addCallback(luabind::object callback);
and when the animation variable is updated, the callback is executed as such (we call the function with one argument):
luabind::call_function<void>(boost::ref(callback), newValue);
My question is the following: How can I use a member function with addCallback? Assuming I have a Ticker:animate(ypos) function, using addCallback on a Ticker instance addCallBack(ticker:animate) does not compile, and addCallBack(ticker.animate) does not work. I understand that member functions in lua have an implicit "self" first parameter.
Any solution or am I forced to use a global function?
Not sure if I understand your question, but if you mean a Lua member function, you can use a closure:
av:addCallback(function(yval) ticker:animate(yval) end)

Resources