From: Charles Oliver Nutter Date: 2009-02-16T06:55:07+09:00 Subject: Re: Iterating a changing Hash under 1.9.1 Phrogz wrote: > The following code shows that Hash#each under 1.9.1p0 does not iterate > over keys added during iteration: > a = [ 1, 2, 3 ]; h = { 0=>0 } > h.each{ |k,v| h[a[k]] = a[k] } > p h > #=> {0=>0, 1=>1} In this case, you're only reassigning the same keys over and over again. Since they're just being reassigned, they don't get pushed to the end of the iteration and you don't loop forever. Lesson one: reassigning an existing key does not move it to the end of iteration order. > However, this code (on 1.9.1p0) results in a ruby process with > unending 100% CPU usage, presumably due to an unending loop that keeps > traversing newly-added items: > h = { 1=>nil, 2=>nil } > h.each{ |k,v| h.delete(k); h[k]=v } > (Credit to "tama" for posting this on the ramaze group.) Here, you are deleting the key before assigning it. That removes it from the original order and re-adds it at the end. So the iteration runs forever because there's always another key to walk...the one you've just re-added. Lesson two: Keys deleted and re-added or keys newly added appear at the end of iteration order. - Charlie