activesupport 5.1.7 → 5.2.4.3
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 +401 -541
- data/MIT-LICENSE +1 -1
- data/README.rdoc +3 -3
- data/lib/active_support.rb +5 -13
- data/lib/active_support/all.rb +2 -0
- data/lib/active_support/array_inquirer.rb +2 -0
- data/lib/active_support/backtrace_cleaner.rb +2 -0
- data/lib/active_support/benchmarkable.rb +2 -0
- data/lib/active_support/builder.rb +2 -0
- data/lib/active_support/cache.rb +197 -83
- data/lib/active_support/cache/file_store.rb +5 -4
- data/lib/active_support/cache/mem_cache_store.rb +39 -39
- data/lib/active_support/cache/memory_store.rb +2 -0
- data/lib/active_support/cache/null_store.rb +2 -0
- data/lib/active_support/cache/redis_cache_store.rb +466 -0
- data/lib/active_support/cache/strategy/local_cache.rb +33 -2
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
- data/lib/active_support/callbacks.rb +28 -39
- data/lib/active_support/concern.rb +10 -4
- data/lib/active_support/concurrency/share_lock.rb +2 -0
- data/lib/active_support/configurable.rb +2 -0
- data/lib/active_support/core_ext.rb +3 -1
- data/lib/active_support/core_ext/array.rb +2 -0
- data/lib/active_support/core_ext/array/access.rb +4 -2
- data/lib/active_support/core_ext/array/conversions.rb +2 -0
- data/lib/active_support/core_ext/array/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +2 -0
- data/lib/active_support/core_ext/array/inquiry.rb +2 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +4 -2
- data/lib/active_support/core_ext/array/wrap.rb +2 -0
- data/lib/active_support/core_ext/benchmark.rb +2 -0
- data/lib/active_support/core_ext/big_decimal.rb +2 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +2 -0
- data/lib/active_support/core_ext/class.rb +2 -0
- data/lib/active_support/core_ext/class/attribute.rb +34 -16
- data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
- data/lib/active_support/core_ext/class/subclasses.rb +1 -2
- data/lib/active_support/core_ext/date.rb +2 -0
- data/lib/active_support/core_ext/date/acts_like.rb +2 -0
- data/lib/active_support/core_ext/date/blank.rb +2 -0
- data/lib/active_support/core_ext/date/calculations.rb +2 -0
- data/lib/active_support/core_ext/date/conversions.rb +10 -9
- data/lib/active_support/core_ext/date/zones.rb +2 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +50 -16
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +3 -1
- data/lib/active_support/core_ext/date_and_time/zones.rb +2 -0
- data/lib/active_support/core_ext/date_time.rb +2 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
- data/lib/active_support/core_ext/date_time/blank.rb +2 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +2 -0
- data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
- data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/digest/uuid.rb +3 -1
- data/lib/active_support/core_ext/enumerable.rb +8 -1
- data/lib/active_support/core_ext/file.rb +2 -0
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/hash.rb +2 -0
- data/lib/active_support/core_ext/hash/compact.rb +2 -0
- data/lib/active_support/core_ext/hash/conversions.rb +4 -2
- data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
- data/lib/active_support/core_ext/hash/except.rb +2 -0
- data/lib/active_support/core_ext/hash/indifferent_access.rb +2 -0
- data/lib/active_support/core_ext/hash/keys.rb +2 -0
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +4 -4
- data/lib/active_support/core_ext/hash/transform_values.rb +2 -0
- data/lib/active_support/core_ext/integer.rb +2 -0
- data/lib/active_support/core_ext/integer/inflections.rb +2 -0
- data/lib/active_support/core_ext/integer/multiple.rb +2 -0
- data/lib/active_support/core_ext/integer/time.rb +7 -14
- data/lib/active_support/core_ext/kernel.rb +2 -0
- data/lib/active_support/core_ext/kernel/agnostics.rb +2 -0
- data/lib/active_support/core_ext/kernel/concern.rb +2 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +2 -0
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/load_error.rb +2 -7
- data/lib/active_support/core_ext/marshal.rb +2 -0
- data/lib/active_support/core_ext/module.rb +3 -0
- data/lib/active_support/core_ext/module/aliasing.rb +2 -0
- data/lib/active_support/core_ext/module/anonymous.rb +2 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -0
- data/lib/active_support/core_ext/module/attribute_accessors.rb +21 -24
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +2 -0
- data/lib/active_support/core_ext/module/concerning.rb +7 -8
- data/lib/active_support/core_ext/module/delegation.rb +31 -29
- data/lib/active_support/core_ext/module/deprecation.rb +2 -0
- data/lib/active_support/core_ext/module/introspection.rb +2 -0
- data/lib/active_support/core_ext/module/reachable.rb +3 -0
- data/lib/active_support/core_ext/module/redefine_method.rb +49 -0
- data/lib/active_support/core_ext/module/remove_method.rb +5 -23
- data/lib/active_support/core_ext/name_error.rb +7 -0
- data/lib/active_support/core_ext/numeric.rb +2 -0
- data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +9 -7
- data/lib/active_support/core_ext/numeric/inquiry.rb +2 -0
- data/lib/active_support/core_ext/numeric/time.rb +7 -15
- data/lib/active_support/core_ext/object.rb +2 -0
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +12 -1
- data/lib/active_support/core_ext/object/conversions.rb +2 -0
- data/lib/active_support/core_ext/object/deep_dup.rb +2 -0
- data/lib/active_support/core_ext/object/duplicable.rb +10 -8
- data/lib/active_support/core_ext/object/inclusion.rb +2 -0
- data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
- data/lib/active_support/core_ext/object/json.rb +8 -0
- data/lib/active_support/core_ext/object/to_param.rb +2 -0
- data/lib/active_support/core_ext/object/to_query.rb +2 -0
- data/lib/active_support/core_ext/object/try.rb +2 -0
- data/lib/active_support/core_ext/object/with_options.rb +3 -1
- data/lib/active_support/core_ext/range.rb +4 -1
- data/lib/active_support/core_ext/range/compare_range.rb +61 -0
- data/lib/active_support/core_ext/range/conversions.rb +9 -1
- data/lib/active_support/core_ext/range/each.rb +5 -1
- data/lib/active_support/core_ext/range/include_range.rb +2 -22
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
- data/lib/active_support/core_ext/range/overlaps.rb +2 -0
- data/lib/active_support/core_ext/regexp.rb +2 -0
- data/lib/active_support/core_ext/securerandom.rb +2 -0
- data/lib/active_support/core_ext/string.rb +2 -0
- data/lib/active_support/core_ext/string/access.rb +2 -0
- data/lib/active_support/core_ext/string/behavior.rb +2 -0
- data/lib/active_support/core_ext/string/conversions.rb +2 -0
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +2 -0
- data/lib/active_support/core_ext/string/indent.rb +2 -0
- data/lib/active_support/core_ext/string/inflections.rb +26 -12
- data/lib/active_support/core_ext/string/inquiry.rb +2 -0
- data/lib/active_support/core_ext/string/multibyte.rb +4 -0
- data/lib/active_support/core_ext/string/output_safety.rb +6 -7
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
- data/lib/active_support/core_ext/string/strip.rb +2 -0
- data/lib/active_support/core_ext/string/zones.rb +2 -0
- data/lib/active_support/core_ext/time.rb +2 -0
- data/lib/active_support/core_ext/time/acts_like.rb +2 -0
- data/lib/active_support/core_ext/time/calculations.rb +23 -15
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- data/lib/active_support/core_ext/time/conversions.rb +2 -0
- data/lib/active_support/core_ext/time/zones.rb +6 -4
- data/lib/active_support/core_ext/uri.rb +6 -6
- data/lib/active_support/current_attributes.rb +195 -0
- data/lib/active_support/dependencies.rb +25 -26
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +2 -0
- data/lib/active_support/deprecation.rb +4 -2
- data/lib/active_support/deprecation/behaviors.rb +28 -9
- data/lib/active_support/deprecation/constant_accessor.rb +4 -2
- data/lib/active_support/deprecation/instance_delegator.rb +2 -0
- data/lib/active_support/deprecation/method_wrappers.rb +30 -17
- data/lib/active_support/deprecation/proxy_wrappers.rb +5 -2
- data/lib/active_support/deprecation/reporting.rb +5 -3
- data/lib/active_support/descendants_tracker.rb +2 -0
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration.rb +11 -7
- data/lib/active_support/duration/iso8601_parser.rb +4 -2
- data/lib/active_support/duration/iso8601_serializer.rb +4 -2
- data/lib/active_support/encrypted_configuration.rb +49 -0
- data/lib/active_support/encrypted_file.rb +99 -0
- data/lib/active_support/evented_file_update_checker.rb +2 -0
- data/lib/active_support/execution_wrapper.rb +2 -0
- data/lib/active_support/executor.rb +2 -0
- data/lib/active_support/file_update_checker.rb +2 -0
- data/lib/active_support/gem_version.rb +5 -3
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +55 -1
- data/lib/active_support/i18n.rb +3 -1
- data/lib/active_support/i18n_railtie.rb +4 -6
- data/lib/active_support/inflections.rb +2 -0
- data/lib/active_support/inflector.rb +2 -0
- data/lib/active_support/inflector/inflections.rb +20 -4
- data/lib/active_support/inflector/methods.rb +43 -24
- data/lib/active_support/inflector/transliterate.rb +17 -8
- data/lib/active_support/json.rb +2 -0
- data/lib/active_support/json/decoding.rb +2 -0
- data/lib/active_support/json/encoding.rb +2 -0
- data/lib/active_support/key_generator.rb +3 -1
- data/lib/active_support/lazy_load_hooks.rb +2 -0
- data/lib/active_support/log_subscriber.rb +3 -2
- data/lib/active_support/log_subscriber/test_helper.rb +2 -0
- data/lib/active_support/logger.rb +2 -0
- data/lib/active_support/logger_silence.rb +3 -2
- data/lib/active_support/logger_thread_safe_level.rb +4 -1
- data/lib/active_support/message_encryptor.rb +95 -22
- data/lib/active_support/message_verifier.rb +78 -7
- data/lib/active_support/messages/metadata.rb +71 -0
- data/lib/active_support/messages/rotation_configuration.rb +22 -0
- data/lib/active_support/messages/rotator.rb +56 -0
- data/lib/active_support/multibyte.rb +2 -0
- data/lib/active_support/multibyte/chars.rb +2 -0
- data/lib/active_support/multibyte/unicode.rb +4 -2
- data/lib/active_support/notifications.rb +2 -0
- data/lib/active_support/notifications/fanout.rb +4 -2
- data/lib/active_support/notifications/instrumenter.rb +2 -0
- data/lib/active_support/number_helper.rb +2 -0
- data/lib/active_support/number_helper/number_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_currency_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_human_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_phone_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +2 -20
- data/lib/active_support/number_helper/rounding_helper.rb +6 -4
- data/lib/active_support/option_merger.rb +2 -0
- data/lib/active_support/ordered_hash.rb +2 -0
- data/lib/active_support/ordered_options.rb +5 -3
- data/lib/active_support/per_thread_registry.rb +2 -0
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +2 -0
- data/lib/active_support/railtie.rb +37 -8
- data/lib/active_support/reloader.rb +7 -5
- data/lib/active_support/rescuable.rb +3 -2
- data/lib/active_support/security_utils.rb +15 -11
- data/lib/active_support/string_inquirer.rb +2 -0
- data/lib/active_support/subscriber.rb +8 -2
- data/lib/active_support/tagged_logging.rb +2 -0
- data/lib/active_support/test_case.rb +3 -2
- data/lib/active_support/testing/assertions.rb +31 -14
- data/lib/active_support/testing/autorun.rb +2 -0
- data/lib/active_support/testing/constant_lookup.rb +2 -0
- data/lib/active_support/testing/declarative.rb +2 -0
- data/lib/active_support/testing/deprecation.rb +2 -0
- data/lib/active_support/testing/file_fixtures.rb +2 -0
- data/lib/active_support/testing/isolation.rb +3 -1
- data/lib/active_support/testing/method_call_assertions.rb +2 -0
- data/lib/active_support/testing/setup_and_teardown.rb +12 -7
- data/lib/active_support/testing/stream.rb +2 -0
- data/lib/active_support/testing/tagged_logging.rb +2 -0
- data/lib/active_support/testing/time_helpers.rb +33 -3
- data/lib/active_support/time.rb +2 -0
- data/lib/active_support/time_with_zone.rb +38 -0
- data/lib/active_support/values/time_zone.rb +20 -8
- data/lib/active_support/version.rb +2 -0
- data/lib/active_support/xml_mini.rb +4 -2
- data/lib/active_support/xml_mini/jdom.rb +4 -2
- data/lib/active_support/xml_mini/libxml.rb +3 -1
- data/lib/active_support/xml_mini/libxmlsax.rb +4 -2
- data/lib/active_support/xml_mini/nokogiri.rb +3 -1
- data/lib/active_support/xml_mini/nokogirisax.rb +3 -1
- data/lib/active_support/xml_mini/rexml.rb +3 -1
- metadata +17 -5
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveSupport
|
2
4
|
# Returns the version of the currently loaded Active Support as a <tt>Gem::Version</tt>.
|
3
5
|
def self.gem_version
|
@@ -6,9 +8,9 @@ module ActiveSupport
|
|
6
8
|
|
7
9
|
module VERSION
|
8
10
|
MAJOR = 5
|
9
|
-
MINOR =
|
10
|
-
TINY =
|
11
|
-
PRE =
|
11
|
+
MINOR = 2
|
12
|
+
TINY = 4
|
13
|
+
PRE = "3"
|
12
14
|
|
13
15
|
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
|
14
16
|
end
|
data/lib/active_support/gzip.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/hash/keys"
|
2
4
|
require "active_support/core_ext/hash/reverse_merge"
|
3
5
|
|
@@ -161,6 +163,19 @@ module ActiveSupport
|
|
161
163
|
super(convert_key(key))
|
162
164
|
end
|
163
165
|
|
166
|
+
# Same as <tt>Hash#assoc</tt> where the key passed as argument can be
|
167
|
+
# either a string or a symbol:
|
168
|
+
#
|
169
|
+
# counters = ActiveSupport::HashWithIndifferentAccess.new
|
170
|
+
# counters[:foo] = 1
|
171
|
+
#
|
172
|
+
# counters.assoc('foo') # => ["foo", 1]
|
173
|
+
# counters.assoc(:foo) # => ["foo", 1]
|
174
|
+
# counters.assoc(:zoo) # => nil
|
175
|
+
def assoc(key)
|
176
|
+
super(convert_key(key))
|
177
|
+
end
|
178
|
+
|
164
179
|
# Same as <tt>Hash#fetch</tt> where the key passed as argument can be
|
165
180
|
# either a string or a symbol:
|
166
181
|
#
|
@@ -215,6 +230,19 @@ module ActiveSupport
|
|
215
230
|
indices.collect { |key| self[convert_key(key)] }
|
216
231
|
end
|
217
232
|
|
233
|
+
# Returns an array of the values at the specified indices, but also
|
234
|
+
# raises an exception when one of the keys can't be found.
|
235
|
+
#
|
236
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
237
|
+
# hash[:a] = 'x'
|
238
|
+
# hash[:b] = 'y'
|
239
|
+
# hash.fetch_values('a', 'b') # => ["x", "y"]
|
240
|
+
# hash.fetch_values('a', 'c') { |key| 'z' } # => ["x", "z"]
|
241
|
+
# hash.fetch_values('a', 'c') # => KeyError: key not found: "c"
|
242
|
+
def fetch_values(*indices, &block)
|
243
|
+
indices.collect { |key| fetch(key, &block) }
|
244
|
+
end if Hash.method_defined?(:fetch_values)
|
245
|
+
|
218
246
|
# Returns a shallow copy of the hash.
|
219
247
|
#
|
220
248
|
# hash = ActiveSupport::HashWithIndifferentAccess.new({ a: { b: 'b' } })
|
@@ -245,11 +273,13 @@ module ActiveSupport
|
|
245
273
|
def reverse_merge(other_hash)
|
246
274
|
super(self.class.new(other_hash))
|
247
275
|
end
|
276
|
+
alias_method :with_defaults, :reverse_merge
|
248
277
|
|
249
278
|
# Same semantics as +reverse_merge+ but modifies the receiver in-place.
|
250
279
|
def reverse_merge!(other_hash)
|
251
|
-
|
280
|
+
super(self.class.new(other_hash))
|
252
281
|
end
|
282
|
+
alias_method :with_defaults!, :reverse_merge!
|
253
283
|
|
254
284
|
# Replaces the contents of this hash with other_hash.
|
255
285
|
#
|
@@ -271,6 +301,7 @@ module ActiveSupport
|
|
271
301
|
undef :symbolize_keys!
|
272
302
|
undef :deep_symbolize_keys!
|
273
303
|
def symbolize_keys; to_hash.symbolize_keys! end
|
304
|
+
alias_method :to_options, :symbolize_keys
|
274
305
|
def deep_symbolize_keys; to_hash.deep_symbolize_keys! end
|
275
306
|
def to_options!; self end
|
276
307
|
|
@@ -289,6 +320,29 @@ module ActiveSupport
|
|
289
320
|
dup.tap { |hash| hash.transform_values!(*args, &block) }
|
290
321
|
end
|
291
322
|
|
323
|
+
def transform_keys(*args, &block)
|
324
|
+
return to_enum(:transform_keys) unless block_given?
|
325
|
+
dup.tap { |hash| hash.transform_keys!(*args, &block) }
|
326
|
+
end
|
327
|
+
|
328
|
+
def transform_keys!
|
329
|
+
return enum_for(:transform_keys!) { size } unless block_given?
|
330
|
+
keys.each do |key|
|
331
|
+
self[yield(key)] = delete(key)
|
332
|
+
end
|
333
|
+
self
|
334
|
+
end
|
335
|
+
|
336
|
+
def slice(*keys)
|
337
|
+
keys.map! { |key| convert_key(key) }
|
338
|
+
self.class.new(super)
|
339
|
+
end
|
340
|
+
|
341
|
+
def slice!(*keys)
|
342
|
+
keys.map! { |key| convert_key(key) }
|
343
|
+
super
|
344
|
+
end
|
345
|
+
|
292
346
|
def compact
|
293
347
|
dup.tap(&:compact!)
|
294
348
|
end
|
data/lib/active_support/i18n.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/hash/deep_merge"
|
2
4
|
require "active_support/core_ext/hash/except"
|
3
5
|
require "active_support/core_ext/hash/slice"
|
@@ -10,4 +12,4 @@ end
|
|
10
12
|
require "active_support/lazy_load_hooks"
|
11
13
|
|
12
14
|
ActiveSupport.run_load_hooks(:i18n)
|
13
|
-
I18n.load_path <<
|
15
|
+
I18n.load_path << File.expand_path("locale/en.yml", __dir__)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support"
|
2
4
|
require "active_support/file_update_checker"
|
3
5
|
require "active_support/core_ext/array/wrap"
|
@@ -42,7 +44,7 @@ module I18n
|
|
42
44
|
case setting
|
43
45
|
when :railties_load_path
|
44
46
|
reloadable_paths = value
|
45
|
-
app.config.i18n.load_path.unshift(*value.
|
47
|
+
app.config.i18n.load_path.unshift(*value.flat_map(&:existent))
|
46
48
|
when :load_path
|
47
49
|
I18n.load_path += value
|
48
50
|
else
|
@@ -58,7 +60,7 @@ module I18n
|
|
58
60
|
directories = watched_dirs_with_extensions(reloadable_paths)
|
59
61
|
reloader = app.config.file_watcher.new(I18n.load_path.dup, directories) do
|
60
62
|
I18n.load_path.keep_if { |p| File.exist?(p) }
|
61
|
-
I18n.load_path |= reloadable_paths.
|
63
|
+
I18n.load_path |= reloadable_paths.flat_map(&:existent)
|
62
64
|
|
63
65
|
I18n.reload!
|
64
66
|
end
|
@@ -66,10 +68,6 @@ module I18n
|
|
66
68
|
app.reloaders << reloader
|
67
69
|
app.reloader.to_run do
|
68
70
|
reloader.execute_if_updated { require_unload_lock! }
|
69
|
-
# TODO: remove the following line as soon as the return value of
|
70
|
-
# callbacks is ignored, that is, returning `false` does not
|
71
|
-
# display a deprecation warning or halts the callback chain.
|
72
|
-
true
|
73
71
|
end
|
74
72
|
reloader.execute
|
75
73
|
|
@@ -1,7 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "concurrent/map"
|
2
4
|
require "active_support/core_ext/array/prepend_and_append"
|
3
5
|
require "active_support/core_ext/regexp"
|
4
6
|
require "active_support/i18n"
|
7
|
+
require "active_support/deprecation"
|
5
8
|
|
6
9
|
module ActiveSupport
|
7
10
|
module Inflector
|
@@ -65,16 +68,21 @@ module ActiveSupport
|
|
65
68
|
end
|
66
69
|
|
67
70
|
attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms, :acronym_regex
|
71
|
+
deprecate :acronym_regex
|
72
|
+
|
73
|
+
attr_reader :acronyms_camelize_regex, :acronyms_underscore_regex # :nodoc:
|
68
74
|
|
69
75
|
def initialize
|
70
|
-
@plurals, @singulars, @uncountables, @humans, @acronyms
|
76
|
+
@plurals, @singulars, @uncountables, @humans, @acronyms = [], [], Uncountables.new, [], {}
|
77
|
+
define_acronym_regex_patterns
|
71
78
|
end
|
72
79
|
|
73
80
|
# Private, for the test suite.
|
74
81
|
def initialize_dup(orig) # :nodoc:
|
75
|
-
%w(plurals singulars uncountables humans acronyms
|
82
|
+
%w(plurals singulars uncountables humans acronyms).each do |scope|
|
76
83
|
instance_variable_set("@#{scope}", orig.send(scope).dup)
|
77
84
|
end
|
85
|
+
define_acronym_regex_patterns
|
78
86
|
end
|
79
87
|
|
80
88
|
# Specifies a new acronym. An acronym must be specified as it will appear
|
@@ -128,7 +136,7 @@ module ActiveSupport
|
|
128
136
|
# camelize 'mcdonald' # => 'McDonald'
|
129
137
|
def acronym(word)
|
130
138
|
@acronyms[word.downcase] = word
|
131
|
-
|
139
|
+
define_acronym_regex_patterns
|
132
140
|
end
|
133
141
|
|
134
142
|
# Specifies a new pluralization rule and its replacement. The rule can
|
@@ -219,10 +227,18 @@ module ActiveSupport
|
|
219
227
|
case scope
|
220
228
|
when :all
|
221
229
|
@plurals, @singulars, @uncountables, @humans = [], [], Uncountables.new, []
|
222
|
-
|
230
|
+
else
|
223
231
|
instance_variable_set "@#{scope}", []
|
224
232
|
end
|
225
233
|
end
|
234
|
+
|
235
|
+
private
|
236
|
+
|
237
|
+
def define_acronym_regex_patterns
|
238
|
+
@acronym_regex = @acronyms.empty? ? /(?=a)b/ : /#{@acronyms.values.join("|")}/
|
239
|
+
@acronyms_camelize_regex = /^(?:#{@acronym_regex}(?=\b|[A-Z_])|\w)/
|
240
|
+
@acronyms_underscore_regex = /(?:(?<=([A-Za-z\d]))|\b)(#{@acronym_regex})(?=\b|[^a-z])/
|
241
|
+
end
|
226
242
|
end
|
227
243
|
|
228
244
|
# Yields a singleton instance of Inflector::Inflections so you can specify
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/inflections"
|
2
4
|
require "active_support/core_ext/regexp"
|
3
5
|
|
@@ -28,7 +30,7 @@ module ActiveSupport
|
|
28
30
|
# pluralize('CamelOctopus') # => "CamelOctopi"
|
29
31
|
# pluralize('ley', :es) # => "leyes"
|
30
32
|
def pluralize(word, locale = :en)
|
31
|
-
apply_inflections(word, inflections(locale).plurals)
|
33
|
+
apply_inflections(word, inflections(locale).plurals, locale)
|
32
34
|
end
|
33
35
|
|
34
36
|
# The reverse of #pluralize, returns the singular form of a word in a
|
@@ -45,7 +47,7 @@ module ActiveSupport
|
|
45
47
|
# singularize('CamelOctopi') # => "CamelOctopus"
|
46
48
|
# singularize('leyes', :es) # => "ley"
|
47
49
|
def singularize(word, locale = :en)
|
48
|
-
apply_inflections(word, inflections(locale).singulars)
|
50
|
+
apply_inflections(word, inflections(locale).singulars, locale)
|
49
51
|
end
|
50
52
|
|
51
53
|
# Converts strings to UpperCamelCase.
|
@@ -69,7 +71,7 @@ module ActiveSupport
|
|
69
71
|
if uppercase_first_letter
|
70
72
|
string = string.sub(/^[a-z\d]*/) { |match| inflections.acronyms[match] || match.capitalize }
|
71
73
|
else
|
72
|
-
string = string.sub(
|
74
|
+
string = string.sub(inflections.acronyms_camelize_regex) { |match| match.downcase }
|
73
75
|
end
|
74
76
|
string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }
|
75
77
|
string.gsub!("/".freeze, "::".freeze)
|
@@ -90,7 +92,7 @@ module ActiveSupport
|
|
90
92
|
def underscore(camel_cased_word)
|
91
93
|
return camel_cased_word unless /[A-Z-]|::/.match?(camel_cased_word)
|
92
94
|
word = camel_cased_word.to_s.gsub("::".freeze, "/".freeze)
|
93
|
-
word.gsub!(
|
95
|
+
word.gsub!(inflections.acronyms_underscore_regex) { "#{$1 && '_'.freeze }#{$2.downcase}" }
|
94
96
|
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2'.freeze)
|
95
97
|
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2'.freeze)
|
96
98
|
word.tr!("-".freeze, "_".freeze)
|
@@ -108,33 +110,38 @@ module ActiveSupport
|
|
108
110
|
# * Replaces underscores with spaces, if any.
|
109
111
|
# * Downcases all words except acronyms.
|
110
112
|
# * Capitalizes the first word.
|
111
|
-
#
|
112
113
|
# The capitalization of the first word can be turned off by setting the
|
113
114
|
# +:capitalize+ option to false (default is true).
|
114
115
|
#
|
115
|
-
#
|
116
|
-
#
|
117
|
-
#
|
118
|
-
# humanize('
|
116
|
+
# The trailing '_id' can be kept and capitalized by setting the
|
117
|
+
# optional parameter +keep_id_suffix+ to true (default is false).
|
118
|
+
#
|
119
|
+
# humanize('employee_salary') # => "Employee salary"
|
120
|
+
# humanize('author_id') # => "Author"
|
121
|
+
# humanize('author_id', capitalize: false) # => "author"
|
122
|
+
# humanize('_id') # => "Id"
|
123
|
+
# humanize('author_id', keep_id_suffix: true) # => "Author Id"
|
119
124
|
#
|
120
125
|
# If "SSL" was defined to be an acronym:
|
121
126
|
#
|
122
127
|
# humanize('ssl_error') # => "SSL error"
|
123
128
|
#
|
124
|
-
def humanize(lower_case_and_underscored_word,
|
129
|
+
def humanize(lower_case_and_underscored_word, capitalize: true, keep_id_suffix: false)
|
125
130
|
result = lower_case_and_underscored_word.to_s.dup
|
126
131
|
|
127
132
|
inflections.humans.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
|
128
133
|
|
129
134
|
result.sub!(/\A_+/, "".freeze)
|
130
|
-
|
135
|
+
unless keep_id_suffix
|
136
|
+
result.sub!(/_id\z/, "".freeze)
|
137
|
+
end
|
131
138
|
result.tr!("_".freeze, " ".freeze)
|
132
139
|
|
133
140
|
result.gsub!(/([a-z\d]*)/i) do |match|
|
134
|
-
"#{inflections.acronyms[match] || match.downcase}"
|
141
|
+
"#{inflections.acronyms[match.downcase] || match.downcase}"
|
135
142
|
end
|
136
143
|
|
137
|
-
if
|
144
|
+
if capitalize
|
138
145
|
result.sub!(/\A\w/) { |match| match.upcase }
|
139
146
|
end
|
140
147
|
|
@@ -154,14 +161,21 @@ module ActiveSupport
|
|
154
161
|
# create a nicer looking title. +titleize+ is meant for creating pretty
|
155
162
|
# output. It is not used in the Rails internals.
|
156
163
|
#
|
164
|
+
# The trailing '_id','Id'.. can be kept and capitalized by setting the
|
165
|
+
# optional parameter +keep_id_suffix+ to true.
|
166
|
+
# By default, this parameter is false.
|
167
|
+
#
|
157
168
|
# +titleize+ is also aliased as +titlecase+.
|
158
169
|
#
|
159
|
-
# titleize('man from the boondocks')
|
160
|
-
# titleize('x-men: the last stand')
|
161
|
-
# titleize('TheManWithoutAPast')
|
162
|
-
# titleize('raiders_of_the_lost_ark')
|
163
|
-
|
164
|
-
|
170
|
+
# titleize('man from the boondocks') # => "Man From The Boondocks"
|
171
|
+
# titleize('x-men: the last stand') # => "X Men: The Last Stand"
|
172
|
+
# titleize('TheManWithoutAPast') # => "The Man Without A Past"
|
173
|
+
# titleize('raiders_of_the_lost_ark') # => "Raiders Of The Lost Ark"
|
174
|
+
# titleize('string_ending_with_id', keep_id_suffix: true) # => "String Ending With Id"
|
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|
|
177
|
+
match.capitalize
|
178
|
+
end
|
165
179
|
end
|
166
180
|
|
167
181
|
# Creates the name of a table like Rails does for models to table names.
|
@@ -315,6 +329,8 @@ module ActiveSupport
|
|
315
329
|
e.name.to_s == camel_cased_word.to_s)
|
316
330
|
rescue ArgumentError => e
|
317
331
|
raise unless /not missing constant #{const_regexp(camel_cased_word)}!$/.match?(e.message)
|
332
|
+
rescue LoadError => e
|
333
|
+
raise unless /Unable to autoload constant #{const_regexp(camel_cased_word)}/.match?(e.message)
|
318
334
|
end
|
319
335
|
|
320
336
|
# Returns the suffix that should be added to a number to denote the position
|
@@ -336,7 +352,7 @@ module ActiveSupport
|
|
336
352
|
when 1; "st"
|
337
353
|
when 2; "nd"
|
338
354
|
when 3; "rd"
|
339
|
-
|
355
|
+
else "th"
|
340
356
|
end
|
341
357
|
end
|
342
358
|
end
|
@@ -375,12 +391,15 @@ module ActiveSupport
|
|
375
391
|
|
376
392
|
# Applies inflection rules for +singularize+ and +pluralize+.
|
377
393
|
#
|
378
|
-
#
|
379
|
-
#
|
380
|
-
|
394
|
+
# If passed an optional +locale+ parameter, the uncountables will be
|
395
|
+
# found for that locale.
|
396
|
+
#
|
397
|
+
# apply_inflections('post', inflections.plurals, :en) # => "posts"
|
398
|
+
# apply_inflections('posts', inflections.singulars, :en) # => "post"
|
399
|
+
def apply_inflections(word, rules, locale = :en)
|
381
400
|
result = word.to_s.dup
|
382
401
|
|
383
|
-
if word.empty? || inflections.uncountables.uncountable?(result)
|
402
|
+
if word.empty? || inflections(locale).uncountables.uncountable?(result)
|
384
403
|
result
|
385
404
|
else
|
386
405
|
rules.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/string/multibyte"
|
2
4
|
require "active_support/i18n"
|
3
5
|
|
@@ -59,26 +61,33 @@ module ActiveSupport
|
|
59
61
|
def transliterate(string, replacement = "?".freeze)
|
60
62
|
raise ArgumentError, "Can only transliterate strings. Received #{string.class.name}" unless string.is_a?(String)
|
61
63
|
|
62
|
-
I18n.transliterate(
|
63
|
-
ActiveSupport::Multibyte::Unicode.
|
64
|
-
|
64
|
+
I18n.transliterate(
|
65
|
+
ActiveSupport::Multibyte::Unicode.normalize(
|
66
|
+
ActiveSupport::Multibyte::Unicode.tidy_bytes(string), :c),
|
67
|
+
replacement: replacement)
|
65
68
|
end
|
66
69
|
|
67
70
|
# Replaces special characters in a string so that it may be used as part of
|
68
71
|
# a 'pretty' URL.
|
69
72
|
#
|
70
73
|
# parameterize("Donald E. Knuth") # => "donald-e-knuth"
|
71
|
-
# parameterize("^
|
74
|
+
# parameterize("^très|Jolie-- ") # => "tres-jolie"
|
72
75
|
#
|
73
|
-
# To use a custom separator, override the
|
76
|
+
# To use a custom separator, override the +separator+ argument.
|
74
77
|
#
|
75
78
|
# parameterize("Donald E. Knuth", separator: '_') # => "donald_e_knuth"
|
76
|
-
# parameterize("^
|
79
|
+
# parameterize("^très|Jolie__ ", separator: '_') # => "tres_jolie"
|
77
80
|
#
|
78
|
-
# To preserve the case of the characters in a string, use the
|
81
|
+
# To preserve the case of the characters in a string, use the +preserve_case+ argument.
|
79
82
|
#
|
80
83
|
# parameterize("Donald E. Knuth", preserve_case: true) # => "Donald-E-Knuth"
|
81
|
-
# parameterize("^
|
84
|
+
# parameterize("^très|Jolie-- ", preserve_case: true) # => "tres-Jolie"
|
85
|
+
#
|
86
|
+
# It preserves dashes and underscores unless they are used as separators:
|
87
|
+
#
|
88
|
+
# parameterize("^très|Jolie__ ") # => "tres-jolie__"
|
89
|
+
# parameterize("^très|Jolie-- ", separator: "_") # => "tres_jolie--"
|
90
|
+
# parameterize("^très_Jolie-- ", separator: ".") # => "tres_jolie--"
|
82
91
|
#
|
83
92
|
def parameterize(string, separator: "-", preserve_case: false)
|
84
93
|
# Replace accented chars with their ASCII equivalents.
|