activesupport 6.1.7.2 → 7.0.0.alpha1
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 +151 -620
- data/MIT-LICENSE +1 -1
- data/lib/active_support/actionable_error.rb +1 -1
- data/lib/active_support/array_inquirer.rb +0 -2
- data/lib/active_support/benchmarkable.rb +2 -2
- data/lib/active_support/cache/file_store.rb +15 -9
- data/lib/active_support/cache/mem_cache_store.rb +119 -28
- data/lib/active_support/cache/memory_store.rb +21 -13
- data/lib/active_support/cache/null_store.rb +10 -2
- data/lib/active_support/cache/redis_cache_store.rb +39 -59
- data/lib/active_support/cache/strategy/local_cache.rb +29 -49
- data/lib/active_support/cache.rb +189 -45
- data/lib/active_support/callbacks.rb +35 -31
- data/lib/active_support/concern.rb +5 -5
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +2 -4
- data/lib/active_support/concurrency/share_lock.rb +2 -2
- data/lib/active_support/configurable.rb +6 -3
- data/lib/active_support/configuration_file.rb +1 -1
- data/lib/active_support/core_ext/array/access.rb +1 -5
- data/lib/active_support/core_ext/array/conversions.rb +6 -6
- data/lib/active_support/core_ext/array/grouping.rb +6 -6
- data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
- data/lib/active_support/core_ext/date/blank.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +2 -2
- data/lib/active_support/core_ext/date_time/blank.rb +1 -1
- data/lib/active_support/core_ext/digest/uuid.rb +13 -13
- data/lib/active_support/core_ext/enumerable.rb +64 -12
- data/lib/active_support/core_ext/file/atomic.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +1 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
- data/lib/active_support/core_ext/module/delegation.rb +2 -8
- data/lib/active_support/core_ext/name_error.rb +2 -8
- data/lib/active_support/core_ext/numeric/conversions.rb +2 -2
- data/lib/active_support/core_ext/object/blank.rb +2 -2
- data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
- data/lib/active_support/core_ext/object/duplicable.rb +11 -0
- data/lib/active_support/core_ext/object/json.rb +29 -24
- data/lib/active_support/core_ext/object/to_query.rb +2 -2
- data/lib/active_support/core_ext/object/try.rb +20 -20
- data/lib/active_support/core_ext/range/compare_range.rb +0 -25
- data/lib/active_support/core_ext/range/each.rb +1 -1
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +1 -1
- data/lib/active_support/core_ext/string/filters.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +1 -1
- data/lib/active_support/core_ext/string/output_safety.rb +60 -64
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +0 -8
- data/lib/active_support/core_ext/time/calculations.rb +4 -5
- data/lib/active_support/core_ext/time/zones.rb +2 -17
- data/lib/active_support/core_ext/uri.rb +0 -14
- data/lib/active_support/current_attributes.rb +17 -2
- data/lib/active_support/dependencies/interlock.rb +10 -18
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +58 -788
- data/lib/active_support/deprecation/behaviors.rb +4 -1
- data/lib/active_support/deprecation/method_wrappers.rb +3 -3
- data/lib/active_support/deprecation/proxy_wrappers.rb +1 -1
- data/lib/active_support/deprecation.rb +1 -1
- data/lib/active_support/descendants_tracker.rb +12 -9
- data/lib/active_support/digest.rb +4 -4
- data/lib/active_support/duration/iso8601_parser.rb +3 -3
- data/lib/active_support/duration/iso8601_serializer.rb +9 -1
- data/lib/active_support/duration.rb +80 -52
- data/lib/active_support/encrypted_configuration.rb +11 -1
- data/lib/active_support/encrypted_file.rb +1 -1
- data/lib/active_support/environment_inquirer.rb +1 -1
- data/lib/active_support/evented_file_update_checker.rb +1 -1
- data/lib/active_support/execution_wrapper.rb +13 -16
- data/lib/active_support/fork_tracker.rb +2 -4
- data/lib/active_support/gem_version.rb +4 -4
- data/lib/active_support/hash_with_indifferent_access.rb +3 -1
- data/lib/active_support/i18n.rb +1 -0
- data/lib/active_support/inflector/inflections.rb +11 -4
- data/lib/active_support/inflector/methods.rb +23 -46
- data/lib/active_support/json/encoding.rb +3 -3
- data/lib/active_support/key_generator.rb +18 -1
- data/lib/active_support/locale/en.yml +1 -1
- data/lib/active_support/log_subscriber.rb +13 -3
- data/lib/active_support/logger_thread_safe_level.rb +5 -13
- data/lib/active_support/message_encryptor.rb +3 -3
- data/lib/active_support/message_verifier.rb +4 -4
- data/lib/active_support/messages/metadata.rb +2 -2
- data/lib/active_support/multibyte/chars.rb +10 -11
- data/lib/active_support/multibyte.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +31 -11
- data/lib/active_support/notifications/instrumenter.rb +17 -0
- data/lib/active_support/notifications.rb +10 -0
- data/lib/active_support/number_helper/number_converter.rb +1 -3
- data/lib/active_support/number_helper/number_to_currency_converter.rb +11 -6
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -1
- data/lib/active_support/number_helper/rounding_helper.rb +1 -5
- data/lib/active_support/number_helper.rb +0 -2
- data/lib/active_support/option_merger.rb +4 -16
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/parameter_filter.rb +5 -0
- data/lib/active_support/per_thread_registry.rb +1 -1
- data/lib/active_support/railtie.rb +33 -10
- data/lib/active_support/reloader.rb +1 -1
- data/lib/active_support/rescuable.rb +2 -2
- data/lib/active_support/secure_compare_rotator.rb +1 -1
- data/lib/active_support/string_inquirer.rb +0 -2
- data/lib/active_support/subscriber.rb +5 -0
- data/lib/active_support/test_case.rb +9 -21
- data/lib/active_support/testing/assertions.rb +34 -4
- data/lib/active_support/testing/deprecation.rb +1 -1
- data/lib/active_support/testing/isolation.rb +1 -1
- data/lib/active_support/testing/method_call_assertions.rb +5 -5
- data/lib/active_support/testing/parallelization/server.rb +4 -0
- data/lib/active_support/testing/parallelization/worker.rb +3 -0
- data/lib/active_support/testing/parallelization.rb +4 -0
- data/lib/active_support/testing/parallelize_executor.rb +76 -0
- data/lib/active_support/testing/stream.rb +3 -5
- data/lib/active_support/testing/tagged_logging.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +13 -2
- data/lib/active_support/time_with_zone.rb +19 -6
- data/lib/active_support/values/time_zone.rb +25 -11
- data/lib/active_support/xml_mini/jdom.rb +1 -1
- data/lib/active_support/xml_mini/libxml.rb +5 -5
- data/lib/active_support/xml_mini/libxmlsax.rb +1 -1
- data/lib/active_support/xml_mini/nokogiri.rb +4 -4
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
- data/lib/active_support/xml_mini/rexml.rb +1 -1
- data/lib/active_support/xml_mini.rb +2 -1
- data/lib/active_support.rb +14 -1
- metadata +14 -29
- data/lib/active_support/core_ext/marshal.rb +0 -26
- data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -120
@@ -54,7 +54,7 @@ module ActiveSupport
|
|
54
54
|
# [+stderr+] Log all deprecation warnings to <tt>$stderr</tt>.
|
55
55
|
# [+log+] Log all deprecation warnings to +Rails.logger+.
|
56
56
|
# [+notify+] Use +ActiveSupport::Notifications+ to notify +deprecation.rails+.
|
57
|
-
# [+silence+] Do nothing.
|
57
|
+
# [+silence+] Do nothing. On Rails, set <tt>config.active_support.report_deprecations = false</tt> to disable all behaviors.
|
58
58
|
#
|
59
59
|
# Setting behaviors only affects deprecations that happen after boot time.
|
60
60
|
# For more information you can read the documentation of the +behavior=+ method.
|
@@ -93,6 +93,9 @@ module ActiveSupport
|
|
93
93
|
# ActiveSupport::Deprecation.behavior = ->(message, callstack, deprecation_horizon, gem_name) {
|
94
94
|
# # custom stuff
|
95
95
|
# }
|
96
|
+
#
|
97
|
+
# If you are using Rails, you can set <tt>config.active_support.report_deprecations = false</tt> to disable
|
98
|
+
# all deprecation behaviors. This is similar to the +silence+ option but more performant.
|
96
99
|
def behavior=(behavior)
|
97
100
|
@behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) }
|
98
101
|
end
|
@@ -62,9 +62,9 @@ module ActiveSupport
|
|
62
62
|
target_module.module_eval do
|
63
63
|
redefine_method(method_name) do |*args, &block|
|
64
64
|
deprecator.deprecation_warning(method_name, message)
|
65
|
-
method.
|
65
|
+
method.bind_call(self, *args, &block)
|
66
66
|
end
|
67
|
-
ruby2_keywords(method_name)
|
67
|
+
ruby2_keywords(method_name)
|
68
68
|
end
|
69
69
|
else
|
70
70
|
mod ||= Module.new
|
@@ -73,7 +73,7 @@ module ActiveSupport
|
|
73
73
|
deprecator.deprecation_warning(method_name, message)
|
74
74
|
super(*args, &block)
|
75
75
|
end
|
76
|
-
ruby2_keywords(method_name)
|
76
|
+
ruby2_keywords(method_name)
|
77
77
|
end
|
78
78
|
end
|
79
79
|
end
|
@@ -38,7 +38,7 @@ module ActiveSupport
|
|
38
38
|
# and the second is a library name.
|
39
39
|
#
|
40
40
|
# ActiveSupport::Deprecation.new('2.0', 'MyLibrary')
|
41
|
-
def initialize(deprecation_horizon = "7.
|
41
|
+
def initialize(deprecation_horizon = "7.1", gem_name = "Rails")
|
42
42
|
self.gem_name = gem_name
|
43
43
|
self.deprecation_horizon = deprecation_horizon
|
44
44
|
# By default, warnings are not silenced and debugging is off.
|
@@ -21,17 +21,20 @@ module ActiveSupport
|
|
21
21
|
arr
|
22
22
|
end
|
23
23
|
|
24
|
-
def clear
|
25
|
-
if
|
26
|
-
@@direct_descendants.
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
24
|
+
def clear(only: nil)
|
25
|
+
if only.nil?
|
26
|
+
@@direct_descendants.clear
|
27
|
+
return
|
28
|
+
end
|
29
|
+
|
30
|
+
@@direct_descendants.each do |klass, direct_descendants_of_klass|
|
31
|
+
if only.member?(klass)
|
32
|
+
@@direct_descendants.delete(klass)
|
33
|
+
else
|
34
|
+
direct_descendants_of_klass.reject! do |direct_descendant_of_class|
|
35
|
+
only.member?(direct_descendant_of_class)
|
31
36
|
end
|
32
37
|
end
|
33
|
-
else
|
34
|
-
@@direct_descendants.clear
|
35
38
|
end
|
36
39
|
end
|
37
40
|
|
@@ -1,12 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
3
|
+
require "openssl"
|
4
4
|
|
5
5
|
module ActiveSupport
|
6
|
-
class Digest
|
7
|
-
class <<self
|
6
|
+
class Digest # :nodoc:
|
7
|
+
class << self
|
8
8
|
def hash_digest_class
|
9
|
-
@hash_digest_class ||= ::Digest::MD5
|
9
|
+
@hash_digest_class ||= OpenSSL::Digest::MD5
|
10
10
|
end
|
11
11
|
|
12
12
|
def hash_digest_class=(klass)
|
@@ -16,11 +16,11 @@ module ActiveSupport
|
|
16
16
|
PERIOD = "."
|
17
17
|
COMMA = ","
|
18
18
|
|
19
|
-
SIGN_MARKER = /\A
|
19
|
+
SIGN_MARKER = /\A-|\+|/
|
20
20
|
DATE_MARKER = /P/
|
21
21
|
TIME_MARKER = /T/
|
22
|
-
DATE_COMPONENT = /(
|
23
|
-
TIME_COMPONENT = /(
|
22
|
+
DATE_COMPONENT = /(-?\d+(?:[.,]\d+)?)(Y|M|D|W)/
|
23
|
+
TIME_COMPONENT = /(-?\d+(?:[.,]\d+)?)(H|M|S)/
|
24
24
|
|
25
25
|
DATE_TO_PART = { "Y" => :years, "M" => :months, "W" => :weeks, "D" => :days }
|
26
26
|
TIME_TO_PART = { "H" => :hours, "M" => :minutes, "S" => :seconds }
|
@@ -27,7 +27,7 @@ module ActiveSupport
|
|
27
27
|
time << "#{parts[:hours]}H" if parts.key?(:hours)
|
28
28
|
time << "#{parts[:minutes]}M" if parts.key?(:minutes)
|
29
29
|
if parts.key?(:seconds)
|
30
|
-
time << "#{
|
30
|
+
time << "#{format_seconds(parts[:seconds])}S"
|
31
31
|
end
|
32
32
|
output << "T#{time}" unless time.empty?
|
33
33
|
output
|
@@ -54,6 +54,14 @@ module ActiveSupport
|
|
54
54
|
def week_mixed_with_date?(parts)
|
55
55
|
parts.key?(:weeks) && (parts.keys & DATE_COMPONENTS).any?
|
56
56
|
end
|
57
|
+
|
58
|
+
def format_seconds(seconds)
|
59
|
+
if @precision
|
60
|
+
sprintf("%0.0#{@precision}f", seconds)
|
61
|
+
else
|
62
|
+
seconds.to_s
|
63
|
+
end
|
64
|
+
end
|
57
65
|
end
|
58
66
|
end
|
59
67
|
end
|
@@ -11,7 +11,7 @@ module ActiveSupport
|
|
11
11
|
#
|
12
12
|
# 1.month.ago # equivalent to Time.now.advance(months: -1)
|
13
13
|
class Duration
|
14
|
-
class Scalar < Numeric
|
14
|
+
class Scalar < Numeric # :nodoc:
|
15
15
|
attr_reader :value
|
16
16
|
delegate :to_i, :to_f, :to_s, to: :value
|
17
17
|
|
@@ -39,11 +39,11 @@ module ActiveSupport
|
|
39
39
|
|
40
40
|
def +(other)
|
41
41
|
if Duration === other
|
42
|
-
seconds = value + other.
|
43
|
-
new_parts = other.
|
42
|
+
seconds = value + other._parts.fetch(:seconds, 0)
|
43
|
+
new_parts = other._parts.merge(seconds: seconds)
|
44
44
|
new_value = value + other.value
|
45
45
|
|
46
|
-
Duration.new(new_value, new_parts)
|
46
|
+
Duration.new(new_value, new_parts, other.variable?)
|
47
47
|
else
|
48
48
|
calculate(:+, other)
|
49
49
|
end
|
@@ -51,12 +51,12 @@ module ActiveSupport
|
|
51
51
|
|
52
52
|
def -(other)
|
53
53
|
if Duration === other
|
54
|
-
seconds = value - other.
|
55
|
-
new_parts = other.
|
54
|
+
seconds = value - other._parts.fetch(:seconds, 0)
|
55
|
+
new_parts = other._parts.transform_values(&:-@)
|
56
56
|
new_parts = new_parts.merge(seconds: seconds)
|
57
57
|
new_value = value - other.value
|
58
58
|
|
59
|
-
Duration.new(new_value, new_parts)
|
59
|
+
Duration.new(new_value, new_parts, other.variable?)
|
60
60
|
else
|
61
61
|
calculate(:-, other)
|
62
62
|
end
|
@@ -64,10 +64,10 @@ module ActiveSupport
|
|
64
64
|
|
65
65
|
def *(other)
|
66
66
|
if Duration === other
|
67
|
-
new_parts = other.
|
67
|
+
new_parts = other._parts.transform_values { |other_value| value * other_value }
|
68
68
|
new_value = value * other.value
|
69
69
|
|
70
|
-
Duration.new(new_value, new_parts)
|
70
|
+
Duration.new(new_value, new_parts, other.variable?)
|
71
71
|
else
|
72
72
|
calculate(:*, other)
|
73
73
|
end
|
@@ -89,6 +89,10 @@ module ActiveSupport
|
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
|
+
def variable? # :nodoc:
|
93
|
+
false
|
94
|
+
end
|
95
|
+
|
92
96
|
private
|
93
97
|
def calculate(op, other)
|
94
98
|
if Scalar === other
|
@@ -123,8 +127,9 @@ module ActiveSupport
|
|
123
127
|
}.freeze
|
124
128
|
|
125
129
|
PARTS = [:years, :months, :weeks, :days, :hours, :minutes, :seconds].freeze
|
130
|
+
VARIABLE_PARTS = [:years, :months, :weeks, :days].freeze
|
126
131
|
|
127
|
-
|
132
|
+
attr_reader :value
|
128
133
|
|
129
134
|
autoload :ISO8601Parser, "active_support/duration/iso8601_parser"
|
130
135
|
autoload :ISO8601Serializer, "active_support/duration/iso8601_serializer"
|
@@ -140,38 +145,38 @@ module ActiveSupport
|
|
140
145
|
new(calculate_total_seconds(parts), parts)
|
141
146
|
end
|
142
147
|
|
143
|
-
def ===(other)
|
148
|
+
def ===(other) # :nodoc:
|
144
149
|
other.is_a?(Duration)
|
145
150
|
rescue ::NoMethodError
|
146
151
|
false
|
147
152
|
end
|
148
153
|
|
149
|
-
def seconds(value)
|
150
|
-
new(value, seconds: value)
|
154
|
+
def seconds(value) # :nodoc:
|
155
|
+
new(value, { seconds: value }, false)
|
151
156
|
end
|
152
157
|
|
153
|
-
def minutes(value)
|
154
|
-
new(value * SECONDS_PER_MINUTE, minutes: value)
|
158
|
+
def minutes(value) # :nodoc:
|
159
|
+
new(value * SECONDS_PER_MINUTE, { minutes: value }, false)
|
155
160
|
end
|
156
161
|
|
157
|
-
def hours(value)
|
158
|
-
new(value * SECONDS_PER_HOUR, hours: value)
|
162
|
+
def hours(value) # :nodoc:
|
163
|
+
new(value * SECONDS_PER_HOUR, { hours: value }, false)
|
159
164
|
end
|
160
165
|
|
161
|
-
def days(value)
|
162
|
-
new(value * SECONDS_PER_DAY, days: value)
|
166
|
+
def days(value) # :nodoc:
|
167
|
+
new(value * SECONDS_PER_DAY, { days: value }, true)
|
163
168
|
end
|
164
169
|
|
165
|
-
def weeks(value)
|
166
|
-
new(value * SECONDS_PER_WEEK, weeks: value)
|
170
|
+
def weeks(value) # :nodoc:
|
171
|
+
new(value * SECONDS_PER_WEEK, { weeks: value }, true)
|
167
172
|
end
|
168
173
|
|
169
|
-
def months(value)
|
170
|
-
new(value * SECONDS_PER_MONTH, months: value)
|
174
|
+
def months(value) # :nodoc:
|
175
|
+
new(value * SECONDS_PER_MONTH, { months: value }, true)
|
171
176
|
end
|
172
177
|
|
173
|
-
def years(value)
|
174
|
-
new(value * SECONDS_PER_YEAR, years: value)
|
178
|
+
def years(value) # :nodoc:
|
179
|
+
new(value * SECONDS_PER_YEAR, { years: value }, true)
|
175
180
|
end
|
176
181
|
|
177
182
|
# Creates a new Duration from a seconds value that is converted
|
@@ -186,20 +191,24 @@ module ActiveSupport
|
|
186
191
|
end
|
187
192
|
|
188
193
|
parts = {}
|
189
|
-
|
190
|
-
|
194
|
+
remainder = value.round(9)
|
195
|
+
variable = false
|
191
196
|
|
192
197
|
PARTS.each do |part|
|
193
198
|
unless part == :seconds
|
194
199
|
part_in_seconds = PARTS_IN_SECONDS[part]
|
195
|
-
parts[part] = remainder.div(part_in_seconds)
|
200
|
+
parts[part] = remainder.div(part_in_seconds)
|
196
201
|
remainder %= part_in_seconds
|
202
|
+
|
203
|
+
unless parts[part].zero?
|
204
|
+
variable ||= VARIABLE_PARTS.include?(part)
|
205
|
+
end
|
197
206
|
end
|
198
207
|
end unless value == 0
|
199
208
|
|
200
|
-
parts[:seconds] = remainder
|
209
|
+
parts[:seconds] = remainder
|
201
210
|
|
202
|
-
new(value, parts)
|
211
|
+
new(value, parts, variable)
|
203
212
|
end
|
204
213
|
|
205
214
|
private
|
@@ -210,12 +219,23 @@ module ActiveSupport
|
|
210
219
|
end
|
211
220
|
end
|
212
221
|
|
213
|
-
def initialize(value, parts)
|
222
|
+
def initialize(value, parts, variable = nil) # :nodoc:
|
214
223
|
@value, @parts = value, parts
|
215
224
|
@parts.reject! { |k, v| v.zero? } unless value == 0
|
225
|
+
@parts.freeze
|
226
|
+
@variable = variable
|
227
|
+
|
228
|
+
if @variable.nil?
|
229
|
+
@variable = @parts.any? { |part, _| VARIABLE_PARTS.include?(part) }
|
230
|
+
end
|
216
231
|
end
|
217
232
|
|
218
|
-
|
233
|
+
# Returns a copy of the parts hash that defines the duration
|
234
|
+
def parts
|
235
|
+
@parts.dup
|
236
|
+
end
|
237
|
+
|
238
|
+
def coerce(other) # :nodoc:
|
219
239
|
case other
|
220
240
|
when Scalar
|
221
241
|
[other, self]
|
@@ -240,13 +260,13 @@ module ActiveSupport
|
|
240
260
|
# are treated as seconds.
|
241
261
|
def +(other)
|
242
262
|
if Duration === other
|
243
|
-
parts = @parts.merge(other.
|
263
|
+
parts = @parts.merge(other._parts) do |_key, value, other_value|
|
244
264
|
value + other_value
|
245
265
|
end
|
246
|
-
Duration.new(value + other.value, parts)
|
266
|
+
Duration.new(value + other.value, parts, @variable || other.variable?)
|
247
267
|
else
|
248
268
|
seconds = @parts.fetch(:seconds, 0) + other
|
249
|
-
Duration.new(value + other, @parts.merge(seconds: seconds))
|
269
|
+
Duration.new(value + other, @parts.merge(seconds: seconds), @variable)
|
250
270
|
end
|
251
271
|
end
|
252
272
|
|
@@ -259,9 +279,9 @@ module ActiveSupport
|
|
259
279
|
# Multiplies this Duration by a Numeric and returns a new Duration.
|
260
280
|
def *(other)
|
261
281
|
if Scalar === other || Duration === other
|
262
|
-
Duration.new(value * other.value, parts.transform_values { |number| number * other.value })
|
282
|
+
Duration.new(value * other.value, @parts.transform_values { |number| number * other.value }, @variable || other.variable?)
|
263
283
|
elsif Numeric === other
|
264
|
-
Duration.new(value * other, parts.transform_values { |number| number * other })
|
284
|
+
Duration.new(value * other, @parts.transform_values { |number| number * other }, @variable)
|
265
285
|
else
|
266
286
|
raise_type_error(other)
|
267
287
|
end
|
@@ -270,11 +290,11 @@ module ActiveSupport
|
|
270
290
|
# Divides this Duration by a Numeric and returns a new Duration.
|
271
291
|
def /(other)
|
272
292
|
if Scalar === other
|
273
|
-
Duration.new(value / other.value, parts.transform_values { |number| number / other.value })
|
293
|
+
Duration.new(value / other.value, @parts.transform_values { |number| number / other.value }, @variable)
|
274
294
|
elsif Duration === other
|
275
295
|
value / other.value
|
276
296
|
elsif Numeric === other
|
277
|
-
Duration.new(value / other, parts.transform_values { |number| number / other })
|
297
|
+
Duration.new(value / other, @parts.transform_values { |number| number / other }, @variable)
|
278
298
|
else
|
279
299
|
raise_type_error(other)
|
280
300
|
end
|
@@ -292,15 +312,15 @@ module ActiveSupport
|
|
292
312
|
end
|
293
313
|
end
|
294
314
|
|
295
|
-
def -@
|
296
|
-
Duration.new(-value, parts.transform_values(&:-@))
|
315
|
+
def -@ # :nodoc:
|
316
|
+
Duration.new(-value, @parts.transform_values(&:-@), @variable)
|
297
317
|
end
|
298
318
|
|
299
|
-
def +@
|
319
|
+
def +@ # :nodoc:
|
300
320
|
self
|
301
321
|
end
|
302
322
|
|
303
|
-
def is_a?(klass)
|
323
|
+
def is_a?(klass) # :nodoc:
|
304
324
|
Duration == klass || value.is_a?(klass)
|
305
325
|
end
|
306
326
|
alias :kind_of? :is_a?
|
@@ -420,24 +440,24 @@ module ActiveSupport
|
|
420
440
|
alias :until :ago
|
421
441
|
alias :before :ago
|
422
442
|
|
423
|
-
def inspect
|
424
|
-
return "#{value} seconds" if parts.empty?
|
443
|
+
def inspect # :nodoc:
|
444
|
+
return "#{value} seconds" if @parts.empty?
|
425
445
|
|
426
|
-
parts.
|
446
|
+
@parts.
|
427
447
|
sort_by { |unit, _ | PARTS.index(unit) }.
|
428
448
|
map { |unit, val| "#{val} #{val == 1 ? unit.to_s.chop : unit.to_s}" }.
|
429
|
-
to_sentence(locale:
|
449
|
+
to_sentence(locale: false)
|
430
450
|
end
|
431
451
|
|
432
|
-
def as_json(options = nil)
|
452
|
+
def as_json(options = nil) # :nodoc:
|
433
453
|
to_i
|
434
454
|
end
|
435
455
|
|
436
|
-
def init_with(coder)
|
456
|
+
def init_with(coder) # :nodoc:
|
437
457
|
initialize(coder["value"], coder["parts"])
|
438
458
|
end
|
439
459
|
|
440
|
-
def encode_with(coder)
|
460
|
+
def encode_with(coder) # :nodoc:
|
441
461
|
coder.map = { "value" => @value, "parts" => @parts }
|
442
462
|
end
|
443
463
|
|
@@ -447,16 +467,24 @@ module ActiveSupport
|
|
447
467
|
ISO8601Serializer.new(self, precision: precision).serialize
|
448
468
|
end
|
449
469
|
|
470
|
+
def variable? # :nodoc:
|
471
|
+
@variable
|
472
|
+
end
|
473
|
+
|
474
|
+
def _parts # :nodoc:
|
475
|
+
@parts
|
476
|
+
end
|
477
|
+
|
450
478
|
private
|
451
479
|
def sum(sign, time = ::Time.current)
|
452
480
|
unless time.acts_like?(:time) || time.acts_like?(:date)
|
453
481
|
raise ::ArgumentError, "expected a time or date, got #{time.inspect}"
|
454
482
|
end
|
455
483
|
|
456
|
-
if parts.empty?
|
484
|
+
if @parts.empty?
|
457
485
|
time.since(sign * value)
|
458
486
|
else
|
459
|
-
parts.inject(time) do |t, (type, number)|
|
487
|
+
@parts.inject(time) do |t, (type, number)|
|
460
488
|
if type == :seconds
|
461
489
|
t.since(sign * number)
|
462
490
|
elsif type == :minutes
|
@@ -34,8 +34,18 @@ module ActiveSupport
|
|
34
34
|
end
|
35
35
|
|
36
36
|
private
|
37
|
+
def deep_transform(hash)
|
38
|
+
return hash unless hash.is_a?(Hash)
|
39
|
+
|
40
|
+
h = ActiveSupport::InheritableOptions.new
|
41
|
+
hash.each do |k, v|
|
42
|
+
h[k] = deep_transform(v)
|
43
|
+
end
|
44
|
+
h
|
45
|
+
end
|
46
|
+
|
37
47
|
def options
|
38
|
-
@options ||= ActiveSupport::InheritableOptions.new(config)
|
48
|
+
@options ||= ActiveSupport::InheritableOptions.new(deep_transform(config))
|
39
49
|
end
|
40
50
|
|
41
51
|
def deserialize(config)
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require "active_support/string_inquirer"
|
4
4
|
|
5
5
|
module ActiveSupport
|
6
|
-
class EnvironmentInquirer < StringInquirer
|
6
|
+
class EnvironmentInquirer < StringInquirer # :nodoc:
|
7
7
|
DEFAULT_ENVIRONMENTS = ["development", "test", "production"]
|
8
8
|
def initialize(env)
|
9
9
|
super(env)
|
@@ -34,7 +34,7 @@ module ActiveSupport
|
|
34
34
|
# checker.execute_if_updated
|
35
35
|
# # => "changed"
|
36
36
|
#
|
37
|
-
class EventedFileUpdateChecker
|
37
|
+
class EventedFileUpdateChecker # :nodoc: all
|
38
38
|
def initialize(files, dirs = {}, &block)
|
39
39
|
unless block
|
40
40
|
raise ArgumentError, "A block is required to initialize an EventedFileUpdateChecker"
|
@@ -63,21 +63,18 @@ module ActiveSupport
|
|
63
63
|
# after the work has been performed.
|
64
64
|
#
|
65
65
|
# Where possible, prefer +wrap+.
|
66
|
-
def self.run!
|
67
|
-
if
|
68
|
-
|
69
|
-
lost_instance&.complete!
|
66
|
+
def self.run!
|
67
|
+
if active?
|
68
|
+
Null
|
70
69
|
else
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
ensure
|
80
|
-
instance.complete! unless success
|
70
|
+
new.tap do |instance|
|
71
|
+
success = nil
|
72
|
+
begin
|
73
|
+
instance.run!
|
74
|
+
success = true
|
75
|
+
ensure
|
76
|
+
instance.complete! unless success
|
77
|
+
end
|
81
78
|
end
|
82
79
|
end
|
83
80
|
end
|
@@ -106,11 +103,11 @@ module ActiveSupport
|
|
106
103
|
self.active = Concurrent::Hash.new
|
107
104
|
|
108
105
|
def self.active? # :nodoc:
|
109
|
-
@active
|
106
|
+
@active[Thread.current]
|
110
107
|
end
|
111
108
|
|
112
109
|
def run! # :nodoc:
|
113
|
-
self.class.active[Thread.current] =
|
110
|
+
self.class.active[Thread.current] = true
|
114
111
|
run_callbacks(:run)
|
115
112
|
end
|
116
113
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module ActiveSupport
|
4
4
|
module ForkTracker # :nodoc:
|
5
5
|
module CoreExt
|
6
|
-
def fork(
|
6
|
+
def fork(...)
|
7
7
|
if block_given?
|
8
8
|
super do
|
9
9
|
ForkTracker.check!
|
@@ -16,17 +16,15 @@ module ActiveSupport
|
|
16
16
|
pid
|
17
17
|
end
|
18
18
|
end
|
19
|
-
ruby2_keywords(:fork) if respond_to?(:ruby2_keywords, true)
|
20
19
|
end
|
21
20
|
|
22
21
|
module CoreExtPrivate
|
23
22
|
include CoreExt
|
24
23
|
|
25
24
|
private
|
26
|
-
def fork(
|
25
|
+
def fork(...)
|
27
26
|
super
|
28
27
|
end
|
29
|
-
ruby2_keywords(:fork) if respond_to?(:ruby2_keywords, true)
|
30
28
|
end
|
31
29
|
|
32
30
|
@pid = Process.pid
|
@@ -65,7 +65,7 @@ module ActiveSupport
|
|
65
65
|
self
|
66
66
|
end
|
67
67
|
|
68
|
-
def initialize(constructor =
|
68
|
+
def initialize(constructor = nil)
|
69
69
|
if constructor.respond_to?(:to_hash)
|
70
70
|
super()
|
71
71
|
update(constructor)
|
@@ -73,6 +73,8 @@ module ActiveSupport
|
|
73
73
|
hash = constructor.is_a?(Hash) ? constructor : constructor.to_hash
|
74
74
|
self.default = hash.default if hash.default
|
75
75
|
self.default_proc = hash.default_proc if hash.default_proc
|
76
|
+
elsif constructor.nil?
|
77
|
+
super()
|
76
78
|
else
|
77
79
|
super(constructor)
|
78
80
|
end
|
data/lib/active_support/i18n.rb
CHANGED
@@ -5,6 +5,7 @@ require "active_support/core_ext/hash/except"
|
|
5
5
|
require "active_support/core_ext/hash/slice"
|
6
6
|
begin
|
7
7
|
require "i18n"
|
8
|
+
require "i18n/backend/fallbacks"
|
8
9
|
rescue LoadError => e
|
9
10
|
$stderr.puts "The i18n gem is not available. Please add it to your Gemfile and run bundle install"
|
10
11
|
raise e
|
@@ -16,13 +16,13 @@ module ActiveSupport
|
|
16
16
|
# inflect.plural /^(ox)$/i, '\1\2en'
|
17
17
|
# inflect.singular /^(ox)en/i, '\1'
|
18
18
|
#
|
19
|
-
# inflect.irregular '
|
19
|
+
# inflect.irregular 'cactus', 'cacti'
|
20
20
|
#
|
21
21
|
# inflect.uncountable 'equipment'
|
22
22
|
# end
|
23
23
|
#
|
24
24
|
# New rules are added at the top. So in the example above, the irregular
|
25
|
-
# rule for
|
25
|
+
# rule for cactus will now be the first of the pluralization and
|
26
26
|
# singularization rules that is runs. This guarantees that your rules run
|
27
27
|
# before any of the rules that may already have been loaded.
|
28
28
|
class Inflections
|
@@ -64,6 +64,13 @@ module ActiveSupport
|
|
64
64
|
@__instance__[locale] ||= new
|
65
65
|
end
|
66
66
|
|
67
|
+
def self.instance_or_fallback(locale)
|
68
|
+
I18n.fallbacks[locale].each do |k|
|
69
|
+
return @__instance__[k] if @__instance__.key?(k)
|
70
|
+
end
|
71
|
+
instance(locale)
|
72
|
+
end
|
73
|
+
|
67
74
|
attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms
|
68
75
|
|
69
76
|
attr_reader :acronyms_camelize_regex, :acronyms_underscore_regex # :nodoc:
|
@@ -160,7 +167,7 @@ module ActiveSupport
|
|
160
167
|
# regular expressions. You simply pass the irregular in singular and
|
161
168
|
# plural form.
|
162
169
|
#
|
163
|
-
# irregular '
|
170
|
+
# irregular 'cactus', 'cacti'
|
164
171
|
# irregular 'person', 'people'
|
165
172
|
def irregular(singular, plural)
|
166
173
|
@uncountables.delete(singular)
|
@@ -248,7 +255,7 @@ module ActiveSupport
|
|
248
255
|
if block_given?
|
249
256
|
yield Inflections.instance(locale)
|
250
257
|
else
|
251
|
-
Inflections.
|
258
|
+
Inflections.instance_or_fallback(locale)
|
252
259
|
end
|
253
260
|
end
|
254
261
|
end
|