* class.c (method_entry_i, class_instance_method_list,
rb_obj_singleton_methods): should not include methods of superclasses if recur is false. [ruby-dev:48854] [Bug #10826] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49493 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
a44f7a3ee6
commit
dc3ea52e1c
@ -1,3 +1,9 @@
|
|||||||
|
Wed Feb 4 15:34:25 2015 Shugo Maeda <shugo@ruby-lang.org>
|
||||||
|
|
||||||
|
* class.c (method_entry_i, class_instance_method_list,
|
||||||
|
rb_obj_singleton_methods): should not include methods of
|
||||||
|
superclasses if recur is false. [ruby-dev:48854] [Bug #10826]
|
||||||
|
|
||||||
Wed Feb 4 16:32:40 2015 Matt Hoyle <matt@deployable.co>
|
Wed Feb 4 16:32:40 2015 Matt Hoyle <matt@deployable.co>
|
||||||
|
|
||||||
* ext/bigdecimal/bigdecimal.c (VpSetPTR): fix a typo, 'expoennt'
|
* ext/bigdecimal/bigdecimal.c (VpSetPTR): fix a typo, 'expoennt'
|
||||||
|
38
class.c
38
class.c
@ -1125,25 +1125,32 @@ ins_methods_pub_i(st_data_t name, st_data_t type, st_data_t ary)
|
|||||||
return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PUBLIC);
|
return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PUBLIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct method_entry_arg {
|
||||||
|
st_table *list;
|
||||||
|
int recur;
|
||||||
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
method_entry_i(st_data_t key, st_data_t value, st_data_t data)
|
method_entry_i(st_data_t key, st_data_t value, st_data_t data)
|
||||||
{
|
{
|
||||||
const rb_method_entry_t *me = (const rb_method_entry_t *)value;
|
const rb_method_entry_t *me = (const rb_method_entry_t *)value;
|
||||||
st_table *list = (st_table *)data;
|
struct method_entry_arg *arg = (struct method_entry_arg *)data;
|
||||||
long type;
|
long type;
|
||||||
|
|
||||||
if (me && me->def->type == VM_METHOD_TYPE_REFINED) {
|
if (me && me->def->type == VM_METHOD_TYPE_REFINED) {
|
||||||
|
VALUE klass = me->klass;
|
||||||
me = rb_resolve_refined_method(Qnil, me, NULL);
|
me = rb_resolve_refined_method(Qnil, me, NULL);
|
||||||
if (!me) return ST_CONTINUE;
|
if (!me) return ST_CONTINUE;
|
||||||
|
if (!arg->recur && me->klass != klass) return ST_CONTINUE;
|
||||||
}
|
}
|
||||||
if (!st_lookup(list, key, 0)) {
|
if (!st_lookup(arg->list, key, 0)) {
|
||||||
if (UNDEFINED_METHOD_ENTRY_P(me)) {
|
if (UNDEFINED_METHOD_ENTRY_P(me)) {
|
||||||
type = -1; /* none */
|
type = -1; /* none */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
type = VISI(me->flag);
|
type = VISI(me->flag);
|
||||||
}
|
}
|
||||||
st_add_direct(list, key, type);
|
st_add_direct(arg->list, key, type);
|
||||||
}
|
}
|
||||||
return ST_CONTINUE;
|
return ST_CONTINUE;
|
||||||
}
|
}
|
||||||
@ -1153,7 +1160,7 @@ class_instance_method_list(int argc, const VALUE *argv, VALUE mod, int obj, int
|
|||||||
{
|
{
|
||||||
VALUE ary;
|
VALUE ary;
|
||||||
int recur, prepended = 0;
|
int recur, prepended = 0;
|
||||||
st_table *list;
|
struct method_entry_arg me_arg;
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
recur = TRUE;
|
recur = TRUE;
|
||||||
@ -1169,16 +1176,17 @@ class_instance_method_list(int argc, const VALUE *argv, VALUE mod, int obj, int
|
|||||||
prepended = 1;
|
prepended = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
list = st_init_numtable();
|
me_arg.list = st_init_numtable();
|
||||||
|
me_arg.recur = recur;
|
||||||
for (; mod; mod = RCLASS_SUPER(mod)) {
|
for (; mod; mod = RCLASS_SUPER(mod)) {
|
||||||
if (RCLASS_M_TBL(mod)) st_foreach(RCLASS_M_TBL(mod), method_entry_i, (st_data_t)list);
|
if (RCLASS_M_TBL(mod)) st_foreach(RCLASS_M_TBL(mod), method_entry_i, (st_data_t)&me_arg);
|
||||||
if (BUILTIN_TYPE(mod) == T_ICLASS && !prepended) continue;
|
if (BUILTIN_TYPE(mod) == T_ICLASS && !prepended) continue;
|
||||||
if (obj && FL_TEST(mod, FL_SINGLETON)) continue;
|
if (obj && FL_TEST(mod, FL_SINGLETON)) continue;
|
||||||
if (!recur) break;
|
if (!recur) break;
|
||||||
}
|
}
|
||||||
ary = rb_ary_new();
|
ary = rb_ary_new();
|
||||||
st_foreach(list, func, ary);
|
st_foreach(me_arg.list, func, ary);
|
||||||
st_free_table(list);
|
st_free_table(me_arg.list);
|
||||||
|
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
@ -1391,7 +1399,8 @@ VALUE
|
|||||||
rb_obj_singleton_methods(int argc, const VALUE *argv, VALUE obj)
|
rb_obj_singleton_methods(int argc, const VALUE *argv, VALUE obj)
|
||||||
{
|
{
|
||||||
VALUE recur, ary, klass, origin;
|
VALUE recur, ary, klass, origin;
|
||||||
st_table *list, *mtbl;
|
struct method_entry_arg me_arg;
|
||||||
|
st_table *mtbl;
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
recur = Qtrue;
|
recur = Qtrue;
|
||||||
@ -1401,22 +1410,23 @@ rb_obj_singleton_methods(int argc, const VALUE *argv, VALUE obj)
|
|||||||
}
|
}
|
||||||
klass = CLASS_OF(obj);
|
klass = CLASS_OF(obj);
|
||||||
origin = RCLASS_ORIGIN(klass);
|
origin = RCLASS_ORIGIN(klass);
|
||||||
list = st_init_numtable();
|
me_arg.list = st_init_numtable();
|
||||||
|
me_arg.recur = recur;
|
||||||
if (klass && FL_TEST(klass, FL_SINGLETON)) {
|
if (klass && FL_TEST(klass, FL_SINGLETON)) {
|
||||||
if ((mtbl = RCLASS_M_TBL(origin)) != 0)
|
if ((mtbl = RCLASS_M_TBL(origin)) != 0)
|
||||||
st_foreach(mtbl, method_entry_i, (st_data_t)list);
|
st_foreach(mtbl, method_entry_i, (st_data_t)&me_arg);
|
||||||
klass = RCLASS_SUPER(klass);
|
klass = RCLASS_SUPER(klass);
|
||||||
}
|
}
|
||||||
if (RTEST(recur)) {
|
if (RTEST(recur)) {
|
||||||
while (klass && (FL_TEST(klass, FL_SINGLETON) || RB_TYPE_P(klass, T_ICLASS))) {
|
while (klass && (FL_TEST(klass, FL_SINGLETON) || RB_TYPE_P(klass, T_ICLASS))) {
|
||||||
if (klass != origin && (mtbl = RCLASS_M_TBL(klass)) != 0)
|
if (klass != origin && (mtbl = RCLASS_M_TBL(klass)) != 0)
|
||||||
st_foreach(mtbl, method_entry_i, (st_data_t)list);
|
st_foreach(mtbl, method_entry_i, (st_data_t)&me_arg);
|
||||||
klass = RCLASS_SUPER(klass);
|
klass = RCLASS_SUPER(klass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ary = rb_ary_new();
|
ary = rb_ary_new();
|
||||||
st_foreach(list, ins_methods_i, ary);
|
st_foreach(me_arg.list, ins_methods_i, ary);
|
||||||
st_free_table(list);
|
st_free_table(me_arg.list);
|
||||||
|
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
|
@ -1362,6 +1362,31 @@ class TestRefinement < Test::Unit::TestCase
|
|||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
module NotIncludeSuperclassMethod
|
||||||
|
class X
|
||||||
|
def foo
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Y < X
|
||||||
|
end
|
||||||
|
|
||||||
|
module Bar
|
||||||
|
refine Y do
|
||||||
|
def foo
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_instance_methods_not_include_superclass_method
|
||||||
|
bug10826 = '[ruby-dev:48854] [Bug #10826]'
|
||||||
|
assert_not_include(NotIncludeSuperclassMethod::Y.instance_methods(false),
|
||||||
|
:foo, bug10826)
|
||||||
|
assert_include(NotIncludeSuperclassMethod::Y.instance_methods(true),
|
||||||
|
:foo, bug10826)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def eval_using(mod, s)
|
def eval_using(mod, s)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user