diff --git a/activesupport/lib/active_support/cache/file_store.rb b/activesupport/lib/active_support/cache/file_store.rb index 2ab632a3a5..4af4909741 100644 --- a/activesupport/lib/active_support/cache/file_store.rb +++ b/activesupport/lib/active_support/cache/file_store.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -require "active_support/core_ext/marshal" require "active_support/core_ext/file/atomic" require "active_support/core_ext/string/conversions" require "uri/common" diff --git a/activesupport/lib/active_support/cache/mem_cache_store.rb b/activesupport/lib/active_support/cache/mem_cache_store.rb index f3482881b9..68b080ab3b 100644 --- a/activesupport/lib/active_support/cache/mem_cache_store.rb +++ b/activesupport/lib/active_support/cache/mem_cache_store.rb @@ -8,7 +8,6 @@ rescue LoadError => e end require "active_support/core_ext/enumerable" -require "active_support/core_ext/marshal" require "active_support/core_ext/array/extract_options" module ActiveSupport diff --git a/activesupport/lib/active_support/cache/redis_cache_store.rb b/activesupport/lib/active_support/cache/redis_cache_store.rb index 065b81eca3..41153ea577 100644 --- a/activesupport/lib/active_support/cache/redis_cache_store.rb +++ b/activesupport/lib/active_support/cache/redis_cache_store.rb @@ -16,7 +16,6 @@ rescue LoadError end require "active_support/digest" -require "active_support/core_ext/marshal" module ActiveSupport module Cache diff --git a/activesupport/lib/active_support/core_ext/marshal.rb b/activesupport/lib/active_support/core_ext/marshal.rb deleted file mode 100644 index 5ff0e34d82..0000000000 --- a/activesupport/lib/active_support/core_ext/marshal.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true - -require "active_support/core_ext/string/inflections" - -module ActiveSupport - module MarshalWithAutoloading # :nodoc: - def load(source, proc = nil) - super(source, proc) - rescue ArgumentError, NameError => exc - if exc.message.match(%r|undefined class/module (.+?)(?:::)?\z|) - # try loading the class/module - loaded = $1.constantize - - raise unless $1 == loaded.name - - # if it is an IO we need to go back to read the object - source.rewind if source.respond_to?(:rewind) - retry - else - raise exc - end - end - end -end - -Marshal.singleton_class.prepend(ActiveSupport::MarshalWithAutoloading) diff --git a/activesupport/test/cache/behaviors.rb b/activesupport/test/cache/behaviors.rb index db51dd69ab..5c40b4bf2b 100644 --- a/activesupport/test/cache/behaviors.rb +++ b/activesupport/test/cache/behaviors.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -require_relative "behaviors/autoloading_cache_behavior" require_relative "behaviors/cache_delete_matched_behavior" require_relative "behaviors/cache_increment_decrement_behavior" require_relative "behaviors/cache_instrumentation_behavior" diff --git a/activesupport/test/cache/behaviors/autoloading_cache_behavior.rb b/activesupport/test/cache/behaviors/autoloading_cache_behavior.rb deleted file mode 100644 index 25e3550c02..0000000000 --- a/activesupport/test/cache/behaviors/autoloading_cache_behavior.rb +++ /dev/null @@ -1,43 +0,0 @@ -# frozen_string_literal: true - -require_relative "../../dependencies_test_helpers" - -module AutoloadingCacheBehavior - include DependenciesTestHelpers - - def test_simple_autoloading - with_autoloading_fixtures do - @cache.write("foo", EM.new) - end - - remove_constants(:EM) - ActiveSupport::Dependencies.clear - - with_autoloading_fixtures do - assert_kind_of EM, @cache.read("foo") - end - - remove_constants(:EM) - ActiveSupport::Dependencies.clear - end - - def test_two_classes_autoloading - with_autoloading_fixtures do - @cache.write("foo", [EM.new, ClassFolder.new]) - end - - remove_constants(:EM, :ClassFolder) - ActiveSupport::Dependencies.clear - - with_autoloading_fixtures do - loaded = @cache.read("foo") - assert_kind_of Array, loaded - assert_equal 2, loaded.size - assert_kind_of EM, loaded[0] - assert_kind_of ClassFolder, loaded[1] - end - - remove_constants(:EM, :ClassFolder) - ActiveSupport::Dependencies.clear - end -end diff --git a/activesupport/test/cache/stores/file_store_test.rb b/activesupport/test/cache/stores/file_store_test.rb index 308c34a959..b43de1b5de 100644 --- a/activesupport/test/cache/stores/file_store_test.rb +++ b/activesupport/test/cache/stores/file_store_test.rb @@ -36,7 +36,6 @@ class FileStoreTest < ActiveSupport::TestCase include CacheDeleteMatchedBehavior include CacheIncrementDecrementBehavior include CacheInstrumentationBehavior - include AutoloadingCacheBehavior def test_clear gitkeep = File.join(cache_dir, ".gitkeep") diff --git a/activesupport/test/cache/stores/mem_cache_store_test.rb b/activesupport/test/cache/stores/mem_cache_store_test.rb index 867d40f262..f65fbcf85d 100644 --- a/activesupport/test/cache/stores/mem_cache_store_test.rb +++ b/activesupport/test/cache/stores/mem_cache_store_test.rb @@ -55,7 +55,6 @@ class MemCacheStoreTest < ActiveSupport::TestCase include CacheIncrementDecrementBehavior include CacheInstrumentationBehavior include EncodedKeyCacheBehavior - include AutoloadingCacheBehavior include ConnectionPoolBehavior include FailureSafetyBehavior diff --git a/activesupport/test/cache/stores/redis_cache_store_test.rb b/activesupport/test/cache/stores/redis_cache_store_test.rb index 9fc4341f54..334ece1862 100644 --- a/activesupport/test/cache/stores/redis_cache_store_test.rb +++ b/activesupport/test/cache/stores/redis_cache_store_test.rb @@ -136,7 +136,6 @@ module ActiveSupport::Cache::RedisCacheStoreTests include LocalCacheBehavior include CacheIncrementDecrementBehavior include CacheInstrumentationBehavior - include AutoloadingCacheBehavior include EncodedKeyCacheBehavior def test_fetch_multi_uses_redis_mget diff --git a/activesupport/test/core_ext/marshal_test.rb b/activesupport/test/core_ext/marshal_test.rb deleted file mode 100644 index 5e72518651..0000000000 --- a/activesupport/test/core_ext/marshal_test.rb +++ /dev/null @@ -1,165 +0,0 @@ -# frozen_string_literal: true - -require_relative "../abstract_unit" -require "active_support/core_ext/marshal" -require_relative "../dependencies_test_helpers" - -class MarshalTest < ActiveSupport::TestCase - include ActiveSupport::Testing::Isolation - include DependenciesTestHelpers - - def teardown - ActiveSupport::Dependencies.clear - remove_constants(:EM, :ClassFolder) - end - - test "that Marshal#load still works" do - sanity_data = ["test", [1, 2, 3], { a: [1, 2, 3] }, ActiveSupport::TestCase] - sanity_data.each do |obj| - dumped = Marshal.dump(obj) - assert_equal Marshal.method(:load).super_method.call(dumped), Marshal.load(dumped) - end - end - - test "that Marshal#load still works when passed a proc" do - example_string = "test" - - example_proc = Proc.new do |o| - if o.is_a?(String) - o.capitalize! - end - end - - dumped = Marshal.dump(example_string) - assert_equal Marshal.load(dumped, example_proc), "Test" - end - - test "that a missing class is autoloaded from string" do - dumped = nil - with_autoloading_fixtures do - dumped = Marshal.dump(EM.new) - end - - remove_constants(:EM) - ActiveSupport::Dependencies.clear - - with_autoloading_fixtures do - object = nil - assert_nothing_raised do - object = Marshal.load(dumped) - end - - assert_kind_of EM, object - end - end - - test "that classes in sub modules work" do - dumped = nil - with_autoloading_fixtures do - dumped = Marshal.dump(ClassFolder::ClassFolderSubclass.new) - end - - remove_constants(:ClassFolder) - ActiveSupport::Dependencies.clear - - with_autoloading_fixtures do - object = nil - assert_nothing_raised do - object = Marshal.load(dumped) - end - - assert_kind_of ClassFolder::ClassFolderSubclass, object - end - end - - test "that more than one missing class is autoloaded" do - dumped = nil - with_autoloading_fixtures do - dumped = Marshal.dump([EM.new, ClassFolder.new]) - end - - remove_constants(:EM, :ClassFolder) - ActiveSupport::Dependencies.clear - - with_autoloading_fixtures do - loaded = Marshal.load(dumped) - assert_equal 2, loaded.size - assert_kind_of EM, loaded[0] - assert_kind_of ClassFolder, loaded[1] - end - end - - test "when one constant resolves to another" do - class Parent; C = Class.new; end - class Child < Parent; C = Class.new; end - - dump = Marshal.dump(Child::C.new) - - Child.send(:remove_const, :C) - - assert_raise(ArgumentError) { Marshal.load(dump) } - end - - test "that a real missing class is causing an exception" do - dumped = nil - with_autoloading_fixtures do - dumped = Marshal.dump(EM.new) - end - - remove_constants(:EM) - ActiveSupport::Dependencies.clear - - assert_raise(NameError) do - Marshal.load(dumped) - end - end - - test "when first class is autoloaded and second not" do - dumped = nil - class SomeClass - end - - with_autoloading_fixtures do - dumped = Marshal.dump([EM.new, SomeClass.new]) - end - - remove_constants(:EM) - self.class.send(:remove_const, :SomeClass) - ActiveSupport::Dependencies.clear - - with_autoloading_fixtures do - assert_raise(NameError) do - Marshal.load(dumped) - end - - assert_nothing_raised do - EM.new - end - - assert_raise(NameError, "We expected SomeClass to not be loaded but it is!") do - SomeClass.new - end - end - end - - test "loading classes from files trigger autoloading" do - Tempfile.open("object_serializer_test") do |f| - with_autoloading_fixtures do - Marshal.dump(EM.new, f) - end - - f.rewind - remove_constants(:EM) - ActiveSupport::Dependencies.clear - - with_autoloading_fixtures do - object = nil - assert_nothing_raised do - object = Marshal.load(f) - end - - assert_kind_of EM, object - end - end - end -end diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md index 94c5e00b07..41c9959705 100644 --- a/guides/source/active_support_core_extensions.md +++ b/guides/source/active_support_core_extensions.md @@ -4000,25 +4000,6 @@ NOTE: Defined in `active_support/core_ext/file/atomic.rb`. [File.atomic_write]: https://api.rubyonrails.org/classes/File.html#method-c-atomic_write -Extensions to `Marshal` ------------------------ - -### `load` - -Active Support adds constant autoloading support to `load`. - -For example, the file cache store deserializes this way: - -```ruby -File.open(file_name) { |f| Marshal.load(f) } -``` - -If the cached data refers to a constant that is unknown at that point, the autoloading mechanism is triggered and if it succeeds the deserialization is retried transparently. - -WARNING. If the argument is an `IO` it needs to respond to `rewind` to be able to retry. Regular files respond to `rewind`. - -NOTE: Defined in `active_support/core_ext/marshal.rb`. - Extensions to `NameError` -------------------------