You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A class that extends BasicObject and implements ==, eql?, and hash fails to match against others in Array#uniq.
As a result, [a, b].uniq == [a, b], even if:
a == b
a.eql? b
and a.hash == b.hash
Test case follows:
## Make sure that Array#uniq works
require 'test/unit'
# A BasicObject that can be used as a Hash key
class BasicWrap < BasicObject
attr_reader :x
def initialize(x)
@x = x
end
def ==(rhs)
@x == rhs.x
end
alias_method :eql?, :==
def hash
@x.hash
end
end
class TestUniq < Test::Unit::TestCase
def test_uniq_with_fixnum
a = [3, 2, 1, 4, 1, 2, 3]
assert(a.uniq == [3, 2, 1, 4])
end
def test_uniq_with_struct
s = Struct.new(:x)
a = [s.new(3), s.new(2), s.new(1), s.new(4), s.new(1), s.new(2), s.new(3)]
assert(a.uniq == [s.new(3), s.new(2), s.new(1), s.new(4)])
end
def test_uniq_with_basic
s = BasicWrap
a = [s.new(3), s.new(2), s.new(1), s.new(4), s.new(1), s.new(2), s.new(3)]
assert(a.uniq == [s.new(3), s.new(2), s.new(1), s.new(4)])
end
end
Ok, the basic issue is that we don't override Object#hashCode or #equals on RubyBasicObject, so they never attempt to dispatch back into Ruby. Since our Hash impl uses those methods, this is obviously not right.
I have a patch that moves #hashCode and #equals up from RubyObject and introduces "checked" calling of them, but it's a little scary. We may want to keep the RubyObject versions around.
A class that extends BasicObject and implements ==, eql?, and hash fails to match against others in Array#uniq.
As a result,
[a, b].uniq == [a, b]
, even if:a == b
a.eql? b
a.hash == b.hash
Test case follows:
jruby results:
MRI results:
The text was updated successfully, but these errors were encountered: