activesupport 6.0.3.4 → 6.1.7.1
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 +456 -398
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/active_support/array_inquirer.rb +4 -2
- data/lib/active_support/backtrace_cleaner.rb +3 -3
- data/lib/active_support/benchmarkable.rb +1 -1
- data/lib/active_support/cache/file_store.rb +5 -4
- data/lib/active_support/cache/mem_cache_store.rb +29 -18
- data/lib/active_support/cache/memory_store.rb +46 -26
- data/lib/active_support/cache/redis_cache_store.rb +27 -27
- data/lib/active_support/cache/strategy/local_cache.rb +21 -6
- data/lib/active_support/cache.rb +92 -45
- data/lib/active_support/callbacks.rb +65 -56
- data/lib/active_support/concern.rb +46 -2
- data/lib/active_support/configurable.rb +3 -3
- data/lib/active_support/configuration_file.rb +51 -0
- data/lib/active_support/core_ext/benchmark.rb +2 -2
- data/lib/active_support/core_ext/class/attribute.rb +34 -44
- data/lib/active_support/core_ext/class/subclasses.rb +17 -38
- data/lib/active_support/core_ext/date/conversions.rb +2 -1
- data/lib/active_support/core_ext/date_and_time/calculations.rb +13 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/digest/uuid.rb +1 -0
- data/lib/active_support/core_ext/enumerable.rb +76 -4
- data/lib/active_support/core_ext/hash/conversions.rb +2 -2
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +1 -1
- data/lib/active_support/core_ext/hash/except.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +1 -1
- data/lib/active_support/core_ext/hash/slice.rb +3 -2
- data/lib/active_support/core_ext/load_error.rb +1 -1
- data/lib/active_support/core_ext/marshal.rb +2 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +23 -29
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +8 -4
- data/lib/active_support/core_ext/module/concerning.rb +8 -2
- data/lib/active_support/core_ext/module/delegation.rb +38 -28
- data/lib/active_support/core_ext/module/introspection.rb +1 -25
- data/lib/active_support/core_ext/name_error.rb +29 -2
- data/lib/active_support/core_ext/numeric/conversions.rb +22 -18
- data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
- data/lib/active_support/core_ext/object/json.rb +13 -2
- data/lib/active_support/core_ext/object/try.rb +2 -2
- data/lib/active_support/core_ext/range/compare_range.rb +9 -3
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +8 -3
- data/lib/active_support/core_ext/regexp.rb +8 -1
- data/lib/active_support/core_ext/string/access.rb +5 -24
- data/lib/active_support/core_ext/string/conversions.rb +1 -0
- data/lib/active_support/core_ext/string/inflections.rb +38 -4
- data/lib/active_support/core_ext/string/inquiry.rb +1 -0
- data/lib/active_support/core_ext/string/multibyte.rb +2 -2
- data/lib/active_support/core_ext/string/output_safety.rb +38 -10
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/time/calculations.rb +22 -1
- data/lib/active_support/core_ext/time/conversions.rb +2 -0
- data/lib/active_support/core_ext/uri.rb +5 -1
- data/lib/active_support/core_ext.rb +1 -1
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +9 -2
- data/lib/active_support/dependencies/zeitwerk_integration.rb +4 -1
- data/lib/active_support/dependencies.rb +43 -19
- data/lib/active_support/deprecation/behaviors.rb +15 -2
- data/lib/active_support/deprecation/disallowed.rb +56 -0
- data/lib/active_support/deprecation/instance_delegator.rb +0 -1
- data/lib/active_support/deprecation/method_wrappers.rb +3 -2
- data/lib/active_support/deprecation/proxy_wrappers.rb +3 -3
- data/lib/active_support/deprecation/reporting.rb +50 -7
- data/lib/active_support/deprecation.rb +6 -1
- data/lib/active_support/descendants_tracker.rb +6 -2
- data/lib/active_support/digest.rb +2 -0
- data/lib/active_support/duration/iso8601_serializer.rb +15 -9
- data/lib/active_support/duration.rb +75 -25
- data/lib/active_support/encrypted_file.rb +19 -2
- data/lib/active_support/environment_inquirer.rb +20 -0
- data/lib/active_support/evented_file_update_checker.rb +69 -133
- data/lib/active_support/execution_wrapper.rb +16 -13
- data/lib/active_support/fork_tracker.rb +64 -0
- data/lib/active_support/gem_version.rb +3 -3
- data/lib/active_support/hash_with_indifferent_access.rb +48 -24
- data/lib/active_support/i18n_railtie.rb +14 -19
- data/lib/active_support/inflector/inflections.rb +1 -2
- data/lib/active_support/inflector/methods.rb +36 -33
- data/lib/active_support/inflector/transliterate.rb +4 -4
- data/lib/active_support/json/decoding.rb +4 -4
- data/lib/active_support/json/encoding.rb +5 -1
- data/lib/active_support/key_generator.rb +1 -1
- data/lib/active_support/locale/en.yml +7 -3
- data/lib/active_support/log_subscriber.rb +8 -0
- data/lib/active_support/logger.rb +1 -1
- data/lib/active_support/logger_silence.rb +2 -26
- data/lib/active_support/logger_thread_safe_level.rb +34 -12
- data/lib/active_support/message_encryptor.rb +4 -7
- data/lib/active_support/message_verifier.rb +5 -5
- data/lib/active_support/messages/metadata.rb +9 -1
- data/lib/active_support/messages/rotation_configuration.rb +2 -1
- data/lib/active_support/messages/rotator.rb +6 -5
- data/lib/active_support/multibyte/chars.rb +4 -42
- data/lib/active_support/multibyte/unicode.rb +9 -83
- data/lib/active_support/notifications/fanout.rb +23 -8
- data/lib/active_support/notifications/instrumenter.rb +6 -15
- data/lib/active_support/notifications.rb +32 -5
- data/lib/active_support/number_helper/number_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_currency_converter.rb +3 -7
- data/lib/active_support/number_helper/number_to_human_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_rounded_converter.rb +9 -5
- data/lib/active_support/number_helper/rounding_helper.rb +12 -28
- data/lib/active_support/number_helper.rb +29 -14
- data/lib/active_support/option_merger.rb +3 -2
- data/lib/active_support/ordered_options.rb +8 -2
- data/lib/active_support/parameter_filter.rb +16 -11
- data/lib/active_support/per_thread_registry.rb +2 -1
- data/lib/active_support/rails.rb +1 -4
- data/lib/active_support/railtie.rb +23 -1
- data/lib/active_support/reloader.rb +1 -1
- data/lib/active_support/rescuable.rb +4 -4
- data/lib/active_support/secure_compare_rotator.rb +51 -0
- data/lib/active_support/security_utils.rb +19 -12
- data/lib/active_support/string_inquirer.rb +4 -2
- data/lib/active_support/subscriber.rb +12 -7
- data/lib/active_support/tagged_logging.rb +30 -5
- data/lib/active_support/testing/assertions.rb +18 -11
- data/lib/active_support/testing/parallelization/server.rb +78 -0
- data/lib/active_support/testing/parallelization/worker.rb +100 -0
- data/lib/active_support/testing/parallelization.rb +12 -95
- data/lib/active_support/testing/time_helpers.rb +40 -3
- data/lib/active_support/time_with_zone.rb +67 -43
- data/lib/active_support/values/time_zone.rb +22 -10
- data/lib/active_support/xml_mini/rexml.rb +8 -1
- data/lib/active_support.rb +13 -1
- metadata +35 -36
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -5
- data/lib/active_support/core_ext/hash/compact.rb +0 -5
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -5
- data/lib/active_support/core_ext/module/reachable.rb +0 -6
- data/lib/active_support/core_ext/numeric/inquiry.rb +0 -5
- data/lib/active_support/core_ext/range/include_range.rb +0 -9
@@ -104,10 +104,16 @@ class Module
|
|
104
104
|
# * grok the behavior of our class in one glance,
|
105
105
|
# * clean up monolithic junk-drawer classes by separating their concerns, and
|
106
106
|
# * stop leaning on protected/private for crude "this is internal stuff" modularity.
|
107
|
+
#
|
108
|
+
# === Prepending concerning
|
109
|
+
#
|
110
|
+
# <tt>concerning</tt> supports a <tt>prepend: true</tt> argument which will <tt>prepend</tt> the
|
111
|
+
# concern instead of using <tt>include</tt> for it.
|
107
112
|
module Concerning
|
108
113
|
# Define a new concern and mix it in.
|
109
|
-
def concerning(topic, &block)
|
110
|
-
|
114
|
+
def concerning(topic, prepend: false, &block)
|
115
|
+
method = prepend ? :prepend : :include
|
116
|
+
__send__(method, concern(topic, &block))
|
111
117
|
end
|
112
118
|
|
113
119
|
# A low-cruft shortcut to define a concern.
|
@@ -170,7 +170,7 @@ class Module
|
|
170
170
|
# The target method must be public, otherwise it will raise +NoMethodError+.
|
171
171
|
def delegate(*methods, to: nil, prefix: nil, allow_nil: nil, private: nil)
|
172
172
|
unless to
|
173
|
-
raise ArgumentError, "Delegation needs a target. Supply
|
173
|
+
raise ArgumentError, "Delegation needs a target. Supply a keyword argument 'to' (e.g. delegate :hello, to: :greeter)."
|
174
174
|
end
|
175
175
|
|
176
176
|
if prefix == true && /^[^a-z_]/.match?(to)
|
@@ -190,7 +190,13 @@ class Module
|
|
190
190
|
to = to.to_s
|
191
191
|
to = "self.#{to}" if DELEGATION_RESERVED_METHOD_NAMES.include?(to)
|
192
192
|
|
193
|
-
|
193
|
+
method_def = []
|
194
|
+
method_names = []
|
195
|
+
|
196
|
+
methods.map do |method|
|
197
|
+
method_name = prefix ? "#{method_prefix}#{method}" : method
|
198
|
+
method_names << method_name.to_sym
|
199
|
+
|
194
200
|
# Attribute writer methods only accept one argument. Makes sure []=
|
195
201
|
# methods still accept two arguments.
|
196
202
|
definition = if /[^\]]=$/.match?(method)
|
@@ -209,34 +215,33 @@ class Module
|
|
209
215
|
# whereas conceptually, from the user point of view, the delegator should
|
210
216
|
# be doing one call.
|
211
217
|
if allow_nil
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
"
|
216
|
-
" _
|
217
|
-
"
|
218
|
-
|
219
|
-
|
218
|
+
method = method.to_s
|
219
|
+
|
220
|
+
method_def <<
|
221
|
+
"def #{method_name}(#{definition})" <<
|
222
|
+
" _ = #{to}" <<
|
223
|
+
" if !_.nil? || nil.respond_to?(:#{method})" <<
|
224
|
+
" _.#{method}(#{definition})" <<
|
225
|
+
" end" <<
|
226
|
+
"end"
|
220
227
|
else
|
221
|
-
|
228
|
+
method = method.to_s
|
229
|
+
method_name = method_name.to_s
|
222
230
|
|
223
|
-
method_def
|
224
|
-
"def #{
|
225
|
-
"
|
226
|
-
" _.#{method}(#{definition})"
|
227
|
-
"rescue NoMethodError => e"
|
228
|
-
" if _.nil? && e.name == :#{method}"
|
229
|
-
"
|
230
|
-
" else"
|
231
|
-
" raise"
|
232
|
-
" end"
|
231
|
+
method_def <<
|
232
|
+
"def #{method_name}(#{definition})" <<
|
233
|
+
" _ = #{to}" <<
|
234
|
+
" _.#{method}(#{definition})" <<
|
235
|
+
"rescue NoMethodError => e" <<
|
236
|
+
" if _.nil? && e.name == :#{method}" <<
|
237
|
+
%( raise DelegationError, "#{self}##{method_name} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}") <<
|
238
|
+
" else" <<
|
239
|
+
" raise" <<
|
240
|
+
" end" <<
|
233
241
|
"end"
|
234
|
-
].join ";"
|
235
242
|
end
|
236
|
-
|
237
|
-
module_eval(method_def, file, line)
|
238
243
|
end
|
239
|
-
|
244
|
+
module_eval(method_def.join(";"), file, line)
|
240
245
|
private(*method_names) if private
|
241
246
|
method_names
|
242
247
|
end
|
@@ -280,13 +285,14 @@ class Module
|
|
280
285
|
# variables, methods, constants, etc.
|
281
286
|
#
|
282
287
|
# The delegated method must be public on the target, otherwise it will
|
283
|
-
# raise +
|
288
|
+
# raise +DelegationError+. If you wish to instead return +nil+,
|
289
|
+
# use the <tt>:allow_nil</tt> option.
|
284
290
|
#
|
285
291
|
# The <tt>marshal_dump</tt> and <tt>_dump</tt> methods are exempt from
|
286
292
|
# delegation due to possible interference when calling
|
287
293
|
# <tt>Marshal.dump(object)</tt>, should the delegation target method
|
288
294
|
# of <tt>object</tt> add or remove instance variables.
|
289
|
-
def delegate_missing_to(target)
|
295
|
+
def delegate_missing_to(target, allow_nil: nil)
|
290
296
|
target = target.to_s
|
291
297
|
target = "self.#{target}" if DELEGATION_RESERVED_METHOD_NAMES.include?(target)
|
292
298
|
|
@@ -307,7 +313,11 @@ class Module
|
|
307
313
|
super
|
308
314
|
rescue NoMethodError
|
309
315
|
if #{target}.nil?
|
310
|
-
|
316
|
+
if #{allow_nil == true}
|
317
|
+
nil
|
318
|
+
else
|
319
|
+
raise DelegationError, "\#{method} delegated to #{target}, but #{target} is nil"
|
320
|
+
end
|
311
321
|
else
|
312
322
|
raise
|
313
323
|
end
|
@@ -11,20 +11,12 @@ class Module
|
|
11
11
|
if defined?(@parent_name)
|
12
12
|
@parent_name
|
13
13
|
else
|
14
|
-
parent_name = name =~ /::[^:]+\
|
14
|
+
parent_name = name =~ /::[^:]+\z/ ? -$` : nil
|
15
15
|
@parent_name = parent_name unless frozen?
|
16
16
|
parent_name
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
def parent_name
|
21
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
22
|
-
`Module#parent_name` has been renamed to `module_parent_name`.
|
23
|
-
`parent_name` is deprecated and will be removed in Rails 6.1.
|
24
|
-
MSG
|
25
|
-
module_parent_name
|
26
|
-
end
|
27
|
-
|
28
20
|
# Returns the module which contains this one according to its name.
|
29
21
|
#
|
30
22
|
# module M
|
@@ -44,14 +36,6 @@ class Module
|
|
44
36
|
module_parent_name ? ActiveSupport::Inflector.constantize(module_parent_name) : Object
|
45
37
|
end
|
46
38
|
|
47
|
-
def parent
|
48
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
49
|
-
`Module#parent` has been renamed to `module_parent`.
|
50
|
-
`parent` is deprecated and will be removed in Rails 6.1.
|
51
|
-
MSG
|
52
|
-
module_parent
|
53
|
-
end
|
54
|
-
|
55
39
|
# Returns all the parents of this module according to its name, ordered from
|
56
40
|
# nested outwards. The receiver is not contained within the result.
|
57
41
|
#
|
@@ -76,12 +60,4 @@ class Module
|
|
76
60
|
parents << Object unless parents.include? Object
|
77
61
|
parents
|
78
62
|
end
|
79
|
-
|
80
|
-
def parents
|
81
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
82
|
-
`Module#parents` has been renamed to `module_parents`.
|
83
|
-
`parents` is deprecated and will be removed in Rails 6.1.
|
84
|
-
MSG
|
85
|
-
module_parents
|
86
|
-
end
|
87
63
|
end
|
@@ -14,9 +14,22 @@ class NameError
|
|
14
14
|
# It extends NameError#message with spell corrections which are SLOW.
|
15
15
|
# We should use original_message message instead.
|
16
16
|
message = respond_to?(:original_message) ? original_message : self.message
|
17
|
+
return unless message.start_with?("uninitialized constant ")
|
17
18
|
|
18
|
-
|
19
|
-
|
19
|
+
receiver = begin
|
20
|
+
self.receiver
|
21
|
+
rescue ArgumentError
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
if receiver == Object
|
26
|
+
name.to_s
|
27
|
+
elsif receiver
|
28
|
+
"#{real_mod_name(receiver)}::#{self.name}"
|
29
|
+
else
|
30
|
+
if match = message.match(/((::)?([A-Z]\w*)(::[A-Z]\w*)*)$/)
|
31
|
+
match[1]
|
32
|
+
end
|
20
33
|
end
|
21
34
|
end
|
22
35
|
|
@@ -35,4 +48,18 @@ class NameError
|
|
35
48
|
missing_name == name.to_s
|
36
49
|
end
|
37
50
|
end
|
51
|
+
|
52
|
+
private
|
53
|
+
UNBOUND_METHOD_MODULE_NAME = Module.instance_method(:name)
|
54
|
+
private_constant :UNBOUND_METHOD_MODULE_NAME
|
55
|
+
|
56
|
+
if UnboundMethod.method_defined?(:bind_call)
|
57
|
+
def real_mod_name(mod)
|
58
|
+
UNBOUND_METHOD_MODULE_NAME.bind_call(mod)
|
59
|
+
end
|
60
|
+
else
|
61
|
+
def real_mod_name(mod)
|
62
|
+
UNBOUND_METHOD_MODULE_NAME.bind(mod).call
|
63
|
+
end
|
64
|
+
end
|
38
65
|
end
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
require "active_support/core_ext/big_decimal/conversions"
|
4
4
|
require "active_support/number_helper"
|
5
|
-
require "active_support/core_ext/module/deprecation"
|
6
5
|
|
7
6
|
module ActiveSupport
|
8
7
|
module NumericWithFormat
|
@@ -27,10 +26,11 @@ module ActiveSupport
|
|
27
26
|
# # => "+1.123.555.1234 x 1343"
|
28
27
|
#
|
29
28
|
# Currency:
|
30
|
-
# 1234567890.50.to_s(:currency)
|
31
|
-
# 1234567890.506.to_s(:currency)
|
32
|
-
# 1234567890.506.to_s(:currency, precision: 3)
|
33
|
-
# 1234567890.506.to_s(:currency,
|
29
|
+
# 1234567890.50.to_s(:currency) # => "$1,234,567,890.50"
|
30
|
+
# 1234567890.506.to_s(:currency) # => "$1,234,567,890.51"
|
31
|
+
# 1234567890.506.to_s(:currency, precision: 3) # => "$1,234,567,890.506"
|
32
|
+
# 1234567890.506.to_s(:currency, round_mode: :down) # => "$1,234,567,890.50"
|
33
|
+
# 1234567890.506.to_s(:currency, locale: :fr) # => "1 234 567 890,51 €"
|
34
34
|
# -1234567890.50.to_s(:currency, negative_format: '(%u%n)')
|
35
35
|
# # => "($1,234,567,890.50)"
|
36
36
|
# 1234567890.50.to_s(:currency, unit: '£', separator: ',', delimiter: '')
|
@@ -43,6 +43,7 @@ module ActiveSupport
|
|
43
43
|
# 100.to_s(:percentage, precision: 0) # => "100%"
|
44
44
|
# 1000.to_s(:percentage, delimiter: '.', separator: ',') # => "1.000,000%"
|
45
45
|
# 302.24398923423.to_s(:percentage, precision: 5) # => "302.24399%"
|
46
|
+
# 302.24398923423.to_s(:percentage, round_mode: :down) # => "302.243%"
|
46
47
|
# 1000.to_s(:percentage, locale: :fr) # => "1 000,000%"
|
47
48
|
# 100.to_s(:percentage, format: '%n %') # => "100.000 %"
|
48
49
|
#
|
@@ -59,6 +60,7 @@ module ActiveSupport
|
|
59
60
|
# Rounded:
|
60
61
|
# 111.2345.to_s(:rounded) # => "111.235"
|
61
62
|
# 111.2345.to_s(:rounded, precision: 2) # => "111.23"
|
63
|
+
# 111.2345.to_s(:rounded, precision: 2, round_mode: :up) # => "111.24"
|
62
64
|
# 13.to_s(:rounded, precision: 5) # => "13.00000"
|
63
65
|
# 389.32314.to_s(:rounded, precision: 0) # => "389"
|
64
66
|
# 111.2345.to_s(:rounded, significant: true) # => "111"
|
@@ -72,19 +74,20 @@ module ActiveSupport
|
|
72
74
|
# # => "1.111,23"
|
73
75
|
#
|
74
76
|
# Human-friendly size in Bytes:
|
75
|
-
# 123.to_s(:human_size)
|
76
|
-
# 1234.to_s(:human_size)
|
77
|
-
# 12345.to_s(:human_size)
|
78
|
-
# 1234567.to_s(:human_size)
|
79
|
-
# 1234567890.to_s(:human_size)
|
80
|
-
# 1234567890123.to_s(:human_size)
|
81
|
-
# 1234567890123456.to_s(:human_size)
|
82
|
-
# 1234567890123456789.to_s(:human_size)
|
83
|
-
# 1234567.to_s(:human_size, precision: 2)
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
77
|
+
# 123.to_s(:human_size) # => "123 Bytes"
|
78
|
+
# 1234.to_s(:human_size) # => "1.21 KB"
|
79
|
+
# 12345.to_s(:human_size) # => "12.1 KB"
|
80
|
+
# 1234567.to_s(:human_size) # => "1.18 MB"
|
81
|
+
# 1234567890.to_s(:human_size) # => "1.15 GB"
|
82
|
+
# 1234567890123.to_s(:human_size) # => "1.12 TB"
|
83
|
+
# 1234567890123456.to_s(:human_size) # => "1.1 PB"
|
84
|
+
# 1234567890123456789.to_s(:human_size) # => "1.07 EB"
|
85
|
+
# 1234567.to_s(:human_size, precision: 2) # => "1.2 MB"
|
86
|
+
# 1234567.to_s(:human_size, precision: 2, round_mode: :up) # => "1.3 MB"
|
87
|
+
# 483989.to_s(:human_size, precision: 2) # => "470 KB"
|
88
|
+
# 1234567.to_s(:human_size, precision: 2, separator: ',') # => "1,2 MB"
|
89
|
+
# 1234567890123.to_s(:human_size, precision: 5) # => "1.1228 TB"
|
90
|
+
# 524288000.to_s(:human_size, precision: 5) # => "500 MB"
|
88
91
|
#
|
89
92
|
# Human-friendly format:
|
90
93
|
# 123.to_s(:human) # => "123"
|
@@ -96,6 +99,7 @@ module ActiveSupport
|
|
96
99
|
# 1234567890123456.to_s(:human) # => "1.23 Quadrillion"
|
97
100
|
# 1234567890123456789.to_s(:human) # => "1230 Quadrillion"
|
98
101
|
# 489939.to_s(:human, precision: 2) # => "490 Thousand"
|
102
|
+
# 489939.to_s(:human, precision: 2, round_mode: :down) # => "480 Thousand"
|
99
103
|
# 489939.to_s(:human, precision: 4) # => "489.9 Thousand"
|
100
104
|
# 1234567.to_s(:human, precision: 4,
|
101
105
|
# significant: false) # => "1.2346 Million"
|
@@ -3,6 +3,7 @@
|
|
3
3
|
# Hack to load json gem first so we can overwrite its to_json.
|
4
4
|
require "json"
|
5
5
|
require "bigdecimal"
|
6
|
+
require "ipaddr"
|
6
7
|
require "uri/generic"
|
7
8
|
require "pathname"
|
8
9
|
require "active_support/core_ext/big_decimal/conversions" # for #to_s
|
@@ -45,7 +46,7 @@ module ActiveSupport
|
|
45
46
|
end
|
46
47
|
end
|
47
48
|
|
48
|
-
[Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass
|
49
|
+
[Enumerable, Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass].reverse_each do |klass|
|
49
50
|
klass.prepend(ActiveSupport::ToJsonWithActiveSupportEncoder)
|
50
51
|
end
|
51
52
|
|
@@ -169,7 +170,11 @@ class Hash
|
|
169
170
|
self
|
170
171
|
end
|
171
172
|
|
172
|
-
|
173
|
+
result = {}
|
174
|
+
subset.each do |k, v|
|
175
|
+
result[k.to_s] = options ? v.as_json(options.dup) : v.as_json
|
176
|
+
end
|
177
|
+
result
|
173
178
|
end
|
174
179
|
end
|
175
180
|
|
@@ -215,6 +220,12 @@ class Pathname #:nodoc:
|
|
215
220
|
end
|
216
221
|
end
|
217
222
|
|
223
|
+
class IPAddr # :nodoc:
|
224
|
+
def as_json(options = nil)
|
225
|
+
to_s
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
218
229
|
class Process::Status #:nodoc:
|
219
230
|
def as_json(options = nil)
|
220
231
|
{ exitstatus: exitstatus, pid: pid }
|
@@ -145,14 +145,14 @@ class NilClass
|
|
145
145
|
#
|
146
146
|
# With +try+
|
147
147
|
# @person.try(:children).try(:first).try(:name)
|
148
|
-
def try(
|
148
|
+
def try(_method_name = nil, *)
|
149
149
|
nil
|
150
150
|
end
|
151
151
|
|
152
152
|
# Calling +try!+ on +nil+ always returns +nil+.
|
153
153
|
#
|
154
154
|
# nil.try!(:name) # => nil
|
155
|
-
def try!(
|
155
|
+
def try!(_method_name = nil, *)
|
156
156
|
nil
|
157
157
|
end
|
158
158
|
end
|
@@ -15,11 +15,13 @@ module ActiveSupport
|
|
15
15
|
# The given range must be fully bounded, with both start and end.
|
16
16
|
def ===(value)
|
17
17
|
if value.is_a?(::Range)
|
18
|
+
is_backwards_op = value.exclude_end? ? :>= : :>
|
19
|
+
return false if value.begin && value.end && value.begin.public_send(is_backwards_op, value.end)
|
18
20
|
# 1...10 includes 1..9 but it does not include 1..10.
|
19
21
|
# 1..10 includes 1...11 but it does not include 1...12.
|
20
22
|
operator = exclude_end? && !value.exclude_end? ? :< : :<=
|
21
23
|
value_max = !exclude_end? && value.exclude_end? ? value.max : value.last
|
22
|
-
super(value.first) && (self.end.nil? || value_max.
|
24
|
+
super(value.first) && (self.end.nil? || value_max.public_send(operator, last))
|
23
25
|
else
|
24
26
|
super
|
25
27
|
end
|
@@ -38,11 +40,13 @@ module ActiveSupport
|
|
38
40
|
# The given range must be fully bounded, with both start and end.
|
39
41
|
def include?(value)
|
40
42
|
if value.is_a?(::Range)
|
43
|
+
is_backwards_op = value.exclude_end? ? :>= : :>
|
44
|
+
return false if value.begin && value.end && value.begin.public_send(is_backwards_op, value.end)
|
41
45
|
# 1...10 includes 1..9 but it does not include 1..10.
|
42
46
|
# 1..10 includes 1...11 but it does not include 1...12.
|
43
47
|
operator = exclude_end? && !value.exclude_end? ? :< : :<=
|
44
48
|
value_max = !exclude_end? && value.exclude_end? ? value.max : value.last
|
45
|
-
super(value.first) && (self.end.nil? || value_max.
|
49
|
+
super(value.first) && (self.end.nil? || value_max.public_send(operator, last))
|
46
50
|
else
|
47
51
|
super
|
48
52
|
end
|
@@ -61,11 +65,13 @@ module ActiveSupport
|
|
61
65
|
# The given range must be fully bounded, with both start and end.
|
62
66
|
def cover?(value)
|
63
67
|
if value.is_a?(::Range)
|
68
|
+
is_backwards_op = value.exclude_end? ? :>= : :>
|
69
|
+
return false if value.begin && value.end && value.begin.public_send(is_backwards_op, value.end)
|
64
70
|
# 1...10 covers 1..9 but it does not cover 1..10.
|
65
71
|
# 1..10 covers 1...11 but it does not cover 1...12.
|
66
72
|
operator = exclude_end? && !value.exclude_end? ? :< : :<=
|
67
73
|
value_max = !exclude_end? && value.exclude_end? ? value.max : value.last
|
68
|
-
super(value.first) && (self.end.nil? || value_max.
|
74
|
+
super(value.first) && (self.end.nil? || value_max.public_send(operator, last))
|
69
75
|
else
|
70
76
|
super
|
71
77
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/time_with_zone"
|
4
|
+
require "active_support/deprecation"
|
4
5
|
|
5
6
|
module ActiveSupport
|
6
7
|
module IncludeTimeWithZone #:nodoc:
|
@@ -9,9 +10,13 @@ module ActiveSupport
|
|
9
10
|
# (1.hour.ago..1.hour.from_now).include?(Time.current) # => true
|
10
11
|
#
|
11
12
|
def include?(value)
|
12
|
-
if self.begin.is_a?(TimeWithZone)
|
13
|
-
|
14
|
-
|
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
|
15
20
|
cover?(value)
|
16
21
|
else
|
17
22
|
super
|
@@ -1,6 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class Regexp
|
3
|
+
class Regexp
|
4
|
+
# Returns +true+ if the regexp has the multiline flag set.
|
5
|
+
#
|
6
|
+
# (/./).multiline? # => false
|
7
|
+
# (/./m).multiline? # => true
|
8
|
+
#
|
9
|
+
# Regexp.new(".").multiline? # => false
|
10
|
+
# Regexp.new(".", Regexp::MULTILINE).multiline? # => true
|
4
11
|
def multiline?
|
5
12
|
options & MULTILINE == MULTILINE
|
6
13
|
end
|
@@ -44,7 +44,7 @@ class String
|
|
44
44
|
# str.from(0).to(-1) # => "hello"
|
45
45
|
# str.from(1).to(-2) # => "ell"
|
46
46
|
def from(position)
|
47
|
-
self[position
|
47
|
+
self[position, length]
|
48
48
|
end
|
49
49
|
|
50
50
|
# Returns a substring from the beginning of the string to the given position.
|
@@ -61,7 +61,8 @@ class String
|
|
61
61
|
# str.from(0).to(-1) # => "hello"
|
62
62
|
# str.from(1).to(-2) # => "ell"
|
63
63
|
def to(position)
|
64
|
-
|
64
|
+
position += size if position < 0
|
65
|
+
self[0, position + 1] || +""
|
65
66
|
end
|
66
67
|
|
67
68
|
# Returns the first character. If a limit is supplied, returns a substring
|
@@ -75,17 +76,7 @@ class String
|
|
75
76
|
# str.first(0) # => ""
|
76
77
|
# str.first(6) # => "hello"
|
77
78
|
def first(limit = 1)
|
78
|
-
|
79
|
-
"Calling String#first with a negative integer limit " \
|
80
|
-
"will raise an ArgumentError in Rails 6.1."
|
81
|
-
) if limit < 0
|
82
|
-
if limit == 0
|
83
|
-
""
|
84
|
-
elsif limit >= size
|
85
|
-
dup
|
86
|
-
else
|
87
|
-
to(limit - 1)
|
88
|
-
end
|
79
|
+
self[0, limit] || raise(ArgumentError, "negative limit")
|
89
80
|
end
|
90
81
|
|
91
82
|
# Returns the last character of the string. If a limit is supplied, returns a substring
|
@@ -99,16 +90,6 @@ class String
|
|
99
90
|
# str.last(0) # => ""
|
100
91
|
# str.last(6) # => "hello"
|
101
92
|
def last(limit = 1)
|
102
|
-
|
103
|
-
"Calling String#last with a negative integer limit " \
|
104
|
-
"will raise an ArgumentError in Rails 6.1."
|
105
|
-
) if limit < 0
|
106
|
-
if limit == 0
|
107
|
-
""
|
108
|
-
elsif limit >= size
|
109
|
-
dup
|
110
|
-
else
|
111
|
-
from(-limit)
|
112
|
-
end
|
93
|
+
self[[length - limit, 0].max, limit] || raise(ArgumentError, "negative limit")
|
113
94
|
end
|
114
95
|
end
|
@@ -18,6 +18,7 @@ class String
|
|
18
18
|
# "2012-12-13T06:12".to_time # => 2012-12-13 06:12:00 +0100
|
19
19
|
# "2012-12-13T06:12".to_time(:utc) # => 2012-12-13 06:12:00 UTC
|
20
20
|
# "12/13/2012".to_time # => ArgumentError: argument out of range
|
21
|
+
# "1604326192".to_time # => ArgumentError: argument out of range
|
21
22
|
def to_time(form = :local)
|
22
23
|
parts = Date._parse(self, false)
|
23
24
|
used_keys = %i(year mon mday hour min sec sec_fraction offset)
|