[Gambas-user] modifying an enumerated set during the loop

Benoît Minisini gambas at ...1...
Wed Jun 25 02:43:11 CEST 2014


Le 25/06/2014 02:30, B Bruen a écrit :
> 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
>

No. An array is an object, and aTest a variable that owns a *reference* 
to the array. If you set aTest to NULL, you just remove the reference, 
not the array by itself, which is referenced by the FOR EACH instruction 
until it ends.

-- 
Benoît Minisini




More information about the User mailing list