On Sat, 10 Dec 2011, Jan Teske wrote:
Hey,
I have a question concerning the behavior of Collections in Squeak. Recently I face a problem when trying to delete some elements from a set during a 'do:' message. Have a look at this sample method:
doFallForAllIn: aSet aSet do: [:block | block fall ifFalse: [aSet remove: block]]
It loops over a set of blocks and performs the fall message on each of them. If a block is not falling I don't want it to be in aSet after the function returned so I remove it from the set. Squeak doesn't seem to like that since some rather strange error now occures: If a block is removed from the set, the next block in the set will be left out from looping... sometimes. Nearly all the time it works as exspected, only sometimes a block is ignored. I couldn't find any pattern when this happens.
So my question is: Has anyone an explanation for this? Does the error occure
This happens, because #remove: will rehash elements in the same chain after the removed element. The rehashed elements may be moved to a lower index, so the loop may not iterate over it at all. You should use #removeAllSuchThat: instead. E.g.:
doFallForAllIn: aSet
aSet removeAllSuchThat: [ :block | block fall not ]
because the way I'm doing it is fundamentally wrong? Or am I just overlooking something and it is possible to remove blocks from a collection while looping over it?
As others pointed out, modifying collections while iterating over them is not supported in general.
Levente
Thanks in advance! _______________________________________________ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners