summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-06-27 07:48:50 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-06-27 07:48:50 +0000
commit8ddbbb33242f413845079b0274c28331cb4aa0f5 (patch)
tree522b12dada77b09073a58130c99c77d62c895b87 /eval.c
parent8634544fa74be0995582bc8056763fcfd38a0702 (diff)
Module#prepend
* class.c (rb_prepend_module): prepend module into another module. * eval.c (rb_mod_prepend): new method Module#prepend. [Feature #1102] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36234 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/eval.c b/eval.c
index 1203a20ecc..37bb35a148 100644
--- a/eval.c
+++ b/eval.c
@@ -954,6 +954,58 @@ rb_mod_include(int argc, VALUE *argv, VALUE module)
return module;
}
+/*
+ * call-seq:
+ * prepend_features(mod) -> mod
+ *
+ * When this module is prepended in another, Ruby calls
+ * <code>prepend_features</code> in this module, passing it the
+ * receiving module in _mod_. Ruby's default implementation is
+ * to overlay the constants, methods, and module variables of this module
+ * to _mod_ if this module has not already been added to
+ * _mod_ or one of its ancestors. See also <code>Module#prepend</code>.
+ */
+
+static VALUE
+rb_mod_prepend_features(VALUE module, VALUE prepend)
+{
+ switch (TYPE(prepend)) {
+ case T_CLASS:
+ case T_MODULE:
+ break;
+ default:
+ Check_Type(prepend, T_CLASS);
+ break;
+ }
+ rb_prepend_module(prepend, module);
+
+ return module;
+}
+
+/*
+ * call-seq:
+ * prepend(module, ...) -> self
+ *
+ * Invokes <code>Module.prepend_features</code> on each parameter in reverse order.
+ */
+
+static VALUE
+rb_mod_prepend(int argc, VALUE *argv, VALUE module)
+{
+ int i;
+ ID id_prepend_features, id_prepended;
+
+ CONST_ID(id_prepend_features, "prepend_features");
+ CONST_ID(id_prepended, "prepended");
+ for (i = 0; i < argc; i++)
+ Check_Type(argv[i], T_MODULE);
+ while (argc--) {
+ rb_funcall(argv[argc], id_prepend_features, 1, module);
+ rb_funcall(argv[argc], id_prepended, 1, module);
+ }
+ return module;
+}
+
void
rb_obj_call_init(VALUE obj, int argc, VALUE *argv)
{
@@ -1213,6 +1265,8 @@ Init_eval(void)
rb_define_private_method(rb_cModule, "append_features", rb_mod_append_features, 1);
rb_define_private_method(rb_cModule, "extend_object", rb_mod_extend_object, 1);
rb_define_private_method(rb_cModule, "include", rb_mod_include, -1);
+ rb_define_private_method(rb_cModule, "prepend_features", rb_mod_prepend_features, 1);
+ rb_define_private_method(rb_cModule, "prepend", rb_mod_prepend, -1);
rb_undef_method(rb_cClass, "module_function");