From c2a7a091cc8cf9352a6df05591788b6a8c0134ad Mon Sep 17 00:00:00 2001 From: nobu Date: Mon, 14 Apr 2014 07:59:42 +0000 Subject: object.c: rb_class_search_ancestor * object.c (rb_class_search_ancestor): return ancestor class or iclass if inherited. * object.c (rb_obj_is_kind_of, rb_class_inherited_p): share function to search the ancestor. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45584 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- object.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'object.c') diff --git a/object.c b/object.c index 9981978622..e5e0da4d4c 100644 --- a/object.c +++ b/object.c @@ -587,6 +587,8 @@ class_or_module_required(VALUE c) return c; } +static VALUE class_search_ancestor(VALUE cl, VALUE c); + /* * call-seq: * obj.instance_of?(class) -> true or false @@ -647,15 +649,27 @@ rb_obj_is_kind_of(VALUE obj, VALUE c) VALUE cl = CLASS_OF(obj); c = class_or_module_required(c); - c = RCLASS_ORIGIN(c); + return class_search_ancestor(cl, RCLASS_ORIGIN(c)) ? Qtrue : Qfalse; +} + +static VALUE +class_search_ancestor(VALUE cl, VALUE c) +{ while (cl) { if (cl == c || RCLASS_M_TBL_WRAPPER(cl) == RCLASS_M_TBL_WRAPPER(c)) - return Qtrue; + return cl; cl = RCLASS_SUPER(cl); } - return Qfalse; + return 0; } +VALUE +rb_class_search_ancestor(VALUE cl, VALUE c) +{ + cl = class_or_module_required(cl); + c = class_or_module_required(c); + return class_search_ancestor(cl, RCLASS_ORIGIN(c)); +} /* * call-seq: @@ -1554,16 +1568,12 @@ rb_class_inherited_p(VALUE mod, VALUE arg) rb_raise(rb_eTypeError, "compared with non class/module"); } arg = RCLASS_ORIGIN(arg); - while (mod) { - if (RCLASS_M_TBL_WRAPPER(mod) == RCLASS_M_TBL_WRAPPER(arg)) - return Qtrue; - mod = RCLASS_SUPER(mod); + if (class_search_ancestor(mod, arg)) { + return Qtrue; } /* not mod < arg; check if mod > arg */ - while (arg) { - if (RCLASS_M_TBL_WRAPPER(arg) == RCLASS_M_TBL_WRAPPER(start)) - return Qfalse; - arg = RCLASS_SUPER(arg); + if (class_search_ancestor(arg, start)) { + return Qfalse; } return Qnil; } -- cgit v1.2.3