зеркало из https://github.com/github/ruby.git
marshal.c: prepended objects
* marshal.c (r_object0): load prepended objects. treat the class of extended object in the included modules as prepended singleton class. [ruby-core:53202] [Bug #8041] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39642 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
e14095fff2
Коммит
0316cf2e52
|
@ -1,3 +1,9 @@
|
|||
Sat Mar 9 00:25:57 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* marshal.c (r_object0): load prepended objects. treat the class of
|
||||
extended object in the included modules as prepended singleton
|
||||
class. [ruby-core:53202] [Bug #8041]
|
||||
|
||||
Fri Mar 8 19:44:00 2013 Akinori MUSHA <knu@iDaemons.org>
|
||||
|
||||
* man/rake.1, man/ruby.1: Use the Pa macro to make URLs stand out.
|
||||
|
|
44
marshal.c
44
marshal.c
|
@ -1387,11 +1387,11 @@ path2class(VALUE path)
|
|||
return v;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
path2module(VALUE path)
|
||||
{
|
||||
VALUE v = rb_path_to_class(path);
|
||||
#define path2module(path) must_be_module(rb_path_to_class(path), path)
|
||||
|
||||
static VALUE
|
||||
must_be_module(VALUE v, VALUE path)
|
||||
{
|
||||
if (!RB_TYPE_P(v, T_MODULE)) {
|
||||
rb_raise(rb_eArgError, "%"PRIsVALUE" does not refer to module", path);
|
||||
}
|
||||
|
@ -1473,16 +1473,36 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
|
|||
|
||||
case TYPE_EXTENDED:
|
||||
{
|
||||
VALUE m = path2module(r_unique(arg));
|
||||
VALUE path = r_unique(arg);
|
||||
VALUE m = rb_path_to_class(path);
|
||||
|
||||
if (NIL_P(extmod)) extmod = rb_ary_tmp_new(0);
|
||||
rb_ary_push(extmod, m);
|
||||
if (RB_TYPE_P(m, T_CLASS)) { /* prepended */
|
||||
VALUE c;
|
||||
|
||||
v = r_object0(arg, 0, extmod);
|
||||
while (RARRAY_LEN(extmod) > 0) {
|
||||
m = rb_ary_pop(extmod);
|
||||
rb_extend_object(v, m);
|
||||
}
|
||||
v = r_object0(arg, 0, Qnil);
|
||||
c = CLASS_OF(v);
|
||||
if (c != m || FL_TEST(c, FL_SINGLETON)) {
|
||||
rb_raise(rb_eArgError,
|
||||
"prepended class %"PRIsVALUE" differs from class %"PRIsVALUE,
|
||||
path, rb_class_name(c));
|
||||
}
|
||||
c = rb_singleton_class(v);
|
||||
while (RARRAY_LEN(extmod) > 0) {
|
||||
m = rb_ary_pop(extmod);
|
||||
rb_prepend_module(c, m);
|
||||
}
|
||||
}
|
||||
else {
|
||||
must_be_module(m, path);
|
||||
if (NIL_P(extmod)) extmod = rb_ary_tmp_new(0);
|
||||
rb_ary_push(extmod, m);
|
||||
|
||||
v = r_object0(arg, 0, extmod);
|
||||
while (RARRAY_LEN(extmod) > 0) {
|
||||
m = rb_ary_pop(extmod);
|
||||
rb_extend_object(v, m);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -75,6 +75,16 @@ module MarshalTestLib
|
|||
marshal_equal_with_ancestry(o1)
|
||||
end
|
||||
|
||||
def test_object_prepend
|
||||
bug8041 = '[ruby-core:53202] [Bug #8041]'
|
||||
|
||||
o1 = MyObject.new(42)
|
||||
o1.singleton_class.class_eval {prepend Mod1}
|
||||
assert_nothing_raised(ArgumentError, bug8041) {
|
||||
marshal_equal_with_ancestry(o1, bug8041)
|
||||
}
|
||||
end
|
||||
|
||||
class MyArray < Array
|
||||
def initialize(v, *args)
|
||||
super(args)
|
||||
|
|
Загрузка…
Ссылка в новой задаче