equal?, == and eql?, ===,

1.BasicObject中定义了 == 和equal?这两个方法,两个方法等价,用来比较两个对象是否是同一个对象,是的话结果就为true。

   既然两者相同,为何要定义两个呢?只是为了再命名一个别名吗?官方解释是==用于给子类重载,equal?永不重载。

结论:①.== 等价于 equal?

        ②.== 用于给子类重载,equal?永不重载

// BasicObject#equal?
               VALUE
rb_obj_equal(VALUE obj1, VALUE obj2)
{
    if (obj1 == obj2) return Qtrue;
    return Qfalse;
}
    
// BasicObject#==
               VALUE
rb_obj_equal(VALUE obj1, VALUE obj2)
{
    if (obj1 == obj2) return Qtrue;
    return Qfalse;
}

2.Object中定义了 === 和eql?这两个方法,这两个方法都等价于==。

   这样在Object层次来看,四个方法完全等价。应该有其特殊的用法,就像equal?一样。

结论:③.==、 equal?、===、eql?都等价

        ④.=== 用于给子类重载,为了在case语句中提供重要的语义。

        ⑤.eql? 用于给子类重载,比较hash key是否相同,测试hash members的相等性。

// Object#===
               VALUE
rb_equal(VALUE obj1, VALUE obj2)
{
    VALUE result;

    if (obj1 == obj2) return Qtrue;
    result = rb_funcall(obj1, id_eq, 1, obj2);
    if (RTEST(result)) return Qtrue;
    return Qfalse;
}
// Object#==;Object#equal?;Object#eql?
               VALUE
rb_obj_equal(VALUE obj1, VALUE obj2)
{
    if (obj1 == obj2) return Qtrue;
    return Qfalse;
}

3.String中重载了==、===、eql?三个方法。

结论:⑥.eql?比较两个字符串的长度和内容。(同一个对象=>相等,不同类=>不等,都是String=>内容比较)

        ⑦.==、=== 等价,用于和另一个对象比较字符串

// String#==
               VALUE
rb_str_equal(VALUE str1, VALUE str2)
{
    if (str1 == str2) return Qtrue;
    if (!RB_TYPE_P(str2, T_STRING)) {
        if (!rb_respond_to(str2, rb_intern("to_str"))) {
            return Qfalse;
        }
        return rb_equal(str2, str1);
    }
    return str_eql(str1, str2);
}
// String#===
               VALUE
rb_str_equal(VALUE str1, VALUE str2)
{
    if (str1 == str2) return Qtrue;
    if (!RB_TYPE_P(str2, T_STRING)) {
        if (!rb_respond_to(str2, rb_intern("to_str"))) {
            return Qfalse;
        }
        return rb_equal(str2, str1);
    }
    return str_eql(str1, str2);
}
// String#eql?
               static VALUE
rb_str_eql(VALUE str1, VALUE str2)
{
    if (str1 == str2) return Qtrue;
    if (!RB_TYPE_P(str2, T_STRING)) return Qfalse;
    return str_eql(str1, str2);
}

 4.Numeric中重载了eql?方法。

结论:⑧.类型和值都相等时,eql?才相等。

// Numeric#eql?
               static VALUE
num_eql(VALUE x, VALUE y)
{
    if (TYPE(x) != TYPE(y)) return Qfalse;

    return rb_equal(x, y);
}
   
1 == 1.0          #=> true
1.eql?(1.0)       #=> false
(1.0).eql?(1.0)   #=> true

1.What's the difference between equal?, eql?, ===, and ==?

2.`String#===` documentation example

    

原文地址:https://www.cnblogs.com/niaomingjian/p/5976736.html