/* * 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; }