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

ruby-changes:62804

From: Marc-Andre <ko1@a...>
Date: Wed, 2 Sep 2020 13:05:34 +0900 (JST)
Subject: [ruby-changes:62804] 5e16857315 (master): Fix constant names set using const_set on a singleton class

https://git.ruby-lang.org/ruby.git/commit/?id=5e16857315

From 5e16857315bf55307c5fc887ca6f03bfa0630a93 Mon Sep 17 00:00:00 2001
From: Marc-Andre Lafortune <github@m...>
Date: Tue, 1 Sep 2020 21:22:20 -0400
Subject: Fix constant names set using const_set on a singleton class

Fixes [Bug #14895]

diff --git a/spec/ruby/core/module/const_set_spec.rb b/spec/ruby/core/module/const_set_spec.rb
index 77a2e59..b537d3f 100644
--- a/spec/ruby/core/module/const_set_spec.rb
+++ b/spec/ruby/core/module/const_set_spec.rb
@@ -20,10 +20,20 @@ describe "Module#const_set" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/module/const_set_spec.rb#L20
     m.name.should == "ConstantSpecs::CS_CONST1000"
   end
 
-  it "does not set the name of a module scoped by an anonymous module" do
-    a, b = Module.new, Module.new
-    a.const_set :B, b
-    b.name.should be_nil
+  ruby_version_is ""..."3.0" do
+    it "does not set the name of a module scoped by an anonymous module" do
+      a, b = Module.new, Module.new
+      a.const_set :B, b
+      b.name.should be_nil
+    end
+  end
+
+  ruby_version_is "3.0" do
+    it "sets the name of a module scoped by an anonymous module" do
+      a, b = Module.new, Module.new
+      a.const_set :B, b
+      b.name.should.end_with? '::B'
+    end
   end
 
   it "sets the name of contained modules when assigning a toplevel anonymous module" do
diff --git a/spec/ruby/core/module/name_spec.rb b/spec/ruby/core/module/name_spec.rb
index ae80375..ca9106a 100644
--- a/spec/ruby/core/module/name_spec.rb
+++ b/spec/ruby/core/module/name_spec.rb
@@ -6,10 +6,20 @@ describe "Module#name" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/module/name_spec.rb#L6
     Module.new.name.should be_nil
   end
 
-  it "is nil when assigned to a constant in an anonymous module" do
-    m = Module.new
-    m::N = Module.new
-    m::N.name.should be_nil
+  ruby_version_is ""..."3.0" do
+    it "is nil when assigned to a constant in an anonymous module" do
+      m = Module.new
+      m::N = Module.new
+      m::N.name.should be_nil
+    end
+  end
+
+  ruby_version_is "3.0" do
+    it "is not nil when assigned to a constant in an anonymous module" do
+      m = Module.new
+      m::N = Module.new
+      m::N.name.should.end_with? '::N'
+    end
   end
 
   it "is not nil for a nested module created with the module keyword" do
diff --git a/spec/ruby/language/module_spec.rb b/spec/ruby/language/module_spec.rb
index 1b41e18..cbc7149 100644
--- a/spec/ruby/language/module_spec.rb
+++ b/spec/ruby/language/module_spec.rb
@@ -69,10 +69,20 @@ describe "Assigning an anonymous module to a constant" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/language/module_spec.rb#L69
     mod.name.should == "ModuleSpecs_CS1"
   end
 
-  it "does not set the name of a module scoped by an anonymous module" do
-    a, b = Module.new, Module.new
-    a::B = b
-    b.name.should be_nil
+  ruby_version_is ""..."3.0" do
+    it "does not set the name of a module scoped by an anonymous module" do
+      a, b = Module.new, Module.new
+      a::B = b
+      b.name.should be_nil
+    end
+  end
+
+  ruby_version_is "3.0" do
+    it "sets the name of a module scoped by an anonymous module" do
+      a, b = Module.new, Module.new
+      a::B = b
+      b.name.should.end_with? '::B'
+    end
   end
 
   it "sets the name of contained modules when assigning a toplevel anonymous module" do
diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb
index d2da384..94e415b 100644
--- a/test/ruby/test_module.rb
+++ b/test/ruby/test_module.rb
@@ -767,13 +767,13 @@ class TestModule < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_module.rb#L767
     n = Module.new
     m.const_set(:N, n)
     assert_nil(m.name)
-    assert_nil(n.name)
+    assert_match(/::N$/, n.name)
     assert_equal([:N], m.constants)
     m.module_eval("module O end")
     assert_equal([:N, :O], m.constants.sort)
     m.module_eval("class C; end")
     assert_equal([:C, :N, :O], m.constants.sort)
-    assert_nil(m::N.name)
+    assert_match(/::N$/, m::N.name)
     assert_match(/\A#<Module:.*>::O\z/, m::O.name)
     assert_match(/\A#<Module:.*>::C\z/, m::C.name)
     self.class.const_set(:M, m)
@@ -2724,6 +2724,12 @@ class TestModule < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_module.rb#L2724
     assert_not_predicate m.clone(freeze: false), :frozen?
   end
 
+  def test_module_name_in_singleton_method
+    s = Object.new.singleton_class
+    mod = s.const_set(:Foo, Module.new)
+    assert_match(/::Foo$/, mod.name, '[Bug #14895]')
+  end
+
   private
 
   def assert_top_method_is_private(method)
diff --git a/variable.c b/variable.c
index 26928ca..3c3b689 100644
--- a/variable.c
+++ b/variable.c
@@ -2854,14 +2854,15 @@ rb_const_set(VALUE klass, ID id, VALUE val) https://github.com/ruby/ruby/blob/trunk/variable.c#L2854
 	    else {
                 int parental_path_permanent;
                 VALUE parental_path = classname(klass, &parental_path_permanent);
-                if (!NIL_P(parental_path)) {
-                    if (parental_path_permanent && !val_path_permanent) {
-                        set_namespace_path(val, build_const_path(parental_path, id));
-                    }
-                    else if (!parental_path_permanent && NIL_P(val_path)) {
-                        rb_ivar_set(val, tmp_classpath, build_const_path(parental_path, id));
-                    }
-		}
+                if (NIL_P(parental_path)) {
+                    parental_path = rb_funcall(klass, rb_intern("to_s"), 0);
+                }
+                if (parental_path_permanent && !val_path_permanent) {
+                    set_namespace_path(val, build_const_path(parental_path, id));
+                }
+                else if (!parental_path_permanent && NIL_P(val_path)) {
+                    rb_ivar_set(val, tmp_classpath, build_const_path(parental_path, id));
+                }
 	    }
 	}
     }
-- 
cgit v0.10.2


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

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