Luau Couroutine stopping thread - lua

I'm trying to make a OnChange Event Listener, I thought of using coroutines to poll the value in a loop, and see if it changed, so
function Changed(Value)
local StartingValue = Value
while true do
if StartingValue ~= Value then
print(Value)
StartingValue = Value
break
end
end
end
local n = 0
local co = coroutine.wrap(function()
Changed(n)
coroutine.yield()
end)
co()
n = (n + 1)
print("Script ended")
Is the Code I thought of for now, But it gets stuck in the Coroutine.. nothing happens after co()
What's going on?

The function Changed() never returns.
At the very beginning you're assigning the Value to the StartingValue, and the break is inside of the if statement that is only executed when the values are different. But they're not because of that initial assignment. So you have the infinite loop that has no means of ending.

Related

recursive lua function always returns nil

alright this is probably a stupid mistake but I cant find it.
I am trying to iterate over a treesitter node to find the parent node i need.
local function getParent(node)
local type_text = node:type()
print(type_text, "node type")
if type_text == "variable_declaration" then
return 1
end
print("RUNNING AGAIN?")
getParent(node:parent())
end
local outp = getParent(node_at_cursor, 0)
print(outp, "outp")
the output:
identifier node type 0
RUNNING AGAIN?
variable_list node type 1
RUNNING AGAIN?
assignment_statement node type 2
RUNNING AGAIN?
variable_declaration node type 3
nil outp
i don't understand why the return value is always nil. it clearly stops at some point, i see that from the print statements. The function enters the if block and should return 1.
thank you
You are not returning anything from the recursive call.
local function getParent(node)
local type_text = node:type()
print(type_text, "node type")
if type_text == "variable_declaration" then
return 1
end
print("RUNNING AGAIN?")
return getParent(node:parent())
end

WoW Lua error; attempt to call a global(a nil value)

I'm new to Lua and was following the tutorial on https://wowwiki.fandom.com/wiki/AddOn_tutorial but i just cant get it to work; i have copied the code but i get the error message "attempt to call a global 'functionname' (a nil value)" on both the SetMapToCurrentZone() and the GetPlayerMapPosition("player") functions.
This is the entire Lua file;
local zone = nil
local TimeSinceLastUpdate = 0
local function UpdateCoordinates(self, elapsed)
if zone ~= GetRealZoneText() then
zone = GetRealZoneText()
SetMapToCurrentZone()
end
TimeSinceLastUpdate = TimeSinceLastUpdate + elapsed
if TimeSinceLastUpdate > .5 then
TimeSinceLastUpdate = 0
local posX, posY = GetPlayerMapPosition("player");
local x = math.floor(posX * 10000)/100
local y = math.floor(posY*10000)/100
eCoordinatesFontString:SetText("|c98FB98ff("..x..", "..y..")")
end
end
function eCoordinates_OnLoad(self, event,...)
self:RegisterEvent("ADDON_LOADED")
end
function eCoordinates_OnEvent(self, event, ...)
if event == "ADDON_LOADED" and ... == "eCoordinates" then
self:UnregisterEvent("ADDON_LOADED")
eCoordinates:SetSize(100, 50)
eCoordinates:SetPoint("TOP", "Minimap", "BOTTOM", 5, -5)
eCoordinates:SetScript("OnUpdate", UpdateCoordinates)
local coordsFont = eCoordinates:CreateFontString("eCoordinatesFontString", "ARTWORK", "GameFontNormal")
coordsFont:SetPoint("CENTER", "eCoordinates", "CENTER", 0, 0)
coordsFont:Show()
eCoordinates:Show()
end
end
How do i fix it?
These functions have been renamed and moved to a wrapper object in 8.0, to C_Map.GetBestMapForUnit (requiring "player" as parameter to yield the same result) and C_Map.GetPlayerMapPosition respectively.
You can probably expect more functions that are called later to throw the same error, their lines just couldn't be reached before. I can check the whole code example when I'm at a desktop again, but you may simply look up these functions on Wowpedia, especially other map-related functions.
I suggest using Wowpedia over Wowwiki, it's a personal preference/impression, the former seems to receive more constant updates.
(The two seem to be merging again now, after splitting 10 years ago)

How can a Lua function return nil, even if the returned value is not nil inside the function?

