This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Hawk777's profile picture

Table Concurrent Iteration And Mutation

Started by Hawk777, 27 February 2012 - 02:29 AM
Hawk777 #1
Posted 27 February 2012 - 03:29 AM
According to the Lua manual, under documentation for the next() function:

The behavior of next is undefined if, during the traversal, you assign any value to a non-existent field in the table. You may however modify existing fields. In particular, you may clear existing fields.

This statement does not restrict the modification, including deletion, of existing elements to only those that are not the current element. I have verified on my native install of Lua that deleting the current element works fine:


Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> t = {2,4,6}
> for k,v in pairs(t) do print(k, ",", v) if v == 4 then t[k]=nil end end
1	,	2
2	,	4
3	,	6
> for k,v in pairs(t) do print(k, ",", v) if v == 4 then t[k]=nil end end
1	,	2
3	,	6
> 

If I run the same code in ComputerCraft Lua, it fails:


Interactive Lua prompt.
Call exit() to exit.
lua> t = {2,4,6}
lua> for k,v in pairs(t) do print(k, ",", v) if v == 4 then t[k]=nil end end
1,2
2,4
lua:1: invalid key to 'next'

This thus appears to violate the specification, and in a rather annoying way since this would make it much easier to delete elements from a table that match a particular predicate.
Casper7526 #2
Posted 27 February 2012 - 03:41 AM
Yes, I can understand the frustration that somethings can cause when they dont work as expected in CC, the problem is even though CC is Lua 5.1, it's not that Lua 5.1, it is LuaJ which is an implementation of Lua 5.1

Try this once and let me know what happens (I'm not on CC atm)


for k,v in pairs(t) do print(k, ",", v) if v == 4 then table.remove(t,k) end end

If it doesn't work however, you can always resort to deleting the table outside of the loop.


for k,v in pairs(t) do print(k, ",", v) if v == 4 then del=k end end table.remove(t,del)

Hmmm after typing all that I realize that maybe you dont want to remove the item from the table and you do just want to nil it out….
Let me know what you think.
Hawk777 #3
Posted 27 February 2012 - 06:07 AM
Unfortunately, my application is using the table as a dictionary and not an array, so table.remove isn't useful. The workaround of compiling a list of elements to delete and then deleting them after the loop is doable, of course, just a bit ugly. I was under the impression that the documentation at lua.org was the language specification, meaning that if LuaJ doesn't obey it then LuaJ is buggy; am I wrong on that assumption? If so, is there an actual language specification that all implementations must follow somewhere I could read instead? Or should this get reported to the LuaJ developers?
Casper7526 #4
Posted 27 February 2012 - 07:03 AM
Yeah, there's not MUCH documentation on LuaJ, there's alittle here and there floating around, but there's definitely missing functions and broken functions inside Luaj, as we've experienced them multiple times. I would say report it to the dev's but I have a feeling they arnt gonna update until they update to 5.2 (if they ever do)
Hawk777 #5
Posted 27 February 2012 - 11:01 AM
Looks like it's already been reported.