Jonathan Leighton wrote:
> On Sun, 2006-01-29 at 23:35 +0900, dblack / wobblini.net wrote:
>> Hi --
>>
>> On Sun, 29 Jan 2006, Jonathan Leighton wrote:
>>
>>> Okay, so let me get this right... if you do
>>>
>>> foo.each { }
>>>
>>> foo is re-evaluated with each iteration? Hence the bug? Why?
>>
>> The length of foo is re-evaluated each time; that's how the decision
>> is made whether or not to keep iterating.  Array#each essentially
>> works like this:
>>
>>    def each
>>      i = 0
>>      while i < length
>>        yield self[i]
>>        i += 1
>>      end
>>      self
>>    end
>>
>> So if the length of the array increases in mid-stream, the iteration
>> will continue, based on the while test.
>>
>> You can always get around this with something like:
>>
>>    array.length.times do |i|
>>      # do something with array[i]
>>    end
>>
>> where length won't be re-evaluated.
>
> Thanks very much! I understand now.

Adding to this I'd say it's generally a good idea not to modify the
container you're iterating (unless it's an array and you iterate by index)
because all sorts of strange things may happen.  (Java folks have
ConcurrentModificationException for this...)  At least you should look
twice whether you need to actually modify the container you walk though.

Kind regards

    robert