Posted 03 January 2016 - 10:40 PM
As you all know, there's not always a nice way in Lua to break out of nested loops. E.g.,
Obviously this starts to look worse the more loops that you're nested in. Now, whether this can be blamed on bad programming practices or not is not really the point of this post, so I won't go into it. Anyways, I figured out a neat little way of solving this problem that some people might enjoy using.
In this code, breakfrom("A") causes both nested functions to terminate, meaning that you get to jump right out of both nested loops without the usual fluff. Calling breakfrom("B") would have the same effect as just doing break.
The code is very simple, so I'll paste it here. For convenience if you want to try it out, pastebin get CFg347Tw brk.
As you can see it just unrolls the stack until the correct label is found. AFAIK it doesn't mess up error handling in any way since it detects whether the error is for the purpose of breaking or not.
So yeah, let me know if you find this useful!
local b = true
while b do
while true do
if endProgram then
b = false
break
end
end
end
Obviously this starts to look worse the more loops that you're nested in. Now, whether this can be blamed on bad programming practices or not is not really the point of this post, so I won't go into it. Anyways, I figured out a neat little way of solving this problem that some people might enjoy using.
mklabel("A", function() while true do
mklabel("B", function() while true do
breakfrom("A")
end end)
end end)
print("Hello World!")
In this code, breakfrom("A") causes both nested functions to terminate, meaning that you get to jump right out of both nested loops without the usual fluff. Calling breakfrom("B") would have the same effect as just doing break.
The code is very simple, so I'll paste it here. For convenience if you want to try it out, pastebin get CFg347Tw brk.
local top
function mklabel(name, func)
if not top then top = func end
local isTop = top == func
local suc, res = pcall(func)
if not suc then
if not res:find("__BREAKFROM") then error(res, -1) end
local target = res:gsub("[^\:]+:[^\:]+: __BREAKFROM", "")
if name ~= target then
if isTop then
error("Tried to break from label '" .. target .. "' which does not exist.", 2)
end
error("__BREAKFROM" .. target)
end
end
if isTop then top = nil end
end
function breakfrom(name)
error("__BREAKFROM" .. name)
end
As you can see it just unrolls the stack until the correct label is found. AFAIK it doesn't mess up error handling in any way since it detects whether the error is for the purpose of breaking or not.
So yeah, let me know if you find this useful!
Edited on 03 January 2016 - 09:52 PM