Feature #14916 » array_eqq.patch
array.c | ||
---|---|---|
return rb_exec_recursive_paired(recursive_eql, ary1, ary2, ary2);
|
||
}
|
||
static VALUE
|
||
recursive_eqq(VALUE ary1, VALUE ary2, int recur)
|
||
{
|
||
long i, len1;
|
||
const VALUE *p1, *p2;
|
||
if (recur) return Qtrue; /* Subtle! */
|
||
p1 = RARRAY_CONST_PTR(ary1);
|
||
p2 = RARRAY_CONST_PTR(ary2);
|
||
len1 = RARRAY_LEN(ary1);
|
||
for (i = 0; i < len1; i++) {
|
||
if (*p1 != *p2) {
|
||
if (rb_funcall(*p1, idEqq, 1, *p2) || rb_equal(*p1, *p2)) {
|
||
len1 = RARRAY_LEN(ary1);
|
||
if (len1 != RARRAY_LEN(ary2))
|
||
return Qfalse;
|
||
if (len1 < i)
|
||
return Qtrue;
|
||
p1 = RARRAY_CONST_PTR(ary1) + i;
|
||
p2 = RARRAY_CONST_PTR(ary2) + i;
|
||
}
|
||
else {
|
||
return Qfalse;
|
||
}
|
||
}
|
||
p1++;
|
||
p2++;
|
||
}
|
||
return Qtrue;
|
||
}
|
||
/*
|
||
* call-seq:
|
||
* ary == other_ary -> bool
|
||
*
|
||
* Equality(===) --- Two arrays are equal if they contain the same number of
|
||
* elements and if each element is equal to (according to Object#==) the
|
||
* corresponding element in +other_ary+.
|
||
*
|
||
* [ String, /\w/ ] === [ "a", "c", 7 ] # => false
|
||
* [ String, /\w/, (1..10) ] === [ "a", "c", 7 ] # => true
|
||
* [ String, /\w/, (1..10) ] === [ "a", "!", 42 ] # => false
|
||
*
|
||
*/
|
||
static VALUE
|
||
rb_ary_eqq(VALUE ary1, VALUE ary2)
|
||
{
|
||
if (ary1 == ary2) return Qtrue;
|
||
if (!RB_TYPE_P(ary2, T_ARRAY)) return Qfalse;
|
||
if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
|
||
if (RARRAY_CONST_PTR(ary1) == RARRAY_CONST_PTR(ary2)) return Qtrue;
|
||
return rb_exec_recursive_paired(recursive_eqq, ary1, ary2, ary2);
|
||
}
|
||
/*
|
||
* call-seq:
|
||
* ary.hash -> integer
|
||
... | ... | |
rb_define_method(rb_cArray, "to_ary", rb_ary_to_ary_m, 0);
|
||
rb_define_method(rb_cArray, "==", rb_ary_equal, 1);
|
||
rb_define_method(rb_cArray, "===", rb_ary_eqq, 1);
|
||
rb_define_method(rb_cArray, "eql?", rb_ary_eql, 1);
|
||
rb_define_method(rb_cArray, "hash", rb_ary_hash, 0);
|
||
test/ruby/test_array.rb | ||
---|---|---|
assert_not_equal([0, 1, 2], [0, 1, 3])
|
||
end
|
||
def test_eqq
|
||
o = Object.new
|
||
def o.==(x); false; end
|
||
def o.===(x); true; end
|
||
assert_operator([o, o, o], :===, [0, 1, 2])
|
||
assert_operator([0, 1, 2], :===, [0, 1, 2])
|
||
assert_operator([], :===, [])
|
||
a = [1, 2, 3]
|
||
a[0] = a
|
||
assert_operator(a, :===, a)
|
||
b = [1, 2, 3]
|
||
b[0] = b
|
||
assert_operator(a, :===, b)
|
||
o2 = Object.new
|
||
def o2.==(x); true; end
|
||
def o2.===(x); false; end
|
||
assert_operator([o2], :===, [1])
|
||
assert_not_operator([o, o], :===, [0, 1, 2])
|
||
assert_not_operator([o, o, o], :===, [0, 1])
|
||
assert_not_operator([0, 1, 2], :===, [o, o, o])
|
||
assert_not_operator([1], :===, [])
|
||
assert_not_operator([], :===, [1])
|
||
assert_not_operator([0, 1, 2], :===, 42)
|
||
assert_not_operator([], :===, 42)
|
||
c = [1, 3, 2]
|
||
c[0] = c
|
||
assert_not_operator(a, :===, c)
|
||
end
|
||
A = Array.new(3, &:to_s)
|
||
B = A.dup
|
||