activesupport 1.2.4 → 8.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +505 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +40 -0
- data/lib/active_support/actionable_error.rb +50 -0
- data/lib/active_support/all.rb +5 -0
- data/lib/active_support/array_inquirer.rb +50 -0
- data/lib/active_support/backtrace_cleaner.rb +234 -0
- data/lib/active_support/benchmark.rb +21 -0
- data/lib/active_support/benchmarkable.rb +53 -0
- data/lib/active_support/broadcast_logger.rb +238 -0
- data/lib/active_support/builder.rb +8 -0
- data/lib/active_support/cache/coder.rb +153 -0
- data/lib/active_support/cache/entry.rb +134 -0
- data/lib/active_support/cache/file_store.rb +244 -0
- data/lib/active_support/cache/mem_cache_store.rb +288 -0
- data/lib/active_support/cache/memory_store.rb +264 -0
- data/lib/active_support/cache/null_store.rb +62 -0
- data/lib/active_support/cache/redis_cache_store.rb +498 -0
- data/lib/active_support/cache/serializer_with_fallback.rb +152 -0
- data/lib/active_support/cache/strategy/local_cache.rb +246 -0
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
- data/lib/active_support/cache.rb +1170 -0
- data/lib/active_support/callbacks.rb +960 -0
- data/lib/active_support/class_attribute.rb +33 -0
- data/lib/active_support/code_generator.rb +79 -0
- data/lib/active_support/concern.rb +217 -0
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
- data/lib/active_support/concurrency/null_lock.rb +13 -0
- data/lib/active_support/concurrency/share_lock.rb +225 -0
- data/lib/active_support/concurrency/thread_monitor.rb +55 -0
- data/lib/active_support/configurable.rb +193 -0
- data/lib/active_support/configuration_file.rb +60 -0
- data/lib/active_support/continuous_integration.rb +145 -0
- data/lib/active_support/core_ext/array/access.rb +100 -0
- data/lib/active_support/core_ext/array/conversions.rb +209 -26
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/extract_options.rb +31 -0
- data/lib/active_support/core_ext/array/grouping.rb +109 -0
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/wrap.rb +48 -0
- data/lib/active_support/core_ext/array.rb +8 -4
- data/lib/active_support/core_ext/benchmark.rb +6 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
- data/lib/active_support/core_ext/big_decimal.rb +3 -0
- data/lib/active_support/core_ext/class/attribute.rb +137 -0
- data/lib/active_support/core_ext/class/attribute_accessors.rb +6 -0
- data/lib/active_support/core_ext/class/subclasses.rb +24 -0
- data/lib/active_support/core_ext/class.rb +4 -0
- data/lib/active_support/core_ext/date/acts_like.rb +10 -0
- data/lib/active_support/core_ext/date/blank.rb +18 -0
- data/lib/active_support/core_ext/date/calculations.rb +161 -0
- data/lib/active_support/core_ext/date/conversions.rb +95 -28
- data/lib/active_support/core_ext/date/zones.rb +8 -0
- data/lib/active_support/core_ext/date.rb +6 -5
- data/lib/active_support/core_ext/date_and_time/calculations.rb +374 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +23 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +16 -0
- data/lib/active_support/core_ext/date_time/blank.rb +18 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +215 -0
- data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +108 -0
- data/lib/active_support/core_ext/date_time.rb +7 -0
- data/lib/active_support/core_ext/digest/uuid.rb +76 -0
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +277 -7
- data/lib/active_support/core_ext/erb/util.rb +201 -0
- data/lib/active_support/core_ext/file/atomic.rb +72 -0
- data/lib/active_support/core_ext/file.rb +3 -0
- data/lib/active_support/core_ext/hash/conversions.rb +262 -0
- data/lib/active_support/core_ext/hash/deep_merge.rb +43 -0
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +12 -0
- data/lib/active_support/core_ext/hash/indifferent_access.rb +19 -55
- data/lib/active_support/core_ext/hash/keys.rb +134 -44
- data/lib/active_support/core_ext/hash/reverse_merge.rb +22 -22
- data/lib/active_support/core_ext/hash/slice.rb +27 -0
- data/lib/active_support/core_ext/hash.rb +9 -8
- data/lib/active_support/core_ext/integer/inflections.rb +29 -13
- data/lib/active_support/core_ext/integer/multiple.rb +12 -0
- data/lib/active_support/core_ext/integer/time.rb +22 -0
- data/lib/active_support/core_ext/integer.rb +4 -6
- data/lib/active_support/core_ext/kernel/concern.rb +14 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +45 -0
- data/lib/active_support/core_ext/kernel/singleton_class.rb +8 -0
- data/lib/active_support/core_ext/kernel.rb +4 -78
- data/lib/active_support/core_ext/load_error.rb +6 -35
- data/lib/active_support/core_ext/module/aliasing.rb +31 -0
- data/lib/active_support/core_ext/module/anonymous.rb +30 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +48 -0
- data/lib/active_support/core_ext/module/attribute_accessors.rb +214 -0
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +175 -0
- data/lib/active_support/core_ext/module/concerning.rb +140 -0
- data/lib/active_support/core_ext/module/delegation.rb +225 -0
- data/lib/active_support/core_ext/module/deprecation.rb +25 -0
- data/lib/active_support/core_ext/module/introspection.rb +65 -0
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +17 -0
- data/lib/active_support/core_ext/module.rb +13 -0
- data/lib/active_support/core_ext/name_error.rb +59 -0
- data/lib/active_support/core_ext/numeric/bytes.rb +73 -42
- data/lib/active_support/core_ext/numeric/conversions.rb +145 -0
- data/lib/active_support/core_ext/numeric/time.rb +64 -57
- data/lib/active_support/core_ext/numeric.rb +4 -6
- data/lib/active_support/core_ext/object/acts_like.rb +45 -0
- data/lib/active_support/core_ext/object/blank.rb +199 -0
- data/lib/active_support/core_ext/object/conversions.rb +6 -0
- data/lib/active_support/core_ext/object/deep_dup.rb +71 -0
- data/lib/active_support/core_ext/object/duplicable.rb +69 -0
- data/lib/active_support/core_ext/object/inclusion.rb +37 -0
- data/lib/active_support/core_ext/object/instance_variables.rb +32 -0
- data/lib/active_support/core_ext/object/json.rb +267 -0
- data/lib/active_support/core_ext/object/to_param.rb +3 -0
- data/lib/active_support/core_ext/object/to_query.rb +93 -0
- data/lib/active_support/core_ext/object/try.rb +158 -0
- data/lib/active_support/core_ext/object/with.rb +46 -0
- data/lib/active_support/core_ext/object/with_options.rb +101 -0
- data/lib/active_support/core_ext/object.rb +17 -0
- data/lib/active_support/core_ext/pathname/blank.rb +20 -0
- data/lib/active_support/core_ext/pathname/existence.rb +23 -0
- data/lib/active_support/core_ext/pathname.rb +4 -0
- data/lib/active_support/core_ext/range/compare_range.rb +57 -0
- data/lib/active_support/core_ext/range/conversions.rb +58 -17
- data/lib/active_support/core_ext/range/overlap.rb +40 -0
- data/lib/active_support/core_ext/range/sole.rb +17 -0
- data/lib/active_support/core_ext/range.rb +5 -4
- data/lib/active_support/core_ext/regexp.rb +14 -0
- data/lib/active_support/core_ext/securerandom.rb +57 -0
- data/lib/active_support/core_ext/string/access.rb +93 -56
- data/lib/active_support/core_ext/string/behavior.rb +8 -0
- data/lib/active_support/core_ext/string/conversions.rb +57 -16
- data/lib/active_support/core_ext/string/exclude.rb +13 -0
- data/lib/active_support/core_ext/string/filters.rb +151 -0
- data/lib/active_support/core_ext/string/indent.rb +45 -0
- data/lib/active_support/core_ext/string/inflections.rb +297 -54
- data/lib/active_support/core_ext/string/inquiry.rb +16 -0
- data/lib/active_support/core_ext/string/multibyte.rb +67 -0
- data/lib/active_support/core_ext/string/output_safety.rb +235 -0
- data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -18
- data/lib/active_support/core_ext/string/strip.rb +27 -0
- data/lib/active_support/core_ext/string/zones.rb +16 -0
- data/lib/active_support/core_ext/string.rb +14 -10
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/thread/backtrace/location.rb +7 -0
- data/lib/active_support/core_ext/time/acts_like.rb +10 -0
- data/lib/active_support/core_ext/time/calculations.rb +358 -153
- data/lib/active_support/core_ext/time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/time/conversions.rb +69 -30
- data/lib/active_support/core_ext/time/zones.rb +97 -0
- data/lib/active_support/core_ext/time.rb +6 -6
- data/lib/active_support/core_ext.rb +5 -1
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +243 -0
- data/lib/active_support/deep_mergeable.rb +53 -0
- data/lib/active_support/delegation.rb +183 -0
- data/lib/active_support/dependencies/autoload.rb +72 -0
- data/lib/active_support/dependencies/interlock.rb +55 -0
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +84 -222
- data/lib/active_support/deprecation/behaviors.rb +148 -0
- data/lib/active_support/deprecation/constant_accessor.rb +74 -0
- data/lib/active_support/deprecation/deprecators.rb +104 -0
- data/lib/active_support/deprecation/disallowed.rb +54 -0
- data/lib/active_support/deprecation/method_wrappers.rb +68 -0
- data/lib/active_support/deprecation/proxy_wrappers.rb +189 -0
- data/lib/active_support/deprecation/reporting.rb +162 -0
- data/lib/active_support/deprecation.rb +81 -0
- data/lib/active_support/deprecator.rb +7 -0
- data/lib/active_support/descendants_tracker.rb +112 -0
- data/lib/active_support/digest.rb +22 -0
- data/lib/active_support/duration/iso8601_parser.rb +123 -0
- data/lib/active_support/duration/iso8601_serializer.rb +64 -0
- data/lib/active_support/duration.rb +524 -0
- data/lib/active_support/editor.rb +70 -0
- data/lib/active_support/encrypted_configuration.rb +126 -0
- data/lib/active_support/encrypted_file.rb +133 -0
- data/lib/active_support/environment_inquirer.rb +40 -0
- data/lib/active_support/error_reporter/test_helper.rb +15 -0
- data/lib/active_support/error_reporter.rb +318 -0
- data/lib/active_support/event_reporter/test_helper.rb +32 -0
- data/lib/active_support/event_reporter.rb +592 -0
- data/lib/active_support/evented_file_update_checker.rb +185 -0
- data/lib/active_support/execution_context/test_helper.rb +13 -0
- data/lib/active_support/execution_context.rb +110 -0
- data/lib/active_support/execution_wrapper.rb +150 -0
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +166 -0
- data/lib/active_support/fork_tracker.rb +43 -0
- data/lib/active_support/gem_version.rb +17 -0
- data/lib/active_support/gzip.rb +41 -0
- data/lib/active_support/hash_with_indifferent_access.rb +464 -0
- data/lib/active_support/html_safe_translation.rb +56 -0
- data/lib/active_support/i18n.rb +17 -0
- data/lib/active_support/i18n_railtie.rb +140 -0
- data/lib/active_support/inflections.rb +68 -49
- data/lib/active_support/inflector/inflections.rb +290 -0
- data/lib/active_support/inflector/methods.rb +387 -0
- data/lib/active_support/inflector/transliterate.rb +147 -0
- data/lib/active_support/inflector.rb +7 -164
- data/lib/active_support/isolated_execution_state.rb +76 -0
- data/lib/active_support/json/decoding.rb +78 -0
- data/lib/active_support/json/encoding.rb +256 -0
- data/lib/active_support/json.rb +4 -0
- data/lib/active_support/key_generator.rb +66 -0
- data/lib/active_support/lazy_load_hooks.rb +107 -0
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +141 -0
- data/lib/active_support/log_subscriber/test_helper.rb +106 -0
- data/lib/active_support/log_subscriber.rb +188 -0
- data/lib/active_support/logger.rb +55 -0
- data/lib/active_support/logger_silence.rb +21 -0
- data/lib/active_support/logger_thread_safe_level.rb +50 -0
- data/lib/active_support/message_encryptor.rb +374 -0
- data/lib/active_support/message_encryptors.rb +193 -0
- data/lib/active_support/message_pack/cache_serializer.rb +23 -0
- data/lib/active_support/message_pack/extensions.rb +310 -0
- data/lib/active_support/message_pack/serializer.rb +63 -0
- data/lib/active_support/message_pack.rb +50 -0
- data/lib/active_support/message_verifier.rb +377 -0
- data/lib/active_support/message_verifiers.rb +189 -0
- data/lib/active_support/messages/codec.rb +65 -0
- data/lib/active_support/messages/metadata.rb +146 -0
- data/lib/active_support/messages/rotation_configuration.rb +23 -0
- data/lib/active_support/messages/rotation_coordinator.rb +102 -0
- data/lib/active_support/messages/rotator.rb +69 -0
- data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
- data/lib/active_support/multibyte/chars.rb +188 -0
- data/lib/active_support/multibyte/unicode.rb +42 -0
- data/lib/active_support/multibyte.rb +27 -0
- data/lib/active_support/notifications/fanout.rb +467 -0
- data/lib/active_support/notifications/instrumenter.rb +240 -0
- data/lib/active_support/notifications.rb +281 -0
- data/lib/active_support/number_helper/number_converter.rb +190 -0
- data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +30 -0
- data/lib/active_support/number_helper/number_to_human_converter.rb +69 -0
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +60 -0
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
- data/lib/active_support/number_helper/number_to_phone_converter.rb +60 -0
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +59 -0
- data/lib/active_support/number_helper/rounding_helper.rb +46 -0
- data/lib/active_support/number_helper.rb +479 -0
- data/lib/active_support/option_merger.rb +38 -0
- data/lib/active_support/ordered_hash.rb +50 -0
- data/lib/active_support/ordered_options.rb +141 -25
- data/lib/active_support/parameter_filter.rb +157 -0
- data/lib/active_support/rails.rb +26 -0
- data/lib/active_support/railtie.rb +180 -0
- data/lib/active_support/reloader.rb +138 -0
- data/lib/active_support/rescuable.rb +176 -0
- data/lib/active_support/secure_compare_rotator.rb +58 -0
- data/lib/active_support/security_utils.rb +38 -0
- data/lib/active_support/string_inquirer.rb +35 -0
- data/lib/active_support/structured_event_subscriber.rb +99 -0
- data/lib/active_support/subscriber.rb +141 -0
- data/lib/active_support/syntax_error_proxy.rb +67 -0
- data/lib/active_support/tagged_logging.rb +157 -0
- data/lib/active_support/test_case.rb +365 -0
- data/lib/active_support/testing/assertions.rb +369 -0
- data/lib/active_support/testing/autorun.rb +10 -0
- data/lib/active_support/testing/constant_lookup.rb +51 -0
- data/lib/active_support/testing/constant_stubbing.rb +54 -0
- data/lib/active_support/testing/declarative.rb +28 -0
- data/lib/active_support/testing/deprecation.rb +82 -0
- data/lib/active_support/testing/error_reporter_assertions.rb +124 -0
- data/lib/active_support/testing/event_reporter_assertions.rb +227 -0
- data/lib/active_support/testing/file_fixtures.rb +38 -0
- data/lib/active_support/testing/isolation.rb +121 -0
- data/lib/active_support/testing/method_call_assertions.rb +69 -0
- data/lib/active_support/testing/notification_assertions.rb +92 -0
- data/lib/active_support/testing/parallelization/server.rb +98 -0
- data/lib/active_support/testing/parallelization/worker.rb +107 -0
- data/lib/active_support/testing/parallelization.rb +79 -0
- data/lib/active_support/testing/parallelize_executor.rb +81 -0
- data/lib/active_support/testing/setup_and_teardown.rb +57 -0
- data/lib/active_support/testing/stream.rb +41 -0
- data/lib/active_support/testing/tagged_logging.rb +27 -0
- data/lib/active_support/testing/tests_without_assertions.rb +19 -0
- data/lib/active_support/testing/time_helpers.rb +273 -0
- data/lib/active_support/time.rb +20 -0
- data/lib/active_support/time_with_zone.rb +613 -0
- data/lib/active_support/values/time_zone.rb +599 -158
- data/lib/active_support/version.rb +7 -6
- data/lib/active_support/xml_mini/jdom.rb +175 -0
- data/lib/active_support/xml_mini/libxml.rb +80 -0
- data/lib/active_support/xml_mini/libxmlsax.rb +83 -0
- data/lib/active_support/xml_mini/nokogiri.rb +83 -0
- data/lib/active_support/xml_mini/nokogirisax.rb +86 -0
- data/lib/active_support/xml_mini/rexml.rb +137 -0
- data/lib/active_support/xml_mini.rb +212 -0
- data/lib/active_support.rb +122 -10
- metadata +524 -93
- data/CHANGELOG +0 -283
- data/lib/active_support/binding_of_caller.rb +0 -84
- data/lib/active_support/breakpoint.rb +0 -523
- data/lib/active_support/class_attribute_accessors.rb +0 -57
- data/lib/active_support/class_inheritable_attributes.rb +0 -117
- data/lib/active_support/clean_logger.rb +0 -36
- data/lib/active_support/core_ext/blank.rb +0 -38
- data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +0 -14
- data/lib/active_support/core_ext/cgi.rb +0 -5
- data/lib/active_support/core_ext/exception.rb +0 -29
- data/lib/active_support/core_ext/integer/even_odd.rb +0 -24
- data/lib/active_support/core_ext/object_and_class.rb +0 -44
- data/lib/active_support/module_attribute_accessors.rb +0 -57
- data/lib/active_support/whiny_nil.rb +0 -38
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_support/concurrency/share_lock"
|
|
4
|
+
|
|
5
|
+
module ActiveSupport # :nodoc:
|
|
6
|
+
module Dependencies # :nodoc:
|
|
7
|
+
class Interlock
|
|
8
|
+
def initialize # :nodoc:
|
|
9
|
+
@lock = ActiveSupport::Concurrency::ShareLock.new
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def loading(&block)
|
|
13
|
+
ActiveSupport.deprecator.warn(
|
|
14
|
+
"ActiveSupport::Dependencies::Interlock#loading is deprecated and " \
|
|
15
|
+
"will be removed in Rails 9.0. The loading interlock is no longer " \
|
|
16
|
+
"used since Rails switched to Zeitwerk for autoloading."
|
|
17
|
+
)
|
|
18
|
+
yield if block
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def unloading(&block)
|
|
22
|
+
@lock.exclusive(purpose: :unload, compatible: [:unload], after_compatible: [:unload], &block)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def start_unloading
|
|
26
|
+
@lock.start_exclusive(purpose: :unload, compatible: [:unload])
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def done_unloading
|
|
30
|
+
@lock.stop_exclusive(compatible: [:unload])
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def start_running
|
|
34
|
+
@lock.start_sharing
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def done_running
|
|
38
|
+
@lock.stop_sharing
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def running(&block)
|
|
42
|
+
@lock.sharing(&block)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def permit_concurrent_loads(&block)
|
|
46
|
+
# Soft deprecated: no deprecation warning for now, but this is a no-op.
|
|
47
|
+
yield if block
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def raw_state(&block) # :nodoc:
|
|
51
|
+
@lock.raw_state(&block)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveSupport::Dependencies::RequireDependency
|
|
4
|
+
# <b>Warning:</b> This method is obsolete. The semantics of the autoloader
|
|
5
|
+
# match Ruby's and you do not need to be defensive with load order anymore.
|
|
6
|
+
# Just refer to classes and modules normally.
|
|
7
|
+
#
|
|
8
|
+
# Engines that do not control the mode in which their parent application runs
|
|
9
|
+
# should call +require_dependency+ where needed in case the runtime mode is
|
|
10
|
+
# +:classic+.
|
|
11
|
+
def require_dependency(filename)
|
|
12
|
+
filename = filename.to_path if filename.respond_to?(:to_path)
|
|
13
|
+
|
|
14
|
+
unless filename.is_a?(String)
|
|
15
|
+
raise ArgumentError, "the file name must be either a String or implement #to_path -- you passed #{filename.inspect}"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
if abspath = ActiveSupport::Dependencies.search_for_file(filename)
|
|
19
|
+
require abspath
|
|
20
|
+
else
|
|
21
|
+
require filename
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# We could define require_dependency in Object directly, but a module makes
|
|
26
|
+
# the extension apparent if you list ancestors.
|
|
27
|
+
Object.prepend(self)
|
|
28
|
+
end
|
|
@@ -1,240 +1,102 @@
|
|
|
1
|
-
|
|
2
|
-
require File.dirname(__FILE__) + '/core_ext/load_error'
|
|
1
|
+
# frozen_string_literal: true
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
extend self
|
|
3
|
+
require "active_support/dependencies/interlock"
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
module ActiveSupport # :nodoc:
|
|
6
|
+
module Dependencies # :nodoc:
|
|
7
|
+
require_relative "dependencies/require_dependency"
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def load?
|
|
14
|
-
mechanism == :load
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def depend_on(file_name, swallow_load_errors = false)
|
|
18
|
-
unless loaded.include?(file_name)
|
|
19
|
-
loaded << file_name
|
|
20
|
-
|
|
21
|
-
begin
|
|
22
|
-
require_or_load(file_name)
|
|
23
|
-
rescue LoadError
|
|
24
|
-
raise unless swallow_load_errors
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
9
|
+
singleton_class.attr_accessor :interlock
|
|
10
|
+
@interlock = Interlock.new
|
|
28
11
|
|
|
29
|
-
|
|
30
|
-
depend_on(file_name, true)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def clear
|
|
34
|
-
self.loaded = [ ]
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def require_or_load(file_name)
|
|
38
|
-
file_name = "#{file_name}.rb" unless ! load? || file_name[-3..-1] == '.rb'
|
|
39
|
-
load? ? load(file_name) : require(file_name)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def remove_subclasses_for(*classes)
|
|
43
|
-
Object.remove_subclasses_of(*classes)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# LoadingModules implement namespace-safe dynamic loading.
|
|
47
|
-
# They support automatic loading via const_missing, allowing contained items to be automatically
|
|
48
|
-
# loaded when required. No extra syntax is required, as expressions such as Controller::Admin::UserController
|
|
49
|
-
# load the relavent files automatically.
|
|
50
|
-
#
|
|
51
|
-
# Ruby-style modules are supported, as a folder named 'submodule' will load 'submodule.rb' when available.
|
|
52
|
-
class LoadingModule < Module #:nodoc:
|
|
53
|
-
attr_reader :path
|
|
54
|
-
attr_reader :root
|
|
55
|
-
|
|
56
|
-
class << self
|
|
57
|
-
def root(*load_paths)
|
|
58
|
-
RootLoadingModule.new(*load_paths)
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def initialize(root, path=[])
|
|
63
|
-
@path = path.clone.freeze
|
|
64
|
-
@root = root
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def root?() self.root == self end
|
|
68
|
-
def load_paths() self.root.load_paths end
|
|
69
|
-
|
|
70
|
-
# Load missing constants if possible.
|
|
71
|
-
def const_missing(name)
|
|
72
|
-
const_load!(name) ? const_get(name) : super(name)
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
# Load the controller class or a parent module.
|
|
76
|
-
def const_load!(name, file_name = nil)
|
|
77
|
-
file_name ||= 'application' if root? && name.to_s == 'ApplicationController'
|
|
78
|
-
path = self.path + [file_name || name]
|
|
79
|
-
|
|
80
|
-
load_paths.each do |load_path|
|
|
81
|
-
fs_path = load_path.filesystem_path(path)
|
|
82
|
-
next unless fs_path
|
|
83
|
-
|
|
84
|
-
case
|
|
85
|
-
when File.directory?(fs_path)
|
|
86
|
-
new_module = LoadingModule.new(self.root, self.path + [name])
|
|
87
|
-
self.const_set name, new_module
|
|
88
|
-
if self.root?
|
|
89
|
-
if Object.const_defined?(name)
|
|
90
|
-
msg = "Cannot load module #{name}: Object::#{name} is set to #{Object.const_get(name).inspect}"
|
|
91
|
-
raise NameError, msg
|
|
92
|
-
end
|
|
93
|
-
Object.const_set(name, new_module)
|
|
94
|
-
end
|
|
95
|
-
break
|
|
96
|
-
when File.file?(fs_path)
|
|
97
|
-
loaded_file = self.root.load_file!(fs_path)
|
|
98
|
-
|
|
99
|
-
# Import the loaded constant from Object provided we are the root node.
|
|
100
|
-
self.const_set(name, Object.const_get(name)) if self.root? && Object.const_defined?(name)
|
|
101
|
-
|
|
102
|
-
# Throw an error if we load the file but we don't find the Object we expect
|
|
103
|
-
if loaded_file and not self.const_defined?(name)
|
|
104
|
-
msg = "Already loaded file '#{fs_path}' but '#{name.to_s}' was not set, perhaps you need to rename '#{fs_path}'?"
|
|
105
|
-
raise LoadError, msg
|
|
106
|
-
end
|
|
107
|
-
break
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
self.const_defined?(name)
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
# Is this name present or loadable?
|
|
115
|
-
# This method is used by Routes to find valid controllers.
|
|
116
|
-
def const_available?(name)
|
|
117
|
-
self.const_defined?(name) || load_paths.any? {|lp| lp.filesystem_path(path + [name])}
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
class RootLoadingModule < LoadingModule #:nodoc:
|
|
122
|
-
attr_reader :load_paths
|
|
12
|
+
# :doc:
|
|
123
13
|
|
|
124
|
-
|
|
125
|
-
|
|
14
|
+
# Execute the supplied block without interference from any
|
|
15
|
+
# concurrent loads.
|
|
16
|
+
def self.run_interlock(&block)
|
|
17
|
+
interlock.running(&block)
|
|
126
18
|
end
|
|
127
19
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
20
|
+
# Execute the supplied block while holding an exclusive lock,
|
|
21
|
+
# preventing any other thread from being inside a #run_interlock
|
|
22
|
+
# block at the same time.
|
|
23
|
+
def self.load_interlock(&block)
|
|
24
|
+
ActiveSupport.deprecator.warn(
|
|
25
|
+
"ActiveSupport::Dependencies.load_interlock is deprecated and " \
|
|
26
|
+
"will be removed in Rails 9.0. The loading interlock is no longer " \
|
|
27
|
+
"used since Rails switched to Zeitwerk for autoloading."
|
|
28
|
+
)
|
|
29
|
+
yield if block
|
|
135
30
|
end
|
|
136
31
|
|
|
137
|
-
#
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
end
|
|
32
|
+
# Execute the supplied block while holding an exclusive lock,
|
|
33
|
+
# preventing any other thread from being inside a #run_interlock
|
|
34
|
+
# block at the same time.
|
|
35
|
+
def self.unload_interlock(&block)
|
|
36
|
+
interlock.unloading(&block)
|
|
143
37
|
end
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
# This object defines a path from which Constants can be loaded.
|
|
147
|
-
class ConstantLoadPath #:nodoc:
|
|
148
|
-
# Create a new load path with the filesystem path
|
|
149
|
-
def initialize(root) @root = root end
|
|
150
|
-
|
|
151
|
-
# Return nil if the path does not exist, or the path to a directory
|
|
152
|
-
# if the path leads to a module, or the path to a file if it leads to an object.
|
|
153
|
-
def filesystem_path(path, allow_module=true)
|
|
154
|
-
fs_path = [@root]
|
|
155
|
-
fs_path += path[0..-2].map {|name| const_name_to_module_name name}
|
|
156
|
-
|
|
157
|
-
if allow_module
|
|
158
|
-
result = File.join(fs_path, const_name_to_module_name(path.last))
|
|
159
|
-
return result if File.directory? result # Return the module path if one exists
|
|
160
|
-
end
|
|
161
38
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
39
|
+
# :nodoc:
|
|
40
|
+
|
|
41
|
+
# The array of directories from which we autoload and reload, if reloading
|
|
42
|
+
# is enabled. The public interface to push directories to this collection
|
|
43
|
+
# from applications or engines is config.autoload_paths.
|
|
44
|
+
#
|
|
45
|
+
# This collection is allowed to have intersection with autoload_once_paths.
|
|
46
|
+
# Common directories are not reloaded.
|
|
47
|
+
singleton_class.attr_accessor :autoload_paths
|
|
48
|
+
self.autoload_paths = []
|
|
49
|
+
|
|
50
|
+
# The array of directories from which we autoload and never reload, even if
|
|
51
|
+
# reloading is enabled. The public interface to push directories to this
|
|
52
|
+
# collection from applications or engines is config.autoload_once_paths.
|
|
53
|
+
singleton_class.attr_accessor :autoload_once_paths
|
|
54
|
+
self.autoload_once_paths = []
|
|
55
|
+
|
|
56
|
+
# This is a private set that collects all eager load paths during bootstrap.
|
|
57
|
+
# Useful for Zeitwerk integration. The public interface to push custom
|
|
58
|
+
# directories to this collection from applications or engines is
|
|
59
|
+
# config.eager_load_paths.
|
|
60
|
+
singleton_class.attr_accessor :_eager_load_paths
|
|
61
|
+
self._eager_load_paths = Set.new
|
|
62
|
+
|
|
63
|
+
# If reloading is enabled, this private set holds autoloaded classes tracked
|
|
64
|
+
# by the descendants tracker. It is populated by an on_load callback in the
|
|
65
|
+
# main autoloader. Used to clear state.
|
|
66
|
+
singleton_class.attr_accessor :_autoloaded_tracked_classes
|
|
67
|
+
self._autoloaded_tracked_classes = Set.new
|
|
68
|
+
|
|
69
|
+
# If reloading is enabled, this private attribute stores the main autoloader
|
|
70
|
+
# of a Rails application. It is `nil` otherwise.
|
|
71
|
+
#
|
|
72
|
+
# The public interface for this autoloader is `Rails.autoloaders.main`.
|
|
73
|
+
singleton_class.attr_accessor :autoloader
|
|
74
|
+
|
|
75
|
+
# Private method that reloads constants autoloaded by the main autoloader.
|
|
76
|
+
#
|
|
77
|
+
# Rails.application.reloader.reload! is the public interface for application
|
|
78
|
+
# reload. That involves more things, like deleting unloaded classes from the
|
|
79
|
+
# internal state of the descendants tracker, or reloading routes.
|
|
80
|
+
def self.clear
|
|
81
|
+
unload_interlock do
|
|
82
|
+
_autoloaded_tracked_classes.clear
|
|
83
|
+
autoloader.reload
|
|
84
|
+
end
|
|
169
85
|
end
|
|
170
86
|
|
|
171
|
-
|
|
172
|
-
|
|
87
|
+
# Private method used by require_dependency.
|
|
88
|
+
def self.search_for_file(relpath)
|
|
89
|
+
relpath += ".rb" unless relpath.end_with?(".rb")
|
|
90
|
+
autoload_paths.each do |autoload_path|
|
|
91
|
+
abspath = File.join(autoload_path, relpath)
|
|
92
|
+
return abspath if File.file?(abspath)
|
|
93
|
+
end
|
|
94
|
+
nil
|
|
173
95
|
end
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
Object.send(:define_method, :require_or_load) { |file_name| Dependencies.require_or_load(file_name) } unless Object.respond_to?(:require_or_load)
|
|
178
|
-
Object.send(:define_method, :require_dependency) { |file_name| Dependencies.depend_on(file_name) } unless Object.respond_to?(:require_dependency)
|
|
179
|
-
Object.send(:define_method, :require_association) { |file_name| Dependencies.associate_with(file_name) } unless Object.respond_to?(:require_association)
|
|
180
|
-
|
|
181
|
-
class Module #:nodoc:
|
|
182
|
-
# Rename the original handler so we can chain it to the new one
|
|
183
|
-
alias :rails_original_const_missing :const_missing
|
|
184
96
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if Object.const_defined?(:Controllers) and Object::Controllers.const_available?(class_id)
|
|
189
|
-
return Object::Controllers.const_get(class_id)
|
|
97
|
+
# Private method that helps configuring the autoloaders.
|
|
98
|
+
def self.eager_load?(path)
|
|
99
|
+
_eager_load_paths.member?(path)
|
|
190
100
|
end
|
|
191
|
-
|
|
192
|
-
file_name = class_id.to_s.demodulize.underscore
|
|
193
|
-
begin
|
|
194
|
-
require_dependency(file_name)
|
|
195
|
-
raise NameError.new("uninitialized constant #{class_id}") unless Object.const_defined?(class_id)
|
|
196
|
-
return Object.const_get(class_id)
|
|
197
|
-
rescue MissingSourceFile => e
|
|
198
|
-
# Convert the exception to a NameError only if the file we are looking for is the missing one.
|
|
199
|
-
raise unless e.is_missing? file_name
|
|
200
|
-
raise NameError.new("uninitialized constant #{class_id}").copy_blame!(e)
|
|
201
|
-
end
|
|
202
|
-
end
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
class Object #:nodoc:
|
|
206
|
-
def load(file, *extras)
|
|
207
|
-
super(file, *extras)
|
|
208
|
-
rescue Object => exception
|
|
209
|
-
exception.blame_file! file
|
|
210
|
-
raise
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
def require(file, *extras)
|
|
214
|
-
super(file, *extras)
|
|
215
|
-
rescue Object => exception
|
|
216
|
-
exception.blame_file! file
|
|
217
|
-
raise
|
|
218
|
-
end
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
# Add file-blaming to exceptions
|
|
222
|
-
class Exception #:nodoc:
|
|
223
|
-
def blame_file!(file)
|
|
224
|
-
(@blamed_files ||= []).unshift file
|
|
225
|
-
end
|
|
226
|
-
|
|
227
|
-
def blamed_files
|
|
228
|
-
@blamed_files ||= []
|
|
229
|
-
end
|
|
230
|
-
|
|
231
|
-
def describe_blame
|
|
232
|
-
return nil if blamed_files.empty?
|
|
233
|
-
"This error occured while loading the following files:\n #{blamed_files.join "\n "}"
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
def copy_blame!(exc)
|
|
237
|
-
@blamed_files = exc.blamed_files.clone
|
|
238
|
-
self
|
|
239
101
|
end
|
|
240
102
|
end
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_support/notifications"
|
|
4
|
+
|
|
5
|
+
module ActiveSupport
|
|
6
|
+
# Raised when ActiveSupport::Deprecation::Behavior#behavior is set with <tt>:raise</tt>.
|
|
7
|
+
# You would set <tt>:raise</tt>, as a behavior to raise errors and proactively report exceptions from deprecations.
|
|
8
|
+
class DeprecationException < StandardError
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class Deprecation
|
|
12
|
+
# Default warning behaviors per Rails.env.
|
|
13
|
+
DEFAULT_BEHAVIORS = {
|
|
14
|
+
raise: ->(message, callstack, deprecator) do
|
|
15
|
+
e = DeprecationException.new(message)
|
|
16
|
+
e.set_backtrace(callstack.map(&:to_s))
|
|
17
|
+
raise e
|
|
18
|
+
end,
|
|
19
|
+
|
|
20
|
+
stderr: ->(message, callstack, deprecator) do
|
|
21
|
+
$stderr.puts(message)
|
|
22
|
+
$stderr.puts callstack.join("\n ") if deprecator.debug
|
|
23
|
+
end,
|
|
24
|
+
|
|
25
|
+
log: ->(message, callstack, deprecator) do
|
|
26
|
+
logger =
|
|
27
|
+
if defined?(Rails.logger) && Rails.logger
|
|
28
|
+
Rails.logger
|
|
29
|
+
else
|
|
30
|
+
require "active_support/logger"
|
|
31
|
+
ActiveSupport::Logger.new($stderr)
|
|
32
|
+
end
|
|
33
|
+
logger.warn message
|
|
34
|
+
logger.debug callstack.join("\n ") if deprecator.debug
|
|
35
|
+
end,
|
|
36
|
+
|
|
37
|
+
notify: ->(message, callstack, deprecator) do
|
|
38
|
+
ActiveSupport::Notifications.instrument(
|
|
39
|
+
"deprecation.#{deprecator.gem_name.underscore.tr("/", "_")}",
|
|
40
|
+
message: message,
|
|
41
|
+
callstack: callstack,
|
|
42
|
+
gem_name: deprecator.gem_name,
|
|
43
|
+
deprecation_horizon: deprecator.deprecation_horizon,
|
|
44
|
+
)
|
|
45
|
+
end,
|
|
46
|
+
|
|
47
|
+
silence: ->(message, callstack, deprecator) { },
|
|
48
|
+
|
|
49
|
+
report: ->(message, callstack, deprecator) do
|
|
50
|
+
error = DeprecationException.new(message)
|
|
51
|
+
error.set_backtrace(callstack.map(&:to_s))
|
|
52
|
+
ActiveSupport.error_reporter.report(error)
|
|
53
|
+
end
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
# Behavior module allows to determine how to display deprecation messages.
|
|
57
|
+
# You can create a custom behavior or set any from the +DEFAULT_BEHAVIORS+
|
|
58
|
+
# constant. Available behaviors are:
|
|
59
|
+
#
|
|
60
|
+
# [+:raise+] Raise ActiveSupport::DeprecationException.
|
|
61
|
+
# [+:stderr+] Log all deprecation warnings to <tt>$stderr</tt>.
|
|
62
|
+
# [+:log+] Log all deprecation warnings to +Rails.logger+.
|
|
63
|
+
# [+:notify+] Use ActiveSupport::Notifications to notify +deprecation.rails+.
|
|
64
|
+
# [+:report+] Use ActiveSupport::ErrorReporter to report deprecations.
|
|
65
|
+
# [+:silence+] Do nothing. On \Rails, set <tt>config.active_support.report_deprecations = false</tt> to disable all behaviors.
|
|
66
|
+
#
|
|
67
|
+
# Setting behaviors only affects deprecations that happen after boot time.
|
|
68
|
+
# For more information you can read the documentation of the #behavior= method.
|
|
69
|
+
module Behavior
|
|
70
|
+
# Whether to print a backtrace along with the warning.
|
|
71
|
+
attr_accessor :debug
|
|
72
|
+
|
|
73
|
+
# Returns the current behavior or if one isn't set, defaults to +:stderr+.
|
|
74
|
+
def behavior
|
|
75
|
+
@behavior ||= [DEFAULT_BEHAVIORS[:stderr]]
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Returns the current behavior for disallowed deprecations or if one isn't set, defaults to +:raise+.
|
|
79
|
+
def disallowed_behavior
|
|
80
|
+
@disallowed_behavior ||= [DEFAULT_BEHAVIORS[:raise]]
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Sets the behavior to the specified value. Can be a single value, array,
|
|
84
|
+
# or an object that responds to +call+.
|
|
85
|
+
#
|
|
86
|
+
# Available behaviors:
|
|
87
|
+
#
|
|
88
|
+
# [+:raise+] Raise ActiveSupport::DeprecationException.
|
|
89
|
+
# [+:stderr+] Log all deprecation warnings to <tt>$stderr</tt>.
|
|
90
|
+
# [+:log+] Log all deprecation warnings to +Rails.logger+.
|
|
91
|
+
# [+:notify+] Use ActiveSupport::Notifications to notify +deprecation.rails+.
|
|
92
|
+
# [+:report+] Use ActiveSupport::ErrorReporter to report deprecations.
|
|
93
|
+
# [+:silence+] Do nothing.
|
|
94
|
+
#
|
|
95
|
+
# Setting behaviors only affects deprecations that happen after boot time.
|
|
96
|
+
# Deprecation warnings raised by gems are not affected by this setting
|
|
97
|
+
# because they happen before \Rails boots up.
|
|
98
|
+
#
|
|
99
|
+
# deprecator = ActiveSupport::Deprecation.new
|
|
100
|
+
# deprecator.behavior = :stderr
|
|
101
|
+
# deprecator.behavior = [:stderr, :log]
|
|
102
|
+
# deprecator.behavior = MyCustomHandler
|
|
103
|
+
# deprecator.behavior = ->(message, callstack, deprecation_horizon, gem_name) {
|
|
104
|
+
# # custom stuff
|
|
105
|
+
# }
|
|
106
|
+
#
|
|
107
|
+
# If you are using \Rails, you can set
|
|
108
|
+
# <tt>config.active_support.report_deprecations = false</tt> to disable
|
|
109
|
+
# all deprecation behaviors. This is similar to the +:silence+ option but
|
|
110
|
+
# more performant.
|
|
111
|
+
def behavior=(behavior)
|
|
112
|
+
@behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) }
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Sets the behavior for disallowed deprecations (those configured by
|
|
116
|
+
# ActiveSupport::Deprecation#disallowed_warnings=) to the specified
|
|
117
|
+
# value. As with #behavior=, this can be a single value, array, or an
|
|
118
|
+
# object that responds to +call+.
|
|
119
|
+
def disallowed_behavior=(behavior)
|
|
120
|
+
@disallowed_behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) }
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
private
|
|
124
|
+
def arity_coerce(behavior)
|
|
125
|
+
unless behavior.respond_to?(:call)
|
|
126
|
+
raise ArgumentError, "#{behavior.inspect} is not a valid deprecation behavior."
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
case arity_of_callable(behavior)
|
|
130
|
+
when 2
|
|
131
|
+
->(message, callstack, deprecator) do
|
|
132
|
+
behavior.call(message, callstack)
|
|
133
|
+
end
|
|
134
|
+
when -2..3
|
|
135
|
+
behavior
|
|
136
|
+
else
|
|
137
|
+
->(message, callstack, deprecator) do
|
|
138
|
+
behavior.call(message, callstack, deprecator.deprecation_horizon, deprecator.gem_name)
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def arity_of_callable(callable)
|
|
144
|
+
callable.respond_to?(:arity) ? callable.arity : callable.method(:call).arity
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveSupport
|
|
4
|
+
class Deprecation
|
|
5
|
+
module DeprecatedConstantAccessor
|
|
6
|
+
def self.included(base)
|
|
7
|
+
require "active_support/inflector/methods"
|
|
8
|
+
|
|
9
|
+
extension = Module.new do
|
|
10
|
+
def const_missing(missing_const_name)
|
|
11
|
+
if class_variable_defined?(:@@_deprecated_constants)
|
|
12
|
+
if (replacement = class_variable_get(:@@_deprecated_constants)[missing_const_name.to_s])
|
|
13
|
+
replacement[:deprecator].warn(replacement[:message] || "#{name}::#{missing_const_name} is deprecated! Use #{replacement[:new]} instead.", caller_locations)
|
|
14
|
+
return ActiveSupport::Inflector.constantize(replacement[:new].to_s)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
super
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Provides a way to rename constants with a deprecation cycle in which
|
|
21
|
+
# both the old and new names work, but using the old one prints a
|
|
22
|
+
# deprecation message.
|
|
23
|
+
#
|
|
24
|
+
# In order to rename <tt>A::B</tt> to <tt>C::D</tt>, you need to delete the
|
|
25
|
+
# definition of <tt>A::B</tt> and declare the deprecation in +A+:
|
|
26
|
+
#
|
|
27
|
+
# require "active_support/deprecation"
|
|
28
|
+
#
|
|
29
|
+
# module A
|
|
30
|
+
# include ActiveSupport::Deprecation::DeprecatedConstantAccessor
|
|
31
|
+
#
|
|
32
|
+
# deprecate_constant "B", "C::D", deprecator: ActiveSupport::Deprecation.new
|
|
33
|
+
# end
|
|
34
|
+
#
|
|
35
|
+
# The first argument is a constant name (no colons). It is the name of
|
|
36
|
+
# the constant you want to deprecate in the enclosing class or module.
|
|
37
|
+
#
|
|
38
|
+
# The second argument is the constant path of the replacement. That
|
|
39
|
+
# has to be a full path even if the replacement is defined in the same
|
|
40
|
+
# namespace as the deprecated one was.
|
|
41
|
+
#
|
|
42
|
+
# In both cases, strings and symbols are supported.
|
|
43
|
+
#
|
|
44
|
+
# The +deprecator+ keyword argument is the object that will print the
|
|
45
|
+
# deprecation message, an instance of ActiveSupport::Deprecation.
|
|
46
|
+
#
|
|
47
|
+
# With that in place, references to <tt>A::B</tt> still work, they
|
|
48
|
+
# evaluate to <tt>C::D</tt> now, and trigger a deprecation warning:
|
|
49
|
+
#
|
|
50
|
+
# DEPRECATION WARNING: A::B is deprecated! Use C::D instead.
|
|
51
|
+
# (called from ...)
|
|
52
|
+
#
|
|
53
|
+
# The message can be customized with the optional +message+ keyword
|
|
54
|
+
# argument.
|
|
55
|
+
#
|
|
56
|
+
# For this to work, a +const_missing+ hook is installed. When client
|
|
57
|
+
# code references the deprecated constant, the callback prints the
|
|
58
|
+
# message and constantizes the replacement.
|
|
59
|
+
#
|
|
60
|
+
# Caveat: If the deprecated constant name is reachable in a different
|
|
61
|
+
# namespace and Ruby constant lookup finds it, the hook won't be
|
|
62
|
+
# called and the deprecation won't work as intended. This may happen,
|
|
63
|
+
# for example, if an ancestor of the enclosing namespace has a
|
|
64
|
+
# constant with the same name. This is an unsupported edge case.
|
|
65
|
+
def deprecate_constant(old_constant_name, new_constant_path, deprecator:, message: nil)
|
|
66
|
+
class_variable_set(:@@_deprecated_constants, {}) unless class_variable_defined?(:@@_deprecated_constants)
|
|
67
|
+
class_variable_get(:@@_deprecated_constants)[old_constant_name.to_s] = { new: new_constant_path, message: message, deprecator: deprecator }
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
base.singleton_class.prepend extension
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|