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

2014-06-24 Thread B Bruen
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 bbr...@paddys-hill.net

--
Open source business process management suite built on Java and Eclipse
Turn processes into business applications with Bonita BPM Community Edition
Quickly connect people, data, and systems into organized workflows
Winner of BOSSIE, CODIE, OW2 and Gartner awards
http://p.sf.net/sfu/Bonitasoft
___
Gambas-user mailing list
Gambas-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/gambas-user


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

2014-06-24 Thread Benoît Minisini
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

--
Open source business process management suite built on Java and Eclipse
Turn processes into business applications with Bonita BPM Community Edition
Quickly connect people, data, and systems into organized workflows
Winner of BOSSIE, CODIE, OW2 and Gartner awards
http://p.sf.net/sfu/Bonitasoft
___
Gambas-user mailing list
Gambas-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/gambas-user


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

2014-06-24 Thread B Bruen
On Wed, 25 Jun 2014 02:43:11 +0200
Benoît Minisini gam...@users.sourceforge.net wrote:

 Le 25/06/2014 02:30, B Bruen a écrit :
  I realise that modifying the enumerated set during a For Each loop is
(Cut)
 
 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
 

Ah, OK. So using 
  If Not aTest Then Break
during the loop appears to resolve the situation.

thanks
Bruce

-- 
B Bruen bbr...@paddys-hill.net

--
Open source business process management suite built on Java and Eclipse
Turn processes into business applications with Bonita BPM Community Edition
Quickly connect people, data, and systems into organized workflows
Winner of BOSSIE, CODIE, OW2 and Gartner awards
http://p.sf.net/sfu/Bonitasoft
___
Gambas-user mailing list
Gambas-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/gambas-user