From: George Ogata Date: 2006-02-22T20:53:35+09:00 Subject: Re: dirty ranges David Vallner writes: > Dňa Utorok 21 Február 2006 04:38 George Ogata napísal: >> But I suggest not modifying range endpoints at all; Ranges themselves >> are immutable, so changing their value indirectly like that is kinda >> going against the grain. And of course, if you ever modify your #end >> while iterating over the range, it's nasal demons. >> > > Pffft. Doesn't even flinch. > > ruby < rng1 = ("a".."g") > rng1.each { |char| > if char == "d" > rng1.end[0] = "j" > end > puts char > } > rng2 = ("a".."j") > rng2.each { |char| > if char == "g" > rng2.end[0] = "d" > end > puts char > } > END > > Outputs: > > a > b > c > d > e > f > g > a > b > c > d > e > f > g > h > i > j > > > Of course, I have absolutely NO idea at all why, and don't particularly feel > like reading Ruby core source. > > David Vallner You're right; modifying #end is okay. Not documented, though. Also note that modifying #begin can break a loop. Whether or not this is counterintuitive depends on the person, I guess. g@crash:~$ irb irb(main):001:0> r = 'a'..'z' => "a".."z" irb(main):002:0> r.each{|s| s << '!'; puts s} a! => "a!".."z" This is another face of Dirk/Tony's concern. Perhaps the first element should be cloned for symmetry and safety. But how: #dup, #clone, something else...? You'd also be adding a new requirement that non-immediate range elements must be copyable. Hmmm...