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
data/lib/active_support/gzip.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
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"
|
5
|
+
require "active_support/core_ext/hash/except"
|
6
|
+
require "active_support/core_ext/hash/slice"
|
3
7
|
|
4
8
|
module ActiveSupport
|
5
9
|
# Implements a hash where keys <tt>:foo</tt> and <tt>"foo"</tt> are considered
|
@@ -61,14 +65,16 @@ module ActiveSupport
|
|
61
65
|
self
|
62
66
|
end
|
63
67
|
|
64
|
-
def initialize(constructor =
|
68
|
+
def initialize(constructor = nil)
|
65
69
|
if constructor.respond_to?(:to_hash)
|
66
70
|
super()
|
67
71
|
update(constructor)
|
68
72
|
|
69
|
-
hash = constructor.to_hash
|
73
|
+
hash = constructor.is_a?(Hash) ? constructor : constructor.to_hash
|
70
74
|
self.default = hash.default if hash.default
|
71
75
|
self.default_proc = hash.default_proc if hash.default_proc
|
76
|
+
elsif constructor.nil?
|
77
|
+
super()
|
72
78
|
else
|
73
79
|
super(constructor)
|
74
80
|
end
|
@@ -88,12 +94,12 @@ module ActiveSupport
|
|
88
94
|
#
|
89
95
|
# This value can be later fetched using either +:key+ or <tt>'key'</tt>.
|
90
96
|
def []=(key, value)
|
91
|
-
regular_writer(convert_key(key), convert_value(value,
|
97
|
+
regular_writer(convert_key(key), convert_value(value, conversion: :assignment))
|
92
98
|
end
|
93
99
|
|
94
100
|
alias_method :store, :[]=
|
95
101
|
|
96
|
-
# Updates the receiver in-place, merging in the
|
102
|
+
# Updates the receiver in-place, merging in the hashes passed as arguments:
|
97
103
|
#
|
98
104
|
# hash_1 = ActiveSupport::HashWithIndifferentAccess.new
|
99
105
|
# hash_1[:key] = 'value'
|
@@ -103,11 +109,14 @@ module ActiveSupport
|
|
103
109
|
#
|
104
110
|
# hash_1.update(hash_2) # => {"key"=>"New Value!"}
|
105
111
|
#
|
106
|
-
#
|
112
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
113
|
+
# hash.update({ "a" => 1 }, { "b" => 2 }) # => { "a" => 1, "b" => 2 }
|
114
|
+
#
|
115
|
+
# The arguments can be either an
|
107
116
|
# <tt>ActiveSupport::HashWithIndifferentAccess</tt> or a regular +Hash+.
|
108
117
|
# In either case the merge respects the semantics of indifferent access.
|
109
118
|
#
|
110
|
-
# If the argument is a regular hash with keys +:key+ and
|
119
|
+
# If the argument is a regular hash with keys +:key+ and <tt>"key"</tt> only one
|
111
120
|
# of the values end up in the receiver, but which one is unspecified.
|
112
121
|
#
|
113
122
|
# When given a block, the value for duplicated keys will be determined
|
@@ -118,18 +127,15 @@ module ActiveSupport
|
|
118
127
|
# hash_1[:key] = 10
|
119
128
|
# hash_2['key'] = 12
|
120
129
|
# hash_1.update(hash_2) { |key, old, new| old + new } # => {"key"=>22}
|
121
|
-
def update(
|
122
|
-
if
|
123
|
-
|
130
|
+
def update(*other_hashes, &block)
|
131
|
+
if other_hashes.size == 1
|
132
|
+
update_with_single_argument(other_hashes.first, block)
|
124
133
|
else
|
125
|
-
|
126
|
-
|
127
|
-
value = yield(convert_key(key), self[key], value)
|
128
|
-
end
|
129
|
-
regular_writer(convert_key(key), convert_value(value))
|
134
|
+
other_hashes.each do |other_hash|
|
135
|
+
update_with_single_argument(other_hash, block)
|
130
136
|
end
|
131
|
-
self
|
132
137
|
end
|
138
|
+
self
|
133
139
|
end
|
134
140
|
|
135
141
|
alias_method :merge!, :update
|
@@ -161,6 +167,19 @@ module ActiveSupport
|
|
161
167
|
super(convert_key(key))
|
162
168
|
end
|
163
169
|
|
170
|
+
# Same as <tt>Hash#assoc</tt> where the key passed as argument can be
|
171
|
+
# either a string or a symbol:
|
172
|
+
#
|
173
|
+
# counters = ActiveSupport::HashWithIndifferentAccess.new
|
174
|
+
# counters[:foo] = 1
|
175
|
+
#
|
176
|
+
# counters.assoc('foo') # => ["foo", 1]
|
177
|
+
# counters.assoc(:foo) # => ["foo", 1]
|
178
|
+
# counters.assoc(:zoo) # => nil
|
179
|
+
def assoc(key)
|
180
|
+
super(convert_key(key))
|
181
|
+
end
|
182
|
+
|
164
183
|
# Same as <tt>Hash#fetch</tt> where the key passed as argument can be
|
165
184
|
# either a string or a symbol:
|
166
185
|
#
|
@@ -175,20 +194,18 @@ module ActiveSupport
|
|
175
194
|
super(convert_key(key), *extras)
|
176
195
|
end
|
177
196
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
super(*args)
|
191
|
-
end
|
197
|
+
# Same as <tt>Hash#dig</tt> where the key passed as argument can be
|
198
|
+
# either a string or a symbol:
|
199
|
+
#
|
200
|
+
# counters = ActiveSupport::HashWithIndifferentAccess.new
|
201
|
+
# counters[:foo] = { bar: 1 }
|
202
|
+
#
|
203
|
+
# counters.dig('foo', 'bar') # => 1
|
204
|
+
# counters.dig(:foo, :bar) # => 1
|
205
|
+
# counters.dig(:zoo) # => nil
|
206
|
+
def dig(*args)
|
207
|
+
args[0] = convert_key(args[0]) if args.size > 0
|
208
|
+
super(*args)
|
192
209
|
end
|
193
210
|
|
194
211
|
# Same as <tt>Hash#default</tt> where the key passed as argument can be
|
@@ -211,8 +228,21 @@ module ActiveSupport
|
|
211
228
|
# hash[:a] = 'x'
|
212
229
|
# hash[:b] = 'y'
|
213
230
|
# hash.values_at('a', 'b') # => ["x", "y"]
|
214
|
-
def values_at(*
|
215
|
-
|
231
|
+
def values_at(*keys)
|
232
|
+
super(*keys.map { |key| convert_key(key) })
|
233
|
+
end
|
234
|
+
|
235
|
+
# Returns an array of the values at the specified indices, but also
|
236
|
+
# raises an exception when one of the keys can't be found.
|
237
|
+
#
|
238
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
239
|
+
# hash[:a] = 'x'
|
240
|
+
# hash[:b] = 'y'
|
241
|
+
# hash.fetch_values('a', 'b') # => ["x", "y"]
|
242
|
+
# hash.fetch_values('a', 'c') { |key| 'z' } # => ["x", "z"]
|
243
|
+
# hash.fetch_values('a', 'c') # => KeyError: key not found: "c"
|
244
|
+
def fetch_values(*indices, &block)
|
245
|
+
super(*indices.map { |key| convert_key(key) }, &block)
|
216
246
|
end
|
217
247
|
|
218
248
|
# Returns a shallow copy of the hash.
|
@@ -232,8 +262,8 @@ module ActiveSupport
|
|
232
262
|
# This method has the same semantics of +update+, except it does not
|
233
263
|
# modify the receiver but rather returns a new hash with indifferent
|
234
264
|
# access with the result of the merge.
|
235
|
-
def merge(
|
236
|
-
dup.update(
|
265
|
+
def merge(*hashes, &block)
|
266
|
+
dup.update(*hashes, &block)
|
237
267
|
end
|
238
268
|
|
239
269
|
# Like +merge+ but the other way around: Merges the receiver into the
|
@@ -245,11 +275,13 @@ module ActiveSupport
|
|
245
275
|
def reverse_merge(other_hash)
|
246
276
|
super(self.class.new(other_hash))
|
247
277
|
end
|
278
|
+
alias_method :with_defaults, :reverse_merge
|
248
279
|
|
249
280
|
# Same semantics as +reverse_merge+ but modifies the receiver in-place.
|
250
281
|
def reverse_merge!(other_hash)
|
251
|
-
|
282
|
+
super(self.class.new(other_hash))
|
252
283
|
end
|
284
|
+
alias_method :with_defaults!, :reverse_merge!
|
253
285
|
|
254
286
|
# Replaces the contents of this hash with other_hash.
|
255
287
|
#
|
@@ -264,6 +296,15 @@ module ActiveSupport
|
|
264
296
|
super(convert_key(key))
|
265
297
|
end
|
266
298
|
|
299
|
+
# Returns a hash with indifferent access that includes everything except given keys.
|
300
|
+
# hash = { a: "x", b: "y", c: 10 }.with_indifferent_access
|
301
|
+
# hash.except(:a, "b") # => {c: 10}.with_indifferent_access
|
302
|
+
# hash # => { a: "x", b: "y", c: 10 }.with_indifferent_access
|
303
|
+
def except(*keys)
|
304
|
+
slice(*self.keys - keys.map { |key| convert_key(key) })
|
305
|
+
end
|
306
|
+
alias_method :without, :except
|
307
|
+
|
267
308
|
def stringify_keys!; self end
|
268
309
|
def deep_stringify_keys!; self end
|
269
310
|
def stringify_keys; dup end
|
@@ -271,6 +312,7 @@ module ActiveSupport
|
|
271
312
|
undef :symbolize_keys!
|
272
313
|
undef :deep_symbolize_keys!
|
273
314
|
def symbolize_keys; to_hash.symbolize_keys! end
|
315
|
+
alias_method :to_options, :symbolize_keys
|
274
316
|
def deep_symbolize_keys; to_hash.deep_symbolize_keys! end
|
275
317
|
def to_options!; self end
|
276
318
|
|
@@ -289,6 +331,29 @@ module ActiveSupport
|
|
289
331
|
dup.tap { |hash| hash.transform_values!(*args, &block) }
|
290
332
|
end
|
291
333
|
|
334
|
+
def transform_keys(*args, &block)
|
335
|
+
return to_enum(:transform_keys) unless block_given?
|
336
|
+
dup.tap { |hash| hash.transform_keys!(*args, &block) }
|
337
|
+
end
|
338
|
+
|
339
|
+
def transform_keys!
|
340
|
+
return enum_for(:transform_keys!) { size } unless block_given?
|
341
|
+
keys.each do |key|
|
342
|
+
self[yield(key)] = delete(key)
|
343
|
+
end
|
344
|
+
self
|
345
|
+
end
|
346
|
+
|
347
|
+
def slice(*keys)
|
348
|
+
keys.map! { |key| convert_key(key) }
|
349
|
+
self.class.new(super)
|
350
|
+
end
|
351
|
+
|
352
|
+
def slice!(*keys)
|
353
|
+
keys.map! { |key| convert_key(key) }
|
354
|
+
super
|
355
|
+
end
|
356
|
+
|
292
357
|
def compact
|
293
358
|
dup.tap(&:compact!)
|
294
359
|
end
|
@@ -299,40 +364,59 @@ module ActiveSupport
|
|
299
364
|
set_defaults(_new_hash)
|
300
365
|
|
301
366
|
each do |key, value|
|
302
|
-
_new_hash[key] = convert_value(value,
|
367
|
+
_new_hash[key] = convert_value(value, conversion: :to_hash)
|
303
368
|
end
|
304
369
|
_new_hash
|
305
370
|
end
|
306
371
|
|
307
372
|
private
|
308
|
-
|
309
|
-
key
|
373
|
+
if Symbol.method_defined?(:name)
|
374
|
+
def convert_key(key)
|
375
|
+
key.kind_of?(Symbol) ? key.name : key
|
376
|
+
end
|
377
|
+
else
|
378
|
+
def convert_key(key)
|
379
|
+
key.kind_of?(Symbol) ? key.to_s : key
|
380
|
+
end
|
310
381
|
end
|
311
382
|
|
312
|
-
def convert_value(value,
|
383
|
+
def convert_value(value, conversion: nil)
|
313
384
|
if value.is_a? Hash
|
314
|
-
if
|
385
|
+
if conversion == :to_hash
|
315
386
|
value.to_hash
|
316
387
|
else
|
317
388
|
value.nested_under_indifferent_access
|
318
389
|
end
|
319
390
|
elsif value.is_a?(Array)
|
320
|
-
if
|
391
|
+
if conversion != :assignment || value.frozen?
|
321
392
|
value = value.dup
|
322
393
|
end
|
323
|
-
value.map! { |e| convert_value(e,
|
394
|
+
value.map! { |e| convert_value(e, conversion: conversion) }
|
324
395
|
else
|
325
396
|
value
|
326
397
|
end
|
327
398
|
end
|
328
399
|
|
329
|
-
def set_defaults(target)
|
400
|
+
def set_defaults(target)
|
330
401
|
if default_proc
|
331
402
|
target.default_proc = default_proc.dup
|
332
403
|
else
|
333
404
|
target.default = default
|
334
405
|
end
|
335
406
|
end
|
407
|
+
|
408
|
+
def update_with_single_argument(other_hash, block)
|
409
|
+
if other_hash.is_a? HashWithIndifferentAccess
|
410
|
+
regular_update(other_hash, &block)
|
411
|
+
else
|
412
|
+
other_hash.to_hash.each_pair do |key, value|
|
413
|
+
if block && key?(key)
|
414
|
+
value = block.call(convert_key(key), self[key], value)
|
415
|
+
end
|
416
|
+
regular_writer(convert_key(key), convert_value(value))
|
417
|
+
end
|
418
|
+
end
|
419
|
+
end
|
336
420
|
end
|
337
421
|
end
|
338
422
|
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
module HtmlSafeTranslation # :nodoc:
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def translate(key, **options)
|
8
|
+
if html_safe_translation_key?(key)
|
9
|
+
html_safe_options = html_escape_translation_options(options)
|
10
|
+
translation = I18n.translate(key, **html_safe_options)
|
11
|
+
html_safe_translation(translation)
|
12
|
+
else
|
13
|
+
I18n.translate(key, **options)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
def html_safe_translation_key?(key)
|
19
|
+
/(?:_|\b)html\z/.match?(key)
|
20
|
+
end
|
21
|
+
|
22
|
+
def html_escape_translation_options(options)
|
23
|
+
options.each do |name, value|
|
24
|
+
unless i18n_option?(name) || (name == :count && value.is_a?(Numeric))
|
25
|
+
options[name] = ERB::Util.html_escape(value.to_s)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def i18n_option?(name)
|
31
|
+
(@i18n_option_names ||= I18n::RESERVED_KEYS.to_set).include?(name)
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
def html_safe_translation(translation)
|
36
|
+
if translation.respond_to?(:map)
|
37
|
+
translation.map { |element| element.respond_to?(:html_safe) ? element.html_safe : element }
|
38
|
+
else
|
39
|
+
translation.respond_to?(:html_safe) ? translation.html_safe : translation
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/active_support/i18n.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
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"
|
4
6
|
begin
|
5
7
|
require "i18n"
|
8
|
+
require "i18n/backend/fallbacks"
|
6
9
|
rescue LoadError => e
|
7
10
|
$stderr.puts "The i18n gem is not available. Please add it to your Gemfile and run bundle install"
|
8
11
|
raise e
|
@@ -10,4 +13,5 @@ end
|
|
10
13
|
require "active_support/lazy_load_hooks"
|
11
14
|
|
12
15
|
ActiveSupport.run_load_hooks(:i18n)
|
13
|
-
I18n.load_path <<
|
16
|
+
I18n.load_path << File.expand_path("locale/en.yml", __dir__)
|
17
|
+
I18n.load_path << File.expand_path("locale/en.rb", __dir__)
|
@@ -1,5 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support"
|
2
|
-
require "active_support/file_update_checker"
|
3
4
|
require "active_support/core_ext/array/wrap"
|
4
5
|
|
5
6
|
# :enddoc:
|
@@ -11,6 +12,8 @@ module I18n
|
|
11
12
|
config.i18n.load_path = []
|
12
13
|
config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
|
13
14
|
|
15
|
+
config.eager_load_namespaces << I18n
|
16
|
+
|
14
17
|
# Set the i18n configuration after initialization since a lot of
|
15
18
|
# configuration is still usually done in application initializers.
|
16
19
|
config.after_initialize do |app|
|
@@ -42,11 +45,13 @@ module I18n
|
|
42
45
|
case setting
|
43
46
|
when :railties_load_path
|
44
47
|
reloadable_paths = value
|
45
|
-
app.config.i18n.load_path.unshift(*value.
|
48
|
+
app.config.i18n.load_path.unshift(*value.flat_map(&:existent))
|
46
49
|
when :load_path
|
47
50
|
I18n.load_path += value
|
51
|
+
when :raise_on_missing_translations
|
52
|
+
forward_raise_on_missing_translations_config(app)
|
48
53
|
else
|
49
|
-
I18n.
|
54
|
+
I18n.public_send("#{setting}=", value)
|
50
55
|
end
|
51
56
|
end
|
52
57
|
|
@@ -58,24 +63,28 @@ module I18n
|
|
58
63
|
directories = watched_dirs_with_extensions(reloadable_paths)
|
59
64
|
reloader = app.config.file_watcher.new(I18n.load_path.dup, directories) do
|
60
65
|
I18n.load_path.keep_if { |p| File.exist?(p) }
|
61
|
-
I18n.load_path |= reloadable_paths.
|
62
|
-
|
63
|
-
I18n.reload!
|
66
|
+
I18n.load_path |= reloadable_paths.flat_map(&:existent)
|
64
67
|
end
|
65
68
|
|
66
69
|
app.reloaders << reloader
|
67
70
|
app.reloader.to_run do
|
68
71
|
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
72
|
end
|
74
73
|
reloader.execute
|
75
74
|
|
76
75
|
@i18n_inited = true
|
77
76
|
end
|
78
77
|
|
78
|
+
def self.forward_raise_on_missing_translations_config(app)
|
79
|
+
ActiveSupport.on_load(:action_view) do
|
80
|
+
ActionView::Helpers::TranslationHelper.raise_on_missing_translations = app.config.i18n.raise_on_missing_translations
|
81
|
+
end
|
82
|
+
|
83
|
+
ActiveSupport.on_load(:action_controller) do
|
84
|
+
AbstractController::Translation.raise_on_missing_translations = app.config.i18n.raise_on_missing_translations
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
79
88
|
def self.include_fallbacks_module
|
80
89
|
I18n.backend.class.include(I18n::Backend::Fallbacks)
|
81
90
|
end
|
@@ -93,10 +102,6 @@ module I18n
|
|
93
102
|
[I18n.default_locale]
|
94
103
|
end
|
95
104
|
|
96
|
-
if args.empty? || args.first.is_a?(Hash)
|
97
|
-
args.unshift I18n.default_locale
|
98
|
-
end
|
99
|
-
|
100
105
|
I18n.fallbacks = I18n::Locale::Fallbacks.new(*args)
|
101
106
|
end
|
102
107
|
|
@@ -1,6 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "concurrent/map"
|
2
|
-
require "active_support/core_ext/array/prepend_and_append"
|
3
|
-
require "active_support/core_ext/regexp"
|
4
4
|
require "active_support/i18n"
|
5
5
|
|
6
6
|
module ActiveSupport
|
@@ -16,13 +16,13 @@ module ActiveSupport
|
|
16
16
|
# inflect.plural /^(ox)$/i, '\1\2en'
|
17
17
|
# inflect.singular /^(ox)en/i, '\1'
|
18
18
|
#
|
19
|
-
# inflect.irregular '
|
19
|
+
# inflect.irregular 'cactus', 'cacti'
|
20
20
|
#
|
21
21
|
# inflect.uncountable 'equipment'
|
22
22
|
# end
|
23
23
|
#
|
24
24
|
# New rules are added at the top. So in the example above, the irregular
|
25
|
-
# rule for
|
25
|
+
# rule for cactus will now be the first of the pluralization and
|
26
26
|
# singularization rules that is runs. This guarantees that your rules run
|
27
27
|
# before any of the rules that may already have been loaded.
|
28
28
|
class Inflections
|
@@ -64,17 +64,28 @@ module ActiveSupport
|
|
64
64
|
@__instance__[locale] ||= new
|
65
65
|
end
|
66
66
|
|
67
|
-
|
67
|
+
def self.instance_or_fallback(locale)
|
68
|
+
I18n.fallbacks[locale].each do |k|
|
69
|
+
return @__instance__[k] if @__instance__.key?(k)
|
70
|
+
end
|
71
|
+
instance(locale)
|
72
|
+
end
|
73
|
+
|
74
|
+
attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms
|
75
|
+
|
76
|
+
attr_reader :acronyms_camelize_regex, :acronyms_underscore_regex # :nodoc:
|
68
77
|
|
69
78
|
def initialize
|
70
|
-
@plurals, @singulars, @uncountables, @humans, @acronyms
|
79
|
+
@plurals, @singulars, @uncountables, @humans, @acronyms = [], [], Uncountables.new, [], {}
|
80
|
+
define_acronym_regex_patterns
|
71
81
|
end
|
72
82
|
|
73
83
|
# Private, for the test suite.
|
74
84
|
def initialize_dup(orig) # :nodoc:
|
75
|
-
%w(plurals singulars uncountables humans acronyms
|
76
|
-
instance_variable_set("@#{scope}", orig.
|
85
|
+
%w(plurals singulars uncountables humans acronyms).each do |scope|
|
86
|
+
instance_variable_set("@#{scope}", orig.public_send(scope).dup)
|
77
87
|
end
|
88
|
+
define_acronym_regex_patterns
|
78
89
|
end
|
79
90
|
|
80
91
|
# Specifies a new acronym. An acronym must be specified as it will appear
|
@@ -128,7 +139,7 @@ module ActiveSupport
|
|
128
139
|
# camelize 'mcdonald' # => 'McDonald'
|
129
140
|
def acronym(word)
|
130
141
|
@acronyms[word.downcase] = word
|
131
|
-
|
142
|
+
define_acronym_regex_patterns
|
132
143
|
end
|
133
144
|
|
134
145
|
# Specifies a new pluralization rule and its replacement. The rule can
|
@@ -156,7 +167,7 @@ module ActiveSupport
|
|
156
167
|
# regular expressions. You simply pass the irregular in singular and
|
157
168
|
# plural form.
|
158
169
|
#
|
159
|
-
# irregular '
|
170
|
+
# irregular 'cactus', 'cacti'
|
160
171
|
# irregular 'person', 'people'
|
161
172
|
def irregular(singular, plural)
|
162
173
|
@uncountables.delete(singular)
|
@@ -211,18 +222,34 @@ module ActiveSupport
|
|
211
222
|
# Clears the loaded inflections within a given scope (default is
|
212
223
|
# <tt>:all</tt>). Give the scope as a symbol of the inflection type, the
|
213
224
|
# options are: <tt>:plurals</tt>, <tt>:singulars</tt>, <tt>:uncountables</tt>,
|
214
|
-
# <tt>:humans</tt>.
|
225
|
+
# <tt>:humans</tt>, <tt>:acronyms</tt>.
|
215
226
|
#
|
216
227
|
# clear :all
|
217
228
|
# clear :plurals
|
218
229
|
def clear(scope = :all)
|
219
230
|
case scope
|
220
231
|
when :all
|
221
|
-
|
222
|
-
|
232
|
+
clear(:acronyms)
|
233
|
+
clear(:plurals)
|
234
|
+
clear(:singulars)
|
235
|
+
clear(:uncountables)
|
236
|
+
clear(:humans)
|
237
|
+
when :acronyms
|
238
|
+
@acronyms = {}
|
239
|
+
define_acronym_regex_patterns
|
240
|
+
when :uncountables
|
241
|
+
@uncountables = Uncountables.new
|
242
|
+
when :plurals, :singulars, :humans
|
223
243
|
instance_variable_set "@#{scope}", []
|
224
244
|
end
|
225
245
|
end
|
246
|
+
|
247
|
+
private
|
248
|
+
def define_acronym_regex_patterns
|
249
|
+
@acronym_regex = @acronyms.empty? ? /(?=a)b/ : /#{@acronyms.values.join("|")}/
|
250
|
+
@acronyms_camelize_regex = /^(?:#{@acronym_regex}(?=\b|[A-Z_])|\w)/
|
251
|
+
@acronyms_underscore_regex = /(?:(?<=([A-Za-z\d]))|\b)(#{@acronym_regex})(?=\b|[^a-z])/
|
252
|
+
end
|
226
253
|
end
|
227
254
|
|
228
255
|
# Yields a singleton instance of Inflector::Inflections so you can specify
|
@@ -237,7 +264,7 @@ module ActiveSupport
|
|
237
264
|
if block_given?
|
238
265
|
yield Inflections.instance(locale)
|
239
266
|
else
|
240
|
-
Inflections.
|
267
|
+
Inflections.instance_or_fallback(locale)
|
241
268
|
end
|
242
269
|
end
|
243
270
|
end
|