[前][次][番号順一覧][スレッド一覧]

ruby-changes:68104

From: Nobuyoshi <ko1@a...>
Date: Fri, 24 Sep 2021 08:29:12 +0900 (JST)
Subject: [ruby-changes:68104] 65285bf673 (master): Consider modified modules initialized [Bug #18185]

https://git.ruby-lang.org/ruby.git/commit/?id=65285bf673

From 65285bf673914424e960671d1d35e357c455985e Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Fri, 24 Sep 2021 00:55:11 +0900
Subject: Consider modified modules initialized [Bug #18185]

---
 class.c                  | 14 ++++++++++----
 eval.c                   |  3 +++
 internal/class.h         |  1 +
 test/ruby/test_module.rb | 26 ++++++++++++++++++++++++++
 4 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/class.c b/class.c
index 46d4408..8e37f8a 100644
--- a/class.c
+++ b/class.c
@@ -358,6 +358,15 @@ RMODULE_UNINITIALIZED(VALUE module) https://github.com/ruby/ruby/blob/trunk/class.c#L358
 }
 
 void
+rb_module_set_initialized(VALUE mod)
+{
+    if (RMODULE_UNINITIALIZED(mod)) {
+        RB_OBJ_WRITE(mod, &RCLASS(mod)->super, 0);
+        /* no more re-initialization */
+    }
+}
+
+void
 rb_module_check_initializable(VALUE mod)
 {
     if (!RMODULE_UNINITIALIZED(mod)) {
@@ -916,10 +925,7 @@ ensure_includable(VALUE klass, VALUE module) https://github.com/ruby/ruby/blob/trunk/class.c#L925
 {
     rb_class_modify_check(klass);
     Check_Type(module, T_MODULE);
-    if (RMODULE_UNINITIALIZED(module)) {
-        RB_OBJ_WRITE(module, &RCLASS(module)->super, 0);
-        /* no more re-initialization */
-    }
+    rb_module_set_initialized(module);
     if (!NIL_P(rb_refinement_module_get_refined_class(module))) {
 	rb_raise(rb_eArgError, "refinement module is not allowed");
     }
diff --git a/eval.c b/eval.c
index 60387f6..880c63b 100644
--- a/eval.c
+++ b/eval.c
@@ -424,6 +424,9 @@ rb_class_modify_check(VALUE klass) https://github.com/ruby/ruby/blob/trunk/eval.c#L424
     if (SPECIAL_CONST_P(klass)) {
 	Check_Type(klass, T_CLASS);
     }
+    if (RB_TYPE_P(klass, T_MODULE)) {
+        rb_module_set_initialized(klass);
+    }
     if (OBJ_FROZEN(klass)) {
 	const char *desc;
 
diff --git a/internal/class.h b/internal/class.h
index 5aaeeb9..a949bfb 100644
--- a/internal/class.h
+++ b/internal/class.h
@@ -115,6 +115,7 @@ int rb_singleton_class_internal_p(VALUE sklass); https://github.com/ruby/ruby/blob/trunk/internal/class.h#L115
 VALUE rb_class_boot(VALUE);
 VALUE rb_class_s_alloc(VALUE klass);
 VALUE rb_module_s_alloc(VALUE klass);
+void rb_module_set_initialized(VALUE module);
 void rb_module_check_initializable(VALUE module);
 VALUE rb_make_metaclass(VALUE, VALUE);
 VALUE rb_include_class_new(VALUE, VALUE);
diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb
index 385d8dd..429fab8 100644
--- a/test/ruby/test_module.rb
+++ b/test/ruby/test_module.rb
@@ -446,6 +446,32 @@ class TestModule < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_module.rb#L446
     end
   end
 
+  class Bug18185 < Module
+    module InstanceMethods
+    end
+    def initialize
+      include InstanceMethods
+    end
+    class Foo
+      attr_reader :key
+      def initialize(key:)
+        @key = key
+      end
+    end
+  end
+
+  def test_module_subclass_initialize
+    mod = Bug18185.new
+    c = Class.new(Bug18185::Foo) do
+      include mod
+    end
+    anc = c.ancestors
+    assert_include(anc, mod)
+    assert_equal(1, anc.count(BasicObject), ->{anc.inspect})
+    b = c.new(key: 1)
+    assert_equal(1, b.key)
+  end
+
   def test_dup
     OtherSetup.call
 
-- 
cgit v1.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]