diff options
author | Jeremy Evans <[email protected]> | 2021-10-08 12:54:26 -0900 |
---|---|---|
committer | GitHub <[email protected]> | 2021-10-08 14:54:26 -0700 |
commit | 08759edea8fb75d46c3e75217e6613465426a0d2 (patch) | |
tree | 7fb4c92e54b0e5fc3767ceeb6c0db645374ae54f /test/ruby/test_autoload.rb | |
parent | ded5a66cb994c5731a17bc9a2420042248a2f1fe (diff) |
Remove autoload for constant if the autoload fails
Previously, if an autoload failed (the file was loaded, but the
constant was not defined by the autoloaded file). Ruby will try
to autoload again if you delete the autoloaded file from
$LOADED_FEATURES. With this change, the autoload and the
constant itself are removed as soon as it fails.
To handle cases where multiple threads are autoloading, when
deleting an autoload, handle the case where another thread
already deleted it.
Fixes [Bug #15790]
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/4715
Merged-By: jeremyevans <[email protected]>
Diffstat (limited to 'test/ruby/test_autoload.rb')
-rw-r--r-- | test/ruby/test_autoload.rb | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/test/ruby/test_autoload.rb b/test/ruby/test_autoload.rb index 98d513da87..7709760d19 100644 --- a/test/ruby/test_autoload.rb +++ b/test/ruby/test_autoload.rb @@ -456,6 +456,31 @@ p Foo::Bar end; end + def test_autoload_after_failed_and_removed_from_loaded_features + Dir.mktmpdir('autoload') do |tmpdir| + autoload_path = File.join(tmpdir, "test-bug-15790.rb") + File.write(autoload_path, '') + + assert_separately(%W[-I #{tmpdir}], <<-RUBY) + path = #{File.realpath(autoload_path).inspect} + autoload :X, path + assert_equal(path, Object.autoload?(:X)) + + assert_raise(NameError){X} + assert_nil(Object.autoload?(:X)) + assert_equal(false, Object.const_defined?(:X)) + + $LOADED_FEATURES.delete(path) + assert_equal(false, Object.const_defined?(:X)) + assert_nil(Object.autoload?(:X)) + + assert_raise(NameError){X} + assert_equal(false, Object.const_defined?(:X)) + assert_nil(Object.autoload?(:X)) + RUBY + end + end + def add_autoload(path) (@autoload_paths ||= []) << path ::Object.class_eval {autoload(:AutoloadTest, path)} @@ -463,7 +488,7 @@ p Foo::Bar def remove_autoload_constant $".replace($" - @autoload_paths) - ::Object.class_eval {remove_const(:AutoloadTest)} + ::Object.class_eval {remove_const(:AutoloadTest)} if defined? Object::AutoloadTest TestAutoload.class_eval {remove_const(:AutoloadTest)} if defined? TestAutoload::AutoloadTest end end |