* 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:
nobu 2013-03-08 15:26:08 +00:00
Родитель e14095fff2
Коммит 0316cf2e52
3 изменённых файлов: 48 добавлений и 12 удалений

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

@ -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.

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

@ -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)