Fix `Module#dup` to frozen module
Before this patch:
$ bin/mruby -e 'p Module.new.freeze.dup.frozen?'  #=> true
After this patch (same as Ruby):
$ bin/mruby -e 'p Module.new.freeze.dup.frozen?'  #=> false
MODIFY
src/class.c
src/class.c
@@ -2077,6 +2077,14 @@ mrb_mod_eqq(mrb_state *mrb, mrb_value mod)
return mrb_bool_value(eqq);
}
+static mrb_value
+mrb_mod_dup(mrb_state *mrb, mrb_value self)
+{
+ mrb_value mod = mrb_obj_clone(mrb, self);
+ MRB_UNSET_FROZEN_FLAG(mrb_obj_ptr(mod));
+ return mod;
+}
+
static mrb_value
mrb_mod_module_function(mrb_state *mrb, mrb_value mod)
{
@@ -2207,6 +2215,7 @@ mrb_init_class(mrb_state *mrb)
mrb_define_method(mrb, mod, "method_defined?", mrb_mod_method_defined, MRB_ARGS_REQ(1)); /* 15.2.2.4.34 */
mrb_define_method(mrb, mod, "define_method", mod_define_method, MRB_ARGS_ARG(1,1));
mrb_define_method(mrb, mod, "===", mrb_mod_eqq, MRB_ARGS_REQ(1)); /* 15.2.2.4.7 */
+ mrb_define_method(mrb, mod, "dup", mrb_mod_dup, MRB_ARGS_NONE());
mrb_undef_method(mrb, cls, "append_features");
mrb_undef_method(mrb, cls, "extend_object");

MODIFY
src/kernel.c
src/kernel.c
@@ -805,5 +805,4 @@ mrb_init_kernel(mrb_state *mrb)
mrb_define_method(mrb, krn, "__to_str", mrb_to_str, MRB_ARGS_NONE()); /* internal */
mrb_include_module(mrb, mrb->object_class, mrb->kernel_module);
- mrb_define_alias(mrb, mrb->module_class, "dup", "clone"); /* XXX */
}

MODIFY
test/t/module.rb
test/t/module.rb
@@ -400,6 +400,29 @@ end
# Not ISO specified
+assert('Module#dup') do
+ module TestModuleDup
+ @@cvar = :cvar
+ class << self
+ attr_accessor :cattr
+ def cmeth; :cmeth end
+ end
+ def cvar; @@cvar end
+ def imeth; :imeth end
+ self.cattr = :cattr
+ end
+
+ m = TestModuleDup.dup
+ o = Object.include(m).new
+ assert_equal(:cattr, m.cattr)
+ assert_equal(:cmeth, m.cmeth)
+ assert_equal(:cvar, o.cvar)
+ assert_equal(:imeth, o.imeth)
+ assert_match("#<Module:0x*>", m.to_s)
+ assert_not_predicate(m, :frozen?)
+ assert_not_predicate(TestModuleDup.freeze.dup, :frozen?)
+end
+
assert('Module#define_method') do
c = Class.new {
define_method(:m1) { :ok }

Fix `Module#dup` to frozen module

Before this patch:

  $ bin/mruby -e 'p Module.new.freeze.dup.frozen?'  #=> true

After this patch (same as Ruby):

  $ bin/mruby -e 'p Module.new.freeze.dup.frozen?'  #=> false