Lua Getting Result Back in LuaJava from Lua function call - lua

How does one get the value back from a Lua function call in LuaJava.
Lets say I have calc.lua:
function foo(n) return n*2 end
I call the function in Java as follows:
LuaState luaState;
this.luaState = LuaStateFactory.newLuaState();
this.luaState.openLibs();
this.luaState.LdoFile("calc.lua");
this.luaState.getGlobal("foo");
this.luaState.pushNumber(5.0);
int retcode=this.luaState.pcall(1, 1,0);
Now what do I have to call on LuaState object to get the result of this last function call foo(5)?
Is there an example somewhere showing Java->Lua invocation with return values from the call?

Would something like this do the trick?
int top_index = luaState.getTop();
double result = luaState.isNumber(top_index) ?
luaState.toNumber(top_index) : 0.0;

Related

What is the logic behind these functions

I am learning Dart, and I can't understand the logic behind this code if anyone can help:
Function applyMultiplier(num multiplier) {
return (num value) {
return value * multiplier;
};
}
final triple = applyMultiplier(3);
print(triple(6)); //output 18
There is an anonymous function inside a named function.
We assigned a function to a variable.
What I don't understand is how did we pass from triple to value. I can't understand the logic behind.
Well, the function applyMultiplier takes a num as argument and returns a function that itself returns the value it is given multiplied by another multiplier. final tripple = applyMultiplier(3) stores this function that is returned from applyMultiplier in the variable triple. Because the variable triple then stores a function it can also be used like a function.

Loop over a function and store as list

I have the following function that clicks a checkbox with splash:
local get_dimensions = splash:jsfunc([[
function () {
for i=1, 5 do
var rect = document.querySelector(string.format('checkbox[number="%d"]'), i)
.getClientRects()[0];
return {[rect.left]: rect.top};
end
}
]])
However, I cannot store a list from the loop into a single variable like rect, so how do I store a list into a variable, and when I return it, it should return a list of values?
Something similar to python, ie.:
def stuff():
rect = []
for i in range(5):
rect.append([...])
return rect
Let's take at your code.
You call splash:jsfunc. This function converts JavaScript into a Lua callable. It takes a single argument. A string that defines a JavaScript function.
yourString = [[
function () {
for i=1, 5 do
var rect = document.querySelector(string.format('checkbox[number="%d"]'), i).getClientRects()[0];
return {[rect.left]: rect.top};
end
}
]]
This looks like some weird mix of Lua and JavaScript.
This is how a JavaScript for loop looks like
for (let i = 0; i < 10; i++) {
// some code
}
This is how a Lua numeric for loop looks like:
Also what's the point of using return in a loop without any condition? This will be executed after the first cycle with i = 1. That's probably not what you want.
So fix the loop so it is JavaScript. Create a Object or Array and return that after the loop is complete.

call function into function in lua

i have code in my lua file and i edit that to look like this
function getUserinfo(user_id)
function call_back_user_info(status , result)
t = {["first_name"]= result.first_name_, ['have_access']= result.have_access_, ["last_name"]=result.last_name_,["user_name"]=result.username_}
return t
end
getUser(user_id,call_back_user_info)
end
i need to return t table value when i call getUserinfo function.but it is get me a nil value !
note :getUser function puts data in to call_back_user_info
how i can resolve this problem? thank
You can't do a "long return" which returns from an outer function from inside of an inner function.
But what you can do is create a local variable which is closed over, like this:
function getUserinfo(user_id)
local t
function call_back_user_info(status , result)
t = {["first_name"]= result.first_name_,
['have_access']= result.have_access_,
["last_name"]=result.last_name_,
["user_name"]=result.username_}
end
getUser(user_id,call_back_user_info)
return t
end

is there aliasing in lua similar to ruby

