activesupport 5.2.0 → 6.0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +479 -330
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -3
- data/lib/active_support.rb +2 -1
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +27 -1
- data/lib/active_support/cache.rb +104 -84
- data/lib/active_support/cache/file_store.rb +29 -30
- data/lib/active_support/cache/mem_cache_store.rb +14 -19
- data/lib/active_support/cache/memory_store.rb +15 -9
- data/lib/active_support/cache/null_store.rb +8 -3
- data/lib/active_support/cache/redis_cache_store.rb +73 -34
- data/lib/active_support/cache/strategy/local_cache.rb +23 -23
- data/lib/active_support/callbacks.rb +16 -8
- data/lib/active_support/concern.rb +31 -4
- 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 +7 -11
- 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/array/prepend_and_append.rb +2 -6
- data/lib/active_support/core_ext/class/attribute.rb +11 -16
- data/lib/active_support/core_ext/class/subclasses.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +6 -5
- data/lib/active_support/core_ext/date_and_time/calculations.rb +24 -47
- 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/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +97 -68
- data/lib/active_support/core_ext/file/atomic.rb +1 -1
- data/lib/active_support/core_ext/hash.rb +1 -2
- data/lib/active_support/core_ext/hash/compact.rb +2 -26
- data/lib/active_support/core_ext/hash/conversions.rb +1 -1
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +0 -29
- data/lib/active_support/core_ext/hash/slice.rb +3 -25
- data/lib/active_support/core_ext/hash/transform_values.rb +2 -29
- 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/module.rb +0 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +7 -10
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +13 -19
- data/lib/active_support/core_ext/module/delegation.rb +41 -8
- data/lib/active_support/core_ext/module/introspection.rb +38 -13
- data/lib/active_support/core_ext/module/reachable.rb +1 -6
- data/lib/active_support/core_ext/module/redefine_method.rb +8 -17
- data/lib/active_support/core_ext/numeric.rb +0 -1
- data/lib/active_support/core_ext/numeric/conversions.rb +124 -128
- data/lib/active_support/core_ext/numeric/inquiry.rb +2 -25
- data/lib/active_support/core_ext/object/blank.rb +1 -2
- data/lib/active_support/core_ext/object/duplicable.rb +7 -114
- data/lib/active_support/core_ext/object/json.rb +1 -0
- data/lib/active_support/core_ext/object/to_query.rb +5 -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.rb +1 -1
- data/lib/active_support/core_ext/range/compare_range.rb +76 -0
- 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_range.rb +6 -22
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +2 -2
- data/lib/active_support/core_ext/regexp.rb +0 -4
- data/lib/active_support/core_ext/securerandom.rb +23 -3
- data/lib/active_support/core_ext/string/access.rb +8 -0
- data/lib/active_support/core_ext/string/filters.rb +42 -1
- data/lib/active_support/core_ext/string/inflections.rb +7 -2
- data/lib/active_support/core_ext/string/multibyte.rb +4 -3
- data/lib/active_support/core_ext/string/output_safety.rb +63 -6
- data/lib/active_support/core_ext/string/strip.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +31 -2
- data/lib/active_support/core_ext/uri.rb +2 -4
- data/lib/active_support/current_attributes.rb +8 -0
- data/lib/active_support/dependencies.rb +77 -18
- data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
- data/lib/active_support/deprecation.rb +1 -1
- data/lib/active_support/deprecation/behaviors.rb +5 -1
- data/lib/active_support/deprecation/method_wrappers.rb +20 -13
- data/lib/active_support/deprecation/proxy_wrappers.rb +28 -5
- data/lib/active_support/deprecation/reporting.rb +1 -1
- data/lib/active_support/descendants_tracker.rb +55 -9
- data/lib/active_support/duration.rb +19 -16
- data/lib/active_support/duration/iso8601_parser.rb +2 -4
- data/lib/active_support/duration/iso8601_serializer.rb +3 -5
- data/lib/active_support/encrypted_configuration.rb +1 -5
- data/lib/active_support/encrypted_file.rb +4 -3
- data/lib/active_support/evented_file_update_checker.rb +39 -10
- data/lib/active_support/execution_wrapper.rb +1 -0
- data/lib/active_support/file_update_checker.rb +0 -1
- data/lib/active_support/gem_version.rb +4 -4
- data/lib/active_support/hash_with_indifferent_access.rb +36 -18
- data/lib/active_support/i18n.rb +1 -0
- data/lib/active_support/i18n_railtie.rb +18 -2
- data/lib/active_support/inflector/inflections.rb +1 -5
- data/lib/active_support/inflector/methods.rb +18 -29
- data/lib/active_support/inflector/transliterate.rb +47 -18
- data/lib/active_support/json/decoding.rb +23 -24
- data/lib/active_support/json/encoding.rb +6 -2
- data/lib/active_support/key_generator.rb +0 -32
- data/lib/active_support/lazy_load_hooks.rb +5 -2
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/log_subscriber.rb +31 -9
- data/lib/active_support/logger.rb +1 -16
- data/lib/active_support/logger_silence.rb +28 -12
- data/lib/active_support/logger_thread_safe_level.rb +28 -5
- data/lib/active_support/message_encryptor.rb +4 -6
- data/lib/active_support/message_verifier.rb +5 -5
- data/lib/active_support/messages/metadata.rb +3 -2
- data/lib/active_support/messages/rotator.rb +4 -4
- data/lib/active_support/multibyte/chars.rb +29 -49
- data/lib/active_support/multibyte/unicode.rb +44 -282
- data/lib/active_support/notifications.rb +41 -4
- data/lib/active_support/notifications/fanout.rb +100 -15
- data/lib/active_support/notifications/instrumenter.rb +80 -9
- data/lib/active_support/number_helper.rb +11 -0
- data/lib/active_support/number_helper/number_converter.rb +4 -5
- data/lib/active_support/number_helper/number_to_currency_converter.rb +9 -10
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +3 -2
- data/lib/active_support/number_helper/number_to_human_converter.rb +3 -2
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -2
- 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 +5 -4
- data/lib/active_support/option_merger.rb +21 -3
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/ordered_options.rb +5 -1
- data/lib/active_support/parameter_filter.rb +128 -0
- data/lib/active_support/rails.rb +0 -6
- data/lib/active_support/reloader.rb +4 -5
- data/lib/active_support/security_utils.rb +1 -1
- data/lib/active_support/string_inquirer.rb +0 -1
- data/lib/active_support/subscriber.rb +65 -22
- data/lib/active_support/tagged_logging.rb +13 -4
- data/lib/active_support/test_case.rb +92 -1
- data/lib/active_support/testing/assertions.rb +15 -1
- 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 +134 -0
- data/lib/active_support/testing/setup_and_teardown.rb +5 -9
- data/lib/active_support/testing/stream.rb +1 -2
- data/lib/active_support/testing/time_helpers.rb +7 -9
- data/lib/active_support/time_with_zone.rb +15 -5
- data/lib/active_support/values/time_zone.rb +14 -8
- 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 +2 -2
- metadata +42 -13
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "strscan"
|
4
|
-
require "active_support/core_ext/regexp"
|
5
4
|
|
6
5
|
module ActiveSupport
|
7
6
|
class Duration
|
@@ -14,8 +13,8 @@ module ActiveSupport
|
|
14
13
|
class ParsingError < ::ArgumentError; end
|
15
14
|
|
16
15
|
PERIOD_OR_COMMA = /\.|,/
|
17
|
-
PERIOD = "."
|
18
|
-
COMMA = ","
|
16
|
+
PERIOD = "."
|
17
|
+
COMMA = ","
|
19
18
|
|
20
19
|
SIGN_MARKER = /\A\-|\+|/
|
21
20
|
DATE_MARKER = /P/
|
@@ -81,7 +80,6 @@ module ActiveSupport
|
|
81
80
|
end
|
82
81
|
|
83
82
|
private
|
84
|
-
|
85
83
|
def finished?
|
86
84
|
scanner.eos?
|
87
85
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/core_ext/object/blank"
|
4
|
-
require "active_support/core_ext/hash/transform_values"
|
5
4
|
|
6
5
|
module ActiveSupport
|
7
6
|
class Duration
|
@@ -15,14 +14,14 @@ module ActiveSupport
|
|
15
14
|
# Builds and returns output string.
|
16
15
|
def serialize
|
17
16
|
parts, sign = normalize
|
18
|
-
return "PT0S"
|
17
|
+
return "PT0S" if parts.empty?
|
19
18
|
|
20
|
-
output = "P"
|
19
|
+
output = +"P"
|
21
20
|
output << "#{parts[:years]}Y" if parts.key?(:years)
|
22
21
|
output << "#{parts[:months]}M" if parts.key?(:months)
|
23
22
|
output << "#{parts[:weeks]}W" if parts.key?(:weeks)
|
24
23
|
output << "#{parts[:days]}D" if parts.key?(:days)
|
25
|
-
time = ""
|
24
|
+
time = +""
|
26
25
|
time << "#{parts[:hours]}H" if parts.key?(:hours)
|
27
26
|
time << "#{parts[:minutes]}M" if parts.key?(:minutes)
|
28
27
|
if parts.key?(:seconds)
|
@@ -33,7 +32,6 @@ module ActiveSupport
|
|
33
32
|
end
|
34
33
|
|
35
34
|
private
|
36
|
-
|
37
35
|
# Return pair of duration's parts and whole duration sign.
|
38
36
|
# Parts are summarized (as they can become repetitive due to addition, etc).
|
39
37
|
# Zero parts are removed as not significant.
|
@@ -38,12 +38,8 @@ module ActiveSupport
|
|
38
38
|
@options ||= ActiveSupport::InheritableOptions.new(config)
|
39
39
|
end
|
40
40
|
|
41
|
-
def serialize(config)
|
42
|
-
config.present? ? YAML.dump(config) : ""
|
43
|
-
end
|
44
|
-
|
45
41
|
def deserialize(config)
|
46
|
-
|
42
|
+
YAML.load(config).presence || {}
|
47
43
|
end
|
48
44
|
end
|
49
45
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "pathname"
|
4
|
+
require "tmpdir"
|
4
5
|
require "active_support/message_encryptor"
|
5
6
|
|
6
7
|
module ActiveSupport
|
@@ -57,7 +58,7 @@ module ActiveSupport
|
|
57
58
|
|
58
59
|
private
|
59
60
|
def writing(contents)
|
60
|
-
tmp_file = "#{
|
61
|
+
tmp_file = "#{Process.pid}.#{content_path.basename.to_s.chomp('.enc')}"
|
61
62
|
tmp_path = Pathname.new File.join(Dir.tmpdir, tmp_file)
|
62
63
|
tmp_path.binwrite contents
|
63
64
|
|
@@ -67,7 +68,7 @@ module ActiveSupport
|
|
67
68
|
|
68
69
|
write(updated_contents) if updated_contents != contents
|
69
70
|
ensure
|
70
|
-
FileUtils.rm(tmp_path) if tmp_path
|
71
|
+
FileUtils.rm(tmp_path) if tmp_path&.exist?
|
71
72
|
end
|
72
73
|
|
73
74
|
|
@@ -93,7 +94,7 @@ module ActiveSupport
|
|
93
94
|
end
|
94
95
|
|
95
96
|
def handle_missing_key
|
96
|
-
raise MissingKeyError
|
97
|
+
raise MissingKeyError.new(key_path: key_path, env_key: env_key) if raise_if_missing_key
|
97
98
|
end
|
98
99
|
end
|
99
100
|
end
|
@@ -52,16 +52,17 @@ module ActiveSupport
|
|
52
52
|
@pid = Process.pid
|
53
53
|
@boot_mutex = Mutex.new
|
54
54
|
|
55
|
-
|
55
|
+
dtw = directories_to_watch
|
56
|
+
@dtw, @missing = dtw.partition(&:exist?)
|
57
|
+
|
58
|
+
if @dtw.any?
|
56
59
|
# Loading listen triggers warnings. These are originated by a legit
|
57
60
|
# usage of attr_* macros for private attributes, but adds a lot of noise
|
58
61
|
# to our test suite. Thus, we lazy load it and disable warnings locally.
|
59
62
|
silence_warnings do
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
raise LoadError, "Could not load the 'listen' gem. Add `gem 'listen'` to the development group of your Gemfile", e.backtrace
|
64
|
-
end
|
63
|
+
require "listen"
|
64
|
+
rescue LoadError => e
|
65
|
+
raise LoadError, "Could not load the 'listen' gem. Add `gem 'listen'` to the development group of your Gemfile", e.backtrace
|
65
66
|
end
|
66
67
|
end
|
67
68
|
boot!
|
@@ -75,6 +76,19 @@ module ActiveSupport
|
|
75
76
|
@updated.make_true
|
76
77
|
end
|
77
78
|
end
|
79
|
+
|
80
|
+
if @missing.any?(&:exist?)
|
81
|
+
@boot_mutex.synchronize do
|
82
|
+
appeared, @missing = @missing.partition(&:exist?)
|
83
|
+
shutdown!
|
84
|
+
|
85
|
+
@dtw += appeared
|
86
|
+
boot!
|
87
|
+
|
88
|
+
@updated.make_true
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
78
92
|
@updated.true?
|
79
93
|
end
|
80
94
|
|
@@ -93,7 +107,21 @@ module ActiveSupport
|
|
93
107
|
|
94
108
|
private
|
95
109
|
def boot!
|
96
|
-
|
110
|
+
normalize_dirs!
|
111
|
+
|
112
|
+
unless @dtw.empty?
|
113
|
+
Listen.to(*@dtw, &method(:changed)).start
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def shutdown!
|
118
|
+
Listen.stop
|
119
|
+
end
|
120
|
+
|
121
|
+
def normalize_dirs!
|
122
|
+
@dirs.transform_keys! do |dir|
|
123
|
+
dir.exist? ? dir.realpath : dir
|
124
|
+
end
|
97
125
|
end
|
98
126
|
|
99
127
|
def changed(modified, added, removed)
|
@@ -113,7 +141,9 @@ module ActiveSupport
|
|
113
141
|
ext = @ph.normalize_extension(file.extname)
|
114
142
|
|
115
143
|
file.dirname.ascend do |dir|
|
116
|
-
|
144
|
+
matching = @dirs[dir]
|
145
|
+
|
146
|
+
if matching && (matching.empty? || matching.include?(ext))
|
117
147
|
break true
|
118
148
|
elsif dir == @lcsp || dir.root?
|
119
149
|
break false
|
@@ -123,7 +153,7 @@ module ActiveSupport
|
|
123
153
|
end
|
124
154
|
|
125
155
|
def directories_to_watch
|
126
|
-
dtw =
|
156
|
+
dtw = @files.map(&:dirname) + @dirs.keys
|
127
157
|
dtw.compact!
|
128
158
|
dtw.uniq!
|
129
159
|
|
@@ -194,7 +224,6 @@ module ActiveSupport
|
|
194
224
|
end
|
195
225
|
|
196
226
|
private
|
197
|
-
|
198
227
|
def ascendant_of?(base, other)
|
199
228
|
base != other && other.ascend do |ascendant|
|
200
229
|
break true if base == ascendant
|
@@ -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
|
@@ -163,6 +164,19 @@ module ActiveSupport
|
|
163
164
|
super(convert_key(key))
|
164
165
|
end
|
165
166
|
|
167
|
+
# Same as <tt>Hash#assoc</tt> where the key passed as argument can be
|
168
|
+
# either a string or a symbol:
|
169
|
+
#
|
170
|
+
# counters = ActiveSupport::HashWithIndifferentAccess.new
|
171
|
+
# counters[:foo] = 1
|
172
|
+
#
|
173
|
+
# counters.assoc('foo') # => ["foo", 1]
|
174
|
+
# counters.assoc(:foo) # => ["foo", 1]
|
175
|
+
# counters.assoc(:zoo) # => nil
|
176
|
+
def assoc(key)
|
177
|
+
super(convert_key(key))
|
178
|
+
end
|
179
|
+
|
166
180
|
# Same as <tt>Hash#fetch</tt> where the key passed as argument can be
|
167
181
|
# either a string or a symbol:
|
168
182
|
#
|
@@ -177,20 +191,18 @@ module ActiveSupport
|
|
177
191
|
super(convert_key(key), *extras)
|
178
192
|
end
|
179
193
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
super(*args)
|
193
|
-
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)
|
194
206
|
end
|
195
207
|
|
196
208
|
# Same as <tt>Hash#default</tt> where the key passed as argument can be
|
@@ -213,8 +225,8 @@ module ActiveSupport
|
|
213
225
|
# hash[:a] = 'x'
|
214
226
|
# hash[:b] = 'y'
|
215
227
|
# hash.values_at('a', 'b') # => ["x", "y"]
|
216
|
-
def values_at(*
|
217
|
-
|
228
|
+
def values_at(*keys)
|
229
|
+
super(*keys.map { |key| convert_key(key) })
|
218
230
|
end
|
219
231
|
|
220
232
|
# Returns an array of the values at the specified indices, but also
|
@@ -227,8 +239,8 @@ module ActiveSupport
|
|
227
239
|
# hash.fetch_values('a', 'c') { |key| 'z' } # => ["x", "z"]
|
228
240
|
# hash.fetch_values('a', 'c') # => KeyError: key not found: "c"
|
229
241
|
def fetch_values(*indices, &block)
|
230
|
-
indices.
|
231
|
-
end
|
242
|
+
super(*indices.map { |key| convert_key(key) }, &block)
|
243
|
+
end
|
232
244
|
|
233
245
|
# Returns a shallow copy of the hash.
|
234
246
|
#
|
@@ -281,6 +293,11 @@ module ActiveSupport
|
|
281
293
|
super(convert_key(key))
|
282
294
|
end
|
283
295
|
|
296
|
+
def except(*keys)
|
297
|
+
slice(*self.keys - keys.map { |key| convert_key(key) })
|
298
|
+
end
|
299
|
+
alias_method :without, :except
|
300
|
+
|
284
301
|
def stringify_keys!; self end
|
285
302
|
def deep_stringify_keys!; self end
|
286
303
|
def stringify_keys; dup end
|
@@ -288,6 +305,7 @@ module ActiveSupport
|
|
288
305
|
undef :symbolize_keys!
|
289
306
|
undef :deep_symbolize_keys!
|
290
307
|
def symbolize_keys; to_hash.symbolize_keys! end
|
308
|
+
alias_method :to_options, :symbolize_keys
|
291
309
|
def deep_symbolize_keys; to_hash.deep_symbolize_keys! end
|
292
310
|
def to_options!; self end
|
293
311
|
|
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,10 @@ module I18n
|
|
13
12
|
config.i18n.load_path = []
|
14
13
|
config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
|
15
14
|
|
15
|
+
if I18n.respond_to?(:eager_load!)
|
16
|
+
config.eager_load_namespaces << I18n
|
17
|
+
end
|
18
|
+
|
16
19
|
# Set the i18n configuration after initialization since a lot of
|
17
20
|
# configuration is still usually done in application initializers.
|
18
21
|
config.after_initialize do |app|
|
@@ -88,9 +91,22 @@ module I18n
|
|
88
91
|
when Hash, Array
|
89
92
|
Array.wrap(fallbacks)
|
90
93
|
else # TrueClass
|
91
|
-
[]
|
94
|
+
[I18n.default_locale]
|
92
95
|
end
|
93
96
|
|
97
|
+
if args.empty? || args.first.is_a?(Hash)
|
98
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
99
|
+
Using I18n fallbacks with an empty `defaults` sets the defaults to
|
100
|
+
include the `default_locale`. This behavior will change in Rails 6.1.
|
101
|
+
If you desire the default locale to be included in the defaults, please
|
102
|
+
explicitly configure it with `config.i18n.fallbacks.defaults =
|
103
|
+
[I18n.default_locale]` or `config.i18n.fallbacks = [I18n.default_locale,
|
104
|
+
{...}]`. If you want to opt-in to the new behavior, use
|
105
|
+
`config.i18n.fallbacks.defaults = [nil, {...}]`.
|
106
|
+
MSG
|
107
|
+
args.unshift I18n.default_locale
|
108
|
+
end
|
109
|
+
|
94
110
|
I18n.fallbacks = I18n::Locale::Fallbacks.new(*args)
|
95
111
|
end
|
96
112
|
|
@@ -1,8 +1,6 @@
|
|
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
5
|
require "active_support/deprecation"
|
8
6
|
|
@@ -67,8 +65,7 @@ module ActiveSupport
|
|
67
65
|
@__instance__[locale] ||= new
|
68
66
|
end
|
69
67
|
|
70
|
-
attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms
|
71
|
-
deprecate :acronym_regex
|
68
|
+
attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms
|
72
69
|
|
73
70
|
attr_reader :acronyms_camelize_regex, :acronyms_underscore_regex # :nodoc:
|
74
71
|
|
@@ -233,7 +230,6 @@ module ActiveSupport
|
|
233
230
|
end
|
234
231
|
|
235
232
|
private
|
236
|
-
|
237
233
|
def define_acronym_regex_patterns
|
238
234
|
@acronym_regex = @acronyms.empty? ? /(?=a)b/ : /#{@acronyms.values.join("|")}/
|
239
235
|
@acronyms_camelize_regex = /^(?:#{@acronym_regex}(?=\b|[A-Z_])|\w)/
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/inflections"
|
4
|
-
require "active_support/core_ext/regexp"
|
5
4
|
|
6
5
|
module ActiveSupport
|
7
6
|
# The Inflector transforms words from singular to plural, class names to table
|
@@ -74,7 +73,7 @@ module ActiveSupport
|
|
74
73
|
string = string.sub(inflections.acronyms_camelize_regex) { |match| match.downcase }
|
75
74
|
end
|
76
75
|
string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }
|
77
|
-
string.gsub!("/"
|
76
|
+
string.gsub!("/", "::")
|
78
77
|
string
|
79
78
|
end
|
80
79
|
|
@@ -91,11 +90,11 @@ module ActiveSupport
|
|
91
90
|
# camelize(underscore('SSLError')) # => "SslError"
|
92
91
|
def underscore(camel_cased_word)
|
93
92
|
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!("-"
|
93
|
+
word = camel_cased_word.to_s.gsub("::", "/")
|
94
|
+
word.gsub!(inflections.acronyms_underscore_regex) { "#{$1 && '_' }#{$2.downcase}" }
|
95
|
+
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
96
|
+
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
97
|
+
word.tr!("-", "_")
|
99
98
|
word.downcase!
|
100
99
|
word
|
101
100
|
end
|
@@ -131,11 +130,11 @@ module ActiveSupport
|
|
131
130
|
|
132
131
|
inflections.humans.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
|
133
132
|
|
134
|
-
result.sub!(/\A_+/, ""
|
133
|
+
result.sub!(/\A_+/, "")
|
135
134
|
unless keep_id_suffix
|
136
|
-
result.sub!(/_id\z/, ""
|
135
|
+
result.sub!(/_id\z/, "")
|
137
136
|
end
|
138
|
-
result.tr!("_"
|
137
|
+
result.tr!("_", " ")
|
139
138
|
|
140
139
|
result.gsub!(/([a-z\d]*)/i) do |match|
|
141
140
|
"#{inflections.acronyms[match.downcase] || match.downcase}"
|
@@ -197,17 +196,17 @@ module ActiveSupport
|
|
197
196
|
#
|
198
197
|
# Singular names are not handled correctly:
|
199
198
|
#
|
200
|
-
# classify('calculus') # => "
|
199
|
+
# classify('calculus') # => "Calculu"
|
201
200
|
def classify(table_name)
|
202
201
|
# strip out any leading schema name
|
203
|
-
camelize(singularize(table_name.to_s.sub(/.*\./, ""
|
202
|
+
camelize(singularize(table_name.to_s.sub(/.*\./, "")))
|
204
203
|
end
|
205
204
|
|
206
205
|
# Replaces underscores with dashes in the string.
|
207
206
|
#
|
208
207
|
# dasherize('puni_puni') # => "puni-puni"
|
209
208
|
def dasherize(underscored_word)
|
210
|
-
underscored_word.tr("_"
|
209
|
+
underscored_word.tr("_", "-")
|
211
210
|
end
|
212
211
|
|
213
212
|
# Removes the module part from the expression in the string.
|
@@ -270,7 +269,7 @@ module ActiveSupport
|
|
270
269
|
# NameError is raised when the name is not in CamelCase or the constant is
|
271
270
|
# unknown.
|
272
271
|
def constantize(camel_cased_word)
|
273
|
-
names = camel_cased_word.split("::"
|
272
|
+
names = camel_cased_word.split("::")
|
274
273
|
|
275
274
|
# Trigger a built-in NameError exception including the ill-formed constant in the message.
|
276
275
|
Object.const_get(camel_cased_word) if names.empty?
|
@@ -329,6 +328,8 @@ module ActiveSupport
|
|
329
328
|
e.name.to_s == camel_cased_word.to_s)
|
330
329
|
rescue ArgumentError => e
|
331
330
|
raise unless /not missing constant #{const_regexp(camel_cased_word)}!$/.match?(e.message)
|
331
|
+
rescue LoadError => e
|
332
|
+
raise unless /Unable to autoload constant #{const_regexp(camel_cased_word)}/.match?(e.message)
|
332
333
|
end
|
333
334
|
|
334
335
|
# Returns the suffix that should be added to a number to denote the position
|
@@ -341,18 +342,7 @@ module ActiveSupport
|
|
341
342
|
# ordinal(-11) # => "th"
|
342
343
|
# ordinal(-1021) # => "st"
|
343
344
|
def ordinal(number)
|
344
|
-
|
345
|
-
|
346
|
-
if (11..13).include?(abs_number % 100)
|
347
|
-
"th"
|
348
|
-
else
|
349
|
-
case abs_number % 10
|
350
|
-
when 1; "st"
|
351
|
-
when 2; "nd"
|
352
|
-
when 3; "rd"
|
353
|
-
else "th"
|
354
|
-
end
|
355
|
-
end
|
345
|
+
I18n.translate("number.nth.ordinals", number: number)
|
356
346
|
end
|
357
347
|
|
358
348
|
# Turns a number into an ordinal string used to denote the position in an
|
@@ -365,18 +355,17 @@ module ActiveSupport
|
|
365
355
|
# ordinalize(-11) # => "-11th"
|
366
356
|
# ordinalize(-1021) # => "-1021st"
|
367
357
|
def ordinalize(number)
|
368
|
-
"
|
358
|
+
I18n.translate("number.nth.ordinalized", number: number)
|
369
359
|
end
|
370
360
|
|
371
361
|
private
|
372
|
-
|
373
362
|
# Mounts a regular expression, returned as a string to ease interpolation,
|
374
363
|
# that will match part by part the given constant.
|
375
364
|
#
|
376
365
|
# const_regexp("Foo::Bar::Baz") # => "Foo(::Bar(::Baz)?)?"
|
377
366
|
# const_regexp("::") # => "::"
|
378
367
|
def const_regexp(camel_cased_word)
|
379
|
-
parts = camel_cased_word.split("::"
|
368
|
+
parts = camel_cased_word.split("::")
|
380
369
|
|
381
370
|
return Regexp.escape(camel_cased_word) if parts.blank?
|
382
371
|
|