* proc.c (mnew_from_me): achieve the original defined_class from
  prepended iclass, to fix inherited owner.
* proc.c (method_owner): return the defined class, but not the
  class which the method object is created from.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44179 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2013-12-13 15:18:12 +00:00
Родитель 537f327653
Коммит b7c2f5bc93
3 изменённых файлов: 22 добавлений и 5 удалений

Просмотреть файл

@ -1,3 +1,11 @@
Sat Dec 14 00:18:08 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
* proc.c (mnew_from_me): achieve the original defined_class from
prepended iclass, to fix inherited owner.
* proc.c (method_owner): return the defined class, but not the
class which the method object is created from.
Fri Dec 13 22:29:21 2013 Nobuyoshi Nakada <nobu@ruby-lang.org> Fri Dec 13 22:29:21 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
* proc.c (method_owner): return the class where alias is defined, not * proc.c (method_owner): return the class where alias is defined, not

10
proc.c
Просмотреть файл

@ -1168,6 +1168,10 @@ mnew_from_me(rb_method_entry_t *me, VALUE defined_class, VALUE klass,
goto again; goto again;
} }
if (RB_TYPE_P(defined_class, T_ICLASS)) {
defined_class = RBASIC_CLASS(defined_class);
}
klass = defined_class; klass = defined_class;
while (rclass != klass && while (rclass != klass &&
@ -1175,10 +1179,6 @@ mnew_from_me(rb_method_entry_t *me, VALUE defined_class, VALUE klass,
rclass = RCLASS_SUPER(rclass); rclass = RCLASS_SUPER(rclass);
} }
if (RB_TYPE_P(klass, T_ICLASS)) {
klass = RBASIC(klass)->klass;
}
gen_method: gen_method:
method = TypedData_Make_Struct(mclass, struct METHOD, &method_data_type, data); method = TypedData_Make_Struct(mclass, struct METHOD, &method_data_type, data);
@ -1395,7 +1395,7 @@ method_owner(VALUE obj)
struct METHOD *data; struct METHOD *data;
TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data); TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data);
return data->rclass; return data->defined_class;
} }
void void

Просмотреть файл

@ -180,6 +180,15 @@ class TestMethod < Test::Unit::TestCase
assert_equal(Array.instance_method(:map).hash, Array.instance_method(:collect).hash) assert_equal(Array.instance_method(:map).hash, Array.instance_method(:collect).hash)
end end
def test_owner
c = Class.new do
def foo; end
end
assert_equal(c, c.instance_method(:foo).owner)
c2 = Class.new(c)
assert_equal(c, c2.instance_method(:foo).owner)
end
def test_receiver_name_owner def test_receiver_name_owner
o = Object.new o = Object.new
def o.foo; end def o.foo; end