activesupport 5.1.7 → 7.0.4.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 +259 -585
- data/MIT-LICENSE +1 -1
- data/README.rdoc +6 -5
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/all.rb +2 -0
- data/lib/active_support/array_inquirer.rb +4 -2
- data/lib/active_support/backtrace_cleaner.rb +33 -5
- data/lib/active_support/benchmarkable.rb +5 -3
- data/lib/active_support/builder.rb +2 -0
- data/lib/active_support/cache/file_store.rb +50 -43
- data/lib/active_support/cache/mem_cache_store.rb +194 -67
- data/lib/active_support/cache/memory_store.rb +70 -34
- data/lib/active_support/cache/null_store.rb +18 -3
- data/lib/active_support/cache/redis_cache_store.rb +474 -0
- data/lib/active_support/cache/strategy/local_cache.rb +73 -50
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
- data/lib/active_support/cache.rb +556 -220
- data/lib/active_support/callbacks.rb +264 -159
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +81 -8
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +16 -0
- data/lib/active_support/concurrency/share_lock.rb +4 -3
- data/lib/active_support/configurable.rb +17 -16
- data/lib/active_support/configuration_file.rb +51 -0
- data/lib/active_support/core_ext/array/access.rb +18 -8
- data/lib/active_support/core_ext/array/conversions.rb +20 -17
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +8 -6
- data/lib/active_support/core_ext/array/inquiry.rb +4 -2
- data/lib/active_support/core_ext/array/wrap.rb +2 -0
- data/lib/active_support/core_ext/array.rb +4 -1
- data/lib/active_support/core_ext/benchmark.rb +4 -2
- data/lib/active_support/core_ext/big_decimal/conversions.rb +3 -1
- data/lib/active_support/core_ext/big_decimal.rb +2 -0
- data/lib/active_support/core_ext/class/attribute.rb +50 -47
- data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
- data/lib/active_support/core_ext/class/subclasses.rb +10 -24
- data/lib/active_support/core_ext/class.rb +2 -0
- data/lib/active_support/core_ext/date/acts_like.rb +2 -0
- data/lib/active_support/core_ext/date/blank.rb +3 -1
- data/lib/active_support/core_ext/date/calculations.rb +17 -14
- data/lib/active_support/core_ext/date/conversions.rb +24 -22
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/date/zones.rb +2 -0
- data/lib/active_support/core_ext/date.rb +3 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +65 -41
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -1
- data/lib/active_support/core_ext/date_and_time/zones.rb +2 -1
- data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
- data/lib/active_support/core_ext/date_time/blank.rb +3 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +3 -1
- data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
- data/lib/active_support/core_ext/date_time/conversions.rb +15 -14
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/date_time.rb +3 -0
- data/lib/active_support/core_ext/digest/uuid.rb +42 -14
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +244 -72
- data/lib/active_support/core_ext/file/atomic.rb +6 -2
- data/lib/active_support/core_ext/file.rb +2 -0
- data/lib/active_support/core_ext/hash/conversions.rb +7 -6
- data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +4 -2
- data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
- data/lib/active_support/core_ext/hash/keys.rb +4 -31
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +8 -29
- data/lib/active_support/core_ext/hash.rb +3 -2
- data/lib/active_support/core_ext/integer/inflections.rb +2 -0
- data/lib/active_support/core_ext/integer/multiple.rb +3 -1
- data/lib/active_support/core_ext/integer/time.rb +7 -14
- data/lib/active_support/core_ext/integer.rb +2 -0
- data/lib/active_support/core_ext/kernel/concern.rb +2 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +6 -4
- data/lib/active_support/core_ext/kernel/singleton_class.rb +3 -1
- data/lib/active_support/core_ext/kernel.rb +2 -1
- data/lib/active_support/core_ext/load_error.rb +3 -8
- 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 +4 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +46 -56
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +36 -27
- data/lib/active_support/core_ext/module/concerning.rb +15 -10
- data/lib/active_support/core_ext/module/delegation.rb +97 -58
- data/lib/active_support/core_ext/module/deprecation.rb +2 -0
- data/lib/active_support/core_ext/module/introspection.rb +18 -15
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +5 -23
- data/lib/active_support/core_ext/module.rb +3 -1
- data/lib/active_support/core_ext/name_error.rb +30 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +134 -129
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
- data/lib/active_support/core_ext/numeric/time.rb +7 -15
- data/lib/active_support/core_ext/numeric.rb +3 -1
- data/lib/active_support/core_ext/object/acts_like.rb +41 -6
- data/lib/active_support/core_ext/object/blank.rb +15 -5
- data/lib/active_support/core_ext/object/conversions.rb +2 -0
- data/lib/active_support/core_ext/object/deep_dup.rb +3 -1
- data/lib/active_support/core_ext/object/duplicable.rb +16 -110
- 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 +51 -26
- data/lib/active_support/core_ext/object/to_param.rb +2 -0
- data/lib/active_support/core_ext/object/to_query.rb +4 -2
- data/lib/active_support/core_ext/object/try.rb +26 -14
- data/lib/active_support/core_ext/object/with_options.rb +24 -3
- data/lib/active_support/core_ext/object.rb +2 -0
- data/lib/active_support/core_ext/pathname/existence.rb +21 -0
- data/lib/active_support/core_ext/pathname.rb +3 -0
- data/lib/active_support/core_ext/range/compare_range.rb +57 -0
- data/lib/active_support/core_ext/range/conversions.rb +35 -25
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/range/each.rb +6 -3
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +7 -0
- data/lib/active_support/core_ext/range/overlaps.rb +3 -1
- data/lib/active_support/core_ext/range.rb +4 -1
- data/lib/active_support/core_ext/regexp.rb +10 -5
- data/lib/active_support/core_ext/securerandom.rb +25 -3
- data/lib/active_support/core_ext/string/access.rb +7 -16
- data/lib/active_support/core_ext/string/behavior.rb +2 -0
- data/lib/active_support/core_ext/string/conversions.rb +5 -2
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +44 -1
- data/lib/active_support/core_ext/string/indent.rb +2 -0
- data/lib/active_support/core_ext/string/inflections.rb +69 -16
- data/lib/active_support/core_ext/string/inquiry.rb +4 -1
- data/lib/active_support/core_ext/string/multibyte.rb +9 -4
- data/lib/active_support/core_ext/string/output_safety.rb +135 -27
- data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
- data/lib/active_support/core_ext/string/strip.rb +5 -1
- data/lib/active_support/core_ext/string/zones.rb +2 -0
- data/lib/active_support/core_ext/string.rb +2 -0
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/time/acts_like.rb +2 -0
- data/lib/active_support/core_ext/time/calculations.rb +81 -24
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- data/lib/active_support/core_ext/time/conversions.rb +17 -12
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/time/zones.rb +12 -25
- data/lib/active_support/core_ext/time.rb +3 -0
- data/lib/active_support/core_ext/uri.rb +4 -23
- data/lib/active_support/core_ext.rb +4 -1
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +226 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +12 -18
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +59 -715
- data/lib/active_support/deprecation/behaviors.rb +48 -13
- data/lib/active_support/deprecation/constant_accessor.rb +4 -2
- data/lib/active_support/deprecation/disallowed.rb +56 -0
- data/lib/active_support/deprecation/instance_delegator.rb +2 -1
- data/lib/active_support/deprecation/method_wrappers.rb +29 -21
- data/lib/active_support/deprecation/proxy_wrappers.rb +34 -8
- data/lib/active_support/deprecation/reporting.rb +54 -9
- data/lib/active_support/deprecation.rb +10 -3
- data/lib/active_support/descendants_tracker.rb +192 -34
- data/lib/active_support/digest.rb +22 -0
- data/lib/active_support/duration/iso8601_parser.rb +9 -9
- data/lib/active_support/duration/iso8601_serializer.rb +29 -15
- data/lib/active_support/duration.rb +158 -72
- data/lib/active_support/encrypted_configuration.rb +56 -0
- data/lib/active_support/encrypted_file.rb +129 -0
- data/lib/active_support/environment_inquirer.rb +20 -0
- data/lib/active_support/error_reporter.rb +117 -0
- data/lib/active_support/evented_file_update_checker.rb +87 -122
- data/lib/active_support/execution_context/test_helper.rb +13 -0
- data/lib/active_support/execution_context.rb +53 -0
- data/lib/active_support/execution_wrapper.rb +46 -21
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/executor.rb +2 -0
- data/lib/active_support/file_update_checker.rb +2 -1
- data/lib/active_support/fork_tracker.rb +71 -0
- data/lib/active_support/gem_version.rb +7 -5
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +126 -42
- data/lib/active_support/html_safe_translation.rb +43 -0
- data/lib/active_support/i18n.rb +5 -1
- data/lib/active_support/i18n_railtie.rb +19 -14
- data/lib/active_support/inflections.rb +2 -0
- data/lib/active_support/inflector/inflections.rb +41 -14
- data/lib/active_support/inflector/methods.rb +73 -87
- data/lib/active_support/inflector/transliterate.rb +56 -18
- data/lib/active_support/inflector.rb +2 -0
- data/lib/active_support/isolated_execution_state.rb +72 -0
- data/lib/active_support/json/decoding.rb +27 -26
- data/lib/active_support/json/encoding.rb +16 -6
- data/lib/active_support/json.rb +2 -0
- data/lib/active_support/key_generator.rb +25 -38
- data/lib/active_support/lazy_load_hooks.rb +35 -6
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +8 -4
- data/lib/active_support/log_subscriber/test_helper.rb +4 -2
- data/lib/active_support/log_subscriber.rb +54 -13
- data/lib/active_support/logger.rb +4 -17
- data/lib/active_support/logger_silence.rb +13 -20
- data/lib/active_support/logger_thread_safe_level.rb +48 -10
- data/lib/active_support/message_encryptor.rb +111 -37
- data/lib/active_support/message_verifier.rb +124 -21
- data/lib/active_support/messages/metadata.rb +80 -0
- data/lib/active_support/messages/rotation_configuration.rb +23 -0
- data/lib/active_support/messages/rotator.rb +57 -0
- data/lib/active_support/multibyte/chars.rb +19 -76
- data/lib/active_support/multibyte/unicode.rb +9 -331
- data/lib/active_support/multibyte.rb +3 -1
- data/lib/active_support/notifications/fanout.rb +165 -37
- data/lib/active_support/notifications/instrumenter.rb +92 -11
- data/lib/active_support/notifications.rb +96 -30
- data/lib/active_support/number_helper/number_converter.rb +8 -9
- data/lib/active_support/number_helper/number_to_currency_converter.rb +14 -12
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +6 -3
- data/lib/active_support/number_helper/number_to_human_converter.rb +6 -3
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +7 -4
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +6 -3
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +14 -27
- data/lib/active_support/number_helper/rounding_helper.rb +16 -34
- data/lib/active_support/number_helper.rb +38 -12
- data/lib/active_support/option_merger.rb +19 -6
- data/lib/active_support/ordered_hash.rb +4 -2
- data/lib/active_support/ordered_options.rb +18 -6
- data/lib/active_support/parameter_filter.rb +138 -0
- data/lib/active_support/per_thread_registry.rb +8 -1
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +3 -10
- data/lib/active_support/railtie.rb +112 -11
- data/lib/active_support/reloader.rb +12 -11
- data/lib/active_support/rescuable.rb +19 -18
- data/lib/active_support/ruby_features.rb +7 -0
- data/lib/active_support/secure_compare_rotator.rb +51 -0
- data/lib/active_support/security_utils.rb +26 -15
- data/lib/active_support/string_inquirer.rb +4 -3
- data/lib/active_support/subscriber.rb +81 -42
- data/lib/active_support/tagged_logging.rb +45 -9
- data/lib/active_support/test_case.rb +86 -2
- data/lib/active_support/testing/assertions.rb +89 -21
- 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 +54 -2
- data/lib/active_support/testing/file_fixtures.rb +4 -0
- data/lib/active_support/testing/isolation.rb +6 -4
- data/lib/active_support/testing/method_call_assertions.rb +34 -5
- data/lib/active_support/testing/parallelization/server.rb +82 -0
- data/lib/active_support/testing/parallelization/worker.rb +103 -0
- data/lib/active_support/testing/parallelization.rb +55 -0
- data/lib/active_support/testing/parallelize_executor.rb +76 -0
- data/lib/active_support/testing/setup_and_teardown.rb +12 -7
- data/lib/active_support/testing/stream.rb +6 -7
- data/lib/active_support/testing/tagged_logging.rb +3 -1
- data/lib/active_support/testing/time_helpers.rb +91 -15
- data/lib/active_support/time.rb +2 -0
- data/lib/active_support/time_with_zone.rb +168 -56
- data/lib/active_support/values/time_zone.rb +85 -37
- data/lib/active_support/version.rb +3 -1
- data/lib/active_support/xml_mini/jdom.rb +6 -5
- data/lib/active_support/xml_mini/libxml.rb +9 -7
- data/lib/active_support/xml_mini/libxmlsax.rb +7 -5
- data/lib/active_support/xml_mini/nokogiri.rb +8 -6
- data/lib/active_support/xml_mini/nokogirisax.rb +6 -4
- data/lib/active_support/xml_mini/rexml.rb +13 -4
- data/lib/active_support/xml_mini.rb +10 -15
- data/lib/active_support.rb +30 -9
- metadata +76 -35
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
- data/lib/active_support/core_ext/hash/compact.rb +0 -27
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -30
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
- data/lib/active_support/core_ext/marshal.rb +0 -22
- data/lib/active_support/core_ext/module/reachable.rb +0 -8
- data/lib/active_support/core_ext/numeric/inquiry.rb +0 -26
- data/lib/active_support/core_ext/range/include_range.rb +0 -23
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,5 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/inflections"
|
2
|
-
require "active_support/core_ext/
|
4
|
+
require "active_support/core_ext/object/blank"
|
3
5
|
|
4
6
|
module ActiveSupport
|
5
7
|
# The Inflector transforms words from singular to plural, class names to table
|
@@ -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.
|
@@ -66,13 +68,17 @@ module ActiveSupport
|
|
66
68
|
# camelize(underscore('SSLError')) # => "SslError"
|
67
69
|
def camelize(term, uppercase_first_letter = true)
|
68
70
|
string = term.to_s
|
69
|
-
|
70
|
-
|
71
|
+
# String#camelize takes a symbol (:upper or :lower), so here we also support :lower to keep the methods consistent.
|
72
|
+
if !uppercase_first_letter || uppercase_first_letter == :lower
|
73
|
+
string = string.sub(inflections.acronyms_camelize_regex) { |match| match.downcase! || match }
|
71
74
|
else
|
72
|
-
string = string.sub(/^
|
75
|
+
string = string.sub(/^[a-z\d]*/) { |match| inflections.acronyms[match] || match.capitalize! || match }
|
76
|
+
end
|
77
|
+
string.gsub!(/(?:_|(\/))([a-z\d]*)/i) do
|
78
|
+
word = $2
|
79
|
+
substituted = inflections.acronyms[word] || word.capitalize! || word
|
80
|
+
$1 ? "::#{substituted}" : substituted
|
73
81
|
end
|
74
|
-
string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }
|
75
|
-
string.gsub!("/".freeze, "::".freeze)
|
76
82
|
string
|
77
83
|
end
|
78
84
|
|
@@ -88,12 +94,11 @@ module ActiveSupport
|
|
88
94
|
#
|
89
95
|
# camelize(underscore('SSLError')) # => "SslError"
|
90
96
|
def underscore(camel_cased_word)
|
91
|
-
return camel_cased_word unless /[A-Z-]|::/.match?(camel_cased_word)
|
92
|
-
word = camel_cased_word.to_s.gsub("::"
|
93
|
-
word.gsub!(
|
94
|
-
word.gsub!(/([A-Z
|
95
|
-
word.
|
96
|
-
word.tr!("-".freeze, "_".freeze)
|
97
|
+
return camel_cased_word.to_s unless /[A-Z-]|::/.match?(camel_cased_word)
|
98
|
+
word = camel_cased_word.to_s.gsub("::", "/")
|
99
|
+
word.gsub!(inflections.acronyms_underscore_regex) { "#{$1 && '_' }#{$2.downcase}" }
|
100
|
+
word.gsub!(/([A-Z])(?=[A-Z][a-z])|([a-z\d])(?=[A-Z])/) { ($1 || $2) << "_" }
|
101
|
+
word.tr!("-", "_")
|
97
102
|
word.downcase!
|
98
103
|
word
|
99
104
|
end
|
@@ -104,38 +109,47 @@ module ActiveSupport
|
|
104
109
|
#
|
105
110
|
# * Applies human inflection rules to the argument.
|
106
111
|
# * Deletes leading underscores, if any.
|
107
|
-
# * Removes
|
112
|
+
# * Removes an "_id" suffix if present.
|
108
113
|
# * Replaces underscores with spaces, if any.
|
109
114
|
# * Downcases all words except acronyms.
|
110
115
|
# * Capitalizes the first word.
|
111
|
-
#
|
112
116
|
# The capitalization of the first word can be turned off by setting the
|
113
117
|
# +:capitalize+ option to false (default is true).
|
114
118
|
#
|
115
|
-
#
|
116
|
-
#
|
117
|
-
#
|
118
|
-
# humanize('
|
119
|
+
# The trailing '_id' can be kept and capitalized by setting the
|
120
|
+
# optional parameter +keep_id_suffix+ to true (default is false).
|
121
|
+
#
|
122
|
+
# humanize('employee_salary') # => "Employee salary"
|
123
|
+
# humanize('author_id') # => "Author"
|
124
|
+
# humanize('author_id', capitalize: false) # => "author"
|
125
|
+
# humanize('_id') # => "Id"
|
126
|
+
# humanize('author_id', keep_id_suffix: true) # => "Author id"
|
119
127
|
#
|
120
128
|
# If "SSL" was defined to be an acronym:
|
121
129
|
#
|
122
130
|
# humanize('ssl_error') # => "SSL error"
|
123
131
|
#
|
124
|
-
def humanize(lower_case_and_underscored_word,
|
132
|
+
def humanize(lower_case_and_underscored_word, capitalize: true, keep_id_suffix: false)
|
125
133
|
result = lower_case_and_underscored_word.to_s.dup
|
126
134
|
|
127
135
|
inflections.humans.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
|
128
136
|
|
129
|
-
result.
|
130
|
-
result.
|
131
|
-
|
137
|
+
result.tr!("_", " ")
|
138
|
+
result.lstrip!
|
139
|
+
unless keep_id_suffix
|
140
|
+
result.delete_suffix!(" id")
|
141
|
+
end
|
132
142
|
|
133
|
-
result.gsub!(/([a-z\d]
|
134
|
-
|
143
|
+
result.gsub!(/([a-z\d]+)/i) do |match|
|
144
|
+
match.downcase!
|
145
|
+
inflections.acronyms[match] || match
|
135
146
|
end
|
136
147
|
|
137
|
-
if
|
138
|
-
result.sub!(/\A\w/)
|
148
|
+
if capitalize
|
149
|
+
result.sub!(/\A\w/) do |match|
|
150
|
+
match.upcase!
|
151
|
+
match
|
152
|
+
end
|
139
153
|
end
|
140
154
|
|
141
155
|
result
|
@@ -154,14 +168,21 @@ module ActiveSupport
|
|
154
168
|
# create a nicer looking title. +titleize+ is meant for creating pretty
|
155
169
|
# output. It is not used in the Rails internals.
|
156
170
|
#
|
171
|
+
# The trailing '_id','Id'.. can be kept and capitalized by setting the
|
172
|
+
# optional parameter +keep_id_suffix+ to true.
|
173
|
+
# By default, this parameter is false.
|
174
|
+
#
|
157
175
|
# +titleize+ is also aliased as +titlecase+.
|
158
176
|
#
|
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
|
-
|
177
|
+
# titleize('man from the boondocks') # => "Man From The Boondocks"
|
178
|
+
# titleize('x-men: the last stand') # => "X Men: The Last Stand"
|
179
|
+
# titleize('TheManWithoutAPast') # => "The Man Without A Past"
|
180
|
+
# titleize('raiders_of_the_lost_ark') # => "Raiders Of The Lost Ark"
|
181
|
+
# titleize('string_ending_with_id', keep_id_suffix: true) # => "String Ending With Id"
|
182
|
+
def titleize(word, keep_id_suffix: false)
|
183
|
+
humanize(underscore(word), keep_id_suffix: keep_id_suffix).gsub(/\b(?<!\w['’`()])[a-z]/) do |match|
|
184
|
+
match.capitalize
|
185
|
+
end
|
165
186
|
end
|
166
187
|
|
167
188
|
# Creates the name of a table like Rails does for models to table names.
|
@@ -183,17 +204,17 @@ module ActiveSupport
|
|
183
204
|
#
|
184
205
|
# Singular names are not handled correctly:
|
185
206
|
#
|
186
|
-
# classify('calculus') # => "
|
207
|
+
# classify('calculus') # => "Calculu"
|
187
208
|
def classify(table_name)
|
188
209
|
# strip out any leading schema name
|
189
|
-
camelize(singularize(table_name.to_s.sub(/.*\./, ""
|
210
|
+
camelize(singularize(table_name.to_s.sub(/.*\./, "")))
|
190
211
|
end
|
191
212
|
|
192
213
|
# Replaces underscores with dashes in the string.
|
193
214
|
#
|
194
215
|
# dasherize('puni_puni') # => "puni-puni"
|
195
216
|
def dasherize(underscored_word)
|
196
|
-
underscored_word.tr("_"
|
217
|
+
underscored_word.tr("_", "-")
|
197
218
|
end
|
198
219
|
|
199
220
|
# Removes the module part from the expression in the string.
|
@@ -256,34 +277,7 @@ module ActiveSupport
|
|
256
277
|
# NameError is raised when the name is not in CamelCase or the constant is
|
257
278
|
# unknown.
|
258
279
|
def constantize(camel_cased_word)
|
259
|
-
|
260
|
-
|
261
|
-
# Trigger a built-in NameError exception including the ill-formed constant in the message.
|
262
|
-
Object.const_get(camel_cased_word) if names.empty?
|
263
|
-
|
264
|
-
# Remove the first blank element in case of '::ClassName' notation.
|
265
|
-
names.shift if names.size > 1 && names.first.empty?
|
266
|
-
|
267
|
-
names.inject(Object) do |constant, name|
|
268
|
-
if constant == Object
|
269
|
-
constant.const_get(name)
|
270
|
-
else
|
271
|
-
candidate = constant.const_get(name)
|
272
|
-
next candidate if constant.const_defined?(name, false)
|
273
|
-
next candidate unless Object.const_defined?(name)
|
274
|
-
|
275
|
-
# Go down the ancestors to check if it is owned directly. The check
|
276
|
-
# stops when we reach Object or the end of ancestors tree.
|
277
|
-
constant = constant.ancestors.inject(constant) do |const, ancestor|
|
278
|
-
break const if ancestor == Object
|
279
|
-
break ancestor if ancestor.const_defined?(name, false)
|
280
|
-
const
|
281
|
-
end
|
282
|
-
|
283
|
-
# owner is in Object, so raise
|
284
|
-
constant.const_get(name, false)
|
285
|
-
end
|
286
|
-
end
|
280
|
+
Object.const_get(camel_cased_word)
|
287
281
|
end
|
288
282
|
|
289
283
|
# Tries to find a constant with the name specified in the argument string.
|
@@ -313,8 +307,9 @@ module ActiveSupport
|
|
313
307
|
rescue NameError => e
|
314
308
|
raise if e.name && !(camel_cased_word.to_s.split("::").include?(e.name.to_s) ||
|
315
309
|
e.name.to_s == camel_cased_word.to_s)
|
316
|
-
rescue
|
317
|
-
|
310
|
+
rescue LoadError => e
|
311
|
+
message = e.respond_to?(:original_message) ? e.original_message : e.message
|
312
|
+
raise unless /Unable to autoload constant #{const_regexp(camel_cased_word)}/.match?(message)
|
318
313
|
end
|
319
314
|
|
320
315
|
# Returns the suffix that should be added to a number to denote the position
|
@@ -327,18 +322,7 @@ module ActiveSupport
|
|
327
322
|
# ordinal(-11) # => "th"
|
328
323
|
# ordinal(-1021) # => "st"
|
329
324
|
def ordinal(number)
|
330
|
-
|
331
|
-
|
332
|
-
if (11..13).include?(abs_number % 100)
|
333
|
-
"th"
|
334
|
-
else
|
335
|
-
case abs_number % 10
|
336
|
-
when 1; "st"
|
337
|
-
when 2; "nd"
|
338
|
-
when 3; "rd"
|
339
|
-
else "th"
|
340
|
-
end
|
341
|
-
end
|
325
|
+
I18n.translate("number.nth.ordinals", number: number)
|
342
326
|
end
|
343
327
|
|
344
328
|
# Turns a number into an ordinal string used to denote the position in an
|
@@ -351,36 +335,38 @@ module ActiveSupport
|
|
351
335
|
# ordinalize(-11) # => "-11th"
|
352
336
|
# ordinalize(-1021) # => "-1021st"
|
353
337
|
def ordinalize(number)
|
354
|
-
"
|
338
|
+
I18n.translate("number.nth.ordinalized", number: number)
|
355
339
|
end
|
356
340
|
|
357
341
|
private
|
358
|
-
|
359
342
|
# Mounts a regular expression, returned as a string to ease interpolation,
|
360
343
|
# that will match part by part the given constant.
|
361
344
|
#
|
362
345
|
# const_regexp("Foo::Bar::Baz") # => "Foo(::Bar(::Baz)?)?"
|
363
346
|
# const_regexp("::") # => "::"
|
364
347
|
def const_regexp(camel_cased_word)
|
365
|
-
parts = camel_cased_word.split("::"
|
348
|
+
parts = camel_cased_word.split("::")
|
366
349
|
|
367
350
|
return Regexp.escape(camel_cased_word) if parts.blank?
|
368
351
|
|
369
352
|
last = parts.pop
|
370
353
|
|
371
|
-
parts.reverse
|
354
|
+
parts.reverse!.inject(last) do |acc, part|
|
372
355
|
part.empty? ? acc : "#{part}(::#{acc})?"
|
373
356
|
end
|
374
357
|
end
|
375
358
|
|
376
359
|
# Applies inflection rules for +singularize+ and +pluralize+.
|
377
360
|
#
|
378
|
-
#
|
379
|
-
#
|
380
|
-
|
361
|
+
# If passed an optional +locale+ parameter, the uncountables will be
|
362
|
+
# found for that locale.
|
363
|
+
#
|
364
|
+
# apply_inflections('post', inflections.plurals, :en) # => "posts"
|
365
|
+
# apply_inflections('posts', inflections.singulars, :en) # => "post"
|
366
|
+
def apply_inflections(word, rules, locale = :en)
|
381
367
|
result = word.to_s.dup
|
382
368
|
|
383
|
-
if word.empty? || inflections.uncountables.uncountable?(result)
|
369
|
+
if word.empty? || inflections(locale).uncountables.uncountable?(result)
|
384
370
|
result
|
385
371
|
else
|
386
372
|
rules.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
|
@@ -1,8 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/string/multibyte"
|
2
4
|
require "active_support/i18n"
|
3
5
|
|
4
6
|
module ActiveSupport
|
5
7
|
module Inflector
|
8
|
+
ALLOWED_ENCODINGS_FOR_TRANSLITERATE = [Encoding::UTF_8, Encoding::US_ASCII, Encoding::GB18030].freeze
|
9
|
+
|
6
10
|
# Replaces non-ASCII characters with an ASCII approximation, or if none
|
7
11
|
# exists, a replacement character which defaults to "?".
|
8
12
|
#
|
@@ -49,46 +53,80 @@ module ActiveSupport
|
|
49
53
|
#
|
50
54
|
# Now you can have different transliterations for each locale:
|
51
55
|
#
|
52
|
-
#
|
53
|
-
# transliterate('Jürgen')
|
56
|
+
# transliterate('Jürgen', locale: :en)
|
54
57
|
# # => "Jurgen"
|
55
58
|
#
|
56
|
-
#
|
57
|
-
# transliterate('Jürgen')
|
59
|
+
# transliterate('Jürgen', locale: :de)
|
58
60
|
# # => "Juergen"
|
59
|
-
|
61
|
+
#
|
62
|
+
# Transliteration is restricted to UTF-8, US-ASCII, and GB18030 strings.
|
63
|
+
# Other encodings will raise an ArgumentError.
|
64
|
+
def transliterate(string, replacement = "?", locale: nil)
|
65
|
+
string = string.dup if string.frozen?
|
60
66
|
raise ArgumentError, "Can only transliterate strings. Received #{string.class.name}" unless string.is_a?(String)
|
67
|
+
raise ArgumentError, "Cannot transliterate strings with #{string.encoding} encoding" unless ALLOWED_ENCODINGS_FOR_TRANSLITERATE.include?(string.encoding)
|
68
|
+
|
69
|
+
input_encoding = string.encoding
|
70
|
+
|
71
|
+
# US-ASCII is a subset of UTF-8 so we'll force encoding as UTF-8 if
|
72
|
+
# US-ASCII is given. This way we can let tidy_bytes handle the string
|
73
|
+
# in the same way as we do for UTF-8
|
74
|
+
string.force_encoding(Encoding::UTF_8) if string.encoding == Encoding::US_ASCII
|
61
75
|
|
62
|
-
|
63
|
-
|
64
|
-
|
76
|
+
# GB18030 is Unicode compatible but is not a direct mapping so needs to be
|
77
|
+
# transcoded. Using invalid/undef :replace will result in loss of data in
|
78
|
+
# the event of invalid characters, but since tidy_bytes will replace
|
79
|
+
# invalid/undef with a "?" we're safe to do the same beforehand
|
80
|
+
string.encode!(Encoding::UTF_8, invalid: :replace, undef: :replace) if string.encoding == Encoding::GB18030
|
81
|
+
|
82
|
+
transliterated = I18n.transliterate(
|
83
|
+
ActiveSupport::Multibyte::Unicode.tidy_bytes(string).unicode_normalize(:nfc),
|
84
|
+
replacement: replacement,
|
85
|
+
locale: locale
|
86
|
+
)
|
87
|
+
|
88
|
+
# Restore the string encoding of the input if it was not UTF-8.
|
89
|
+
# Apply invalid/undef :replace as tidy_bytes does
|
90
|
+
transliterated.encode!(input_encoding, invalid: :replace, undef: :replace) if input_encoding != transliterated.encoding
|
91
|
+
|
92
|
+
transliterated
|
65
93
|
end
|
66
94
|
|
67
95
|
# Replaces special characters in a string so that it may be used as part of
|
68
96
|
# a 'pretty' URL.
|
69
97
|
#
|
70
98
|
# parameterize("Donald E. Knuth") # => "donald-e-knuth"
|
71
|
-
# parameterize("^
|
99
|
+
# parameterize("^très|Jolie-- ") # => "tres-jolie"
|
72
100
|
#
|
73
|
-
# To use a custom separator, override the
|
101
|
+
# To use a custom separator, override the +separator+ argument.
|
74
102
|
#
|
75
|
-
#
|
76
|
-
#
|
103
|
+
# parameterize("Donald E. Knuth", separator: '_') # => "donald_e_knuth"
|
104
|
+
# parameterize("^très|Jolie__ ", separator: '_') # => "tres_jolie"
|
77
105
|
#
|
78
|
-
# To preserve the case of the characters in a string, use the
|
106
|
+
# To preserve the case of the characters in a string, use the +preserve_case+ argument.
|
79
107
|
#
|
80
108
|
# parameterize("Donald E. Knuth", preserve_case: true) # => "Donald-E-Knuth"
|
81
|
-
# parameterize("^
|
109
|
+
# parameterize("^très|Jolie-- ", preserve_case: true) # => "tres-Jolie"
|
110
|
+
#
|
111
|
+
# It preserves dashes and underscores unless they are used as separators:
|
112
|
+
#
|
113
|
+
# parameterize("^très|Jolie__ ") # => "tres-jolie__"
|
114
|
+
# parameterize("^très|Jolie-- ", separator: "_") # => "tres_jolie--"
|
115
|
+
# parameterize("^très_Jolie-- ", separator: ".") # => "tres_jolie--"
|
82
116
|
#
|
83
|
-
|
117
|
+
# If the optional parameter +locale+ is specified,
|
118
|
+
# the word will be parameterized as a word of that language.
|
119
|
+
# By default, this parameter is set to <tt>nil</tt> and it will use
|
120
|
+
# the configured <tt>I18n.locale</tt>.
|
121
|
+
def parameterize(string, separator: "-", preserve_case: false, locale: nil)
|
84
122
|
# Replace accented chars with their ASCII equivalents.
|
85
|
-
parameterized_string = transliterate(string)
|
123
|
+
parameterized_string = transliterate(string, locale: locale)
|
86
124
|
|
87
125
|
# Turn unwanted chars into the separator.
|
88
126
|
parameterized_string.gsub!(/[^a-z0-9\-_]+/i, separator)
|
89
127
|
|
90
128
|
unless separator.nil? || separator.empty?
|
91
|
-
if separator == "-"
|
129
|
+
if separator == "-"
|
92
130
|
re_duplicate_separator = /-{2,}/
|
93
131
|
re_leading_trailing_separator = /^-|-$/i
|
94
132
|
else
|
@@ -99,7 +137,7 @@ module ActiveSupport
|
|
99
137
|
# No more than one of the separator in a row.
|
100
138
|
parameterized_string.gsub!(re_duplicate_separator, separator)
|
101
139
|
# Remove leading/trailing separator.
|
102
|
-
parameterized_string.gsub!(re_leading_trailing_separator, ""
|
140
|
+
parameterized_string.gsub!(re_leading_trailing_separator, "")
|
103
141
|
end
|
104
142
|
|
105
143
|
parameterized_string.downcase! unless preserve_case
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "fiber"
|
4
|
+
|
5
|
+
module ActiveSupport
|
6
|
+
module IsolatedExecutionState # :nodoc:
|
7
|
+
@isolation_level = :thread
|
8
|
+
|
9
|
+
Thread.attr_accessor :active_support_execution_state
|
10
|
+
Fiber.attr_accessor :active_support_execution_state
|
11
|
+
|
12
|
+
class << self
|
13
|
+
attr_reader :isolation_level
|
14
|
+
|
15
|
+
def isolation_level=(level)
|
16
|
+
unless %i(thread fiber).include?(level)
|
17
|
+
raise ArgumentError, "isolation_level must be `:thread` or `:fiber`, got: `#{level.inspect}`"
|
18
|
+
end
|
19
|
+
|
20
|
+
if level != isolation_level
|
21
|
+
clear
|
22
|
+
singleton_class.alias_method(:current, "current_#{level}")
|
23
|
+
singleton_class.send(:private, :current)
|
24
|
+
@isolation_level = level
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def unique_id
|
29
|
+
self[:__id__] ||= Object.new
|
30
|
+
end
|
31
|
+
|
32
|
+
def [](key)
|
33
|
+
current[key]
|
34
|
+
end
|
35
|
+
|
36
|
+
def []=(key, value)
|
37
|
+
current[key] = value
|
38
|
+
end
|
39
|
+
|
40
|
+
def key?(key)
|
41
|
+
current.key?(key)
|
42
|
+
end
|
43
|
+
|
44
|
+
def delete(key)
|
45
|
+
current.delete(key)
|
46
|
+
end
|
47
|
+
|
48
|
+
def clear
|
49
|
+
current.clear
|
50
|
+
end
|
51
|
+
|
52
|
+
def share_with(other)
|
53
|
+
# Action Controller streaming spawns a new thread and copy thread locals.
|
54
|
+
# We do the same here for backward compatibility, but this is very much a hack
|
55
|
+
# and streaming should be rethought.
|
56
|
+
context = @isolation_level == :thread ? Thread.current : Fiber.current
|
57
|
+
context.active_support_execution_state = other.active_support_execution_state.dup
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
def current_thread
|
62
|
+
Thread.current.active_support_execution_state ||= {}
|
63
|
+
end
|
64
|
+
|
65
|
+
def current_fiber
|
66
|
+
Fiber.current.active_support_execution_state ||= {}
|
67
|
+
end
|
68
|
+
|
69
|
+
alias_method :current, :current_thread
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/module/attribute_accessors"
|
2
4
|
require "active_support/core_ext/module/delegation"
|
3
5
|
require "json"
|
@@ -8,8 +10,8 @@ module ActiveSupport
|
|
8
10
|
|
9
11
|
module JSON
|
10
12
|
# matches YAML-formatted dates
|
11
|
-
DATE_REGEX =
|
12
|
-
DATETIME_REGEX =
|
13
|
+
DATE_REGEX = /\A\d{4}-\d{2}-\d{2}\z/
|
14
|
+
DATETIME_REGEX = /\A(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?)?)\z/
|
13
15
|
|
14
16
|
class << self
|
15
17
|
# Parses a JSON string (JavaScript Object Notation) into a hash.
|
@@ -42,33 +44,32 @@ module ActiveSupport
|
|
42
44
|
end
|
43
45
|
|
44
46
|
private
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
47
|
+
def convert_dates_from(data)
|
48
|
+
case data
|
49
|
+
when nil
|
50
|
+
nil
|
51
|
+
when DATE_REGEX
|
52
|
+
begin
|
53
|
+
Date.parse(data)
|
54
|
+
rescue ArgumentError
|
55
|
+
data
|
56
|
+
end
|
57
|
+
when DATETIME_REGEX
|
58
|
+
begin
|
59
|
+
Time.zone.parse(data)
|
60
|
+
rescue ArgumentError
|
61
|
+
data
|
62
|
+
end
|
63
|
+
when Array
|
64
|
+
data.map! { |d| convert_dates_from(d) }
|
65
|
+
when Hash
|
66
|
+
data.transform_values! do |value|
|
67
|
+
convert_dates_from(value)
|
68
|
+
end
|
69
|
+
else
|
60
70
|
data
|
61
71
|
end
|
62
|
-
when Array
|
63
|
-
data.map! { |d| convert_dates_from(d) }
|
64
|
-
when Hash
|
65
|
-
data.each do |key, value|
|
66
|
-
data[key] = convert_dates_from(value)
|
67
|
-
end
|
68
|
-
else
|
69
|
-
data
|
70
72
|
end
|
71
|
-
end
|
72
73
|
end
|
73
74
|
end
|
74
75
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/object/json"
|
2
4
|
require "active_support/core_ext/module/delegation"
|
3
5
|
|
@@ -20,8 +22,8 @@ module ActiveSupport
|
|
20
22
|
Encoding.json_encoder.new(options).encode(value)
|
21
23
|
end
|
22
24
|
|
23
|
-
module Encoding
|
24
|
-
class JSONGemEncoder
|
25
|
+
module Encoding # :nodoc:
|
26
|
+
class JSONGemEncoder # :nodoc:
|
25
27
|
attr_reader :options
|
26
28
|
|
27
29
|
def initialize(options = nil)
|
@@ -49,12 +51,16 @@ module ActiveSupport
|
|
49
51
|
ESCAPE_REGEX_WITHOUT_HTML_ENTITIES = /[\u2028\u2029]/u
|
50
52
|
|
51
53
|
# This class wraps all the strings we see and does the extra escaping
|
52
|
-
class EscapedString < String
|
54
|
+
class EscapedString < String # :nodoc:
|
53
55
|
def to_json(*)
|
54
56
|
if Encoding.escape_html_entities_in_json
|
55
|
-
|
57
|
+
s = super
|
58
|
+
s.gsub! ESCAPE_REGEX_WITH_HTML_ENTITIES, ESCAPED_CHARS
|
59
|
+
s
|
56
60
|
else
|
57
|
-
|
61
|
+
s = super
|
62
|
+
s.gsub! ESCAPE_REGEX_WITHOUT_HTML_ENTITIES, ESCAPED_CHARS
|
63
|
+
s
|
58
64
|
end
|
59
65
|
end
|
60
66
|
|
@@ -87,7 +93,11 @@ module ActiveSupport
|
|
87
93
|
when Numeric, NilClass, TrueClass, FalseClass
|
88
94
|
value.as_json
|
89
95
|
when Hash
|
90
|
-
|
96
|
+
result = {}
|
97
|
+
value.each do |k, v|
|
98
|
+
result[jsonify(k)] = jsonify(v)
|
99
|
+
end
|
100
|
+
result
|
91
101
|
when Array
|
92
102
|
value.map { |v| jsonify(v) }
|
93
103
|
else
|
data/lib/active_support/json.rb
CHANGED