Can you alias a function (not in a class) in LUA in a similar way to Ruby? In ruby you would do something like this:
alias new_name_for_method method()
def method()
new_name_for_method() # Call original method then do custom code
i = 12 # New code
end
I'm asking because I'm developing for a program that uses LUA scripting and I need to override a function that is declared in a default file.
In Lua, functions are values, treated like any other value (number, string, table, etc.) You can refer to a function value via as many variables as you like.
In your case:
local oldmethod = method
function method(...)
oldmethod(...)
i = 12 -- new code
end
keep in mind that
function method() end
is shorthand for:
method = function() end
function() end just creates a function value, which we assign to the variable method. We could turn around and store that same value in a dozen other variables, or assign a string or number to the method variable. In Lua, variables do not have type, only values do.
More illustration:
print("Hello, World")
donut = print
donut("Hello, World")
t = { foo = { bar = donut } }
t.foo.bar("Hello, World")
assert(t.foo.bar == print) -- same value
FYI, when wrapping a function, if you want its old behavior to be unaffected for now and forever, even if its signature changes, you need to be forward all arguments and return values.
For a pre-hook (new code invoked before the old), this is trivial:
local oldmethod = method
function method(...)
i = 12 -- new code
return oldmethod(...)
end
A post-hook (new code invoked after the old) is a bit more expensive; Lua supports multiple return values and we have to store them all, which requires creating a table:
local oldmethod = method
function method(...)
local return_values = { oldmethod(...) }
i = 12 -- new code
return unpack(return_values)
end
In lua, you can simply override a variable by creating a new function or variable with the same name.
function name_to_override()
print('hi')
end
If you still want to be able to call the old function:
local old_function = name_to_override
function name_to_override()
old_function()
print('hi')
end

Getting a “pointer” to a Lua function stored in C

In the Lua C API I can store a number or a string from the stack with lua_tostring().
How can a “reference” (if that is the correct term) to a Lua function be passed to C through the Lua API? So it can be called later from C, with lua_call(), without having to reference it by its name.
(It really needs to be like that, the C program will call the function somewhere in the future and the program doesn't know anything about the function because the functions to be passed are defined in the Lua program)
In C you can't refer to Lua functions directly but you can represent numbers and strings. So, for a function to "be called later", you can store this function in some table and refer to it by a numeric or string key of the table.
Here's a simpleminded mechanism to start with:
On the Lua side:
funcs = {}
local function register_hanlder(key, fn)
funcs[key] = fn
end
register_handler("on_mouse_click", function()
print "You clicked me!"
end)
On the C side:
/* code not tested */
lua_getglobal(L, "funcs");
lua_getfield(L, -1, "on_mouse_click");
if (!lua_isnil(L, -1)) {
lua_call(L, 0, 0);
else {
// nothing registered
}
Instead of registering the functions in a global table you can register them in the registry table (see luaL_ref). You'll get some integer (that's the key in the registry table where the function value is) that you can pass around in you C code.
Note that if you don't need to store a Lua function "for use later" you don't need any of this: if your C function has some Lua function passed to it via argument you can call it outright.
== Edit:
As I mentioned, instead of using a global variable (the funcs above) you can store the reference to the function in the "registry". Conceptually there's no difference between this method and the previous one.
Let's re-use the previous example: you want the Lua programmer to be able to register a function that would be fired whenever a mouse is clicked in your application.
The Lua side would look like this:
register_mouse_click_handler(function()
print "the mouse was clicked!"
end)
On the C side you define register_mouse_click_handler:
static int the_mouse_click_handler = 0;
static int register_mouse_click_handler(lua_State* L) {
the_mouse_click_handler = luaL_ref(L, LUA_REGISTRYINDEX);
return 0;
}
(...and expose it to Lua.)
Then, in your application, when the mouse is clicked and you want to call the Lua function, you do:
...
if (the_mouse_click_handler != 0) {
lua_rawgeti(L, LUA_REGISTRYINDEX, the_mouse_click_handler);
lua_call(L, 0, 0);
} else {
// No mouse handler was registered.
}
...
(I may have typos in the code.)

Resources