ruby-changes:27590
From: nobu <ko1@a...>
Date: Sat, 9 Mar 2013 00:26:59 +0900 (JST)
Subject: [ruby-changes:27590] nobu:r39642 (trunk): marshal.c: prepended objects
nobu 2013-03-09 00:26:08 +0900 (Sat, 09 Mar 2013) New Revision: 39642 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=39642 Log: 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] Modified files: trunk/ChangeLog trunk/marshal.c trunk/test/ruby/marshaltestlib.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 39641) +++ ChangeLog (revision 39642) @@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sat Mar 9 00:25:57 2013 Nobuyoshi Nakada <nobu@r...> + + * 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@i...> * man/rake.1, man/ruby.1: Use the Pa macro to make URLs stand out. Index: marshal.c =================================================================== --- marshal.c (revision 39641) +++ marshal.c (revision 39642) @@ -1387,11 +1387,11 @@ path2class(VALUE path) https://github.com/ruby/ruby/blob/trunk/marshal.c#L1387 return v; } +#define path2module(path) must_be_module(rb_path_to_class(path), path) + static VALUE -path2module(VALUE path) +must_be_module(VALUE v, VALUE path) { - VALUE v = rb_path_to_class(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 https://github.com/ruby/ruby/blob/trunk/marshal.c#L1473 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; Index: test/ruby/marshaltestlib.rb =================================================================== --- test/ruby/marshaltestlib.rb (revision 39641) +++ test/ruby/marshaltestlib.rb (revision 39642) @@ -75,6 +75,16 @@ module MarshalTestLib https://github.com/ruby/ruby/blob/trunk/test/ruby/marshaltestlib.rb#L75 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) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/