aboutsummaryrefslogtreecommitdiffstats
path: root/marshal.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-03-08 15:26:08 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-03-08 15:26:08 +0000
commit0316cf2e523d9f77e610477697d5a93842b4d4bd (patch)
tree57833bca5dea888008e464c2be185f93b0280055 /marshal.c
parente14095fff2aed4599a69d8c53ee5ca017a6e8826 (diff)
downloadruby-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.c46
1 files changed, 33 insertions, 13 deletions
diff --git a/marshal.c b/marshal.c
index 13f01c003c..7b45d1c835 100644
--- a/marshal.c
+++ b/marshal.c
@@ -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;