activesupport 5.2.4.4 → 6.1.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 +353 -435
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -3
- data/lib/active_support.rb +14 -1
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/array_inquirer.rb +4 -2
- data/lib/active_support/backtrace_cleaner.rb +29 -3
- data/lib/active_support/benchmarkable.rb +1 -1
- data/lib/active_support/cache.rb +142 -78
- data/lib/active_support/cache/file_store.rb +33 -33
- data/lib/active_support/cache/mem_cache_store.rb +32 -20
- data/lib/active_support/cache/memory_store.rb +59 -33
- data/lib/active_support/cache/null_store.rb +8 -3
- data/lib/active_support/cache/redis_cache_store.rb +70 -43
- data/lib/active_support/cache/strategy/local_cache.rb +41 -26
- data/lib/active_support/callbacks.rb +81 -64
- data/lib/active_support/concern.rb +70 -3
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
- data/lib/active_support/concurrency/share_lock.rb +0 -1
- data/lib/active_support/configurable.rb +10 -14
- data/lib/active_support/configuration_file.rb +46 -0
- data/lib/active_support/core_ext.rb +1 -1
- data/lib/active_support/core_ext/array.rb +1 -1
- data/lib/active_support/core_ext/array/access.rb +18 -6
- data/lib/active_support/core_ext/array/conversions.rb +5 -5
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/benchmark.rb +2 -2
- data/lib/active_support/core_ext/class/attribute.rb +32 -47
- data/lib/active_support/core_ext/class/subclasses.rb +17 -38
- data/lib/active_support/core_ext/date/calculations.rb +6 -5
- data/lib/active_support/core_ext/date/conversions.rb +2 -1
- data/lib/active_support/core_ext/date_and_time/calculations.rb +37 -47
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +0 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
- data/lib/active_support/core_ext/date_time/conversions.rb +0 -1
- data/lib/active_support/core_ext/enumerable.rb +171 -75
- data/lib/active_support/core_ext/hash.rb +1 -2
- data/lib/active_support/core_ext/hash/conversions.rb +3 -3
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +2 -2
- data/lib/active_support/core_ext/hash/keys.rb +1 -30
- data/lib/active_support/core_ext/hash/slice.rb +6 -27
- data/lib/active_support/core_ext/integer/multiple.rb +1 -1
- data/lib/active_support/core_ext/kernel.rb +0 -1
- data/lib/active_support/core_ext/load_error.rb +1 -1
- data/lib/active_support/core_ext/marshal.rb +2 -0
- data/lib/active_support/core_ext/module.rb +0 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +30 -39
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +17 -19
- data/lib/active_support/core_ext/module/concerning.rb +8 -2
- data/lib/active_support/core_ext/module/delegation.rb +76 -33
- data/lib/active_support/core_ext/module/introspection.rb +16 -15
- data/lib/active_support/core_ext/module/redefine_method.rb +8 -17
- data/lib/active_support/core_ext/name_error.rb +29 -2
- data/lib/active_support/core_ext/numeric.rb +0 -1
- data/lib/active_support/core_ext/numeric/conversions.rb +129 -129
- data/lib/active_support/core_ext/object/blank.rb +1 -2
- data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
- data/lib/active_support/core_ext/object/duplicable.rb +7 -114
- data/lib/active_support/core_ext/object/json.rb +14 -2
- data/lib/active_support/core_ext/object/try.rb +17 -7
- data/lib/active_support/core_ext/object/with_options.rb +1 -1
- data/lib/active_support/core_ext/range/compare_range.rb +34 -13
- data/lib/active_support/core_ext/range/conversions.rb +31 -29
- data/lib/active_support/core_ext/range/each.rb +0 -1
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +8 -3
- data/lib/active_support/core_ext/regexp.rb +8 -5
- data/lib/active_support/core_ext/securerandom.rb +23 -3
- data/lib/active_support/core_ext/string/access.rb +5 -16
- data/lib/active_support/core_ext/string/conversions.rb +1 -0
- data/lib/active_support/core_ext/string/filters.rb +42 -1
- data/lib/active_support/core_ext/string/inflections.rb +45 -6
- data/lib/active_support/core_ext/string/inquiry.rb +1 -0
- data/lib/active_support/core_ext/string/multibyte.rb +6 -5
- data/lib/active_support/core_ext/string/output_safety.rb +70 -13
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
- data/lib/active_support/core_ext/string/strip.rb +3 -1
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
- data/lib/active_support/core_ext/time/calculations.rb +50 -3
- data/lib/active_support/core_ext/time/conversions.rb +2 -0
- data/lib/active_support/core_ext/uri.rb +6 -1
- data/lib/active_support/current_attributes.rb +15 -2
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/dependencies.rb +109 -34
- data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
- data/lib/active_support/deprecation.rb +6 -1
- data/lib/active_support/deprecation/behaviors.rb +16 -3
- 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 +18 -23
- data/lib/active_support/deprecation/proxy_wrappers.rb +29 -6
- data/lib/active_support/deprecation/reporting.rb +50 -7
- data/lib/active_support/descendants_tracker.rb +59 -9
- data/lib/active_support/duration.rb +90 -38
- data/lib/active_support/duration/iso8601_parser.rb +2 -4
- data/lib/active_support/duration/iso8601_serializer.rb +18 -14
- data/lib/active_support/encrypted_configuration.rb +0 -4
- data/lib/active_support/encrypted_file.rb +22 -4
- data/lib/active_support/environment_inquirer.rb +20 -0
- data/lib/active_support/evented_file_update_checker.rb +82 -117
- data/lib/active_support/execution_wrapper.rb +1 -0
- data/lib/active_support/file_update_checker.rb +0 -1
- data/lib/active_support/fork_tracker.rb +62 -0
- data/lib/active_support/gem_version.rb +4 -4
- data/lib/active_support/hash_with_indifferent_access.rb +64 -41
- data/lib/active_support/i18n.rb +1 -0
- data/lib/active_support/i18n_railtie.rb +15 -8
- data/lib/active_support/inflector/inflections.rb +2 -7
- data/lib/active_support/inflector/methods.rb +49 -58
- data/lib/active_support/inflector/transliterate.rb +47 -18
- data/lib/active_support/json/decoding.rb +25 -26
- data/lib/active_support/json/encoding.rb +11 -3
- data/lib/active_support/key_generator.rb +1 -33
- data/lib/active_support/lazy_load_hooks.rb +5 -2
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +7 -3
- data/lib/active_support/log_subscriber.rb +39 -9
- data/lib/active_support/logger.rb +2 -17
- data/lib/active_support/logger_silence.rb +11 -19
- data/lib/active_support/logger_thread_safe_level.rb +50 -6
- data/lib/active_support/message_encryptor.rb +8 -13
- data/lib/active_support/message_verifier.rb +10 -10
- data/lib/active_support/messages/metadata.rb +11 -2
- data/lib/active_support/messages/rotation_configuration.rb +2 -1
- data/lib/active_support/messages/rotator.rb +10 -9
- data/lib/active_support/multibyte/chars.rb +10 -68
- data/lib/active_support/multibyte/unicode.rb +15 -327
- data/lib/active_support/notifications.rb +72 -8
- data/lib/active_support/notifications/fanout.rb +116 -16
- data/lib/active_support/notifications/instrumenter.rb +71 -9
- data/lib/active_support/number_helper.rb +38 -12
- data/lib/active_support/number_helper/number_converter.rb +5 -6
- data/lib/active_support/number_helper/number_to_currency_converter.rb +4 -9
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +3 -2
- data/lib/active_support/number_helper/number_to_human_converter.rb +4 -3
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +4 -3
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +8 -7
- data/lib/active_support/number_helper/rounding_helper.rb +12 -28
- data/lib/active_support/option_merger.rb +22 -3
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/ordered_options.rb +13 -3
- data/lib/active_support/parameter_filter.rb +133 -0
- data/lib/active_support/per_thread_registry.rb +1 -1
- data/lib/active_support/rails.rb +1 -10
- data/lib/active_support/railtie.rb +23 -1
- data/lib/active_support/reloader.rb +4 -5
- 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 -3
- data/lib/active_support/subscriber.rb +72 -28
- data/lib/active_support/tagged_logging.rb +42 -8
- data/lib/active_support/test_case.rb +91 -0
- data/lib/active_support/testing/assertions.rb +30 -9
- data/lib/active_support/testing/deprecation.rb +0 -1
- data/lib/active_support/testing/file_fixtures.rb +2 -0
- data/lib/active_support/testing/isolation.rb +2 -2
- data/lib/active_support/testing/method_call_assertions.rb +28 -1
- data/lib/active_support/testing/parallelization.rb +51 -0
- 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/stream.rb +1 -2
- data/lib/active_support/testing/time_helpers.rb +47 -12
- data/lib/active_support/time_with_zone.rb +81 -47
- data/lib/active_support/values/time_zone.rb +32 -17
- data/lib/active_support/xml_mini.rb +2 -10
- data/lib/active_support/xml_mini/jdom.rb +2 -3
- data/lib/active_support/xml_mini/libxml.rb +2 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +4 -4
- data/lib/active_support/xml_mini/nokogiri.rb +2 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +3 -3
- data/lib/active_support/xml_mini/rexml.rb +10 -3
- metadata +58 -32
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -9
- data/lib/active_support/core_ext/hash/compact.rb +0 -29
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -32
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
- data/lib/active_support/core_ext/module/reachable.rb +0 -11
- data/lib/active_support/core_ext/numeric/inquiry.rb +0 -28
- data/lib/active_support/core_ext/range/include_range.rb +0 -3
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require "active_support/core_ext/hash/keys"
|
4
4
|
require "active_support/core_ext/hash/reverse_merge"
|
5
|
+
require "active_support/core_ext/hash/except"
|
5
6
|
|
6
7
|
module ActiveSupport
|
7
8
|
# Implements a hash where keys <tt>:foo</tt> and <tt>"foo"</tt> are considered
|
@@ -68,7 +69,7 @@ module ActiveSupport
|
|
68
69
|
super()
|
69
70
|
update(constructor)
|
70
71
|
|
71
|
-
hash = constructor.to_hash
|
72
|
+
hash = constructor.is_a?(Hash) ? constructor : constructor.to_hash
|
72
73
|
self.default = hash.default if hash.default
|
73
74
|
self.default_proc = hash.default_proc if hash.default_proc
|
74
75
|
else
|
@@ -90,12 +91,12 @@ module ActiveSupport
|
|
90
91
|
#
|
91
92
|
# This value can be later fetched using either +:key+ or <tt>'key'</tt>.
|
92
93
|
def []=(key, value)
|
93
|
-
regular_writer(convert_key(key), convert_value(value,
|
94
|
+
regular_writer(convert_key(key), convert_value(value, conversion: :assignment))
|
94
95
|
end
|
95
96
|
|
96
97
|
alias_method :store, :[]=
|
97
98
|
|
98
|
-
# Updates the receiver in-place, merging in the
|
99
|
+
# Updates the receiver in-place, merging in the hashes passed as arguments:
|
99
100
|
#
|
100
101
|
# hash_1 = ActiveSupport::HashWithIndifferentAccess.new
|
101
102
|
# hash_1[:key] = 'value'
|
@@ -105,7 +106,10 @@ module ActiveSupport
|
|
105
106
|
#
|
106
107
|
# hash_1.update(hash_2) # => {"key"=>"New Value!"}
|
107
108
|
#
|
108
|
-
#
|
109
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
110
|
+
# hash.update({ "a" => 1 }, { "b" => 2 }) # => { "a" => 1, "b" => 2 }
|
111
|
+
#
|
112
|
+
# The arguments can be either an
|
109
113
|
# <tt>ActiveSupport::HashWithIndifferentAccess</tt> or a regular +Hash+.
|
110
114
|
# In either case the merge respects the semantics of indifferent access.
|
111
115
|
#
|
@@ -120,18 +124,15 @@ module ActiveSupport
|
|
120
124
|
# hash_1[:key] = 10
|
121
125
|
# hash_2['key'] = 12
|
122
126
|
# hash_1.update(hash_2) { |key, old, new| old + new } # => {"key"=>22}
|
123
|
-
def update(
|
124
|
-
if
|
125
|
-
|
127
|
+
def update(*other_hashes, &block)
|
128
|
+
if other_hashes.size == 1
|
129
|
+
update_with_single_argument(other_hashes.first, block)
|
126
130
|
else
|
127
|
-
|
128
|
-
|
129
|
-
value = yield(convert_key(key), self[key], value)
|
130
|
-
end
|
131
|
-
regular_writer(convert_key(key), convert_value(value))
|
131
|
+
other_hashes.each do |other_hash|
|
132
|
+
update_with_single_argument(other_hash, block)
|
132
133
|
end
|
133
|
-
self
|
134
134
|
end
|
135
|
+
self
|
135
136
|
end
|
136
137
|
|
137
138
|
alias_method :merge!, :update
|
@@ -190,20 +191,18 @@ module ActiveSupport
|
|
190
191
|
super(convert_key(key), *extras)
|
191
192
|
end
|
192
193
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
super(*args)
|
206
|
-
end
|
194
|
+
# Same as <tt>Hash#dig</tt> where the key passed as argument can be
|
195
|
+
# either a string or a symbol:
|
196
|
+
#
|
197
|
+
# counters = ActiveSupport::HashWithIndifferentAccess.new
|
198
|
+
# counters[:foo] = { bar: 1 }
|
199
|
+
#
|
200
|
+
# counters.dig('foo', 'bar') # => 1
|
201
|
+
# counters.dig(:foo, :bar) # => 1
|
202
|
+
# counters.dig(:zoo) # => nil
|
203
|
+
def dig(*args)
|
204
|
+
args[0] = convert_key(args[0]) if args.size > 0
|
205
|
+
super(*args)
|
207
206
|
end
|
208
207
|
|
209
208
|
# Same as <tt>Hash#default</tt> where the key passed as argument can be
|
@@ -226,8 +225,8 @@ module ActiveSupport
|
|
226
225
|
# hash[:a] = 'x'
|
227
226
|
# hash[:b] = 'y'
|
228
227
|
# hash.values_at('a', 'b') # => ["x", "y"]
|
229
|
-
def values_at(*
|
230
|
-
|
228
|
+
def values_at(*keys)
|
229
|
+
super(*keys.map { |key| convert_key(key) })
|
231
230
|
end
|
232
231
|
|
233
232
|
# Returns an array of the values at the specified indices, but also
|
@@ -240,8 +239,8 @@ module ActiveSupport
|
|
240
239
|
# hash.fetch_values('a', 'c') { |key| 'z' } # => ["x", "z"]
|
241
240
|
# hash.fetch_values('a', 'c') # => KeyError: key not found: "c"
|
242
241
|
def fetch_values(*indices, &block)
|
243
|
-
indices.
|
244
|
-
end
|
242
|
+
super(*indices.map { |key| convert_key(key) }, &block)
|
243
|
+
end
|
245
244
|
|
246
245
|
# Returns a shallow copy of the hash.
|
247
246
|
#
|
@@ -260,8 +259,8 @@ module ActiveSupport
|
|
260
259
|
# This method has the same semantics of +update+, except it does not
|
261
260
|
# modify the receiver but rather returns a new hash with indifferent
|
262
261
|
# access with the result of the merge.
|
263
|
-
def merge(
|
264
|
-
dup.update(
|
262
|
+
def merge(*hashes, &block)
|
263
|
+
dup.update(*hashes, &block)
|
265
264
|
end
|
266
265
|
|
267
266
|
# Like +merge+ but the other way around: Merges the receiver into the
|
@@ -294,6 +293,11 @@ module ActiveSupport
|
|
294
293
|
super(convert_key(key))
|
295
294
|
end
|
296
295
|
|
296
|
+
def except(*keys)
|
297
|
+
slice(*self.keys - keys.map { |key| convert_key(key) })
|
298
|
+
end
|
299
|
+
alias_method :without, :except
|
300
|
+
|
297
301
|
def stringify_keys!; self end
|
298
302
|
def deep_stringify_keys!; self end
|
299
303
|
def stringify_keys; dup end
|
@@ -353,40 +357,59 @@ module ActiveSupport
|
|
353
357
|
set_defaults(_new_hash)
|
354
358
|
|
355
359
|
each do |key, value|
|
356
|
-
_new_hash[key] = convert_value(value,
|
360
|
+
_new_hash[key] = convert_value(value, conversion: :to_hash)
|
357
361
|
end
|
358
362
|
_new_hash
|
359
363
|
end
|
360
364
|
|
361
365
|
private
|
362
|
-
|
363
|
-
key
|
366
|
+
if Symbol.method_defined?(:name)
|
367
|
+
def convert_key(key)
|
368
|
+
key.kind_of?(Symbol) ? key.name : key
|
369
|
+
end
|
370
|
+
else
|
371
|
+
def convert_key(key)
|
372
|
+
key.kind_of?(Symbol) ? key.to_s : key
|
373
|
+
end
|
364
374
|
end
|
365
375
|
|
366
|
-
def convert_value(value,
|
376
|
+
def convert_value(value, conversion: nil)
|
367
377
|
if value.is_a? Hash
|
368
|
-
if
|
378
|
+
if conversion == :to_hash
|
369
379
|
value.to_hash
|
370
380
|
else
|
371
381
|
value.nested_under_indifferent_access
|
372
382
|
end
|
373
383
|
elsif value.is_a?(Array)
|
374
|
-
if
|
384
|
+
if conversion != :assignment || value.frozen?
|
375
385
|
value = value.dup
|
376
386
|
end
|
377
|
-
value.map! { |e| convert_value(e,
|
387
|
+
value.map! { |e| convert_value(e, conversion: conversion) }
|
378
388
|
else
|
379
389
|
value
|
380
390
|
end
|
381
391
|
end
|
382
392
|
|
383
|
-
def set_defaults(target)
|
393
|
+
def set_defaults(target)
|
384
394
|
if default_proc
|
385
395
|
target.default_proc = default_proc.dup
|
386
396
|
else
|
387
397
|
target.default = default
|
388
398
|
end
|
389
399
|
end
|
400
|
+
|
401
|
+
def update_with_single_argument(other_hash, block)
|
402
|
+
if other_hash.is_a? HashWithIndifferentAccess
|
403
|
+
regular_update(other_hash, &block)
|
404
|
+
else
|
405
|
+
other_hash.to_hash.each_pair do |key, value|
|
406
|
+
if block && key?(key)
|
407
|
+
value = block.call(convert_key(key), self[key], value)
|
408
|
+
end
|
409
|
+
regular_writer(convert_key(key), convert_value(value))
|
410
|
+
end
|
411
|
+
end
|
412
|
+
end
|
390
413
|
end
|
391
414
|
end
|
392
415
|
|
data/lib/active_support/i18n.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support"
|
4
|
-
require "active_support/file_update_checker"
|
5
4
|
require "active_support/core_ext/array/wrap"
|
6
5
|
|
7
6
|
# :enddoc:
|
@@ -13,6 +12,8 @@ module I18n
|
|
13
12
|
config.i18n.load_path = []
|
14
13
|
config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
|
15
14
|
|
15
|
+
config.eager_load_namespaces << I18n
|
16
|
+
|
16
17
|
# Set the i18n configuration after initialization since a lot of
|
17
18
|
# configuration is still usually done in application initializers.
|
18
19
|
config.after_initialize do |app|
|
@@ -47,8 +48,10 @@ module I18n
|
|
47
48
|
app.config.i18n.load_path.unshift(*value.flat_map(&:existent))
|
48
49
|
when :load_path
|
49
50
|
I18n.load_path += value
|
51
|
+
when :raise_on_missing_translations
|
52
|
+
forward_raise_on_missing_translations_config(app)
|
50
53
|
else
|
51
|
-
I18n.
|
54
|
+
I18n.public_send("#{setting}=", value)
|
52
55
|
end
|
53
56
|
end
|
54
57
|
|
@@ -61,8 +64,6 @@ module I18n
|
|
61
64
|
reloader = app.config.file_watcher.new(I18n.load_path.dup, directories) do
|
62
65
|
I18n.load_path.keep_if { |p| File.exist?(p) }
|
63
66
|
I18n.load_path |= reloadable_paths.flat_map(&:existent)
|
64
|
-
|
65
|
-
I18n.reload!
|
66
67
|
end
|
67
68
|
|
68
69
|
app.reloaders << reloader
|
@@ -74,6 +75,16 @@ module I18n
|
|
74
75
|
@i18n_inited = true
|
75
76
|
end
|
76
77
|
|
78
|
+
def self.forward_raise_on_missing_translations_config(app)
|
79
|
+
ActiveSupport.on_load(:action_view) do
|
80
|
+
self.raise_on_missing_translations = app.config.i18n.raise_on_missing_translations
|
81
|
+
end
|
82
|
+
|
83
|
+
ActiveSupport.on_load(:action_controller) do
|
84
|
+
AbstractController::Translation.raise_on_missing_translations = app.config.i18n.raise_on_missing_translations
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
77
88
|
def self.include_fallbacks_module
|
78
89
|
I18n.backend.class.include(I18n::Backend::Fallbacks)
|
79
90
|
end
|
@@ -91,10 +102,6 @@ module I18n
|
|
91
102
|
[I18n.default_locale]
|
92
103
|
end
|
93
104
|
|
94
|
-
if args.empty? || args.first.is_a?(Hash)
|
95
|
-
args.unshift I18n.default_locale
|
96
|
-
end
|
97
|
-
|
98
105
|
I18n.fallbacks = I18n::Locale::Fallbacks.new(*args)
|
99
106
|
end
|
100
107
|
|
@@ -1,10 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "concurrent/map"
|
4
|
-
require "active_support/core_ext/array/prepend_and_append"
|
5
|
-
require "active_support/core_ext/regexp"
|
6
4
|
require "active_support/i18n"
|
7
|
-
require "active_support/deprecation"
|
8
5
|
|
9
6
|
module ActiveSupport
|
10
7
|
module Inflector
|
@@ -67,8 +64,7 @@ module ActiveSupport
|
|
67
64
|
@__instance__[locale] ||= new
|
68
65
|
end
|
69
66
|
|
70
|
-
attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms
|
71
|
-
deprecate :acronym_regex
|
67
|
+
attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms
|
72
68
|
|
73
69
|
attr_reader :acronyms_camelize_regex, :acronyms_underscore_regex # :nodoc:
|
74
70
|
|
@@ -80,7 +76,7 @@ module ActiveSupport
|
|
80
76
|
# Private, for the test suite.
|
81
77
|
def initialize_dup(orig) # :nodoc:
|
82
78
|
%w(plurals singulars uncountables humans acronyms).each do |scope|
|
83
|
-
instance_variable_set("@#{scope}", orig.
|
79
|
+
instance_variable_set("@#{scope}", orig.public_send(scope).dup)
|
84
80
|
end
|
85
81
|
define_acronym_regex_patterns
|
86
82
|
end
|
@@ -233,7 +229,6 @@ module ActiveSupport
|
|
233
229
|
end
|
234
230
|
|
235
231
|
private
|
236
|
-
|
237
232
|
def define_acronym_regex_patterns
|
238
233
|
@acronym_regex = @acronyms.empty? ? /(?=a)b/ : /#{@acronyms.values.join("|")}/
|
239
234
|
@acronyms_camelize_regex = /^(?:#{@acronym_regex}(?=\b|[A-Z_])|\w)/
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/inflections"
|
4
|
-
require "active_support/core_ext/
|
4
|
+
require "active_support/core_ext/object/blank"
|
5
5
|
|
6
6
|
module ActiveSupport
|
7
7
|
# The Inflector transforms words from singular to plural, class names to table
|
@@ -74,7 +74,7 @@ module ActiveSupport
|
|
74
74
|
string = string.sub(inflections.acronyms_camelize_regex) { |match| match.downcase }
|
75
75
|
end
|
76
76
|
string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }
|
77
|
-
string.gsub!("/"
|
77
|
+
string.gsub!("/", "::")
|
78
78
|
string
|
79
79
|
end
|
80
80
|
|
@@ -91,11 +91,11 @@ module ActiveSupport
|
|
91
91
|
# camelize(underscore('SSLError')) # => "SslError"
|
92
92
|
def underscore(camel_cased_word)
|
93
93
|
return camel_cased_word unless /[A-Z-]|::/.match?(camel_cased_word)
|
94
|
-
word = camel_cased_word.to_s.gsub("::"
|
95
|
-
word.gsub!(inflections.acronyms_underscore_regex) { "#{$1 && '_'
|
96
|
-
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2'
|
97
|
-
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2'
|
98
|
-
word.tr!("-"
|
94
|
+
word = camel_cased_word.to_s.gsub("::", "/")
|
95
|
+
word.gsub!(inflections.acronyms_underscore_regex) { "#{$1 && '_' }#{$2.downcase}" }
|
96
|
+
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
97
|
+
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
98
|
+
word.tr!("-", "_")
|
99
99
|
word.downcase!
|
100
100
|
word
|
101
101
|
end
|
@@ -131,11 +131,11 @@ module ActiveSupport
|
|
131
131
|
|
132
132
|
inflections.humans.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
|
133
133
|
|
134
|
-
result.sub!(/\A_+/, ""
|
134
|
+
result.sub!(/\A_+/, "")
|
135
135
|
unless keep_id_suffix
|
136
|
-
result.
|
136
|
+
result.delete_suffix!("_id")
|
137
137
|
end
|
138
|
-
result.tr!("_"
|
138
|
+
result.tr!("_", " ")
|
139
139
|
|
140
140
|
result.gsub!(/([a-z\d]*)/i) do |match|
|
141
141
|
"#{inflections.acronyms[match.downcase] || match.downcase}"
|
@@ -173,7 +173,7 @@ module ActiveSupport
|
|
173
173
|
# titleize('raiders_of_the_lost_ark') # => "Raiders Of The Lost Ark"
|
174
174
|
# titleize('string_ending_with_id', keep_id_suffix: true) # => "String Ending With Id"
|
175
175
|
def titleize(word, keep_id_suffix: false)
|
176
|
-
humanize(underscore(word), keep_id_suffix: keep_id_suffix).gsub(/\b(?<!\w['’`])[a-z]/) do |match|
|
176
|
+
humanize(underscore(word), keep_id_suffix: keep_id_suffix).gsub(/\b(?<!\w['’`()])[a-z]/) do |match|
|
177
177
|
match.capitalize
|
178
178
|
end
|
179
179
|
end
|
@@ -197,17 +197,17 @@ module ActiveSupport
|
|
197
197
|
#
|
198
198
|
# Singular names are not handled correctly:
|
199
199
|
#
|
200
|
-
# classify('calculus') # => "
|
200
|
+
# classify('calculus') # => "Calculu"
|
201
201
|
def classify(table_name)
|
202
202
|
# strip out any leading schema name
|
203
|
-
camelize(singularize(table_name.to_s.sub(/.*\./, ""
|
203
|
+
camelize(singularize(table_name.to_s.sub(/.*\./, "")))
|
204
204
|
end
|
205
205
|
|
206
206
|
# Replaces underscores with dashes in the string.
|
207
207
|
#
|
208
208
|
# dasherize('puni_puni') # => "puni-puni"
|
209
209
|
def dasherize(underscored_word)
|
210
|
-
underscored_word.tr("_"
|
210
|
+
underscored_word.tr("_", "-")
|
211
211
|
end
|
212
212
|
|
213
213
|
# Removes the module part from the expression in the string.
|
@@ -270,32 +270,36 @@ module ActiveSupport
|
|
270
270
|
# NameError is raised when the name is not in CamelCase or the constant is
|
271
271
|
# unknown.
|
272
272
|
def constantize(camel_cased_word)
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
if
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
const
|
273
|
+
if camel_cased_word.blank? || !camel_cased_word.include?("::")
|
274
|
+
Object.const_get(camel_cased_word)
|
275
|
+
else
|
276
|
+
names = camel_cased_word.split("::")
|
277
|
+
|
278
|
+
# Trigger a built-in NameError exception including the ill-formed constant in the message.
|
279
|
+
Object.const_get(camel_cased_word) if names.empty?
|
280
|
+
|
281
|
+
# Remove the first blank element in case of '::ClassName' notation.
|
282
|
+
names.shift if names.size > 1 && names.first.empty?
|
283
|
+
|
284
|
+
names.inject(Object) do |constant, name|
|
285
|
+
if constant == Object
|
286
|
+
constant.const_get(name)
|
287
|
+
else
|
288
|
+
candidate = constant.const_get(name)
|
289
|
+
next candidate if constant.const_defined?(name, false)
|
290
|
+
next candidate unless Object.const_defined?(name)
|
291
|
+
|
292
|
+
# Go down the ancestors to check if it is owned directly. The check
|
293
|
+
# stops when we reach Object or the end of ancestors tree.
|
294
|
+
constant = constant.ancestors.inject(constant) do |const, ancestor|
|
295
|
+
break const if ancestor == Object
|
296
|
+
break ancestor if ancestor.const_defined?(name, false)
|
297
|
+
const
|
298
|
+
end
|
299
|
+
|
300
|
+
# owner is in Object, so raise
|
301
|
+
constant.const_get(name, false)
|
295
302
|
end
|
296
|
-
|
297
|
-
# owner is in Object, so raise
|
298
|
-
constant.const_get(name, false)
|
299
303
|
end
|
300
304
|
end
|
301
305
|
end
|
@@ -327,10 +331,9 @@ module ActiveSupport
|
|
327
331
|
rescue NameError => e
|
328
332
|
raise if e.name && !(camel_cased_word.to_s.split("::").include?(e.name.to_s) ||
|
329
333
|
e.name.to_s == camel_cased_word.to_s)
|
330
|
-
rescue ArgumentError => e
|
331
|
-
raise unless /not missing constant #{const_regexp(camel_cased_word)}!$/.match?(e.message)
|
332
334
|
rescue LoadError => e
|
333
|
-
|
335
|
+
message = e.respond_to?(:original_message) ? e.original_message : e.message
|
336
|
+
raise unless /Unable to autoload constant #{const_regexp(camel_cased_word)}/.match?(message)
|
334
337
|
end
|
335
338
|
|
336
339
|
# Returns the suffix that should be added to a number to denote the position
|
@@ -343,18 +346,7 @@ module ActiveSupport
|
|
343
346
|
# ordinal(-11) # => "th"
|
344
347
|
# ordinal(-1021) # => "st"
|
345
348
|
def ordinal(number)
|
346
|
-
|
347
|
-
|
348
|
-
if (11..13).include?(abs_number % 100)
|
349
|
-
"th"
|
350
|
-
else
|
351
|
-
case abs_number % 10
|
352
|
-
when 1; "st"
|
353
|
-
when 2; "nd"
|
354
|
-
when 3; "rd"
|
355
|
-
else "th"
|
356
|
-
end
|
357
|
-
end
|
349
|
+
I18n.translate("number.nth.ordinals", number: number)
|
358
350
|
end
|
359
351
|
|
360
352
|
# Turns a number into an ordinal string used to denote the position in an
|
@@ -367,24 +359,23 @@ module ActiveSupport
|
|
367
359
|
# ordinalize(-11) # => "-11th"
|
368
360
|
# ordinalize(-1021) # => "-1021st"
|
369
361
|
def ordinalize(number)
|
370
|
-
"
|
362
|
+
I18n.translate("number.nth.ordinalized", number: number)
|
371
363
|
end
|
372
364
|
|
373
365
|
private
|
374
|
-
|
375
366
|
# Mounts a regular expression, returned as a string to ease interpolation,
|
376
367
|
# that will match part by part the given constant.
|
377
368
|
#
|
378
369
|
# const_regexp("Foo::Bar::Baz") # => "Foo(::Bar(::Baz)?)?"
|
379
370
|
# const_regexp("::") # => "::"
|
380
371
|
def const_regexp(camel_cased_word)
|
381
|
-
parts = camel_cased_word.split("::"
|
372
|
+
parts = camel_cased_word.split("::")
|
382
373
|
|
383
374
|
return Regexp.escape(camel_cased_word) if parts.blank?
|
384
375
|
|
385
376
|
last = parts.pop
|
386
377
|
|
387
|
-
parts.reverse
|
378
|
+
parts.reverse!.inject(last) do |acc, part|
|
388
379
|
part.empty? ? acc : "#{part}(::#{acc})?"
|
389
380
|
end
|
390
381
|
end
|