Lua timer - creating a timer to execute a function every X seconds - lua

Following instructions on https://nodemcu.readthedocs.io/en/release/modules/tmr/#tobjcreate
I am trying to create a timer in my Lua script which will execute a function every 10 seconds. Sample timer from my script:
mytimer = tmr.create
mytimer:register(10000, tmr.ALARM_AUTO, my_function() end)
mytimer:start()
When I execute my script I'm getting a syntax error:
'=' expected near 'mytimer'
What am I doing wrong here?
Thanks

Well instead of asking here, a good starting point would have been to compare your code vs the code example from the documentation you linked:
local mytimer = tmr.create()
mytimer:register(5000, tmr.ALARM_SINGLE, function (t) print("expired"); t:unregister() end)
mytimer:start()
Example: local mytimer = tmr.create()
You mytimer = tmr.create
You're missing the call operator here. Not making mytimer local is bad practice but won't give you an error.
Example: mytimer:register(5000, tmr.ALARM_SINGLE, function (t) print("expired"); t:unregister() end)
You: mytimer:register(10000, tmr.ALARM_AUTO, my_function() end)
I don't know what my_function is. The end doesn't belong here unless you're defining a function in place. then it should look like in the example. Your version would only be ok without the end and if my_function() would return a function value.
function (t) print("expired"); t:unregister() end defines an anonymous function. This resolves to a function value that is used as an argument for the callback parameter of the register function.
You could also do it like:
local callback = function (t) print("expired"); t:unregister() end
mytimer:register(5000, tmr.ALARM_SINGLE, callback)
Anything else is described in the manual.

Related

lua dynamically stop or manipulate a function

What I want to do is to dynamically stop a function in lua. My code that i tried:
local SaveReal = Thread
local stopped = false
--[[
Thread function runs the lua function
that it includes in a separate thread.
It was created before here
and is trying to be manipulated here.
]]--
Thread = function(func)
SaveReal(function()
while(not stopped) do
func()
end
end)
end
Thread(function()
while(true) do
print("Thread working")
end
end)
Maybe if I could read the contents of the function as a string, I could load it into my manipulative function with load. so the code would not work if my flag is not false.
Lua has something called Coroutines to provide multi-tasking (not multi-threading).

How or Can I pass a function with argument as a parameter to a function in lua?

I am not running straight lua but the CC-Tweaks ComputerCraft version. This is an example of what I am trying to accomplish. It does not work as is.
*edited. I got a function to pass, but not one with arguments of its own.
function helloworld(arg)
print(arg)
end
function frepeat(command)
for i=1,10 do
command()
end
end
frepeat(helloworld("hello"))
frepeat(helloworld("hello"))
will not pass the helloworld function like frepeat(helloworld) does, because it always means what it looks like: call helloworld once, then pass that result to frepeat.
You need to define a function doing what you want to pass that function. But an easy way to do that for a single-use function is a function expression:
frepeat( function () helloworld("hello") end )
Here the expression function () helloworld("hello") end results in a function with no name, whose body says to pass "hello" to helloworld each time the function is called.
Try this code:
function helloworld(arg)
print(arg)
end
function frepeat(command,arg)
for i=1,10 do
command(arg)
end
end
frepeat(helloworld,"hello")
If you need multiple arguments, use ... instead of arg.
"repeat" is reserved word in lua. Try this:
function helloworld()
print("hello world")
end
function frepeat(command)
for i=1,10 do
command()
end
end
frepeat(helloworld)

Lua attempt to call method a nil value

I'm lost on what I'm doing wrong here.
I have this simple code:
Queue = {}
Queue.__Index = Queue
function Queue.Create()
local obj = {}
setmetatable(obj, Queue)
return obj
end
function Queue:PushBack(item)
end
q = Queue.Create()
print(q)
q:PushBack(1)
When executing this I get "attempt to call method 'PushBack' (a nil value). However, if I change the PushBack function like this and call it accordingly it works:
function Queue.PushBack(q, item)
end
q = Queue.Create()
print(q)
Queue.PushBack(q, 1)
The code runs and executes correctly. I understand that ":" is syntactic sugar, so it seems to me that
function Queue:PushBack(item)
would be exactly the same as
Queue.PushBack(q, item)
But it dies on me. Does it have to do with how I'm creating the object? I'm pretty lost on this and I can't seem to figure out what exactly is wrong.
The nil signifies that the PushBack function is not found in the first case.
The reason your code doesn't work, is because you have unintentionally misspelt __Index as it should be:
Queue.__index = Queue
with i of __index being lower-case.
Once corrected, your code should work.

Post-hook a function, post-process and pass through all returns

I have a post-hook function that receives some data for itself, reference to another function and arguments for that arbitrary function in .... This function does some post-processing, after referenced function returns. For simplicity let's just note time:
function passthrough(tag, func, ...)
metric1[tag] = os.time()
func(...)
metric2[tag] = os.time()
end
Since I need to postprocess, I can't immediately return func(...) and I don't know in advance how many returns there will be. How can I passthrough those returns after I'm done with post-processing?
So far I can think only of packing call in local results = { func(...) } and then using return unpack(results) or making a postprocessor factory that'd generate postprocessing closure with all necessary data as upvalues:
local function generate_postprocessor(tag)
return function(...)
metric2[tag] = os.time()
return ...
end
end
function passthrough2(tag, func, ...)
metric1[tag] = os.time()
return generate_postprocessor(tag)(func(...))
end
However, both those approaches would introduce some overhead that is undesirable, considering high amount of iterations and real-time nature of application. Is there anything simpler?
You don't need the closure. func is called before calling your closure generator anyway. You just need a function that passes its arguments straight through to its return values to give you a hook point for your second tag:
function passthrough_return(tag, ...)
metric2[tag] = os.time()
return ...
end
function passthrough(tag, func, ...)
metric1[tag] = os.time()
return passthrough_return(tag, func(...))
end
You're still getting the overhead of an extra function call, but that's better than creating a closure or a table and far less than the overhead of your pre/post processing.

Error while trying to call a class method: attempt to index local 'self' (a nil value) - Lua

I'm creating a lua script that should run on the TI-Nspire calculator. The problem is that while running my script I get the error Attempt to index local 'self' (a nil value) when the button:activate() method is called. The parser says the error is in the 8th line in the code below. The problematic code is as follows:
button = class(view)
function button:init()
self.selected = false
end
function button:activate()
self.selected = true
end
I call the activate function like this:
item = button()
local action = "activate"
local arguments = {}
item[action](unpack(arguments))
I am aware the class() function doesn't exist in "stock" Lua, it's a function available in the TI-Nspire Lua implementation. You can find its definition and usage here.
obj:methodname(args) is sugar for obj.methodname(obj,args). So, if you want to use the syntax item[action](unpack(arguments)), you need to use item[action](item,unpack(arguments)). Otherwise, try item:activate(unpack(arguments)) if you can use method explicitly.

Resources