Bug #9340

Document order related behavior in Array#uniq

Added by Andrew Grimm 4 months ago. Updated 2 months ago.

[ruby-core:59457]
Status:Closed
Priority:Normal
Assignee:Yui NARUSE
Category:-
Target version:next minor
ruby -v:ruby 2.1.0p0 (2013-12-25 revision 44422) [x86_64-linux] Backport:1.9.3: DONTNEED, 2.0.0: DONTNEED, 2.1: DONE

Description

The behavior of Array#uniq without a block in Ruby 2.1.0 is inconsistent with the behavior of Array#uniq in Ruby 2.0.0, and with the behavior of Array#uniq with a block in Ruby 2.1.0.

Array#uniq without a block in Ruby 2.1.0 returns the last item that is duplicate, while everything else returns the first item that is duplicate.

class Person
  attr_reader :name

  def initialize(id, name)
    # @id is not used by hash or eql?
    @id = id
    @name = name
  end

  def hash
    [@name].hash
  end

  def eql?(other)
    [@name].eql?([other.name])
  end
end

p1 = Person.new(1, "Bob")
p2 = Person.new(2, "Bob")
p3 = Person.new(3, "Bob")

arr = [p1, p2, p3]
arr2 = arr.uniq {|p| p}
arr3 = arr.uniq
p RUBY_VERSION
p arr2
p arr3

Gives

"2.1.0"
[#<Person:0x007f1b47ef7720 @id=1, @name="Bob">]
[#<Person:0x007f1b47ef7680 @id=3, @name="Bob">]

"2.0.0"
[#<Person:0x007ffa9203bf30 @id=1, @name="Bob">]
[#<Person:0x007ffa9203bf30 @id=1, @name="Bob">]

This behavior does not contradict what RDoc says about Array#uniq, so people ought not to rely upon which duplicate item is chosen. However, at the very least, different behavior for Array#uniq with and without a block would be somewhat unexpected.

Should the documentation explicitly warn that uniq is not guaranteed to choose the first duplicate item?

As Ruby 2.1.0 has already been released, I assume it is too late to change the behavior of Array#uniq .

Associated revisions

Revision 44512
Added by Aman Gupta 4 months ago

array.c: return first unique element in Array#uniq

  • array.c (aryaddhash): Fix consistency issue between Array#uniq and Array#uniq! [Bug #9340]
  • test/ruby/test_array.rb (class TestArray): regression test for above.

History

#1 Updated by Felix Bünemann 4 months ago

Yes, this should be fixed. I just linked a few failing specs in sass to this issue: https://github.com/nex3/sass/issues/1064

#2 Updated by Aman Gupta 4 months ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r44512.
Andrew, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


array.c: return first unique element in Array#uniq

  • array.c (aryaddhash): Fix consistency issue between Array#uniq and Array#uniq! [Bug #9340]
  • test/ruby/test_array.rb (class TestArray): regression test for above.

#3 Updated by Aman Gupta 4 months ago

  • Assignee set to Yui NARUSE
  • Target version set to next minor
  • % Done changed from 100 to 0
  • Backport changed from 1.9.3: UNKNOWN, 2.0.0: UNKNOWN, 2.1: UNKNOWN to 1.9.3: UNKNOWN, 2.0.0: UNKNOWN, 2.1: REQUIRED

#4 Updated by Usaku NAKAMURA 3 months ago

  • Backport changed from 1.9.3: UNKNOWN, 2.0.0: UNKNOWN, 2.1: REQUIRED to 1.9.3: DONTNEED, 2.0.0: DONTNEED, 2.1: REQUIRED

#5 Updated by Yui NARUSE 2 months ago

  • Backport changed from 1.9.3: DONTNEED, 2.0.0: DONTNEED, 2.1: REQUIRED to 1.9.3: DONTNEED, 2.0.0: DONTNEED, 2.1: DONE

Also available in: Atom PDF