summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-05-31 16:16:06 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-05-31 16:16:06 +0000
commit604fe33b4493271c6116733548c3cddb12d2ace1 (patch)
tree20c77fbbdc1a48f25e7672847a8db805ac3eaa80 /eval.c
parentfcc86b0f4c443b7ab28fb61831b81767a8798292 (diff)
* class.c (rb_mix_module): implement Module#mix.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31873 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/eval.c b/eval.c
index d5f2c4cc1d..5831ca251d 100644
--- a/eval.c
+++ b/eval.c
@@ -880,6 +880,69 @@ rb_mod_include(int argc, VALUE *argv, VALUE module)
return module;
}
+/*
+ * call-seq:
+ * mix(module, ...) -> module
+ *
+ * Mix +Module+> into self.
+ */
+
+static VALUE
+rb_mod_mix_into(int argc, VALUE *argv, VALUE klass)
+{
+ VALUE module, tmp, constants = Qnil, methods = Qnil;
+ st_table *const_tbl = 0, *method_tbl = 0;
+ int i = 0;
+
+ if (argc < 1 || argc > 3) {
+ wrong_args:
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
+ }
+ module = argv[i++];
+
+ switch (TYPE(module)) {
+ case T_CLASS:
+ case T_MODULE:
+ break;
+ default:
+ Check_Type(module, T_CLASS);
+ break;
+ }
+ if (i < argc) {
+ constants = argv[i++];
+ if (!NIL_P(tmp = rb_check_array_type(constants))) {
+ constants = tmp;
+ }
+ else if (!NIL_P(methods = rb_check_hash_type(constants))) {
+ constants = Qnil;
+ }
+ else {
+ Check_Type(constants, T_HASH);
+ }
+ }
+ if (i < argc && NIL_P(methods)) {
+ methods = argv[i++];
+ if (NIL_P(tmp = rb_check_hash_type(methods))) {
+ Check_Type(methods, T_HASH);
+ }
+ methods = tmp;
+ }
+ if (i < argc) goto wrong_args;
+ if (!NIL_P(constants)) {
+ VALUE hash = rb_hash_new();
+ for (i = 0; i < RARRAY_LEN(constants); ++i) {
+ rb_hash_update_by(hash, RARRAY_PTR(constants)[i], NULL);
+ }
+ const_tbl = RHASH_TBL(RB_GC_GUARD(constants) = hash);
+ }
+ if (!NIL_P(methods)) {
+ method_tbl = RHASH_TBL(RB_GC_GUARD(methods));
+ }
+
+ rb_mix_module(klass, module, const_tbl, method_tbl);
+ return module;
+}
+
void
rb_obj_call_init(VALUE obj, int argc, VALUE *argv)
{
@@ -1144,6 +1207,7 @@ 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, "mix", rb_mod_mix_into, -1);
rb_undef_method(rb_cClass, "module_function");