summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-04-14 07:59:42 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-04-14 07:59:42 +0000
commitc2a7a091cc8cf9352a6df05591788b6a8c0134ad (patch)
tree301549c2a630340278f3260bd0cf72ec7042fcc6
parentc3b82fc66e7e983513b059ca88ac7fe749aecb5b (diff)
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
-rw-r--r--internal.h1
-rw-r--r--object.c32
2 files changed, 22 insertions, 11 deletions
diff --git a/internal.h b/internal.h
index fc17da98d5..36424437f9 100644
--- a/internal.h
+++ b/internal.h
@@ -715,6 +715,7 @@ rb_float_new_inline(double d)
/* object.c */
VALUE rb_obj_equal(VALUE obj1, VALUE obj2);
+VALUE rb_class_search_ancestor(VALUE klass, VALUE super);
struct RBasicRaw {
VALUE flags;
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;
}