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

ruby-changes:72232

From: Jean <ko1@a...>
Date: Sat, 18 Jun 2022 21:49:14 +0900 (JST)
Subject: [ruby-changes:72232] eca31d24d6 (master): [Bug #18813] Warn when autoload has to lookup in parent namespace

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

From eca31d24d606a73def3674938112dc3c5b79c445 Mon Sep 17 00:00:00 2001
From: Jean Boussier <jean.boussier@g...>
Date: Sat, 18 Jun 2022 10:29:52 +0200
Subject: [Bug #18813] Warn when autoload has to lookup in parent namespace

This is a verbose mode only warning.
---
 spec/ruby/core/module/autoload_spec.rb | 30 ++++++++++++++++++++++++++++++
 test/ruby/test_autoload.rb             | 17 +++++++++++++++++
 variable.c                             | 16 ++++++++++++++++
 3 files changed, 63 insertions(+)

diff --git a/spec/ruby/core/module/autoload_spec.rb b/spec/ruby/core/module/autoload_spec.rb
index 7e7e7a2139..af04ab26c8 100644
--- a/spec/ruby/core/module/autoload_spec.rb
+++ b/spec/ruby/core/module/autoload_spec.rb
@@ -577,6 +577,36 @@ describe "Module#autoload" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/module/autoload_spec.rb#L577
       end
     end
 
+    ruby_version_is "3.2" do
+      it "warns once in verbose mode if the constant was defined in a parent scope" do
+        ScratchPad.record -> {
+          ModuleSpecs::DeclaredInCurrentDefinedInParent = :declared_in_current_defined_in_parent
+        }
+
+        module ModuleSpecs
+          module Autoload
+            autoload :DeclaredInCurrentDefinedInParent, fixture(__FILE__, "autoload_callback.rb")
+            self.autoload?(:DeclaredInCurrentDefinedInParent).should == fixture(__FILE__, "autoload_callback.rb")
+            const_defined?(:DeclaredInCurrentDefinedInParent).should == true
+
+            -> {
+              DeclaredInCurrentDefinedInParent
+            }.should complain(
+              /Expected .*autoload_callback.rb to define ModuleSpecs::Autoload::DeclaredInCurrentDefinedInParent but it didn't/,
+              verbose: true,
+            )
+
+            -> {
+              DeclaredInCurrentDefinedInParent
+            }.should_not complain(/.*/, verbose: true)
+            self.autoload?(:DeclaredInCurrentDefinedInParent).should == nil
+            const_defined?(:DeclaredInCurrentDefinedInParent).should == false
+            ModuleSpecs.const_defined?(:DeclaredInCurrentDefinedInParent).should == true
+          end
+        end
+      end
+    end
+
     ruby_version_is "3.1" do
       it "looks up in parent scope after failed autoload" do
         @remove << :DeclaredInCurrentDefinedInParent
diff --git a/test/ruby/test_autoload.rb b/test/ruby/test_autoload.rb
index bd875ec008..2e1a6ef2b9 100644
--- a/test/ruby/test_autoload.rb
+++ b/test/ruby/test_autoload.rb
@@ -479,6 +479,7 @@ p Foo::Bar https://github.com/ruby/ruby/blob/trunk/test/ruby/test_autoload.rb#L479
       File.write(autoload_path, '')
 
       assert_separately(%W[-I #{tmpdir}], <<-RUBY)
+        $VERBOSE = nil
         path = #{File.realpath(autoload_path).inspect}
         autoload :X, path
         assert_equal(path, Object.autoload?(:X))
@@ -557,4 +558,20 @@ p Foo::Bar https://github.com/ruby/ruby/blob/trunk/test/ruby/test_autoload.rb#L558
       RUBY
     end
   end
+
+  def test_autoload_parent_namespace
+    Dir.mktmpdir('autoload') do |tmpdir|
+      autoload_path = File.join(tmpdir, "some_const.rb")
+      File.write(autoload_path, 'class SomeConst; end')
+
+      assert_separately(%W[-I #{tmpdir}], <<-RUBY)
+        module SomeNamespace
+          autoload :SomeConst, #{File.realpath(autoload_path).inspect}
+          assert_warning(%r{/some_const\.rb to define SomeNamespace::SomeConst but it didn't}) do
+            assert_not_nil SomeConst
+          end
+        end
+      RUBY
+    end
+  end
 end
diff --git a/variable.c b/variable.c
index bf48e711f0..bde8937486 100644
--- a/variable.c
+++ b/variable.c
@@ -2672,6 +2672,22 @@ autoload_try_load(VALUE _arguments) https://github.com/ruby/ruby/blob/trunk/variable.c#L2672
         result = Qfalse;
 
         rb_const_remove(arguments->module, arguments->name);
+
+        if (arguments->module == rb_cObject) {
+            rb_warning(
+                "Expected %"PRIsVALUE" to define %"PRIsVALUE" but it didn't",
+                arguments->autoload_data->feature,
+                ID2SYM(arguments->name)
+            );
+        }
+        else {
+            rb_warning(
+                "Expected %"PRIsVALUE" to define %"PRIsVALUE"::%"PRIsVALUE" but it didn't",
+                arguments->autoload_data->feature,
+                arguments->module,
+                ID2SYM(arguments->name)
+            );
+        }
     }
     else {
         // Otherwise, it was loaded, copy the flags from the autoload constant:
-- 
cgit v1.2.1


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

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