Project

General

Profile

Feature #14916 » array_eqq.patch

Support `to_ary` - osyo (manga osyo), 08/09/2018 02:22 AM

View differences:

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)) {
if (rb_respond_to(ary2, idTo_ary)) {
return rb_ary_eqq(ary1, to_ary(ary2));
}
else {
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])
o3 = Object.new
def o3.to_ary
[1]
end
assert_operator([Integer], :===, o3)
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
(3-3/3)