diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-03-08 15:26:08 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-03-08 15:26:08 +0000 |
commit | 0316cf2e523d9f77e610477697d5a93842b4d4bd (patch) | |
tree | 57833bca5dea888008e464c2be185f93b0280055 /marshal.c | |
parent | e14095fff2aed4599a69d8c53ee5ca017a6e8826 (diff) | |
download | ruby-0316cf2e523d9f77e610477697d5a93842b4d4bd.tar.gz |
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
Diffstat (limited to 'marshal.c')
-rw-r--r-- | marshal.c | 46 |
1 files changed, 33 insertions, 13 deletions
@@ -1387,11 +1387,11 @@ path2class(VALUE path) 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, VALUE extmod) case TYPE_EXTENDED: { - VALUE m = path2module(r_unique(arg)); - - 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); - } + VALUE path = r_unique(arg); + VALUE m = rb_path_to_class(path); + + if (RB_TYPE_P(m, T_CLASS)) { /* prepended */ + VALUE c; + + 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; |