[Gambas-user] modifying an enumerated set during the loop
B Bruen
bbruen at ...2308...
Wed Jun 25 02:30:03 CEST 2014
I realise that modifying the enumerated set during a For Each loop is fraught with danger but I do have a situation where this is "necessary". The following is a very simplified mock up of an anomaly in gambas that I am seeing. The real situation is complex, I'll explain it later in this post.
The following code shows several variants of changing the enumerated set during the loop. (I could have also attached a source archive, but its probably quicker to just paste this in a new project main module.) The simulation is simply a "rocket launch count-down" .
Public Sub Main()
Dim aTest As String[]
Dim sItem As String
' Run 1: Simple enumeration (obviously works)
aTest = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
aTest.Reverse
For Each sItem In aTest
Print sItem
Next
Print "Blast off"
' Run 2: Nullify the whole array during the enumeration (continues as if enumeration is working on a copy)
aTest = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
Debug aTest
aTest.Reverse
Debug aTest ' prove that this is not duping the`array
For Each sItem In aTest
Debug aTest
Print sItem
If sitem = "8" Then aTest = Null ' but the enumeration continues???
Next
Print "Blast off"
Print aTest = Null
' Delete (all) elements within the enumeration
aTest = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
aTest.Reverse
For Each sItem In aTest
Print sItem
If sitem = "8" Then
aTest.Delete(0, aTest.Count) ' leaves a non-null but empty array, the loop exits once this has been executed
Endif
Next
Print "Blast off"
End
Run 1 is just a simple enumeration, no changes are made to the set during the loop (sanity check !).
In Run 2, when the count gets to 8 we nullify the entire array. However, the enumeration loop still continues and includes all the elements from the original array???
In Run 3, when the count gets to 8 we delete the entire array. Now the enumeration stops at that point. This is what I would expect in Run 2???
In our real situation, we receive a bunch of xml "packets" (a packet being a complete xml document) that are queued for processing in such an array. Quite often, the list of packets to be processed includes duplicate, or earlier, versions of some information relevant to a specific entity identified within the packet. So once we have processed the latest version, hence the array reversal, all packets containing earlier information regarding that entity are irrelevant.
In the real code we don't actually delete or nullify the queue array, but use a separate routine to remove the elements in the array that are no longer relevant, sometimes this will empty the reversed array entirely (or at least the rest of it). Now, as the Run 3 example works as I expect, i.e. the loop is "truncated", generally everything is fine. But, there are uncommon, but not infrequent, situations where the entire array can be nullified, this is what scares me as the code that handles this entire mess is spread out over multiple tasks and such like.
So, shouldn't the Run 2 loop truncate like Run 3?
regards
Bruce
--
B Bruen <bbruen at ...2308...>
More information about the User
mailing list