Project

General

Profile

Feature #14916 » array_eqq.patch

`===` で比較するだけ - osyo (manga osyo), 07/17/2018 04:54 PM

View differences:

array.c
3957 3957
    return rb_exec_recursive_paired(recursive_eql, ary1, ary2, ary2);
3958 3958
}
3959 3959

  
3960
static VALUE
3961
recursive_eqq(VALUE ary1, VALUE ary2, int recur)
3962
{
3963
    long i, len1;
3964
    const VALUE *p1, *p2;
3965

  
3966
    if (recur) return Qtrue; /* Subtle! */
3967

  
3968
    p1 = RARRAY_CONST_PTR(ary1);
3969
    p2 = RARRAY_CONST_PTR(ary2);
3970
    len1 = RARRAY_LEN(ary1);
3971

  
3972
    for (i = 0; i < len1; i++) {
3973
	if (*p1 != *p2) {
3974
	    if (rb_funcall(*p1, idEqq, 1, *p2)) {
3975
		len1 = RARRAY_LEN(ary1);
3976
		if (len1 != RARRAY_LEN(ary2))
3977
		    return Qfalse;
3978
		if (len1 < i)
3979
		    return Qtrue;
3980
		p1 = RARRAY_CONST_PTR(ary1) + i;
3981
		p2 = RARRAY_CONST_PTR(ary2) + i;
3982
	    }
3983
	    else {
3984
		return Qfalse;
3985
	    }
3986
	}
3987
	p1++;
3988
	p2++;
3989
    }
3990
    return Qtrue;
3991
}
3992

  
3993
/*
3994
 *  call-seq:
3995
 *     ary == other_ary   ->   bool
3996
 *
3997
 *  Equality(===) --- Two arrays are equal if they contain the same number of
3998
 *  elements and if each element is equal to (according to Object#==) the
3999
 *  corresponding element in +other_ary+.
4000
 *
4001
 *     [ String, /\w/ ]          === [ "a", "c", 7 ]   # => false
4002
 *     [ String, /\w/, (1..10) ] === [ "a", "c", 7 ]   # => true
4003
 *     [ String, /\w/, (1..10) ] === [ "a", "!", 42 ]  # => false
4004
 *
4005
 */
4006

  
4007
static VALUE
4008
rb_ary_eqq(VALUE ary1, VALUE ary2)
4009
{
4010
    if (ary1 == ary2) return Qtrue;
4011
    if (!RB_TYPE_P(ary2, T_ARRAY)) return Qfalse;
4012
    if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
4013
    if (RARRAY_CONST_PTR(ary1) == RARRAY_CONST_PTR(ary2)) return Qtrue;
4014
    return rb_exec_recursive_paired(recursive_eqq, ary1, ary2, ary2);
4015
}
4016

  
3960 4017
/*
3961 4018
 *  call-seq:
3962 4019
 *     ary.hash   -> integer
......
6258 6315
    rb_define_method(rb_cArray, "to_ary", rb_ary_to_ary_m, 0);
6259 6316

  
6260 6317
    rb_define_method(rb_cArray, "==", rb_ary_equal, 1);
6318
    rb_define_method(rb_cArray, "===", rb_ary_eqq, 1);
6261 6319
    rb_define_method(rb_cArray, "eql?", rb_ary_eql, 1);
6262 6320
    rb_define_method(rb_cArray, "hash", rb_ary_hash, 0);
6263 6321

  
test/ruby/test_array.rb
2389 2389
    assert_not_equal([0, 1, 2], [0, 1, 3])
2390 2390
  end
2391 2391

  
2392
  def test_eqq
2393
    o = Object.new
2394
    def o.==(x); false; end
2395
    def o.===(x); true; end
2396
    assert_operator([o, o, o], :===, [0, 1, 2])
2397
    assert_operator([0, 1, 2], :===, [0, 1, 2])
2398
    assert_operator([], :===, [])
2399
    a = [1, 2, 3]
2400
    a[0] = a
2401
    assert_operator(a, :===, a)
2402
    b = [1, 2, 3]
2403
    b[0] = b
2404
    assert_operator(a, :===, b)
2405

  
2406
    assert_not_operator([o, o], :===, [0, 1, 2])
2407
    assert_not_operator([o, o, o], :===, [0, 1])
2408
    assert_not_operator([0, 1, 2], :===, [o, o, o])
2409
    assert_not_operator([1], :===, [])
2410
    assert_not_operator([], :===, [1])
2411
    assert_not_operator([0, 1, 2], :===, 42)
2412
    assert_not_operator([], :===, 42)
2413

  
2414
    c = [1, 3, 2]
2415
    c[0] = c
2416
    assert_not_operator(a, :===, c)
2417
  end
2418

  
2392 2419
  A = Array.new(3, &:to_s)
2393 2420
  B = A.dup
2394 2421