|
Valkenar Beginner
Joined: 12 Aug 2009 Posts: 15
|
Posted: Mon Aug 08, 2011 10:59 pm
Lua functions can't return functions as values |
Given these settings:
Code: |
<class name="Test" id="737">
<func name="test1" language="Lua" id="738">
<value>a = zs.execfunc("test2")
print("Type: " .. type(a))
print("Tostring: " .. tostring(a))
print("Call: " .. a())</value>
</func>
<func name="test2" language="Lua" id="739">
<value>return(function() return("test2 result") end)</value>
</func>
</class>
|
I would expect that test2 would return the function to test1, but instead it only returns the result of tostring() on it. |
|
|
|
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Tue Aug 09, 2011 2:03 am |
Perhaps I don't understand what you are doing but here is what I see: You want a zscript function to return a Lua function.
The way I see it, the called function is going to return a zscript value which will look like a string to Lua.
You are returning 'function() return("test2 result") end' to Lua. So, IMHO, the interpreter will treat it just like a string. You would have to run a pre-processor of some kind between the call to the CMUD function and the return to Lua. I can't see how the interpreter could view the return value as an executable chunk.
You may take this with a grain of salt as I am not any kind of Lua expert :) |
|
_________________ Sic itur ad astra. |
|
|
|
Valkenar Beginner
Joined: 12 Aug 2009 Posts: 15
|
Posted: Tue Aug 09, 2011 1:29 pm |
Well both of those functions were lua, not zscript. In lua functions are first-class objects. That means you can do this:
Code: |
function ReturnAFunction(ExtraString)
return (function()
print("This is a function that got returned. " .. ExtraString)
end)
end
function DoSomething()
functionObject = ReturnAFunction("Pineapple")
functionObject()
end
|
And if you call DoSomething() the result will be:
This is a function that got returned. Pineapple
All of that is just to say that you should be able to pass function objects back and forth between Lua functions. Since neither of the functions I had up there was in zscript, I thought it should work. |
|
|
|
orphean Apprentice
Joined: 21 Oct 2008 Posts: 147 Location: Olympia, WA
|
Posted: Tue Aug 09, 2011 4:51 pm |
I'm guessing the issue is that it's a CMUD user function returning the lua function. I have no idea what exactl zs.execfunc is doing but its most likely a host function registered with the Lua environment and isn't handling that correctly, Zugg will have to verify. One way to narrow it down would be to put your second lua function in the same place as the first and make sure it works correctly in the Lua environment without involving the host functions (it should work fine)
|
|
|
|
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Wed Aug 10, 2011 1:37 am |
I understand that functions are first class objects. That was not my point. You are using zs.execfunc which executes a CMUD function. The fact that the CMUD function contains Lua code is irrelevant, as far as I can tell. My opinion is that the object of zs.execfunc (i.e. the function) is treated as an independent chunk. You are mixing your interpreters. If you want a function to return a Lua function then put it in the same chunk (which you can do by loading all your Lua code during the onLoad or onConnect events) and then just simply call the function that returns a function.
There is no connection between the calling and called chunks. I don't know exactly who zs.execfunc works, but I imagine that it does not return a Lua object, instead, it returns a compatible string. On the other hand, I hope that I am wrong and that your code should work, I can visualize lots of uses for that kind of interface. |
|
_________________ Sic itur ad astra. |
|
|
|
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Fri Aug 12, 2011 1:46 am |
OK, I have some news for you. I've been experimenting and I've come up with something:
Code: |
-- body of CMUD function test1
f = assert(loadstring(zs.execfunc("test2"))) -- call function and compile return. Use assert to stop execution if there is an error.
--
f() -- make compiled chunk executable.
--
--Below is your original code.
--
print("Type: " .. type(a))
print("Tostring: " .. tostring(a))
print("Call: " .. a())
|
Then, change test2 to return a string representation of the function:
Code: |
-- body of CMUD function test2
return 'function a(...) return "test2 result" end'
|
Now executing test1 gets this result:
Code: |
Type: function
Tostring: function: 0B094C70
Call: test2 result
|
I mentioned in my previous post that you needed to pre-process the return string and that is how I did it. With some work
it can be made to do what you want. However, let me warn you that, in terms of execution time, this methodology is very expensive.
NOTE: I couldn't get it to work with the return string representing an anonymous function.
I hope this helps. |
|
_________________ Sic itur ad astra. |
|
|
|
|
|