activesupport 5.2.0 → 6.0.3.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.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +479 -330
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -3
- data/lib/active_support.rb +2 -1
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +27 -1
- data/lib/active_support/cache.rb +104 -84
- data/lib/active_support/cache/file_store.rb +29 -30
- data/lib/active_support/cache/mem_cache_store.rb +14 -19
- data/lib/active_support/cache/memory_store.rb +15 -9
- data/lib/active_support/cache/null_store.rb +8 -3
- data/lib/active_support/cache/redis_cache_store.rb +73 -34
- data/lib/active_support/cache/strategy/local_cache.rb +23 -23
- data/lib/active_support/callbacks.rb +16 -8
- data/lib/active_support/concern.rb +31 -4
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
- data/lib/active_support/concurrency/share_lock.rb +0 -1
- data/lib/active_support/configurable.rb +7 -11
- data/lib/active_support/core_ext/array.rb +1 -1
- data/lib/active_support/core_ext/array/access.rb +18 -6
- data/lib/active_support/core_ext/array/conversions.rb +5 -5
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +2 -6
- data/lib/active_support/core_ext/class/attribute.rb +11 -16
- data/lib/active_support/core_ext/class/subclasses.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +6 -5
- data/lib/active_support/core_ext/date_and_time/calculations.rb +24 -47
- data/lib/active_support/core_ext/date_and_time/zones.rb +0 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
- data/lib/active_support/core_ext/date_time/conversions.rb +0 -1
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +97 -68
- data/lib/active_support/core_ext/file/atomic.rb +1 -1
- data/lib/active_support/core_ext/hash.rb +1 -2
- data/lib/active_support/core_ext/hash/compact.rb +2 -26
- data/lib/active_support/core_ext/hash/conversions.rb +1 -1
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +0 -29
- data/lib/active_support/core_ext/hash/slice.rb +3 -25
- data/lib/active_support/core_ext/hash/transform_values.rb +2 -29
- data/lib/active_support/core_ext/integer/multiple.rb +1 -1
- data/lib/active_support/core_ext/kernel.rb +0 -1
- data/lib/active_support/core_ext/load_error.rb +1 -1
- data/lib/active_support/core_ext/module.rb +0 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +7 -10
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +13 -19
- data/lib/active_support/core_ext/module/delegation.rb +41 -8
- data/lib/active_support/core_ext/module/introspection.rb +38 -13
- data/lib/active_support/core_ext/module/reachable.rb +1 -6
- data/lib/active_support/core_ext/module/redefine_method.rb +8 -17
- data/lib/active_support/core_ext/numeric.rb +0 -1
- data/lib/active_support/core_ext/numeric/conversions.rb +124 -128
- data/lib/active_support/core_ext/numeric/inquiry.rb +2 -25
- data/lib/active_support/core_ext/object/blank.rb +1 -2
- data/lib/active_support/core_ext/object/duplicable.rb +7 -114
- data/lib/active_support/core_ext/object/json.rb +1 -0
- data/lib/active_support/core_ext/object/to_query.rb +5 -2
- data/lib/active_support/core_ext/object/try.rb +17 -7
- data/lib/active_support/core_ext/object/with_options.rb +1 -1
- data/lib/active_support/core_ext/range.rb +1 -1
- data/lib/active_support/core_ext/range/compare_range.rb +76 -0
- data/lib/active_support/core_ext/range/conversions.rb +31 -29
- data/lib/active_support/core_ext/range/each.rb +0 -1
- data/lib/active_support/core_ext/range/include_range.rb +6 -22
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +2 -2
- data/lib/active_support/core_ext/regexp.rb +0 -4
- data/lib/active_support/core_ext/securerandom.rb +23 -3
- data/lib/active_support/core_ext/string/access.rb +8 -0
- data/lib/active_support/core_ext/string/filters.rb +42 -1
- data/lib/active_support/core_ext/string/inflections.rb +7 -2
- data/lib/active_support/core_ext/string/multibyte.rb +4 -3
- data/lib/active_support/core_ext/string/output_safety.rb +63 -6
- data/lib/active_support/core_ext/string/strip.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +31 -2
- data/lib/active_support/core_ext/uri.rb +2 -4
- data/lib/active_support/current_attributes.rb +8 -0
- data/lib/active_support/dependencies.rb +77 -18
- data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
- data/lib/active_support/deprecation.rb +1 -1
- data/lib/active_support/deprecation/behaviors.rb +5 -1
- data/lib/active_support/deprecation/method_wrappers.rb +20 -13
- data/lib/active_support/deprecation/proxy_wrappers.rb +28 -5
- data/lib/active_support/deprecation/reporting.rb +1 -1
- data/lib/active_support/descendants_tracker.rb +55 -9
- data/lib/active_support/duration.rb +19 -16
- data/lib/active_support/duration/iso8601_parser.rb +2 -4
- data/lib/active_support/duration/iso8601_serializer.rb +3 -5
- data/lib/active_support/encrypted_configuration.rb +1 -5
- data/lib/active_support/encrypted_file.rb +4 -3
- data/lib/active_support/evented_file_update_checker.rb +39 -10
- data/lib/active_support/execution_wrapper.rb +1 -0
- data/lib/active_support/file_update_checker.rb +0 -1
- data/lib/active_support/gem_version.rb +4 -4
- data/lib/active_support/hash_with_indifferent_access.rb +36 -18
- data/lib/active_support/i18n.rb +1 -0
- data/lib/active_support/i18n_railtie.rb +18 -2
- data/lib/active_support/inflector/inflections.rb +1 -5
- data/lib/active_support/inflector/methods.rb +18 -29
- data/lib/active_support/inflector/transliterate.rb +47 -18
- data/lib/active_support/json/decoding.rb +23 -24
- data/lib/active_support/json/encoding.rb +6 -2
- data/lib/active_support/key_generator.rb +0 -32
- data/lib/active_support/lazy_load_hooks.rb +5 -2
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/log_subscriber.rb +31 -9
- data/lib/active_support/logger.rb +1 -16
- data/lib/active_support/logger_silence.rb +28 -12
- data/lib/active_support/logger_thread_safe_level.rb +28 -5
- data/lib/active_support/message_encryptor.rb +4 -6
- data/lib/active_support/message_verifier.rb +5 -5
- data/lib/active_support/messages/metadata.rb +3 -2
- data/lib/active_support/messages/rotator.rb +4 -4
- data/lib/active_support/multibyte/chars.rb +29 -49
- data/lib/active_support/multibyte/unicode.rb +44 -282
- data/lib/active_support/notifications.rb +41 -4
- data/lib/active_support/notifications/fanout.rb +100 -15
- data/lib/active_support/notifications/instrumenter.rb +80 -9
- data/lib/active_support/number_helper.rb +11 -0
- data/lib/active_support/number_helper/number_converter.rb +4 -5
- data/lib/active_support/number_helper/number_to_currency_converter.rb +9 -10
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +3 -2
- data/lib/active_support/number_helper/number_to_human_converter.rb +3 -2
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -2
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +5 -4
- data/lib/active_support/option_merger.rb +21 -3
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/ordered_options.rb +5 -1
- data/lib/active_support/parameter_filter.rb +128 -0
- data/lib/active_support/rails.rb +0 -6
- data/lib/active_support/reloader.rb +4 -5
- data/lib/active_support/security_utils.rb +1 -1
- data/lib/active_support/string_inquirer.rb +0 -1
- data/lib/active_support/subscriber.rb +65 -22
- data/lib/active_support/tagged_logging.rb +13 -4
- data/lib/active_support/test_case.rb +92 -1
- data/lib/active_support/testing/assertions.rb +15 -1
- data/lib/active_support/testing/deprecation.rb +0 -1
- data/lib/active_support/testing/file_fixtures.rb +2 -0
- data/lib/active_support/testing/isolation.rb +2 -2
- data/lib/active_support/testing/method_call_assertions.rb +28 -1
- data/lib/active_support/testing/parallelization.rb +134 -0
- data/lib/active_support/testing/setup_and_teardown.rb +5 -9
- data/lib/active_support/testing/stream.rb +1 -2
- data/lib/active_support/testing/time_helpers.rb +7 -9
- data/lib/active_support/time_with_zone.rb +15 -5
- data/lib/active_support/values/time_zone.rb +14 -8
- data/lib/active_support/xml_mini.rb +2 -10
- data/lib/active_support/xml_mini/jdom.rb +2 -3
- data/lib/active_support/xml_mini/libxml.rb +2 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +4 -4
- data/lib/active_support/xml_mini/nokogiri.rb +2 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +3 -3
- data/lib/active_support/xml_mini/rexml.rb +2 -2
- metadata +42 -13
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "set"
|
4
|
+
require "active_support/core_ext/string/inflections"
|
5
|
+
|
6
|
+
module ActiveSupport
|
7
|
+
module Dependencies
|
8
|
+
module ZeitwerkIntegration # :nodoc: all
|
9
|
+
module Decorations
|
10
|
+
def clear
|
11
|
+
Dependencies.unload_interlock do
|
12
|
+
Rails.autoloaders.main.reload
|
13
|
+
rescue Zeitwerk::ReloadingDisabledError
|
14
|
+
raise "reloading is disabled because config.cache_classes is true"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def constantize(cpath)
|
19
|
+
ActiveSupport::Inflector.constantize(cpath)
|
20
|
+
end
|
21
|
+
|
22
|
+
def safe_constantize(cpath)
|
23
|
+
ActiveSupport::Inflector.safe_constantize(cpath)
|
24
|
+
end
|
25
|
+
|
26
|
+
def autoloaded_constants
|
27
|
+
Rails.autoloaders.main.unloadable_cpaths
|
28
|
+
end
|
29
|
+
|
30
|
+
def autoloaded?(object)
|
31
|
+
cpath = object.is_a?(Module) ? real_mod_name(object) : object.to_s
|
32
|
+
Rails.autoloaders.main.unloadable_cpath?(cpath)
|
33
|
+
end
|
34
|
+
|
35
|
+
def verbose=(verbose)
|
36
|
+
l = verbose ? logger || Rails.logger : nil
|
37
|
+
Rails.autoloaders.each { |autoloader| autoloader.logger = l }
|
38
|
+
end
|
39
|
+
|
40
|
+
def unhook!
|
41
|
+
:no_op
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module RequireDependency
|
46
|
+
def require_dependency(filename)
|
47
|
+
filename = filename.to_path if filename.respond_to?(:to_path)
|
48
|
+
if abspath = ActiveSupport::Dependencies.search_for_file(filename)
|
49
|
+
require abspath
|
50
|
+
else
|
51
|
+
require filename
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
module Inflector
|
57
|
+
# Concurrent::Map is not needed. This is a private class, and overrides
|
58
|
+
# must be defined while the application boots.
|
59
|
+
@overrides = {}
|
60
|
+
|
61
|
+
def self.camelize(basename, _abspath)
|
62
|
+
@overrides[basename] || basename.camelize
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.inflect(overrides)
|
66
|
+
@overrides.merge!(overrides)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class << self
|
71
|
+
def take_over(enable_reloading:)
|
72
|
+
setup_autoloaders(enable_reloading)
|
73
|
+
freeze_paths
|
74
|
+
decorate_dependencies
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
def setup_autoloaders(enable_reloading)
|
79
|
+
Dependencies.autoload_paths.each do |autoload_path|
|
80
|
+
# Zeitwerk only accepts existing directories in `push_dir` to
|
81
|
+
# prevent misconfigurations.
|
82
|
+
next unless File.directory?(autoload_path)
|
83
|
+
|
84
|
+
autoloader = \
|
85
|
+
autoload_once?(autoload_path) ? Rails.autoloaders.once : Rails.autoloaders.main
|
86
|
+
|
87
|
+
autoloader.push_dir(autoload_path)
|
88
|
+
autoloader.do_not_eager_load(autoload_path) unless eager_load?(autoload_path)
|
89
|
+
end
|
90
|
+
|
91
|
+
Rails.autoloaders.main.enable_reloading if enable_reloading
|
92
|
+
Rails.autoloaders.each(&:setup)
|
93
|
+
end
|
94
|
+
|
95
|
+
def autoload_once?(autoload_path)
|
96
|
+
Dependencies.autoload_once_paths.include?(autoload_path)
|
97
|
+
end
|
98
|
+
|
99
|
+
def eager_load?(autoload_path)
|
100
|
+
Dependencies._eager_load_paths.member?(autoload_path)
|
101
|
+
end
|
102
|
+
|
103
|
+
def freeze_paths
|
104
|
+
Dependencies.autoload_paths.freeze
|
105
|
+
Dependencies.autoload_once_paths.freeze
|
106
|
+
Dependencies._eager_load_paths.freeze
|
107
|
+
end
|
108
|
+
|
109
|
+
def decorate_dependencies
|
110
|
+
Dependencies.unhook!
|
111
|
+
Dependencies.singleton_class.prepend(Decorations)
|
112
|
+
Object.prepend(RequireDependency)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -35,7 +35,7 @@ module ActiveSupport
|
|
35
35
|
# and the second is a library name.
|
36
36
|
#
|
37
37
|
# ActiveSupport::Deprecation.new('2.0', 'MyLibrary')
|
38
|
-
def initialize(deprecation_horizon = "6.
|
38
|
+
def initialize(deprecation_horizon = "6.1", gem_name = "Rails")
|
39
39
|
self.gem_name = gem_name
|
40
40
|
self.deprecation_horizon = deprecation_horizon
|
41
41
|
# By default, warnings are not silenced and debugging is off.
|
@@ -43,7 +43,7 @@ module ActiveSupport
|
|
43
43
|
deprecation_horizon: deprecation_horizon)
|
44
44
|
},
|
45
45
|
|
46
|
-
silence: ->(message, callstack, deprecation_horizon, gem_name) {},
|
46
|
+
silence: ->(message, callstack, deprecation_horizon, gem_name) { },
|
47
47
|
}
|
48
48
|
|
49
49
|
# Behavior module allows to determine how to display deprecation messages.
|
@@ -94,6 +94,10 @@ module ActiveSupport
|
|
94
94
|
|
95
95
|
private
|
96
96
|
def arity_coerce(behavior)
|
97
|
+
unless behavior.respond_to?(:call)
|
98
|
+
raise ArgumentError, "#{behavior.inspect} is not a valid deprecation behavior."
|
99
|
+
end
|
100
|
+
|
97
101
|
if behavior.arity == 4 || behavior.arity == -1
|
98
102
|
behavior
|
99
103
|
else
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/core_ext/module/aliasing"
|
4
3
|
require "active_support/core_ext/array/extract_options"
|
4
|
+
require "active_support/core_ext/module/redefine_method"
|
5
5
|
|
6
6
|
module ActiveSupport
|
7
7
|
class Deprecation
|
@@ -53,24 +53,31 @@ module ActiveSupport
|
|
53
53
|
options = method_names.extract_options!
|
54
54
|
deprecator = options.delete(:deprecator) || self
|
55
55
|
method_names += options.keys
|
56
|
+
mod = nil
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
58
|
+
method_names.each do |method_name|
|
59
|
+
if target_module.method_defined?(method_name) || target_module.private_method_defined?(method_name)
|
60
|
+
method = target_module.instance_method(method_name)
|
61
|
+
target_module.module_eval do
|
62
|
+
redefine_method(method_name) do |*args, &block|
|
63
|
+
deprecator.deprecation_warning(method_name, options[method_name])
|
64
|
+
method.bind(self).call(*args, &block)
|
65
|
+
end
|
66
|
+
ruby2_keywords(method_name) if respond_to?(:ruby2_keywords, true)
|
62
67
|
end
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
68
|
+
else
|
69
|
+
mod ||= Module.new
|
70
|
+
mod.module_eval do
|
71
|
+
define_method(method_name) do |*args, &block|
|
72
|
+
deprecator.deprecation_warning(method_name, options[method_name])
|
73
|
+
super(*args, &block)
|
74
|
+
end
|
75
|
+
ruby2_keywords(method_name) if respond_to?(:ruby2_keywords, true)
|
69
76
|
end
|
70
77
|
end
|
71
78
|
end
|
72
79
|
|
73
|
-
target_module.prepend(mod)
|
80
|
+
target_module.prepend(mod) if mod
|
74
81
|
end
|
75
82
|
end
|
76
83
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/core_ext/regexp"
|
4
|
-
|
5
3
|
module ActiveSupport
|
6
4
|
class Deprecation
|
7
5
|
class DeprecationProxy #:nodoc:
|
@@ -122,7 +120,14 @@ module ActiveSupport
|
|
122
120
|
# # => DEPRECATION WARNING: PLANETS is deprecated! Use PLANETS_POST_2006 instead.
|
123
121
|
# (Backtrace information…)
|
124
122
|
# ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]
|
125
|
-
class DeprecatedConstantProxy <
|
123
|
+
class DeprecatedConstantProxy < Module
|
124
|
+
def self.new(*args, **kwargs, &block)
|
125
|
+
object = args.first
|
126
|
+
|
127
|
+
return object unless object
|
128
|
+
super
|
129
|
+
end
|
130
|
+
|
126
131
|
def initialize(old_const, new_const, deprecator = ActiveSupport::Deprecation.instance, message: "#{old_const} is deprecated! Use #{new_const} instead.")
|
127
132
|
require "active_support/inflector/methods"
|
128
133
|
|
@@ -132,6 +137,18 @@ module ActiveSupport
|
|
132
137
|
@message = message
|
133
138
|
end
|
134
139
|
|
140
|
+
instance_methods.each { |m| undef_method m unless /^__|^object_id$/.match?(m) }
|
141
|
+
|
142
|
+
# Don't give a deprecation warning on inspect since test/unit and error
|
143
|
+
# logs rely on it for diagnostics.
|
144
|
+
def inspect
|
145
|
+
target.inspect
|
146
|
+
end
|
147
|
+
|
148
|
+
# Don't give a deprecation warning on methods that IRB may invoke
|
149
|
+
# during tab-completion.
|
150
|
+
delegate :hash, :instance_methods, :name, to: :target
|
151
|
+
|
135
152
|
# Returns the class of the new constant.
|
136
153
|
#
|
137
154
|
# PLANETS_POST_2006 = %w(mercury venus earth mars jupiter saturn uranus neptune)
|
@@ -146,8 +163,14 @@ module ActiveSupport
|
|
146
163
|
ActiveSupport::Inflector.constantize(@new_const.to_s)
|
147
164
|
end
|
148
165
|
|
149
|
-
def
|
150
|
-
@deprecator.warn(@message,
|
166
|
+
def const_missing(name)
|
167
|
+
@deprecator.warn(@message, caller_locations)
|
168
|
+
target.const_get(name)
|
169
|
+
end
|
170
|
+
|
171
|
+
def method_missing(called, *args, &block)
|
172
|
+
@deprecator.warn(@message, caller_locations)
|
173
|
+
target.__send__(called, *args, &block)
|
151
174
|
end
|
152
175
|
end
|
153
176
|
end
|
@@ -104,7 +104,7 @@ module ActiveSupport
|
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
107
|
-
RAILS_GEM_ROOT = File.expand_path("../../../..", __dir__)
|
107
|
+
RAILS_GEM_ROOT = File.expand_path("../../../..", __dir__) + "/"
|
108
108
|
|
109
109
|
def ignored_callstack(path)
|
110
110
|
path.start_with?(RAILS_GEM_ROOT) || path.start_with?(RbConfig::CONFIG["rubylibdir"])
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "weakref"
|
4
|
+
|
3
5
|
module ActiveSupport
|
4
6
|
# This module provides an internal implementation to track descendants
|
5
7
|
# which is faster than iterating through ObjectSpace.
|
@@ -8,7 +10,8 @@ module ActiveSupport
|
|
8
10
|
|
9
11
|
class << self
|
10
12
|
def direct_descendants(klass)
|
11
|
-
@@direct_descendants[klass]
|
13
|
+
descendants = @@direct_descendants[klass]
|
14
|
+
descendants ? descendants.to_a : []
|
12
15
|
end
|
13
16
|
|
14
17
|
def descendants(klass)
|
@@ -20,10 +23,10 @@ module ActiveSupport
|
|
20
23
|
def clear
|
21
24
|
if defined? ActiveSupport::Dependencies
|
22
25
|
@@direct_descendants.each do |klass, descendants|
|
23
|
-
if
|
26
|
+
if Dependencies.autoloaded?(klass)
|
24
27
|
@@direct_descendants.delete(klass)
|
25
28
|
else
|
26
|
-
descendants.reject! { |v|
|
29
|
+
descendants.reject! { |v| Dependencies.autoloaded?(v) }
|
27
30
|
end
|
28
31
|
end
|
29
32
|
else
|
@@ -34,16 +37,18 @@ module ActiveSupport
|
|
34
37
|
# This is the only method that is not thread safe, but is only ever called
|
35
38
|
# during the eager loading phase.
|
36
39
|
def store_inherited(klass, descendant)
|
37
|
-
(@@direct_descendants[klass] ||=
|
40
|
+
(@@direct_descendants[klass] ||= DescendantsArray.new) << descendant
|
38
41
|
end
|
39
42
|
|
40
43
|
private
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
44
|
+
def accumulate_descendants(klass, acc)
|
45
|
+
if direct_descendants = @@direct_descendants[klass]
|
46
|
+
direct_descendants.each do |direct_descendant|
|
47
|
+
acc << direct_descendant
|
48
|
+
accumulate_descendants(direct_descendant, acc)
|
49
|
+
end
|
50
|
+
end
|
45
51
|
end
|
46
|
-
end
|
47
52
|
end
|
48
53
|
|
49
54
|
def inherited(base)
|
@@ -58,5 +63,46 @@ module ActiveSupport
|
|
58
63
|
def descendants
|
59
64
|
DescendantsTracker.descendants(self)
|
60
65
|
end
|
66
|
+
|
67
|
+
# DescendantsArray is an array that contains weak references to classes.
|
68
|
+
class DescendantsArray # :nodoc:
|
69
|
+
include Enumerable
|
70
|
+
|
71
|
+
def initialize
|
72
|
+
@refs = []
|
73
|
+
end
|
74
|
+
|
75
|
+
def initialize_copy(orig)
|
76
|
+
@refs = @refs.dup
|
77
|
+
end
|
78
|
+
|
79
|
+
def <<(klass)
|
80
|
+
cleanup!
|
81
|
+
@refs << WeakRef.new(klass)
|
82
|
+
end
|
83
|
+
|
84
|
+
def each
|
85
|
+
@refs.each do |ref|
|
86
|
+
yield ref.__getobj__
|
87
|
+
rescue WeakRef::RefError
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def refs_size
|
92
|
+
@refs.size
|
93
|
+
end
|
94
|
+
|
95
|
+
def cleanup!
|
96
|
+
@refs.delete_if { |ref| !ref.weakref_alive? }
|
97
|
+
end
|
98
|
+
|
99
|
+
def reject!
|
100
|
+
@refs.reject! do |ref|
|
101
|
+
yield ref.__getobj__
|
102
|
+
rescue WeakRef::RefError
|
103
|
+
true
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
61
107
|
end
|
62
108
|
end
|
@@ -4,7 +4,6 @@ require "active_support/core_ext/array/conversions"
|
|
4
4
|
require "active_support/core_ext/module/delegation"
|
5
5
|
require "active_support/core_ext/object/acts_like"
|
6
6
|
require "active_support/core_ext/string/filters"
|
7
|
-
require "active_support/deprecation"
|
8
7
|
|
9
8
|
module ActiveSupport
|
10
9
|
# Provides accurate date and time measurements using Date#advance and
|
@@ -183,15 +182,15 @@ module ActiveSupport
|
|
183
182
|
#
|
184
183
|
def build(value)
|
185
184
|
parts = {}
|
186
|
-
remainder = value.
|
185
|
+
remainder = value.round(9)
|
187
186
|
|
188
187
|
PARTS.each do |part|
|
189
188
|
unless part == :seconds
|
190
189
|
part_in_seconds = PARTS_IN_SECONDS[part]
|
191
190
|
parts[part] = remainder.div(part_in_seconds)
|
192
|
-
remainder
|
191
|
+
remainder %= part_in_seconds
|
193
192
|
end
|
194
|
-
end
|
193
|
+
end unless value == 0
|
195
194
|
|
196
195
|
parts[:seconds] = remainder
|
197
196
|
|
@@ -199,7 +198,6 @@ module ActiveSupport
|
|
199
198
|
end
|
200
199
|
|
201
200
|
private
|
202
|
-
|
203
201
|
def calculate_total_seconds(parts)
|
204
202
|
parts.inject(0) do |total, (part, value)|
|
205
203
|
total + value * PARTS_IN_SECONDS[part]
|
@@ -210,12 +208,15 @@ module ActiveSupport
|
|
210
208
|
def initialize(value, parts) #:nodoc:
|
211
209
|
@value, @parts = value, parts.to_h
|
212
210
|
@parts.default = 0
|
213
|
-
@parts.reject! { |k, v| v.zero? }
|
211
|
+
@parts.reject! { |k, v| v.zero? } unless value == 0
|
214
212
|
end
|
215
213
|
|
216
214
|
def coerce(other) #:nodoc:
|
217
|
-
|
215
|
+
case other
|
216
|
+
when Scalar
|
218
217
|
[other, self]
|
218
|
+
when Duration
|
219
|
+
[Scalar.new(other.value), self]
|
219
220
|
else
|
220
221
|
[Scalar.new(other), self]
|
221
222
|
end
|
@@ -336,8 +337,8 @@ module ActiveSupport
|
|
336
337
|
# 1.year.to_i # => 31556952
|
337
338
|
#
|
338
339
|
# In such cases, Ruby's core
|
339
|
-
# Date[
|
340
|
-
# Time[
|
340
|
+
# Date[https://ruby-doc.org/stdlib/libdoc/date/rdoc/Date.html] and
|
341
|
+
# Time[https://ruby-doc.org/stdlib/libdoc/time/rdoc/Time.html] should be used for precision
|
341
342
|
# date and time arithmetic.
|
342
343
|
def to_i
|
343
344
|
@value.to_i
|
@@ -370,10 +371,9 @@ module ActiveSupport
|
|
370
371
|
alias :before :ago
|
371
372
|
|
372
373
|
def inspect #:nodoc:
|
373
|
-
return "
|
374
|
+
return "#{value} seconds" if parts.empty?
|
374
375
|
|
375
376
|
parts.
|
376
|
-
reduce(::Hash.new(0)) { |h, (l, r)| h[l] += r; h }.
|
377
377
|
sort_by { |unit, _ | PARTS.index(unit) }.
|
378
378
|
map { |unit, val| "#{val} #{val == 1 ? unit.to_s.chop : unit.to_s}" }.
|
379
379
|
to_sentence(locale: ::I18n.default_locale)
|
@@ -398,10 +398,15 @@ module ActiveSupport
|
|
398
398
|
end
|
399
399
|
|
400
400
|
private
|
401
|
-
|
402
401
|
def sum(sign, time = ::Time.current)
|
403
|
-
|
404
|
-
|
402
|
+
unless time.acts_like?(:time) || time.acts_like?(:date)
|
403
|
+
raise ::ArgumentError, "expected a time or date, got #{time.inspect}"
|
404
|
+
end
|
405
|
+
|
406
|
+
if parts.empty?
|
407
|
+
time.since(sign * value)
|
408
|
+
else
|
409
|
+
parts.inject(time) do |t, (type, number)|
|
405
410
|
if type == :seconds
|
406
411
|
t.since(sign * number)
|
407
412
|
elsif type == :minutes
|
@@ -411,8 +416,6 @@ module ActiveSupport
|
|
411
416
|
else
|
412
417
|
t.advance(type => sign * number)
|
413
418
|
end
|
414
|
-
else
|
415
|
-
raise ::ArgumentError, "expected a time or date, got #{time.inspect}"
|
416
419
|
end
|
417
420
|
end
|
418
421
|
end
|