summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2012-12-25 04:35:50 -0800
committerYukihiro "Matz" Matsumoto <[email protected]>2012-12-25 04:35:50 -0800
commitc0af042603a0bc0b65ad238299d61be45ef963ff (patch)
tree3e071f2ebecb51f9a225759596ec8c3eb6cd78c2
parent74554e041a96be45dc64352e905107f0b394a673 (diff)
parent3ffe8fe105adfb5df81e7da2996a01e576ed41f9 (diff)
downloadmruby-c0af042603a0bc0b65ad238299d61be45ef963ff.tar.gz
mruby-c0af042603a0bc0b65ad238299d61be45ef963ff.zip
Merge pull request #671 from skandhas/pr-add-Module_remove_class_variable
Add Module#remove_class_variable for mruby.
-rw-r--r--src/class.c51
-rw-r--r--test/t/module.rb10
2 files changed, 61 insertions, 0 deletions
diff --git a/src/class.c b/src/class.c
index 0ed18e1c5..db334cf3a 100644
--- a/src/class.c
+++ b/src/class.c
@@ -1545,6 +1545,56 @@ mrb_mod_cvar_set(mrb_state *mrb, mrb_value mod)
return value;
}
+/* 15.2.2.4.39 */
+/*
+ * call-seq:
+ * remove_class_variable(sym) -> obj
+ *
+ * Removes the definition of the <i>sym</i>, returning that
+ * constant's value.
+ *
+ * class Dummy
+ * @@var = 99
+ * puts @@var
+ * p class_variables
+ * remove_class_variable(:@@var)
+ * p class_variables
+ * end
+ *
+ * <em>produces:</em>
+ *
+ * 99
+ * [:@@var]
+ * []
+ */
+
+mrb_value
+mrb_mod_remove_cvar(mrb_state *mrb, mrb_value mod)
+{
+ mrb_value sym, val;
+ mrb_sym id;
+
+ mrb_get_args(mrb, "o", &sym);
+
+ id = mrb_sym_value(mrb,sym);
+ check_cv_name(mrb, id);
+
+ val = mrb_iv_remove(mrb, mod, id);
+
+ if (!mrb_undef_p(val)) return val;
+
+ if (mrb_cv_defined(mrb, mod, id)){
+ mrb_name_error(mrb, id, "cannot remove %s for %s",
+ mrb_sym2name(mrb, id), mrb_class_name(mrb, mrb_class_ptr(mod)));
+ }
+
+ mrb_name_error(mrb, id, "class variable %s not defined for %s",
+ mrb_sym2name(mrb, id), mrb_class_name(mrb, mrb_class_ptr(mod)));
+
+ /* not reached */
+ return mrb_nil_value();
+}
+
static void
check_const_name(mrb_state *mrb, mrb_sym id)
{
@@ -1659,6 +1709,7 @@ mrb_init_class(mrb_state *mrb)
mrb_define_method(mrb, mod, "included_modules", mrb_mod_included_modules, ARGS_NONE()); /* 15.2.2.4.30 */
mrb_define_method(mrb, mod, "instance_methods", mrb_mod_instance_methods, ARGS_ANY()); /* 15.2.2.4.33 */
mrb_define_method(mrb, mod, "module_eval", mrb_mod_module_eval, ARGS_ANY()); /* 15.2.2.4.35 */
+ mrb_define_method(mrb, mod, "remove_class_variable", mrb_mod_remove_cvar, ARGS_REQ(1)); /* 15.2.2.4.39 */
mrb_define_method(mrb, mod, "to_s", mrb_mod_to_s, ARGS_NONE());
mrb_define_method(mrb, mod, "inspect", mrb_mod_to_s, ARGS_NONE());
diff --git a/test/t/module.rb b/test/t/module.rb
index b3b1ccf1a..deacb3309 100644
--- a/test/t/module.rb
+++ b/test/t/module.rb
@@ -208,6 +208,16 @@ assert('Module#module_eval', '15.2.2.4.35') do
Test4ModuleEval.module_eval{ @b } == 12
end
+assert('Module#remove_class_variable', '15.2.2.4.39') do
+ class Test4RemoveClassVariable
+ @@cv = 99
+ end
+
+ Test4RemoveClassVariable.remove_class_variable(:@@cv) == 99 and
+ not Test4RemoveClassVariable.class_variables.include? :@@cv
+end
+
+
# Not ISO specified
assert('Module#to_s') do