/*
* call-seq:
* mod <= other => true, false, or nil
*
* Returns true if <i>mod</i> is a subclass of <i>other</i> or
* is the same as <i>other</i>. Returns
* <code>nil</code> if there's no relationship between the two.
* (Think of the relationship in terms of the class definition:
* "class A<B" implies "A<B").
*
*/
VALUE
rb_class_inherited_p(mod, arg)
VALUE mod, arg;
{
VALUE start = mod;
if (mod == arg) return Qtrue;
switch (TYPE(arg)) {
case T_MODULE:
case T_CLASS:
break;
default:
rb_raise(rb_eTypeError, "compared with non class/module");
}
if (FL_TEST(mod, FL_SINGLETON)) {
if (RCLASS(mod)->m_tbl == RCLASS(arg)->m_tbl)
return Qtrue;
mod = RBASIC(mod)->klass;
}
while (mod) {
if (RCLASS(mod)->m_tbl == RCLASS(arg)->m_tbl)
return Qtrue;
mod = RCLASS(mod)->super;
}
/* not mod < arg; check if mod > arg */
while (arg) {
if (RCLASS(arg)->m_tbl == RCLASS(start)->m_tbl)
return Qfalse;
arg = RCLASS(arg)->super;
}
return Qnil;
}