зеркало из https://github.com/github/ruby.git
proc.c: fix inherited owner
* 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:
Родитель
537f327653
Коммит
b7c2f5bc93
|
@ -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
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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче