From: Jacob Fugal Date: 2005-10-08T07:21:11+09:00 Subject: Re: select! not present but reject! is On 10/7/05, Mark Hubbart wrote: > On 10/7/05, Jacob Fugal wrote: > > I just fail to see why select should lose it's complementary > > relationship with reject when a bang is added. I suggest we retain > > that relationship and let select! and reject! remain complementary. > > With select and reject we have the following tautology[1]: > > > > def test(ary) > > selected = ary.select { |e| yield e } > > rejected = ary.reject { |e| yield e } > > rebuilt = selected + rejected > > (rebuilt - ary).empty? and (ary - rebuilt).empty? > > end > > > > I propose select! and reject! should have a similar tautology: > > > > def test(ary) > > selected = ary.dup.select! { |e| yield e } > > rejected = ary.dup.reject! { |e| yield e } > > rebuilt = selected + rejected > > (rebuilt - ary).empty? and (ary - rebuilt).empty? > > end > > The english words "select" and "reject" are not opposites. "reject" > and "keep" might be, as someone else suggested. Funny thing is, it was me that suggested 'keep!'. :) But my argument isn't that "select" and "reject" are necessarily opposites in English, but that the *existing* non-bang versions of "select" and "reject" in Ruby *are*. > Going back, say you have a box of apples, some of which are shiny, the > rest of which are dull. You don't want the dull ones. If you say: > > apple_box.reject! {|apple| apple.dull?} > > ...it sounds like you want to reject, or throw out, any dull apples, > leaving only the shiny ones. The opposite would be: > > apple_box.keep! {|apple| apple.shiny?} > > ...because you want to keep only the shiny ones. "keep" implies that > the rest are not kept, and are thrown out. > > On the other hand, if you said: > > apple_box.select! {|apple| apple.shiny?} > > It implies that you want to keep both; you remove the selected ones > from the box, and leave the unselected ones behind. The English usage of "select" could imply that, and I think that's what bothers David as well. But, again, my goal isn't consistency with English (although some of my previous posts in this thread may have appeared that way), but rather consistency within Ruby. "select" and "reject" are already direct opposites, so in my mind "select!" and "reject!" should also be direct opposites. > Note that your tautology (as written) for select!/reject! works for > this version also. "select!" would return an array of the values > removed from the apple_box. Yes, but this is actually incidental and buggy. I'm of the camp which prefers any bang method should return either self (for chaining) or nil. I wouldn't want select!/reject! to return either the selected or rejected elements. Rather, my example should have been: def test( ary ) (selected = ary.dup).select! { |e| yield e } (rejected = ary.dup).reject! { |e| yield e } rebuilt = selected + rejected (rebuilt - ary).empty? and (ary - rebuilt).empty? end Under David's interpretation of "select!", this function would rarely return true, whereas I would expect it to always return true. > Also, I'm not really advocating any action here. I'm just suggesting > that it would be a little weird for "select!" to be the exact opposite > of "reject!", since the Ruby definitions wouldn't stand up to the > English ones. I'll concede that, but IMNSHO consistency between the non-bang and bang versions seems more important. Jacob Fugal