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)) {
|
||
|
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)
|
||
|
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
|
||