I want to keep looping.
After some investigation I think I was able to find the source of the error. Imagine the table as a list of elements. Next uses an element's next-pointer to get to the next element. The issue is the following:
If I provide a table
tbl = {[1]="a", [2]="b", [3]="c"}
, the pointers look something like this: 1.next = 2, 2.next = 3.
Deleting the second entry by doing
tbl[2] = nil
will change the pointers and result in: 1.next = 3.
It appears as if the next() implementation is working on a different table, than I edit during the loop itself. On the Lua side, I successfully removed the 2. element. The LuaJ side however tries accessing tbl[2], because it did not update the pointers and is thus using 1.next = 2.
Actually, what happens is that pairs calls next with the last key it returned, so if you delete the entry for that key from the table it won't find it when calling next.
Using your example:
tbl = {[1]="a", [2]="b", [3]="c"}
pairs initially calls next with no key, and returns the first key and its value. You check for the value and it's not the one to delete, so it keeps looping. Then pairs calls next with 1 (the first key) as the key, and return the second key and its value. You remove that entry. pairs calls next with that key, but there's no such key in the table, so it errors.
Another solution (instead of writing your own next function) would be to use a while loop like this:
local key = next(tbl) -- get the first key
while key do
if tbl[key] == valueToDelete then -- check if it's the value to delete
local k = key -- store the key
key = next(tbl, key) -- get the next key first
tbl[k] = nil -- and then delete the value
else
key = next(tbl, key) -- get the next key
end
end
(Not tested, but it should work)