On 10/7/05, David A. Black <dblack / wobblini.net> wrote:
> Hi --
>
> On Fri, 7 Oct 2005, Rob Rypka wrote:
>
> > By your logic, reject! is also wrong.  johnny.reject! should reject
> > the items, and then give them to you, which is the same as your
> > select!.  That's not what it does, though...
>
> See my previous post -- it shows the difference (between reject! and
> my sense of select!), which is in the return values.

And that's where it confuses me. select and reject are complements, so
why couldn't it be expected that select! and reject! be complements as
well? Changing the semantics of select from converse of reject without
bang to synonym for reject (differing only in return value) with bang
makes no sense at all to me.

> > In all honesty, I don't care what it's called, but reject! feels like
> > it should have an opposite.
>
> Similarly (in case it's unclear), I have no underlying objection to
> the idea of a reject! opposite :-)

At least we're all agreed on that. :)

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

Jacob Fugal