activesupport 7.0.0.alpha2 → 7.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +103 -0
- data/lib/active_support/cache/mem_cache_store.rb +9 -5
- data/lib/active_support/cache/memory_store.rb +2 -2
- data/lib/active_support/cache/redis_cache_store.rb +3 -8
- data/lib/active_support/cache/strategy/local_cache.rb +6 -12
- data/lib/active_support/callbacks.rb +145 -50
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/core_ext/array/conversions.rb +3 -1
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
- data/lib/active_support/core_ext/array.rb +1 -0
- data/lib/active_support/core_ext/class/subclasses.rb +4 -2
- data/lib/active_support/core_ext/date/calculations.rb +2 -2
- data/lib/active_support/core_ext/date/conversions.rb +3 -3
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/date.rb +1 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -1
- data/lib/active_support/core_ext/date_time/conversions.rb +5 -5
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/date_time.rb +1 -0
- data/lib/active_support/core_ext/digest/uuid.rb +26 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +2 -0
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +19 -10
- data/lib/active_support/core_ext/numeric/conversions.rb +78 -75
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
- data/lib/active_support/core_ext/numeric.rb +1 -0
- data/lib/active_support/core_ext/object/with_options.rb +20 -1
- data/lib/active_support/core_ext/pathname/existence.rb +21 -0
- data/lib/active_support/core_ext/pathname.rb +3 -0
- data/lib/active_support/core_ext/range/conversions.rb +8 -8
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +4 -25
- data/lib/active_support/core_ext/range.rb +1 -1
- data/lib/active_support/core_ext/time/calculations.rb +1 -1
- data/lib/active_support/core_ext/time/conversions.rb +4 -3
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/time/zones.rb +2 -2
- data/lib/active_support/core_ext/time.rb +1 -0
- data/lib/active_support/core_ext/uri.rb +3 -13
- data/lib/active_support/core_ext.rb +1 -0
- data/lib/active_support/current_attributes.rb +26 -25
- data/lib/active_support/descendants_tracker.rb +175 -69
- data/lib/active_support/duration.rb +4 -3
- data/lib/active_support/error_reporter.rb +117 -0
- data/lib/active_support/execution_context/test_helper.rb +13 -0
- data/lib/active_support/execution_context.rb +53 -0
- data/lib/active_support/execution_wrapper.rb +30 -4
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/fork_tracker.rb +18 -9
- data/lib/active_support/gem_version.rb +1 -1
- data/lib/active_support/html_safe_translation.rb +43 -0
- data/lib/active_support/i18n_railtie.rb +1 -1
- data/lib/active_support/inflector/inflections.rb +12 -3
- data/lib/active_support/inflector/methods.rb +2 -2
- data/lib/active_support/isolated_execution_state.rb +56 -0
- data/lib/active_support/logger_thread_safe_level.rb +2 -3
- data/lib/active_support/message_encryptor.rb +5 -0
- data/lib/active_support/message_verifier.rb +42 -10
- data/lib/active_support/multibyte/unicode.rb +0 -12
- data/lib/active_support/notifications/fanout.rb +61 -55
- data/lib/active_support/notifications/instrumenter.rb +15 -15
- data/lib/active_support/notifications.rb +5 -21
- data/lib/active_support/option_merger.rb +4 -0
- data/lib/active_support/per_thread_registry.rb +4 -0
- data/lib/active_support/railtie.rb +38 -11
- data/lib/active_support/ruby_features.rb +7 -0
- data/lib/active_support/subscriber.rb +2 -18
- data/lib/active_support/tagged_logging.rb +1 -1
- data/lib/active_support/testing/deprecation.rb +52 -1
- data/lib/active_support/testing/isolation.rb +1 -1
- data/lib/active_support/time_with_zone.rb +34 -6
- data/lib/active_support/values/time_zone.rb +5 -0
- data/lib/active_support/xml_mini.rb +3 -3
- data/lib/active_support.rb +7 -4
- metadata +25 -8
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
module DeprecatedRangeWithFormat # :nodoc:
|
5
|
+
NOT_SET = Object.new # :nodoc:
|
6
|
+
def to_s(format = NOT_SET)
|
7
|
+
if formatter = RangeWithFormat::RANGE_FORMATS[format]
|
8
|
+
ActiveSupport::Deprecation.warn(
|
9
|
+
"Range#to_s(#{format.inspect}) is deprecated. Please use Range#to_formatted_s(#{format.inspect}) instead."
|
10
|
+
)
|
11
|
+
formatter.call(first, last)
|
12
|
+
elsif format == NOT_SET
|
13
|
+
super()
|
14
|
+
else
|
15
|
+
ActiveSupport::Deprecation.warn(
|
16
|
+
"Range#to_s(#{format.inspect}) is deprecated. Please use Range#to_formatted_s(#{format.inspect}) instead."
|
17
|
+
)
|
18
|
+
super()
|
19
|
+
end
|
20
|
+
end
|
21
|
+
alias_method :to_default_s, :to_s
|
22
|
+
deprecate :to_default_s
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
Range.prepend(ActiveSupport::DeprecatedRangeWithFormat)
|
@@ -1,28 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require "active_support/deprecation"
|
5
|
-
|
6
|
-
module ActiveSupport
|
7
|
-
module IncludeTimeWithZone # :nodoc:
|
8
|
-
# Extends the default Range#include? to support ActiveSupport::TimeWithZone.
|
9
|
-
#
|
10
|
-
# (1.hour.ago..1.hour.from_now).include?(Time.current) # => true
|
11
|
-
#
|
12
|
-
def include?(value)
|
13
|
-
if self.begin.is_a?(TimeWithZone) || self.end.is_a?(TimeWithZone)
|
14
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
15
|
-
Using `Range#include?` to check the inclusion of a value in
|
16
|
-
a date time range is deprecated.
|
17
|
-
It is recommended to use `Range#cover?` instead of `Range#include?` to
|
18
|
-
check the inclusion of a value in a date time range.
|
19
|
-
MSG
|
20
|
-
cover?(value)
|
21
|
-
else
|
22
|
-
super
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
3
|
+
# frozen_string_literal: true
|
27
4
|
|
28
|
-
|
5
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
6
|
+
`active_support/core_ext/range/include_time_with_zone` is deprecated and will be removed in Rails 7.1.
|
7
|
+
MSG
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/core_ext/range/conversions"
|
4
|
+
require "active_support/core_ext/range/deprecated_conversions" unless ENV["RAILS_DISABLE_DEPRECATED_TO_S_CONVERSION"]
|
4
5
|
require "active_support/core_ext/range/compare_range"
|
5
|
-
require "active_support/core_ext/range/include_time_with_zone"
|
6
6
|
require "active_support/core_ext/range/overlaps"
|
7
7
|
require "active_support/core_ext/range/each"
|
@@ -305,7 +305,7 @@ class Time
|
|
305
305
|
other.is_a?(DateTime) ? to_f - other.to_f : minus_without_coercion(other)
|
306
306
|
end
|
307
307
|
alias_method :minus_without_coercion, :-
|
308
|
-
alias_method :-, :minus_with_coercion
|
308
|
+
alias_method :-, :minus_with_coercion # rubocop:disable Lint/DuplicateMethods
|
309
309
|
|
310
310
|
# Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
|
311
311
|
# can be chronologically compared with a Time
|
@@ -27,12 +27,12 @@ class Time
|
|
27
27
|
|
28
28
|
# Converts to a formatted string. See DATE_FORMATS for built-in formats.
|
29
29
|
#
|
30
|
-
# This method is aliased to <tt>
|
30
|
+
# This method is aliased to <tt>to_fs</tt>.
|
31
31
|
#
|
32
32
|
# time = Time.now # => 2007-01-18 06:10:17 -06:00
|
33
33
|
#
|
34
34
|
# time.to_formatted_s(:time) # => "06:10"
|
35
|
-
# time.
|
35
|
+
# time.to_fs(:time) # => "06:10"
|
36
36
|
#
|
37
37
|
# time.to_formatted_s(:db) # => "2007-01-18 06:10:17"
|
38
38
|
# time.to_formatted_s(:number) # => "20070118061017"
|
@@ -54,11 +54,12 @@ class Time
|
|
54
54
|
if formatter = DATE_FORMATS[format]
|
55
55
|
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
|
56
56
|
else
|
57
|
+
# Change to `to_s` when deprecation is gone. Also deprecate `to_default_s`.
|
57
58
|
to_default_s
|
58
59
|
end
|
59
60
|
end
|
61
|
+
alias_method :to_fs, :to_formatted_s
|
60
62
|
alias_method :to_default_s, :to_s
|
61
|
-
alias_method :to_s, :to_formatted_s
|
62
63
|
|
63
64
|
# Returns a formatted string of the offset from UTC, or an alternative
|
64
65
|
# string if the time zone is already UTC.
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "time"
|
4
|
+
|
5
|
+
class Time
|
6
|
+
NOT_SET = Object.new # :nodoc:
|
7
|
+
def to_s(format = NOT_SET) # :nodoc:
|
8
|
+
if formatter = DATE_FORMATS[format]
|
9
|
+
ActiveSupport::Deprecation.warn(
|
10
|
+
"Time#to_s(#{format.inspect}) is deprecated. Please use Time#to_formatted_s(#{format.inspect}) instead."
|
11
|
+
)
|
12
|
+
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
|
13
|
+
elsif format == NOT_SET
|
14
|
+
to_default_s
|
15
|
+
else
|
16
|
+
ActiveSupport::Deprecation.warn(
|
17
|
+
"Time#to_s(#{format.inspect}) is deprecated. Please use Time#to_formatted_s(#{format.inspect}) instead."
|
18
|
+
)
|
19
|
+
to_default_s
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -12,7 +12,7 @@ class Time
|
|
12
12
|
# Returns the TimeZone for the current request, if this has been set (via Time.zone=).
|
13
13
|
# If <tt>Time.zone</tt> has not been set for the current request, returns the TimeZone specified in <tt>config.time_zone</tt>.
|
14
14
|
def zone
|
15
|
-
|
15
|
+
::ActiveSupport::IsolatedExecutionState[:time_zone] || zone_default
|
16
16
|
end
|
17
17
|
|
18
18
|
# Sets <tt>Time.zone</tt> to a TimeZone object for the current request/thread.
|
@@ -39,7 +39,7 @@ class Time
|
|
39
39
|
# end
|
40
40
|
# end
|
41
41
|
def zone=(time_zone)
|
42
|
-
|
42
|
+
::ActiveSupport::IsolatedExecutionState[:time_zone] = find_zone!(time_zone)
|
43
43
|
end
|
44
44
|
|
45
45
|
# Allows override of <tt>Time.zone</tt> locally inside supplied block;
|
@@ -4,4 +4,5 @@ require "active_support/core_ext/time/acts_like"
|
|
4
4
|
require "active_support/core_ext/time/calculations"
|
5
5
|
require "active_support/core_ext/time/compatibility"
|
6
6
|
require "active_support/core_ext/time/conversions"
|
7
|
+
require "active_support/core_ext/time/deprecated_conversions" unless ENV["RAILS_DISABLE_DEPRECATED_TO_S_CONVERSION"]
|
7
8
|
require "active_support/core_ext/time/zones"
|
@@ -1,15 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
class << self
|
7
|
-
def parser
|
8
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
9
|
-
URI.parser is deprecated and will be removed in Rails 7.0.
|
10
|
-
Use `URI::DEFAULT_PARSER` instead.
|
11
|
-
MSG
|
12
|
-
URI::DEFAULT_PARSER
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
3
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
4
|
+
`active_support/core_ext/uri` is deprecated and will be removed in Rails 7.1.
|
5
|
+
MSG
|
@@ -98,25 +98,37 @@ module ActiveSupport
|
|
98
98
|
|
99
99
|
# Declares one or more attributes that will be given both class and instance accessor methods.
|
100
100
|
def attribute(*names)
|
101
|
-
generated_attribute_methods
|
101
|
+
ActiveSupport::CodeGenerator.batch(generated_attribute_methods, __FILE__, __LINE__) do |owner|
|
102
102
|
names.each do |name|
|
103
|
-
|
104
|
-
|
103
|
+
owner.define_cached_method(name, namespace: :current_attributes) do |batch|
|
104
|
+
batch <<
|
105
|
+
"def #{name}" <<
|
106
|
+
"attributes[:#{name}]" <<
|
107
|
+
"end"
|
105
108
|
end
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
+
owner.define_cached_method("#{name}=", namespace: :current_attributes) do |batch|
|
110
|
+
batch <<
|
111
|
+
"def #{name}=(value)" <<
|
112
|
+
"attributes[:#{name}] = value" <<
|
113
|
+
"end"
|
109
114
|
end
|
110
115
|
end
|
111
116
|
end
|
112
117
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
118
|
+
ActiveSupport::CodeGenerator.batch(singleton_class, __FILE__, __LINE__) do |owner|
|
119
|
+
names.each do |name|
|
120
|
+
owner.define_cached_method(name, namespace: :current_attributes_delegation) do |batch|
|
121
|
+
batch <<
|
122
|
+
"def #{name}" <<
|
123
|
+
"instance.#{name}" <<
|
124
|
+
"end"
|
125
|
+
end
|
126
|
+
owner.define_cached_method("#{name}=", namespace: :current_attributes_delegation) do |batch|
|
127
|
+
batch <<
|
128
|
+
"def #{name}=(value)" <<
|
129
|
+
"instance.#{name} = value" <<
|
130
|
+
"end"
|
131
|
+
end
|
120
132
|
end
|
121
133
|
end
|
122
134
|
end
|
@@ -143,24 +155,13 @@ module ActiveSupport
|
|
143
155
|
current_instances.clear
|
144
156
|
end
|
145
157
|
|
146
|
-
def _use_thread_variables=(value) # :nodoc:
|
147
|
-
clear_all
|
148
|
-
@@use_thread_variables = value
|
149
|
-
end
|
150
|
-
@@use_thread_variables = false
|
151
|
-
|
152
158
|
private
|
153
159
|
def generated_attribute_methods
|
154
160
|
@generated_attribute_methods ||= Module.new.tap { |mod| include mod }
|
155
161
|
end
|
156
162
|
|
157
163
|
def current_instances
|
158
|
-
|
159
|
-
Thread.current.thread_variable_get(:current_attributes_instances) ||
|
160
|
-
Thread.current.thread_variable_set(:current_attributes_instances, {})
|
161
|
-
else
|
162
|
-
Thread.current[:current_attributes_instances] ||= {}
|
163
|
-
end
|
164
|
+
IsolatedExecutionState[:current_attributes_instances] ||= {}
|
164
165
|
end
|
165
166
|
|
166
167
|
def current_instances_key
|
@@ -1,113 +1,219 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "weakref"
|
4
|
+
require "active_support/ruby_features"
|
4
5
|
|
5
6
|
module ActiveSupport
|
6
7
|
# This module provides an internal implementation to track descendants
|
7
8
|
# which is faster than iterating through ObjectSpace.
|
8
9
|
module DescendantsTracker
|
9
|
-
@@direct_descendants = {}
|
10
|
-
|
11
10
|
class << self
|
12
11
|
def direct_descendants(klass)
|
13
|
-
|
14
|
-
|
12
|
+
ActiveSupport::Deprecation.warn(<<~MSG)
|
13
|
+
ActiveSupport::DescendantsTracker.direct_descendants is deprecated and will be removed in Rails 7.1.
|
14
|
+
Use ActiveSupport::DescendantsTracker.subclasses instead.
|
15
|
+
MSG
|
16
|
+
subclasses(klass)
|
15
17
|
end
|
16
|
-
|
18
|
+
end
|
19
|
+
|
20
|
+
@clear_disabled = false
|
21
|
+
|
22
|
+
if RubyFeatures::CLASS_SUBCLASSES
|
23
|
+
@@excluded_descendants = if RUBY_ENGINE == "ruby"
|
24
|
+
# On MRI `ObjectSpace::WeakMap` keys are weak references.
|
25
|
+
# So we can simply use WeakMap as a `Set`.
|
26
|
+
ObjectSpace::WeakMap.new
|
27
|
+
else
|
28
|
+
# On TruffleRuby `ObjectSpace::WeakMap` keys are strong references.
|
29
|
+
# So we use `object_id` as a key and the actual object as a value.
|
30
|
+
#
|
31
|
+
# JRuby for now doesn't have Class#descendant, but when it will, it will likely
|
32
|
+
# have the same WeakMap semantic than Truffle so we future proof this as much as possible.
|
33
|
+
class WeakSet # :nodoc:
|
34
|
+
def initialize
|
35
|
+
@map = ObjectSpace::WeakMap.new
|
36
|
+
end
|
17
37
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
38
|
+
def [](object)
|
39
|
+
@map.key?(object.object_id)
|
40
|
+
end
|
41
|
+
|
42
|
+
def []=(object, _present)
|
43
|
+
@map[object.object_id] = object
|
44
|
+
end
|
45
|
+
end
|
46
|
+
WeakSet.new
|
22
47
|
end
|
23
48
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
49
|
+
class << self
|
50
|
+
def disable_clear! # :nodoc:
|
51
|
+
unless @clear_disabled
|
52
|
+
@clear_disabled = true
|
53
|
+
remove_method(:subclasses)
|
54
|
+
remove_method(:descendants)
|
55
|
+
@@excluded_descendants = nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def subclasses(klass)
|
60
|
+
klass.subclasses
|
28
61
|
end
|
29
62
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
63
|
+
def descendants(klass)
|
64
|
+
klass.descendants
|
65
|
+
end
|
66
|
+
|
67
|
+
def clear(classes) # :nodoc:
|
68
|
+
raise "DescendantsTracker.clear was disabled because config.cache_classes = true" if @clear_disabled
|
69
|
+
|
70
|
+
classes.each do |klass|
|
71
|
+
@@excluded_descendants[klass] = true
|
72
|
+
klass.descendants.each do |descendant|
|
73
|
+
@@excluded_descendants[descendant] = true
|
36
74
|
end
|
37
75
|
end
|
38
76
|
end
|
77
|
+
|
78
|
+
def native? # :nodoc:
|
79
|
+
true
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def subclasses
|
84
|
+
subclasses = super
|
85
|
+
subclasses.reject! { |d| @@excluded_descendants[d] }
|
86
|
+
subclasses
|
87
|
+
end
|
88
|
+
|
89
|
+
def descendants
|
90
|
+
descendants = super
|
91
|
+
descendants.reject! { |d| @@excluded_descendants[d] }
|
92
|
+
descendants
|
39
93
|
end
|
40
94
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
95
|
+
def direct_descendants
|
96
|
+
ActiveSupport::Deprecation.warn(<<~MSG)
|
97
|
+
ActiveSupport::DescendantsTracker#direct_descendants is deprecated and will be removed in Rails 7.1.
|
98
|
+
Use #subclasses instead.
|
99
|
+
MSG
|
100
|
+
subclasses
|
45
101
|
end
|
102
|
+
else
|
103
|
+
@@direct_descendants = {}
|
104
|
+
|
105
|
+
class << self
|
106
|
+
def disable_clear! # :nodoc:
|
107
|
+
@clear_disabled = true
|
108
|
+
end
|
109
|
+
|
110
|
+
def subclasses(klass)
|
111
|
+
descendants = @@direct_descendants[klass]
|
112
|
+
descendants ? descendants.to_a : []
|
113
|
+
end
|
114
|
+
|
115
|
+
def descendants(klass)
|
116
|
+
arr = []
|
117
|
+
accumulate_descendants(klass, arr)
|
118
|
+
arr
|
119
|
+
end
|
120
|
+
|
121
|
+
def clear(classes) # :nodoc:
|
122
|
+
raise "DescendantsTracker.clear was disabled because config.cache_classes = true" if @clear_disabled
|
46
123
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
124
|
+
@@direct_descendants.each do |klass, direct_descendants_of_klass|
|
125
|
+
if classes.member?(klass)
|
126
|
+
@@direct_descendants.delete(klass)
|
127
|
+
else
|
128
|
+
direct_descendants_of_klass.reject! do |direct_descendant_of_class|
|
129
|
+
classes.member?(direct_descendant_of_class)
|
130
|
+
end
|
53
131
|
end
|
54
132
|
end
|
55
133
|
end
|
56
|
-
end
|
57
134
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
end
|
135
|
+
def native? # :nodoc:
|
136
|
+
false
|
137
|
+
end
|
62
138
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
139
|
+
# This is the only method that is not thread safe, but is only ever called
|
140
|
+
# during the eager loading phase.
|
141
|
+
def store_inherited(klass, descendant)
|
142
|
+
(@@direct_descendants[klass] ||= DescendantsArray.new) << descendant
|
143
|
+
end
|
67
144
|
|
68
|
-
|
69
|
-
|
70
|
-
|
145
|
+
private
|
146
|
+
def accumulate_descendants(klass, acc)
|
147
|
+
if direct_descendants = @@direct_descendants[klass]
|
148
|
+
direct_descendants.each do |direct_descendant|
|
149
|
+
acc << direct_descendant
|
150
|
+
accumulate_descendants(direct_descendant, acc)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
71
155
|
|
72
|
-
|
73
|
-
|
74
|
-
|
156
|
+
def inherited(base)
|
157
|
+
DescendantsTracker.store_inherited(self, base)
|
158
|
+
super
|
159
|
+
end
|
75
160
|
|
76
|
-
def
|
77
|
-
|
161
|
+
def direct_descendants
|
162
|
+
ActiveSupport::Deprecation.warn(<<~MSG)
|
163
|
+
ActiveSupport::DescendantsTracker#direct_descendants is deprecated and will be removed in Rails 7.1.
|
164
|
+
Use #subclasses instead.
|
165
|
+
MSG
|
166
|
+
DescendantsTracker.subclasses(self)
|
78
167
|
end
|
79
168
|
|
80
|
-
def
|
81
|
-
|
169
|
+
def subclasses
|
170
|
+
DescendantsTracker.subclasses(self)
|
82
171
|
end
|
83
172
|
|
84
|
-
def
|
85
|
-
|
173
|
+
def descendants
|
174
|
+
DescendantsTracker.descendants(self)
|
86
175
|
end
|
87
176
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
177
|
+
# DescendantsArray is an array that contains weak references to classes.
|
178
|
+
class DescendantsArray # :nodoc:
|
179
|
+
include Enumerable
|
180
|
+
|
181
|
+
def initialize
|
182
|
+
@refs = []
|
94
183
|
end
|
95
|
-
self
|
96
|
-
end
|
97
184
|
|
98
|
-
|
99
|
-
|
100
|
-
|
185
|
+
def initialize_copy(orig)
|
186
|
+
@refs = @refs.dup
|
187
|
+
end
|
101
188
|
|
102
|
-
|
103
|
-
|
104
|
-
|
189
|
+
def <<(klass)
|
190
|
+
@refs << WeakRef.new(klass)
|
191
|
+
end
|
105
192
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
193
|
+
def each
|
194
|
+
@refs.reject! do |ref|
|
195
|
+
yield ref.__getobj__
|
196
|
+
false
|
197
|
+
rescue WeakRef::RefError
|
198
|
+
true
|
199
|
+
end
|
200
|
+
self
|
201
|
+
end
|
202
|
+
|
203
|
+
def refs_size
|
204
|
+
@refs.size
|
205
|
+
end
|
206
|
+
|
207
|
+
def cleanup!
|
208
|
+
@refs.delete_if { |ref| !ref.weakref_alive? }
|
209
|
+
end
|
210
|
+
|
211
|
+
def reject!
|
212
|
+
@refs.reject! do |ref|
|
213
|
+
yield ref.__getobj__
|
214
|
+
rescue WeakRef::RefError
|
215
|
+
true
|
216
|
+
end
|
111
217
|
end
|
112
218
|
end
|
113
219
|
end
|
@@ -191,13 +191,14 @@ module ActiveSupport
|
|
191
191
|
end
|
192
192
|
|
193
193
|
parts = {}
|
194
|
-
|
194
|
+
remainder_sign = value <=> 0
|
195
|
+
remainder = value.round(9).abs
|
195
196
|
variable = false
|
196
197
|
|
197
198
|
PARTS.each do |part|
|
198
199
|
unless part == :seconds
|
199
200
|
part_in_seconds = PARTS_IN_SECONDS[part]
|
200
|
-
parts[part] = remainder.div(part_in_seconds)
|
201
|
+
parts[part] = remainder.div(part_in_seconds) * remainder_sign
|
201
202
|
remainder %= part_in_seconds
|
202
203
|
|
203
204
|
unless parts[part].zero?
|
@@ -206,7 +207,7 @@ module ActiveSupport
|
|
206
207
|
end
|
207
208
|
end unless value == 0
|
208
209
|
|
209
|
-
parts[:seconds] = remainder
|
210
|
+
parts[:seconds] = remainder * remainder_sign
|
210
211
|
|
211
212
|
new(value, parts, variable)
|
212
213
|
end
|