Array#uniq!

There are a number of “bang” methods that do this. If I recall
correctly, matz has said they do this so that you CAN’T chain the
methods.

I thought Matz had said it was because there’d be no equally
efficient way to determine the did-anything-change test, otherwise.

Interesting.

Seems that you’ve traded the need to pre-check with the inability to
chain.

···

Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com

I’ve thought about this for awhile and had on my to do list a catalog
of how container objects respond to various methods that are meant to
change the contents of the container.

The inspiration for these thoughts is the implementation in the set
class, where the default is to return the object whether or not the
method modified the contents of the container. If one wants to know
whether the modification occurred, one calls the method with a question
mark appended.

For example Set#add(object) will add the object if it does not exist in
the set and return the modified set. If the object is in the set, it is
not added and the set is returned. Set#add?(object) will add the object
if not already present and return ‘nil’ if the object is already
present.

The array class provides similar functionality for the nil case for at
least one method (Array#delete), but uses a block rather than a
question mark. Array#delete(object) returns nil if the object is not in
the array and returns the deleted object if it is in the array.
However, if a block is used, the block is executed if the object is not
in the array. For example,

a = Array.new(1, 2, 3, 4, 5)
a.delete(6) { a }

returns the array [1, 2, 3, 4, 5].

I don’t know whether or how these method returns should be changed, but
I do think the topic is worth further thought and discussion.

Regards,

Mark

Mark Wilson wrote:

The inspiration for these thoughts is the implementation in the set
class, where the default is to return the object whether or not the
method modified the contents of the container. If one wants to know
whether the modification occurred, one calls the method with a question
mark appended.

For example Set#add(object) will add the object if it does not exist in
the set and return the modified set. If the object is in the set, it is
not added and the set is returned. Set#add?(object) will add the object
if not already present and return ‘nil’ if the object is already present.

[snippage]

I don’t know whether or how these method returns should be changed, but
I do think the topic is worth further thought and discussion.

I’ve thought about these issues, too… I usd to be bitten frequently
by the nil-return bug^H^H^H feature. But then I just fell out of the
habit of chaining certain methods.

I never use the fact that they return nil.

On the other hand, the add? method seems a little unintuitive to me…
in principle I like it OK, but it is a little unusual that a ?-method
changes its receiver. I don’t know anywhere else that happens.

I once suggested as a joke four other suffixes: !!, ??, ?!, and !?.
But the last of these is looking slightly more serious and less of a
joke now. But no, I’m not seriously proposing it. Who would use a
language feature like !? on a method name?

Cheers,
Hal

Hmmm…what if they could take an argument that allowed the user to
explicitly return the receiver? :

arr.sort!(1).uniq!(1).each { |e| ... }

Kinda busy…what about

a = Array.new
a.bang_returns_receiver = true

or

a = Array.new
a.bang_returns_nil_if_receiver_not_modified = true

making the return of the receiver the default (better method names would
be good :->).

Ultimately, I guess I still don’t see how modifying the receiver is more
dangerous than making a copy unless somehow

a.sort!.uniq!.each { |e| ... }

would give you a different list of elements than

a.sort.uniq.each { |e| ... }

OTOH, I haven’t run into a case where making copies has given me any
problems.

Jim

···

On Wed, 27 Aug 2003 05:52:06 +0900 Hal Fulton hal9000@hypermetrics.com wrote:

I’ve thought about these issues, too… I usd to be bitten frequently
by the nil-return bug^H^H^H feature. But then I just fell out of the
habit of chaining certain methods.

I never use the fact that they return nil.