I have created a function that (pseudo)randomly creates a table containing numbers. I then loop this function until at least correct result is found. As soon as I've confirmed that at least one such result exists, I stop the function and return the table.
When I create tables containing small values, there are no issues. However, once the random numbers grow to the range of hundreds, the function begins to return nil, even though the table is true the line before I return it.
local sort = table.sort
local random = math.random
local aMin, aMax = 8, 12
local bMin, bMax = 200, 2000
local function compare( a, b )
return a < b
end
local function getNumbers()
local valid = false
local numbers = {}
-- Generate a random length table, containing random number values.
for i = 1, random( aMin, aMax ) do
numbers[i] = random( bMin, bMax )
end
sort( numbers, compare )
-- See if a specific sequence of numbers exist in the table.
for i = 2, #numbers do
if numbers[i-1]+1 == numbers[i] or numbers[i-1] == numbers[i] then
-- Sequence found, so stop.
valid = true
break
end
end
for i = 1, #numbers-1 do
for j = i+1, #numbers do
if numbers[j] % numbers[i] == 0 and numbers[i] ~= 1 then
valid = true
break
end
end
end
if valid then
print( "Within function:", numbers )
return numbers
else
getNumbers()
end
end
local numbers = getNumbers()
print( "Outside function:", numbers )
This function, to my understanding, is supposed to loop infinitely until I find a valid sequence. The only way that the function can even end, according to my code, is if valid is true.
Sometimes, more often than not, with large numbers the function simply outputs a nil value to the outside of the function. What is going on here?
You're just doing getNumbers() to recurse instead of return getNumbers(). This means that if the recursion gets entered, the final returned value will be nil no matter what else happens.
In the else case of the if valid then, you are not returning anything. You only return anything in the valid case. In the else case, a recursive call may return something, but then you ignore that returned value. The print you see is corresponding to the return from the recursive call; it isn't making it out the original call.
You mean to return getNumbers().

String compatibility error, attempt to index a nil value

I am using Gideros and getting this error:
main.lua:47: attempt to index a nil value
stack traceback:
main.lua:47: in function 'func'
[string "compatibility.lua"]:36: in function <[string "compatibility.lua"]:35>
I have this piece of code and as soon as the text is displayed, it gives me the above mentioned error:How can I fix this?
function onEnter()
function youLoose()
local font2 = TTFont.new("billo.ttf", 20, "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
LooserText = TextField.new(font2, "You Loose , Try AGAIN?")
LooserText:setPosition(100, 100)
stage:addChild(LooserText)
Timer = Timer.delayedCall(1000, removing)
end --line 36
end
function removing()
LooserText:getParent():removeChild(LooserText) --line 47
end
The index nil error means that on that line you are probably getting nil as a return value from LooserText:getParent().
Why you would be getting nil for that I can't tell you other than presumably because it doesn't have one.
The documentation indicates that there is no error condition for Stage.addChild except that the object added must be a Sprite. TextField inherits Sprite so there is no apparent reason for you to get this error. However, you should not re-assign the return value of delayedCall to a global variable of same name as the Timer class, this could affect other parts of the application. Since you don't use the returned Timer instance, I have removed the assignment. Also, if the stage:addChild succeeded then the removing can use stage. One thing that is strange is that your onEnter just defines youLose() but does not call it or return it, is this part of code you ommitted? In any case, you need to add some sanity checks to verify that what you think is happening is really happening w/r/t child add/remove:
function onEnter()
function youLoose()
local font2 = TTFont.new("billo.ttf", 20, "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
LoserText = TextField.new(font2, "You Lose , Try AGAIN?")
LoserText:setPosition(100, 100)
print('Stage num children:' .. stage:getNumChildren())
stage:addChild(LoserText)
print('Stage num children:' .. stage:getNumChildren())
print('LoserText is stage child #' .. stage:getChildIndex(LoserText))
Timer.delayedCall(1000, removing)
end
end
function removing()
print('Stage num children:' .. stage:getNumChildren())
print('LoserText is stage child #' .. stage:getChildIndex(LoserText))
stage:removeChild(LoserText)
print('Stage num children:' .. stage:getNumChildren())
end

Redis: Lua script to return every other nth element of a sorted set

I am trying to put together a lua script to be called from Redis (via an EVAL call) in order to return every other nth element of a sorted set (nth being the rank in the set, not the score).
There are very few online examples of Lua scripts that can be used to build upon, would anyone be able to point me in the right direction?
local function copyNOtherElements(table, interval, startpos)
local elemno = 1
local rettab = {}
for k, v in ipairs(table) do
if k >= startpos and (k - startpos) % interval == 0 then
rettab[elemno] = v
elemno = elemno + 1
end
end
return rettab
end
Sorry about formatting, typing on a phone. that's assuming the table is a 1 based array
For future readers, adding Redis into the previous answer, and a bit more efficient code to iterate the Nth elements:
local function zrange_pick(zset_key, step, start, stop)
-- The next four lines can be removed along with the start/stop params if not needed as in OP Q.
if start == nil than
start = 0
if end == nil than
end = -1
local set_by_score = redis.call('ZRANGE', zset_key, start, end)
local result = {}
for n = 1, #set_by_score, step do
table.insert(result, set_by_score[n])
end
return result
end

Resources