activesupport 6.1.4.6 → 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 -551
- 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 -12
- 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 -36
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +0 -8
- data/lib/active_support/core_ext/time/calculations.rb +6 -5
- data/lib/active_support/core_ext/time/zones.rb +2 -17
- data/lib/active_support/core_ext/uri.rb +1 -15
- data/lib/active_support/current_attributes.rb +17 -1
- 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 +5 -3
- 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 +77 -48
- 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 -47
- 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/unicode.rb +2 -2
- 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 -0
- data/lib/active_support/railtie.rb +34 -11
- 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/tagged_logging.rb +1 -1
- data/lib/active_support/test_case.rb +9 -21
- data/lib/active_support/testing/assertions.rb +35 -5
- 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 -9
- 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 -28
- data/lib/active_support/core_ext/marshal.rb +0 -26
- data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
@@ -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 = "
|
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,10 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "openssl"
|
4
|
+
|
3
5
|
module ActiveSupport
|
4
|
-
class Digest
|
5
|
-
class <<self
|
6
|
+
class Digest # :nodoc:
|
7
|
+
class << self
|
6
8
|
def hash_digest_class
|
7
|
-
@hash_digest_class ||= ::Digest::MD5
|
9
|
+
@hash_digest_class ||= OpenSSL::Digest::MD5
|
8
10
|
end
|
9
11
|
|
10
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
|
@@ -187,18 +192,23 @@ module ActiveSupport
|
|
187
192
|
|
188
193
|
parts = {}
|
189
194
|
remainder = value.round(9)
|
195
|
+
variable = false
|
190
196
|
|
191
197
|
PARTS.each do |part|
|
192
198
|
unless part == :seconds
|
193
199
|
part_in_seconds = PARTS_IN_SECONDS[part]
|
194
200
|
parts[part] = remainder.div(part_in_seconds)
|
195
201
|
remainder %= part_in_seconds
|
202
|
+
|
203
|
+
unless parts[part].zero?
|
204
|
+
variable ||= VARIABLE_PARTS.include?(part)
|
205
|
+
end
|
196
206
|
end
|
197
207
|
end unless value == 0
|
198
208
|
|
199
209
|
parts[:seconds] = remainder
|
200
210
|
|
201
|
-
new(value, parts)
|
211
|
+
new(value, parts, variable)
|
202
212
|
end
|
203
213
|
|
204
214
|
private
|
@@ -209,12 +219,23 @@ module ActiveSupport
|
|
209
219
|
end
|
210
220
|
end
|
211
221
|
|
212
|
-
def initialize(value, parts)
|
222
|
+
def initialize(value, parts, variable = nil) # :nodoc:
|
213
223
|
@value, @parts = value, parts
|
214
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
|
215
231
|
end
|
216
232
|
|
217
|
-
|
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:
|
218
239
|
case other
|
219
240
|
when Scalar
|
220
241
|
[other, self]
|
@@ -239,13 +260,13 @@ module ActiveSupport
|
|
239
260
|
# are treated as seconds.
|
240
261
|
def +(other)
|
241
262
|
if Duration === other
|
242
|
-
parts = @parts.merge(other.
|
263
|
+
parts = @parts.merge(other._parts) do |_key, value, other_value|
|
243
264
|
value + other_value
|
244
265
|
end
|
245
|
-
Duration.new(value + other.value, parts)
|
266
|
+
Duration.new(value + other.value, parts, @variable || other.variable?)
|
246
267
|
else
|
247
268
|
seconds = @parts.fetch(:seconds, 0) + other
|
248
|
-
Duration.new(value + other, @parts.merge(seconds: seconds))
|
269
|
+
Duration.new(value + other, @parts.merge(seconds: seconds), @variable)
|
249
270
|
end
|
250
271
|
end
|
251
272
|
|
@@ -258,9 +279,9 @@ module ActiveSupport
|
|
258
279
|
# Multiplies this Duration by a Numeric and returns a new Duration.
|
259
280
|
def *(other)
|
260
281
|
if Scalar === other || Duration === other
|
261
|
-
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?)
|
262
283
|
elsif Numeric === other
|
263
|
-
Duration.new(value * other, parts.transform_values { |number| number * other })
|
284
|
+
Duration.new(value * other, @parts.transform_values { |number| number * other }, @variable)
|
264
285
|
else
|
265
286
|
raise_type_error(other)
|
266
287
|
end
|
@@ -269,11 +290,11 @@ module ActiveSupport
|
|
269
290
|
# Divides this Duration by a Numeric and returns a new Duration.
|
270
291
|
def /(other)
|
271
292
|
if Scalar === other
|
272
|
-
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)
|
273
294
|
elsif Duration === other
|
274
295
|
value / other.value
|
275
296
|
elsif Numeric === other
|
276
|
-
Duration.new(value / other, parts.transform_values { |number| number / other })
|
297
|
+
Duration.new(value / other, @parts.transform_values { |number| number / other }, @variable)
|
277
298
|
else
|
278
299
|
raise_type_error(other)
|
279
300
|
end
|
@@ -291,15 +312,15 @@ module ActiveSupport
|
|
291
312
|
end
|
292
313
|
end
|
293
314
|
|
294
|
-
def -@
|
295
|
-
Duration.new(-value, parts.transform_values(&:-@))
|
315
|
+
def -@ # :nodoc:
|
316
|
+
Duration.new(-value, @parts.transform_values(&:-@), @variable)
|
296
317
|
end
|
297
318
|
|
298
|
-
def +@
|
319
|
+
def +@ # :nodoc:
|
299
320
|
self
|
300
321
|
end
|
301
322
|
|
302
|
-
def is_a?(klass)
|
323
|
+
def is_a?(klass) # :nodoc:
|
303
324
|
Duration == klass || value.is_a?(klass)
|
304
325
|
end
|
305
326
|
alias :kind_of? :is_a?
|
@@ -419,24 +440,24 @@ module ActiveSupport
|
|
419
440
|
alias :until :ago
|
420
441
|
alias :before :ago
|
421
442
|
|
422
|
-
def inspect
|
423
|
-
return "#{value} seconds" if parts.empty?
|
443
|
+
def inspect # :nodoc:
|
444
|
+
return "#{value} seconds" if @parts.empty?
|
424
445
|
|
425
|
-
parts.
|
446
|
+
@parts.
|
426
447
|
sort_by { |unit, _ | PARTS.index(unit) }.
|
427
448
|
map { |unit, val| "#{val} #{val == 1 ? unit.to_s.chop : unit.to_s}" }.
|
428
|
-
to_sentence(locale:
|
449
|
+
to_sentence(locale: false)
|
429
450
|
end
|
430
451
|
|
431
|
-
def as_json(options = nil)
|
452
|
+
def as_json(options = nil) # :nodoc:
|
432
453
|
to_i
|
433
454
|
end
|
434
455
|
|
435
|
-
def init_with(coder)
|
456
|
+
def init_with(coder) # :nodoc:
|
436
457
|
initialize(coder["value"], coder["parts"])
|
437
458
|
end
|
438
459
|
|
439
|
-
def encode_with(coder)
|
460
|
+
def encode_with(coder) # :nodoc:
|
440
461
|
coder.map = { "value" => @value, "parts" => @parts }
|
441
462
|
end
|
442
463
|
|
@@ -446,16 +467,24 @@ module ActiveSupport
|
|
446
467
|
ISO8601Serializer.new(self, precision: precision).serialize
|
447
468
|
end
|
448
469
|
|
470
|
+
def variable? # :nodoc:
|
471
|
+
@variable
|
472
|
+
end
|
473
|
+
|
474
|
+
def _parts # :nodoc:
|
475
|
+
@parts
|
476
|
+
end
|
477
|
+
|
449
478
|
private
|
450
479
|
def sum(sign, time = ::Time.current)
|
451
480
|
unless time.acts_like?(:time) || time.acts_like?(:date)
|
452
481
|
raise ::ArgumentError, "expected a time or date, got #{time.inspect}"
|
453
482
|
end
|
454
483
|
|
455
|
-
if parts.empty?
|
484
|
+
if @parts.empty?
|
456
485
|
time.since(sign * value)
|
457
486
|
else
|
458
|
-
parts.inject(time) do |t, (type, number)|
|
487
|
+
@parts.inject(time) do |t, (type, number)|
|
459
488
|
if type == :seconds
|
460
489
|
t.since(sign * number)
|
461
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
|