From 2e3d43e5775799d1b4d6672a3a18b3fc5777c52b Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sun, 19 Sep 2021 22:22:09 +0900 Subject: [PATCH] Allow to include uninitialized modules [Bug #18177] The module that is about to be included is considered initialized. --- class.c | 3 ++- test/ruby/test_module.rb | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/class.c b/class.c index e0e8b17c94..46d44085d5 100644 --- a/class.c +++ b/class.c @@ -917,7 +917,8 @@ ensure_includable(VALUE klass, VALUE module) rb_class_modify_check(klass); Check_Type(module, T_MODULE); if (RMODULE_UNINITIALIZED(module)) { - rb_raise(rb_eArgError, "uninitialized module"); + RB_OBJ_WRITE(module, &RCLASS(module)->super, 0); + /* no more re-initialization */ } if (!NIL_P(rb_refinement_module_get_refined_class(module))) { rb_raise(rb_eArgError, "refinement module is not allowed"); diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb index b36b8b7810..385d8dddfe 100644 --- a/test/ruby/test_module.rb +++ b/test/ruby/test_module.rb @@ -432,6 +432,18 @@ class TestModule < Test::Unit::TestCase initialize_copy(Module.new) end end + + m = Class.new(Module) do + def initialize_copy(other) + # leave uninitialized + end + end.new.dup + c = Class.new + assert_operator(c.include(m), :<, m) + cp = Module.instance_method(:initialize_copy) + assert_raise(TypeError) do + cp.bind_call(m, Module.new) + end end def test_dup