Array#uniq!

Anyone know why Array#uniq returns an array in every case and
Array#uniq! returns nil if nothing is removed? I’d prefer it to return
the array in every case but I’m sure my attempt to reduce one line of
code (no flames on this plz, it’s just fun) are superseded by some
really important concept I don’t know about. :slight_smile:

Michael

The exclamation point usually means that the array is modified in place,
and thus its return value should not be the uniquified array, but rather
something that can tell you if the array elements were unique, and if
not, what elements were responsible.

That way, you can say something like:

a = some stuff

if b = a.uniq!
puts “array was unique.”
else
puts "array was not unique: multiple instances of " + b.join(', ')
end

That is a whole lot better than having to store a copy of the old array
and then do set subtraction with the uniquified array.

-Kurt

···

On Wed, Aug 27, 2003 at 01:48:14AM +0900, mgarriss wrote:

Anyone know why Array#uniq returns an array in every case and
Array#uniq! returns nil if nothing is removed? I’d prefer it to return
the array in every case but I’m sure my attempt to reduce one line of
code (no flames on this plz, it’s just fun) are superseded by some
really important concept I don’t know about. :slight_smile:

Michael

======= End of Original Message =======<

Anyone know why Array#uniq returns an array in every case and
Array#uniq! returns nil if nothing is removed?

Well, you can look at the thread

   http://www.ruby-talk.org/3758 (there is a thread frame)
   [ruby-talk:03758] Array.uniq! returning nil

  with [ruby-talk:03785] http://www.ruby-talk.org/3785

Guy Decoux

Array#uniq! modifies the receiver, you should not rely on the objects
that are returned. However, if the receiver was really changed, uniq!
returns a true (not false and not nil) value. You can code something
like that:

if ary.uniq!
puts "Made it unique: " + ary.inspect
else
puts "Was already unique: " + ary.inspect
end

I wonder if it would be better to return an instance of TrueClass
because I think a lot of people will code mistakes like that:

new_ary = ary.uniq!
new_ary.each do |x|
# …
end

Perhaps this works most of the time, but it’s just waiting for a
disaster to happen.

···

On 2003-08-27 01:48:14 +0900, mgarriss wrote:

Anyone know why Array#uniq returns an array in every case and
Array#uniq! returns nil if nothing is removed?


Will the virus impact my Macintosh if I am using a non-Microsoft e-mail
program, such as Eudora? If you are using an Macintosh e-mail program that
is not from Microsoft, we recommend checking with that particular company.
But most likely other e-mail programs like Eudora are not designed to
enable virus replication.
http://www.microsoft.com/mac/products/office/2001/virus_alert.asp

Kurt M. Dresner wrote:

The exclamation point usually means that the array is modified in place,
and thus its return value should not be the uniquified array, but rather
something that can tell you if the array elements were unique, and if
not, what elements were responsible.

That way, you can say something like:

a = some stuff

if b = a.uniq!
puts “array was unique.”
else
puts "array was not unique: multiple instances of " + b.join(', ')
end

That is a whole lot better than having to store a copy of the old array
and then do set subtraction with the uniquified array.

-Kurt

I’ll just use ‘(a = a.uniq).some_method’ to keep it in place. In my
case the array is tiny and this is done very rarely so no performance hit.

This doesn’t work: Array#uniq! just returns the now changed receiver.

···

On 2003-08-27 02:00:55 +0900, Kurt M. Dresner wrote:

That is a whole lot better than having to store a copy of the old array
and then do set subtraction with the uniquified array.


Many companies that have made themselves dependent on IBM-equipment (and
in doing so have sold their soul to the devil) will collapse under the
sheer weight of the unmastered complexity of their data processing
systems.
– Edsger Dijkstra, How do we tell truths that might hurt?

Florian Frank wrote:

Anyone know why Array#uniq returns an array in every case and
Array#uniq! returns nil if nothing is removed?

Array#uniq! modifies the receiver, you should not rely on the objects
that are returned. However, if the receiver was really changed, uniq!
returns a true (not false and not nil) value. You can code something
like that:

if ary.uniq!
puts "Made it unique: " + ary.inspect
else
puts "Was already unique: " + ary.inspect
end

I wonder if it would be better to return an instance of TrueClass
because I think a lot of people will code mistakes like that:

new_ary = ary.uniq!
new_ary.each do |x|

end

Perhaps this works most of the time, but it’s just waiting for a
disaster to happen.

Just such a disaster prompted my original post. It turned out that in
almost all cases there where duplicates in my array. Then came that one
case where there where not. “Hmmm, why does my program that had been
working report something about no on NilClass? I haven’t changed
anything.” The moral of this story is that I should read the docs on
any method I’ve never used but want to use. :wink:

Michael

···

On 2003-08-27 01:48:14 +0900, mgarriss wrote: