From: Hal Fulton Date: 2003-08-30T03:35:17+09:00 Subject: Re: #collect with block modifying receiver dblack@superlink.net wrote: >>>I wouldn't like that, personally. I don't remember exactly where, but I >>>believe that I have a piece of code taking advantage of the fact that a >>>receiver *can* be modified during iteration. I don't modify during a >>>#collect, but during an #each. One of the things you can do is: >>> >>> arr.each { |e| arr << f.flatten if f.kind_of?(Array) } >> >>Well, if I understand Matz correctly, this behavior is not guaranteed. >> >>If that's the case, you should change this to avoid being bitten >>the way I was. > > > I think (Matz - ?) that Matz was talking specifically about changing > the length of the receiver during an iteration, since that raises the > question of how many iterations there should be, what the next one > should be if something gets sliced out, etc. > > Just modifying the objects during an iteration is different, I think. > #map! does it, for example. Or: > > names.each {|name| name.upcase!} > > I'm pretty sure there's no danger with in-place things like this > (as opposed to things that alter the meaning of the 'place' you're > 'in' :-) Yes, I agree. But to avoid confusion for others, let me point out that Austin's code *does* change the length of the receiver. However, let's examine this at a slightly finer granularity. It seems likely to me that it is "safer" to increase the length of a container (to append) than it is to decrease its length, to add/delete in the middle, and so on. The "less safe" behavior was what the randomizing code did. It worked under 1.6.* and now fails under 1.8.0. OK, here's a modified question for Matz. If we are iterating over a list, and the block *appends* to the list, is the behavior guaranteed and the code thus acceptable? Hal