activesupport 4.2.11.1 → 6.0.3.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 +399 -411
- data/MIT-LICENSE +2 -2
- data/README.rdoc +7 -7
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/all.rb +5 -3
- data/lib/active_support/array_inquirer.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +34 -6
- data/lib/active_support/benchmarkable.rb +6 -4
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache/file_store.rb +58 -53
- data/lib/active_support/cache/mem_cache_store.rb +95 -91
- data/lib/active_support/cache/memory_store.rb +39 -36
- data/lib/active_support/cache/null_store.rb +11 -7
- data/lib/active_support/cache/redis_cache_store.rb +493 -0
- data/lib/active_support/cache/strategy/local_cache.rb +75 -42
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
- data/lib/active_support/cache.rb +331 -217
- data/lib/active_support/callbacks.rb +650 -592
- data/lib/active_support/concern.rb +35 -6
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
- data/lib/active_support/concurrency/share_lock.rb +226 -0
- data/lib/active_support/configurable.rb +13 -14
- data/lib/active_support/core_ext/array/access.rb +41 -1
- data/lib/active_support/core_ext/array/conversions.rb +24 -20
- 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 +11 -18
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +4 -6
- data/lib/active_support/core_ext/array/wrap.rb +7 -4
- data/lib/active_support/core_ext/array.rb +9 -6
- data/lib/active_support/core_ext/benchmark.rb +3 -1
- data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/class/attribute.rb +45 -31
- data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
- data/lib/active_support/core_ext/class/subclasses.rb +20 -6
- data/lib/active_support/core_ext/class.rb +4 -3
- data/lib/active_support/core_ext/date/acts_like.rb +3 -1
- data/lib/active_support/core_ext/date/blank.rb +14 -0
- data/lib/active_support/core_ext/date/calculations.rb +17 -14
- data/lib/active_support/core_ext/date/conversions.rb +25 -23
- data/lib/active_support/core_ext/date/zones.rb +4 -2
- data/lib/active_support/core_ext/date.rb +6 -4
- data/lib/active_support/core_ext/date_and_time/calculations.rb +154 -65
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +4 -3
- data/lib/active_support/core_ext/date_and_time/zones.rb +12 -13
- data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
- data/lib/active_support/core_ext/date_time/blank.rb +14 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +37 -19
- data/lib/active_support/core_ext/date_time/compatibility.rb +8 -6
- data/lib/active_support/core_ext/date_time/conversions.rb +16 -13
- data/lib/active_support/core_ext/date_time.rb +7 -5
- data/lib/active_support/core_ext/digest/uuid.rb +7 -5
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +114 -22
- data/lib/active_support/core_ext/file/atomic.rb +38 -31
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/hash/compact.rb +4 -23
- data/lib/active_support/core_ext/hash/conversions.rb +62 -41
- data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +12 -9
- data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
- data/lib/active_support/core_ext/hash/keys.rb +19 -42
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +5 -27
- data/lib/active_support/core_ext/hash/transform_values.rb +4 -22
- data/lib/active_support/core_ext/hash.rb +10 -9
- data/lib/active_support/core_ext/integer/inflections.rb +3 -1
- data/lib/active_support/core_ext/integer/multiple.rb +3 -1
- data/lib/active_support/core_ext/integer/time.rb +11 -18
- data/lib/active_support/core_ext/integer.rb +5 -3
- data/lib/active_support/core_ext/kernel/concern.rb +5 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +5 -5
- data/lib/active_support/core_ext/load_error.rb +3 -22
- data/lib/active_support/core_ext/marshal.rb +8 -8
- data/lib/active_support/core_ext/module/aliasing.rb +6 -44
- data/lib/active_support/core_ext/module/anonymous.rb +12 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
- data/lib/active_support/core_ext/module/attribute_accessors.rb +46 -46
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +144 -0
- data/lib/active_support/core_ext/module/concerning.rb +11 -12
- data/lib/active_support/core_ext/module/delegation.rb +133 -30
- data/lib/active_support/core_ext/module/deprecation.rb +4 -2
- data/lib/active_support/core_ext/module/introspection.rb +44 -19
- data/lib/active_support/core_ext/module/reachable.rb +5 -7
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +8 -3
- data/lib/active_support/core_ext/module.rb +13 -11
- data/lib/active_support/core_ext/name_error.rb +22 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +129 -136
- data/lib/active_support/core_ext/numeric/inquiry.rb +5 -0
- data/lib/active_support/core_ext/numeric/time.rb +35 -23
- data/lib/active_support/core_ext/numeric.rb +5 -3
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +27 -3
- data/lib/active_support/core_ext/object/conversions.rb +6 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
- data/lib/active_support/core_ext/object/duplicable.rb +13 -93
- data/lib/active_support/core_ext/object/inclusion.rb +5 -3
- data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
- data/lib/active_support/core_ext/object/json.rb +51 -20
- data/lib/active_support/core_ext/object/to_param.rb +3 -1
- data/lib/active_support/core_ext/object/to_query.rb +10 -5
- data/lib/active_support/core_ext/object/try.rb +81 -23
- data/lib/active_support/core_ext/object/with_options.rb +16 -3
- data/lib/active_support/core_ext/object.rb +14 -13
- data/lib/active_support/core_ext/range/compare_range.rb +76 -0
- data/lib/active_support/core_ext/range/conversions.rb +37 -15
- data/lib/active_support/core_ext/range/each.rb +18 -17
- data/lib/active_support/core_ext/range/include_range.rb +7 -21
- 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/range.rb +7 -4
- data/lib/active_support/core_ext/regexp.rb +2 -0
- data/lib/active_support/core_ext/securerandom.rb +45 -0
- data/lib/active_support/core_ext/string/access.rb +16 -6
- data/lib/active_support/core_ext/string/behavior.rb +3 -1
- data/lib/active_support/core_ext/string/conversions.rb +7 -4
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +48 -6
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +66 -24
- data/lib/active_support/core_ext/string/inquiry.rb +3 -1
- data/lib/active_support/core_ext/string/multibyte.rb +16 -7
- data/lib/active_support/core_ext/string/output_safety.rb +93 -40
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
- data/lib/active_support/core_ext/string/strip.rb +6 -5
- data/lib/active_support/core_ext/string/zones.rb +4 -2
- data/lib/active_support/core_ext/string.rb +15 -13
- data/lib/active_support/core_ext/time/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +115 -52
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- data/lib/active_support/core_ext/time/conversions.rb +20 -13
- data/lib/active_support/core_ext/time/zones.rb +41 -7
- data/lib/active_support/core_ext/time.rb +7 -6
- data/lib/active_support/core_ext/uri.rb +6 -7
- data/lib/active_support/core_ext.rb +3 -1
- data/lib/active_support/current_attributes.rb +203 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +57 -0
- data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
- data/lib/active_support/dependencies.rb +208 -166
- data/lib/active_support/deprecation/behaviors.rb +44 -11
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/instance_delegator.rb +17 -2
- data/lib/active_support/deprecation/method_wrappers.rb +61 -21
- data/lib/active_support/deprecation/proxy_wrappers.rb +81 -30
- data/lib/active_support/deprecation/reporting.rb +32 -12
- data/lib/active_support/deprecation.rb +12 -9
- data/lib/active_support/descendants_tracker.rb +57 -9
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration/iso8601_parser.rb +123 -0
- data/lib/active_support/duration/iso8601_serializer.rb +53 -0
- data/lib/active_support/duration.rb +315 -40
- data/lib/active_support/encrypted_configuration.rb +45 -0
- data/lib/active_support/encrypted_file.rb +100 -0
- data/lib/active_support/evented_file_update_checker.rb +234 -0
- data/lib/active_support/execution_wrapper.rb +129 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +62 -37
- data/lib/active_support/gem_version.rb +6 -4
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +129 -30
- data/lib/active_support/i18n.rb +9 -6
- data/lib/active_support/i18n_railtie.rb +50 -14
- data/lib/active_support/inflections.rb +13 -11
- data/lib/active_support/inflector/inflections.rb +58 -13
- data/lib/active_support/inflector/methods.rb +159 -145
- data/lib/active_support/inflector/transliterate.rb +84 -34
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/json/decoding.rb +32 -30
- data/lib/active_support/json/encoding.rb +17 -60
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/key_generator.rb +11 -43
- data/lib/active_support/lazy_load_hooks.rb +53 -20
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber/test_helper.rb +14 -12
- data/lib/active_support/log_subscriber.rb +44 -19
- data/lib/active_support/logger.rb +9 -23
- data/lib/active_support/logger_silence.rb +32 -14
- data/lib/active_support/logger_thread_safe_level.rb +32 -8
- data/lib/active_support/message_encryptor.rb +166 -53
- data/lib/active_support/message_verifier.rb +149 -16
- data/lib/active_support/messages/metadata.rb +72 -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/chars.rb +56 -63
- data/lib/active_support/multibyte/unicode.rb +56 -290
- data/lib/active_support/multibyte.rb +4 -2
- data/lib/active_support/notifications/fanout.rb +109 -22
- data/lib/active_support/notifications/instrumenter.rb +107 -16
- data/lib/active_support/notifications.rb +51 -10
- data/lib/active_support/number_helper/number_converter.rb +16 -15
- data/lib/active_support/number_helper/number_to_currency_converter.rb +14 -15
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +11 -4
- data/lib/active_support/number_helper/number_to_human_converter.rb +13 -10
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +11 -9
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +15 -5
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +25 -57
- data/lib/active_support/number_helper/rounding_helper.rb +66 -0
- data/lib/active_support/number_helper.rb +105 -68
- data/lib/active_support/option_merger.rb +24 -4
- data/lib/active_support/ordered_hash.rb +7 -5
- data/lib/active_support/ordered_options.rb +27 -5
- data/lib/active_support/parameter_filter.rb +128 -0
- data/lib/active_support/per_thread_registry.rb +9 -4
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +10 -8
- data/lib/active_support/railtie.rb +43 -9
- data/lib/active_support/reloader.rb +130 -0
- data/lib/active_support/rescuable.rb +108 -53
- data/lib/active_support/security_utils.rb +15 -11
- data/lib/active_support/string_inquirer.rb +11 -4
- data/lib/active_support/subscriber.rb +74 -30
- data/lib/active_support/tagged_logging.rb +25 -13
- data/lib/active_support/test_case.rb +107 -44
- data/lib/active_support/testing/assertions.rb +151 -20
- data/lib/active_support/testing/autorun.rb +4 -2
- data/lib/active_support/testing/constant_lookup.rb +2 -1
- data/lib/active_support/testing/declarative.rb +3 -1
- data/lib/active_support/testing/deprecation.rb +13 -10
- data/lib/active_support/testing/file_fixtures.rb +38 -0
- data/lib/active_support/testing/isolation.rb +35 -26
- data/lib/active_support/testing/method_call_assertions.rb +70 -0
- data/lib/active_support/testing/parallelization.rb +134 -0
- data/lib/active_support/testing/setup_and_teardown.rb +13 -8
- data/lib/active_support/testing/stream.rb +43 -0
- data/lib/active_support/testing/tagged_logging.rb +3 -1
- data/lib/active_support/testing/time_helpers.rb +84 -20
- data/lib/active_support/time.rb +14 -12
- data/lib/active_support/time_with_zone.rb +179 -39
- data/lib/active_support/values/time_zone.rb +203 -63
- data/lib/active_support/version.rb +3 -1
- data/lib/active_support/xml_mini/jdom.rb +116 -115
- data/lib/active_support/xml_mini/libxml.rb +16 -13
- data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
- data/lib/active_support/xml_mini/nokogiri.rb +14 -12
- data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
- data/lib/active_support/xml_mini/rexml.rb +11 -9
- data/lib/active_support/xml_mini.rb +38 -46
- data/lib/active_support.rb +13 -11
- metadata +84 -26
- data/lib/active_support/concurrency/latch.rb +0 -27
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
- data/lib/active_support/core_ext/date_time/zones.rb +0 -6
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
- data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
- data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
- data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
- data/lib/active_support/core_ext/object/itself.rb +0 -15
- data/lib/active_support/core_ext/struct.rb +0 -6
- data/lib/active_support/core_ext/thread.rb +0 -86
- data/lib/active_support/core_ext/time/marshal.rb +0 -30
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,5 +1,8 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/hash/keys"
|
4
|
+
require "active_support/core_ext/hash/reverse_merge"
|
5
|
+
require "active_support/core_ext/hash/except"
|
3
6
|
|
4
7
|
module ActiveSupport
|
5
8
|
# Implements a hash where keys <tt>:foo</tt> and <tt>"foo"</tt> are considered
|
@@ -40,6 +43,12 @@ module ActiveSupport
|
|
40
43
|
# rgb = { black: '#000000', white: '#FFFFFF' }.with_indifferent_access
|
41
44
|
#
|
42
45
|
# which may be handy.
|
46
|
+
#
|
47
|
+
# To access this class outside of Rails, require the core extension with:
|
48
|
+
#
|
49
|
+
# require "active_support/core_ext/hash/indifferent_access"
|
50
|
+
#
|
51
|
+
# which will, in turn, require this file.
|
43
52
|
class HashWithIndifferentAccess < Hash
|
44
53
|
# Returns +true+ so that <tt>Array#extract_options!</tt> finds members of
|
45
54
|
# this class.
|
@@ -59,24 +68,12 @@ module ActiveSupport
|
|
59
68
|
if constructor.respond_to?(:to_hash)
|
60
69
|
super()
|
61
70
|
update(constructor)
|
62
|
-
else
|
63
|
-
super(constructor)
|
64
|
-
end
|
65
|
-
end
|
66
71
|
|
67
|
-
|
68
|
-
|
69
|
-
self
|
72
|
+
hash = constructor.to_hash
|
73
|
+
self.default = hash.default if hash.default
|
74
|
+
self.default_proc = hash.default_proc if hash.default_proc
|
70
75
|
else
|
71
|
-
super
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def self.new_from_hash_copying_default(hash)
|
76
|
-
hash = hash.to_hash
|
77
|
-
new(hash).tap do |new_hash|
|
78
|
-
new_hash.default = hash.default
|
79
|
-
new_hash.default_proc = hash.default_proc if hash.default_proc
|
76
|
+
super(constructor)
|
80
77
|
end
|
81
78
|
end
|
82
79
|
|
@@ -92,7 +89,7 @@ module ActiveSupport
|
|
92
89
|
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
93
90
|
# hash[:key] = 'value'
|
94
91
|
#
|
95
|
-
# This value can be later fetched using either +:key+ or
|
92
|
+
# This value can be later fetched using either +:key+ or <tt>'key'</tt>.
|
96
93
|
def []=(key, value)
|
97
94
|
regular_writer(convert_key(key), convert_value(value, for: :assignment))
|
98
95
|
end
|
@@ -154,6 +151,32 @@ module ActiveSupport
|
|
154
151
|
alias_method :has_key?, :key?
|
155
152
|
alias_method :member?, :key?
|
156
153
|
|
154
|
+
# Same as <tt>Hash#[]</tt> where the key passed as argument can be
|
155
|
+
# either a string or a symbol:
|
156
|
+
#
|
157
|
+
# counters = ActiveSupport::HashWithIndifferentAccess.new
|
158
|
+
# counters[:foo] = 1
|
159
|
+
#
|
160
|
+
# counters['foo'] # => 1
|
161
|
+
# counters[:foo] # => 1
|
162
|
+
# counters[:zoo] # => nil
|
163
|
+
def [](key)
|
164
|
+
super(convert_key(key))
|
165
|
+
end
|
166
|
+
|
167
|
+
# Same as <tt>Hash#assoc</tt> where the key passed as argument can be
|
168
|
+
# either a string or a symbol:
|
169
|
+
#
|
170
|
+
# counters = ActiveSupport::HashWithIndifferentAccess.new
|
171
|
+
# counters[:foo] = 1
|
172
|
+
#
|
173
|
+
# counters.assoc('foo') # => ["foo", 1]
|
174
|
+
# counters.assoc(:foo) # => ["foo", 1]
|
175
|
+
# counters.assoc(:zoo) # => nil
|
176
|
+
def assoc(key)
|
177
|
+
super(convert_key(key))
|
178
|
+
end
|
179
|
+
|
157
180
|
# Same as <tt>Hash#fetch</tt> where the key passed as argument can be
|
158
181
|
# either a string or a symbol:
|
159
182
|
#
|
@@ -168,14 +191,55 @@ module ActiveSupport
|
|
168
191
|
super(convert_key(key), *extras)
|
169
192
|
end
|
170
193
|
|
194
|
+
# Same as <tt>Hash#dig</tt> where the key passed as argument can be
|
195
|
+
# either a string or a symbol:
|
196
|
+
#
|
197
|
+
# counters = ActiveSupport::HashWithIndifferentAccess.new
|
198
|
+
# counters[:foo] = { bar: 1 }
|
199
|
+
#
|
200
|
+
# counters.dig('foo', 'bar') # => 1
|
201
|
+
# counters.dig(:foo, :bar) # => 1
|
202
|
+
# counters.dig(:zoo) # => nil
|
203
|
+
def dig(*args)
|
204
|
+
args[0] = convert_key(args[0]) if args.size > 0
|
205
|
+
super(*args)
|
206
|
+
end
|
207
|
+
|
208
|
+
# Same as <tt>Hash#default</tt> where the key passed as argument can be
|
209
|
+
# either a string or a symbol:
|
210
|
+
#
|
211
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new(1)
|
212
|
+
# hash.default # => 1
|
213
|
+
#
|
214
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new { |hash, key| key }
|
215
|
+
# hash.default # => nil
|
216
|
+
# hash.default('foo') # => 'foo'
|
217
|
+
# hash.default(:foo) # => 'foo'
|
218
|
+
def default(*args)
|
219
|
+
super(*args.map { |arg| convert_key(arg) })
|
220
|
+
end
|
221
|
+
|
171
222
|
# Returns an array of the values at the specified indices:
|
172
223
|
#
|
173
224
|
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
174
225
|
# hash[:a] = 'x'
|
175
226
|
# hash[:b] = 'y'
|
176
227
|
# hash.values_at('a', 'b') # => ["x", "y"]
|
177
|
-
def values_at(*
|
178
|
-
|
228
|
+
def values_at(*keys)
|
229
|
+
super(*keys.map { |key| convert_key(key) })
|
230
|
+
end
|
231
|
+
|
232
|
+
# Returns an array of the values at the specified indices, but also
|
233
|
+
# raises an exception when one of the keys can't be found.
|
234
|
+
#
|
235
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
236
|
+
# hash[:a] = 'x'
|
237
|
+
# hash[:b] = 'y'
|
238
|
+
# hash.fetch_values('a', 'b') # => ["x", "y"]
|
239
|
+
# hash.fetch_values('a', 'c') { |key| 'z' } # => ["x", "z"]
|
240
|
+
# hash.fetch_values('a', 'c') # => KeyError: key not found: "c"
|
241
|
+
def fetch_values(*indices, &block)
|
242
|
+
super(*indices.map { |key| convert_key(key) }, &block)
|
179
243
|
end
|
180
244
|
|
181
245
|
# Returns a shallow copy of the hash.
|
@@ -184,7 +248,7 @@ module ActiveSupport
|
|
184
248
|
# dup = hash.dup
|
185
249
|
# dup[:a][:c] = 'c'
|
186
250
|
#
|
187
|
-
# hash[:a][:c] # =>
|
251
|
+
# hash[:a][:c] # => "c"
|
188
252
|
# dup[:a][:c] # => "c"
|
189
253
|
def dup
|
190
254
|
self.class.new(self).tap do |new_hash|
|
@@ -196,7 +260,7 @@ module ActiveSupport
|
|
196
260
|
# modify the receiver but rather returns a new hash with indifferent
|
197
261
|
# access with the result of the merge.
|
198
262
|
def merge(hash, &block)
|
199
|
-
|
263
|
+
dup.update(hash, &block)
|
200
264
|
end
|
201
265
|
|
202
266
|
# Like +merge+ but the other way around: Merges the receiver into the
|
@@ -206,20 +270,22 @@ module ActiveSupport
|
|
206
270
|
# hash['a'] = nil
|
207
271
|
# hash.reverse_merge(a: 0, b: 1) # => {"a"=>nil, "b"=>1}
|
208
272
|
def reverse_merge(other_hash)
|
209
|
-
super(self.class.
|
273
|
+
super(self.class.new(other_hash))
|
210
274
|
end
|
275
|
+
alias_method :with_defaults, :reverse_merge
|
211
276
|
|
212
277
|
# Same semantics as +reverse_merge+ but modifies the receiver in-place.
|
213
278
|
def reverse_merge!(other_hash)
|
214
|
-
|
279
|
+
super(self.class.new(other_hash))
|
215
280
|
end
|
281
|
+
alias_method :with_defaults!, :reverse_merge!
|
216
282
|
|
217
283
|
# Replaces the contents of this hash with other_hash.
|
218
284
|
#
|
219
285
|
# h = { "a" => 100, "b" => 200 }
|
220
286
|
# h.replace({ "c" => 300, "d" => 400 }) # => {"c"=>300, "d"=>400}
|
221
287
|
def replace(other_hash)
|
222
|
-
super(self.class.
|
288
|
+
super(self.class.new(other_hash))
|
223
289
|
end
|
224
290
|
|
225
291
|
# Removes the specified key from the hash.
|
@@ -227,6 +293,11 @@ module ActiveSupport
|
|
227
293
|
super(convert_key(key))
|
228
294
|
end
|
229
295
|
|
296
|
+
def except(*keys)
|
297
|
+
slice(*self.keys - keys.map { |key| convert_key(key) })
|
298
|
+
end
|
299
|
+
alias_method :without, :except
|
300
|
+
|
230
301
|
def stringify_keys!; self end
|
231
302
|
def deep_stringify_keys!; self end
|
232
303
|
def stringify_keys; dup end
|
@@ -234,14 +305,17 @@ module ActiveSupport
|
|
234
305
|
undef :symbolize_keys!
|
235
306
|
undef :deep_symbolize_keys!
|
236
307
|
def symbolize_keys; to_hash.symbolize_keys! end
|
308
|
+
alias_method :to_options, :symbolize_keys
|
237
309
|
def deep_symbolize_keys; to_hash.deep_symbolize_keys! end
|
238
310
|
def to_options!; self end
|
239
311
|
|
240
312
|
def select(*args, &block)
|
313
|
+
return to_enum(:select) unless block_given?
|
241
314
|
dup.tap { |hash| hash.select!(*args, &block) }
|
242
315
|
end
|
243
316
|
|
244
317
|
def reject(*args, &block)
|
318
|
+
return to_enum(:reject) unless block_given?
|
245
319
|
dup.tap { |hash| hash.reject!(*args, &block) }
|
246
320
|
end
|
247
321
|
|
@@ -250,6 +324,29 @@ module ActiveSupport
|
|
250
324
|
dup.tap { |hash| hash.transform_values!(*args, &block) }
|
251
325
|
end
|
252
326
|
|
327
|
+
def transform_keys(*args, &block)
|
328
|
+
return to_enum(:transform_keys) unless block_given?
|
329
|
+
dup.tap { |hash| hash.transform_keys!(*args, &block) }
|
330
|
+
end
|
331
|
+
|
332
|
+
def transform_keys!
|
333
|
+
return enum_for(:transform_keys!) { size } unless block_given?
|
334
|
+
keys.each do |key|
|
335
|
+
self[yield(key)] = delete(key)
|
336
|
+
end
|
337
|
+
self
|
338
|
+
end
|
339
|
+
|
340
|
+
def slice(*keys)
|
341
|
+
keys.map! { |key| convert_key(key) }
|
342
|
+
self.class.new(super)
|
343
|
+
end
|
344
|
+
|
345
|
+
def slice!(*keys)
|
346
|
+
keys.map! { |key| convert_key(key) }
|
347
|
+
super
|
348
|
+
end
|
349
|
+
|
253
350
|
def compact
|
254
351
|
dup.tap(&:compact!)
|
255
352
|
end
|
@@ -265,12 +362,12 @@ module ActiveSupport
|
|
265
362
|
_new_hash
|
266
363
|
end
|
267
364
|
|
268
|
-
|
269
|
-
def convert_key(key)
|
365
|
+
private
|
366
|
+
def convert_key(key) # :doc:
|
270
367
|
key.kind_of?(Symbol) ? key.to_s : key
|
271
368
|
end
|
272
369
|
|
273
|
-
def convert_value(value, options = {})
|
370
|
+
def convert_value(value, options = {}) # :doc:
|
274
371
|
if value.is_a? Hash
|
275
372
|
if options[:for] == :to_hash
|
276
373
|
value.to_hash
|
@@ -287,7 +384,7 @@ module ActiveSupport
|
|
287
384
|
end
|
288
385
|
end
|
289
386
|
|
290
|
-
def set_defaults(target)
|
387
|
+
def set_defaults(target) # :doc:
|
291
388
|
if default_proc
|
292
389
|
target.default_proc = default_proc.dup
|
293
390
|
else
|
@@ -297,4 +394,6 @@ module ActiveSupport
|
|
297
394
|
end
|
298
395
|
end
|
299
396
|
|
397
|
+
# :stopdoc:
|
398
|
+
|
300
399
|
HashWithIndifferentAccess = ActiveSupport::HashWithIndifferentAccess
|
data/lib/active_support/i18n.rb
CHANGED
@@ -1,13 +1,16 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/hash/deep_merge"
|
4
|
+
require "active_support/core_ext/hash/except"
|
5
|
+
require "active_support/core_ext/hash/slice"
|
4
6
|
begin
|
5
|
-
require
|
7
|
+
require "i18n"
|
6
8
|
rescue LoadError => e
|
7
9
|
$stderr.puts "The i18n gem is not available. Please add it to your Gemfile and run bundle install"
|
8
10
|
raise e
|
9
11
|
end
|
10
|
-
require
|
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__)
|
16
|
+
I18n.load_path << File.expand_path("locale/en.rb", __dir__)
|
@@ -1,7 +1,10 @@
|
|
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
|
|
6
|
+
# :enddoc:
|
7
|
+
|
5
8
|
module I18n
|
6
9
|
class Railtie < Rails::Railtie
|
7
10
|
config.i18n = ActiveSupport::OrderedOptions.new
|
@@ -9,6 +12,10 @@ module I18n
|
|
9
12
|
config.i18n.load_path = []
|
10
13
|
config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
|
11
14
|
|
15
|
+
if I18n.respond_to?(:eager_load!)
|
16
|
+
config.eager_load_namespaces << I18n
|
17
|
+
end
|
18
|
+
|
12
19
|
# Set the i18n configuration after initialization since a lot of
|
13
20
|
# configuration is still usually done in application initializers.
|
14
21
|
config.after_initialize do |app|
|
@@ -21,8 +28,6 @@ module I18n
|
|
21
28
|
I18n::Railtie.initialize_i18n(app)
|
22
29
|
end
|
23
30
|
|
24
|
-
protected
|
25
|
-
|
26
31
|
@i18n_inited = false
|
27
32
|
|
28
33
|
# Setup i18n configuration.
|
@@ -37,10 +42,12 @@ module I18n
|
|
37
42
|
enforce_available_locales = I18n.enforce_available_locales if enforce_available_locales.nil?
|
38
43
|
I18n.enforce_available_locales = false
|
39
44
|
|
45
|
+
reloadable_paths = []
|
40
46
|
app.config.i18n.each do |setting, value|
|
41
47
|
case setting
|
42
48
|
when :railties_load_path
|
43
|
-
|
49
|
+
reloadable_paths = value
|
50
|
+
app.config.i18n.load_path.unshift(*value.flat_map(&:existent))
|
44
51
|
when :load_path
|
45
52
|
I18n.load_path += value
|
46
53
|
else
|
@@ -53,28 +60,51 @@ module I18n
|
|
53
60
|
# Restore available locales check so it will take place from now on.
|
54
61
|
I18n.enforce_available_locales = enforce_available_locales
|
55
62
|
|
56
|
-
|
63
|
+
directories = watched_dirs_with_extensions(reloadable_paths)
|
64
|
+
reloader = app.config.file_watcher.new(I18n.load_path.dup, directories) do
|
65
|
+
I18n.load_path.keep_if { |p| File.exist?(p) }
|
66
|
+
I18n.load_path |= reloadable_paths.flat_map(&:existent)
|
67
|
+
|
68
|
+
I18n.reload!
|
69
|
+
end
|
70
|
+
|
57
71
|
app.reloaders << reloader
|
58
|
-
|
72
|
+
app.reloader.to_run do
|
73
|
+
reloader.execute_if_updated { require_unload_lock! }
|
74
|
+
end
|
59
75
|
reloader.execute
|
60
76
|
|
61
77
|
@i18n_inited = true
|
62
78
|
end
|
63
79
|
|
64
80
|
def self.include_fallbacks_module
|
65
|
-
I18n.backend.class.
|
81
|
+
I18n.backend.class.include(I18n::Backend::Fallbacks)
|
66
82
|
end
|
67
83
|
|
68
84
|
def self.init_fallbacks(fallbacks)
|
69
85
|
include_fallbacks_module
|
70
86
|
|
71
|
-
args =
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
Array
|
76
|
-
|
77
|
-
|
87
|
+
args = \
|
88
|
+
case fallbacks
|
89
|
+
when ActiveSupport::OrderedOptions
|
90
|
+
[*(fallbacks[:defaults] || []) << fallbacks[:map]].compact
|
91
|
+
when Hash, Array
|
92
|
+
Array.wrap(fallbacks)
|
93
|
+
else # TrueClass
|
94
|
+
[I18n.default_locale]
|
95
|
+
end
|
96
|
+
|
97
|
+
if args.empty? || args.first.is_a?(Hash)
|
98
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
99
|
+
Using I18n fallbacks with an empty `defaults` sets the defaults to
|
100
|
+
include the `default_locale`. This behavior will change in Rails 6.1.
|
101
|
+
If you desire the default locale to be included in the defaults, please
|
102
|
+
explicitly configure it with `config.i18n.fallbacks.defaults =
|
103
|
+
[I18n.default_locale]` or `config.i18n.fallbacks = [I18n.default_locale,
|
104
|
+
{...}]`. If you want to opt-in to the new behavior, use
|
105
|
+
`config.i18n.fallbacks.defaults = [nil, {...}]`.
|
106
|
+
MSG
|
107
|
+
args.unshift I18n.default_locale
|
78
108
|
end
|
79
109
|
|
80
110
|
I18n.fallbacks = I18n::Locale::Fallbacks.new(*args)
|
@@ -90,5 +120,11 @@ module I18n
|
|
90
120
|
raise "Unexpected fallback type #{fallbacks.inspect}"
|
91
121
|
end
|
92
122
|
end
|
123
|
+
|
124
|
+
def self.watched_dirs_with_extensions(paths)
|
125
|
+
paths.each_with_object({}) do |path, result|
|
126
|
+
result[path.absolute_current] = path.extensions
|
127
|
+
end
|
128
|
+
end
|
93
129
|
end
|
94
130
|
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/inflector/inflections"
|
2
4
|
|
3
5
|
#--
|
4
6
|
# Defines the standard inflection rules. These are the starting point for
|
@@ -8,8 +10,8 @@ require 'active_support/inflector/inflections'
|
|
8
10
|
#++
|
9
11
|
module ActiveSupport
|
10
12
|
Inflector.inflections(:en) do |inflect|
|
11
|
-
inflect.plural(/$/,
|
12
|
-
inflect.plural(/s$/i,
|
13
|
+
inflect.plural(/$/, "s")
|
14
|
+
inflect.plural(/s$/i, "s")
|
13
15
|
inflect.plural(/^(ax|test)is$/i, '\1es')
|
14
16
|
inflect.plural(/(octop|vir)us$/i, '\1i')
|
15
17
|
inflect.plural(/(octop|vir)i$/i, '\1i')
|
@@ -18,7 +20,7 @@ module ActiveSupport
|
|
18
20
|
inflect.plural(/(buffal|tomat)o$/i, '\1oes')
|
19
21
|
inflect.plural(/([ti])um$/i, '\1a')
|
20
22
|
inflect.plural(/([ti])a$/i, '\1a')
|
21
|
-
inflect.plural(/sis$/i,
|
23
|
+
inflect.plural(/sis$/i, "ses")
|
22
24
|
inflect.plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves')
|
23
25
|
inflect.plural(/(hive)$/i, '\1s')
|
24
26
|
inflect.plural(/([^aeiouy]|qu)y$/i, '\1ies')
|
@@ -30,7 +32,7 @@ module ActiveSupport
|
|
30
32
|
inflect.plural(/^(oxen)$/i, '\1')
|
31
33
|
inflect.plural(/(quiz)$/i, '\1zes')
|
32
34
|
|
33
|
-
inflect.singular(/s$/i,
|
35
|
+
inflect.singular(/s$/i, "")
|
34
36
|
inflect.singular(/(ss)$/i, '\1')
|
35
37
|
inflect.singular(/(n)ews$/i, '\1ews')
|
36
38
|
inflect.singular(/([ti])a$/i, '\1um')
|
@@ -58,12 +60,12 @@ module ActiveSupport
|
|
58
60
|
inflect.singular(/(quiz)zes$/i, '\1')
|
59
61
|
inflect.singular(/(database)s$/i, '\1')
|
60
62
|
|
61
|
-
inflect.irregular(
|
62
|
-
inflect.irregular(
|
63
|
-
inflect.irregular(
|
64
|
-
inflect.irregular(
|
65
|
-
inflect.irregular(
|
66
|
-
inflect.irregular(
|
63
|
+
inflect.irregular("person", "people")
|
64
|
+
inflect.irregular("man", "men")
|
65
|
+
inflect.irregular("child", "children")
|
66
|
+
inflect.irregular("sex", "sexes")
|
67
|
+
inflect.irregular("move", "moves")
|
68
|
+
inflect.irregular("zombie", "zombies")
|
67
69
|
|
68
70
|
inflect.uncountable(%w(equipment information rice money species series fish sheep jeans police))
|
69
71
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "concurrent/map"
|
4
|
+
require "active_support/i18n"
|
5
|
+
require "active_support/deprecation"
|
4
6
|
|
5
7
|
module ActiveSupport
|
6
8
|
module Inflector
|
@@ -25,23 +27,59 @@ module ActiveSupport
|
|
25
27
|
# singularization rules that is runs. This guarantees that your rules run
|
26
28
|
# before any of the rules that may already have been loaded.
|
27
29
|
class Inflections
|
28
|
-
@__instance__ =
|
30
|
+
@__instance__ = Concurrent::Map.new
|
31
|
+
|
32
|
+
class Uncountables < Array
|
33
|
+
def initialize
|
34
|
+
@regex_array = []
|
35
|
+
super
|
36
|
+
end
|
37
|
+
|
38
|
+
def delete(entry)
|
39
|
+
super entry
|
40
|
+
@regex_array.delete(to_regex(entry))
|
41
|
+
end
|
42
|
+
|
43
|
+
def <<(*word)
|
44
|
+
add(word)
|
45
|
+
end
|
46
|
+
|
47
|
+
def add(words)
|
48
|
+
words = words.flatten.map(&:downcase)
|
49
|
+
concat(words)
|
50
|
+
@regex_array += words.map { |word| to_regex(word) }
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
def uncountable?(str)
|
55
|
+
@regex_array.any? { |regex| regex.match? str }
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
def to_regex(string)
|
60
|
+
/\b#{::Regexp.escape(string)}\Z/i
|
61
|
+
end
|
62
|
+
end
|
29
63
|
|
30
64
|
def self.instance(locale = :en)
|
31
65
|
@__instance__[locale] ||= new
|
32
66
|
end
|
33
67
|
|
34
|
-
attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms
|
68
|
+
attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms
|
69
|
+
|
70
|
+
attr_reader :acronyms_camelize_regex, :acronyms_underscore_regex # :nodoc:
|
35
71
|
|
36
72
|
def initialize
|
37
|
-
@plurals, @singulars, @uncountables, @humans, @acronyms
|
73
|
+
@plurals, @singulars, @uncountables, @humans, @acronyms = [], [], Uncountables.new, [], {}
|
74
|
+
define_acronym_regex_patterns
|
38
75
|
end
|
39
76
|
|
40
77
|
# Private, for the test suite.
|
41
78
|
def initialize_dup(orig) # :nodoc:
|
42
|
-
%w(plurals singulars uncountables humans acronyms
|
79
|
+
%w(plurals singulars uncountables humans acronyms).each do |scope|
|
43
80
|
instance_variable_set("@#{scope}", orig.send(scope).dup)
|
44
81
|
end
|
82
|
+
define_acronym_regex_patterns
|
45
83
|
end
|
46
84
|
|
47
85
|
# Specifies a new acronym. An acronym must be specified as it will appear
|
@@ -95,7 +133,7 @@ module ActiveSupport
|
|
95
133
|
# camelize 'mcdonald' # => 'McDonald'
|
96
134
|
def acronym(word)
|
97
135
|
@acronyms[word.downcase] = word
|
98
|
-
|
136
|
+
define_acronym_regex_patterns
|
99
137
|
end
|
100
138
|
|
101
139
|
# Specifies a new pluralization rule and its replacement. The rule can
|
@@ -160,7 +198,7 @@ module ActiveSupport
|
|
160
198
|
# uncountable 'money', 'information'
|
161
199
|
# uncountable %w( money information rice )
|
162
200
|
def uncountable(*words)
|
163
|
-
@uncountables
|
201
|
+
@uncountables.add(words)
|
164
202
|
end
|
165
203
|
|
166
204
|
# Specifies a humanized form of a string by a regular expression rule or
|
@@ -184,12 +222,19 @@ module ActiveSupport
|
|
184
222
|
# clear :plurals
|
185
223
|
def clear(scope = :all)
|
186
224
|
case scope
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
225
|
+
when :all
|
226
|
+
@plurals, @singulars, @uncountables, @humans = [], [], Uncountables.new, []
|
227
|
+
else
|
228
|
+
instance_variable_set "@#{scope}", []
|
191
229
|
end
|
192
230
|
end
|
231
|
+
|
232
|
+
private
|
233
|
+
def define_acronym_regex_patterns
|
234
|
+
@acronym_regex = @acronyms.empty? ? /(?=a)b/ : /#{@acronyms.values.join("|")}/
|
235
|
+
@acronyms_camelize_regex = /^(?:#{@acronym_regex}(?=\b|[A-Z_])|\w)/
|
236
|
+
@acronyms_underscore_regex = /(?:(?<=([A-Za-z\d]))|\b)(#{@acronym_regex})(?=\b|[^a-z])/
|
237
|
+
end
|
193
238
|
end
|
194
239
|
|
195
240
|
# Yields a singleton instance of Inflector::Inflections so you can specify
|