activesupport 5.0.0 → 6.1.0
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 +5 -5
- data/CHANGELOG.md +343 -590
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -4
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/all.rb +5 -3
- data/lib/active_support/array_inquirer.rb +11 -5
- data/lib/active_support/backtrace_cleaner.rb +33 -5
- data/lib/active_support/benchmarkable.rb +5 -3
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache/file_store.rb +45 -53
- data/lib/active_support/cache/mem_cache_store.rb +81 -79
- data/lib/active_support/cache/memory_store.rb +69 -41
- data/lib/active_support/cache/null_store.rb +11 -4
- data/lib/active_support/cache/redis_cache_store.rb +493 -0
- data/lib/active_support/cache/strategy/local_cache.rb +74 -37
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
- data/lib/active_support/cache.rb +332 -161
- data/lib/active_support/callbacks.rb +657 -586
- data/lib/active_support/concern.rb +79 -6
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
- data/lib/active_support/concurrency/share_lock.rb +59 -19
- data/lib/active_support/configurable.rb +15 -17
- data/lib/active_support/configuration_file.rb +46 -0
- data/lib/active_support/core_ext/array/access.rb +21 -7
- data/lib/active_support/core_ext/array/conversions.rb +20 -18
- 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 +3 -1
- data/lib/active_support/core_ext/array/inquiry.rb +3 -1
- data/lib/active_support/core_ext/array/wrap.rb +2 -0
- data/lib/active_support/core_ext/array.rb +9 -7
- data/lib/active_support/core_ext/benchmark.rb +5 -3
- data/lib/active_support/core_ext/big_decimal/conversions.rb +6 -6
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/class/attribute.rb +52 -49
- data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
- data/lib/active_support/core_ext/class/subclasses.rb +18 -26
- data/lib/active_support/core_ext/class.rb +4 -2
- data/lib/active_support/core_ext/date/acts_like.rb +3 -1
- data/lib/active_support/core_ext/date/blank.rb +3 -1
- data/lib/active_support/core_ext/date/calculations.rb +16 -13
- data/lib/active_support/core_ext/date/conversions.rb +23 -21
- data/lib/active_support/core_ext/date/zones.rb +4 -2
- data/lib/active_support/core_ext/date.rb +7 -5
- data/lib/active_support/core_ext/date_and_time/calculations.rb +82 -53
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -5
- data/lib/active_support/core_ext/date_and_time/zones.rb +9 -9
- data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
- data/lib/active_support/core_ext/date_time/blank.rb +3 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +23 -11
- data/lib/active_support/core_ext/date_time/compatibility.rb +15 -2
- data/lib/active_support/core_ext/date_time/conversions.rb +14 -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 +165 -29
- data/lib/active_support/core_ext/file/atomic.rb +7 -5
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +40 -39
- 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 +3 -2
- data/lib/active_support/core_ext/hash/keys.rb +9 -36
- 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 +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 +3 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +3 -1
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +5 -4
- data/lib/active_support/core_ext/load_error.rb +2 -23
- data/lib/active_support/core_ext/marshal.rb +6 -2
- data/lib/active_support/core_ext/module/aliasing.rb +5 -48
- data/lib/active_support/core_ext/module/anonymous.rb +2 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +7 -5
- data/lib/active_support/core_ext/module/attribute_accessors.rb +53 -59
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +31 -24
- data/lib/active_support/core_ext/module/concerning.rb +16 -11
- data/lib/active_support/core_ext/module/delegation.rb +159 -44
- data/lib/active_support/core_ext/module/deprecation.rb +2 -0
- data/lib/active_support/core_ext/module/introspection.rb +23 -26
- 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 +13 -12
- data/lib/active_support/core_ext/name_error.rb +36 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +129 -134
- data/lib/active_support/core_ext/numeric/time.rb +18 -26
- data/lib/active_support/core_ext/numeric.rb +5 -4
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +14 -2
- data/lib/active_support/core_ext/object/conversions.rb +6 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +4 -2
- data/lib/active_support/core_ext/object/duplicable.rb +13 -62
- data/lib/active_support/core_ext/object/inclusion.rb +3 -1
- data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
- data/lib/active_support/core_ext/object/json.rb +42 -15
- 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 +20 -8
- data/lib/active_support/core_ext/object/with_options.rb +15 -2
- data/lib/active_support/core_ext/object.rb +14 -12
- data/lib/active_support/core_ext/range/compare_range.rb +82 -0
- data/lib/active_support/core_ext/range/conversions.rb +35 -25
- data/lib/active_support/core_ext/range/each.rb +5 -2
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +28 -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 +10 -1
- data/lib/active_support/core_ext/securerandom.rb +28 -6
- data/lib/active_support/core_ext/string/access.rb +9 -18
- 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 +47 -4
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +78 -29
- data/lib/active_support/core_ext/string/inquiry.rb +4 -1
- data/lib/active_support/core_ext/string/multibyte.rb +10 -5
- data/lib/active_support/core_ext/string/output_safety.rb +86 -31
- 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 +4 -2
- data/lib/active_support/core_ext/string.rb +15 -13
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/time/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +117 -45
- data/lib/active_support/core_ext/time/compatibility.rb +13 -2
- data/lib/active_support/core_ext/time/conversions.rb +18 -12
- data/lib/active_support/core_ext/time/zones.rb +9 -7
- data/lib/active_support/core_ext/time.rb +7 -5
- data/lib/active_support/core_ext/uri.rb +12 -7
- data/lib/active_support/core_ext.rb +3 -2
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +208 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +7 -1
- data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
- data/lib/active_support/dependencies.rb +172 -98
- data/lib/active_support/deprecation/behaviors.rb +45 -13
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/disallowed.rb +56 -0
- data/lib/active_support/deprecation/instance_delegator.rb +16 -2
- data/lib/active_support/deprecation/method_wrappers.rb +32 -17
- data/lib/active_support/deprecation/proxy_wrappers.rb +35 -7
- data/lib/active_support/deprecation/reporting.rb +61 -16
- data/lib/active_support/deprecation.rb +17 -9
- data/lib/active_support/descendants_tracker.rb +61 -9
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration/iso8601_parser.rb +67 -66
- data/lib/active_support/duration/iso8601_serializer.rb +25 -17
- data/lib/active_support/duration.rb +349 -46
- data/lib/active_support/encrypted_configuration.rb +45 -0
- data/lib/active_support/encrypted_file.rb +117 -0
- data/lib/active_support/environment_inquirer.rb +20 -0
- data/lib/active_support/evented_file_update_checker.rb +88 -112
- data/lib/active_support/execution_wrapper.rb +25 -13
- data/lib/active_support/executor.rb +3 -1
- data/lib/active_support/file_update_checker.rb +56 -51
- data/lib/active_support/fork_tracker.rb +62 -0
- data/lib/active_support/gem_version.rb +4 -2
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +153 -49
- data/lib/active_support/i18n.rb +9 -6
- data/lib/active_support/i18n_railtie.rb +30 -20
- data/lib/active_support/inflections.rb +13 -11
- data/lib/active_support/inflector/inflections.rb +28 -15
- data/lib/active_support/inflector/methods.rb +120 -109
- data/lib/active_support/inflector/transliterate.rb +60 -25
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/json/decoding.rb +30 -29
- data/lib/active_support/json/encoding.rb +22 -11
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/key_generator.rb +6 -36
- 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 +7 -3
- data/lib/active_support/log_subscriber/test_helper.rb +11 -9
- data/lib/active_support/log_subscriber.rb +51 -18
- data/lib/active_support/logger.rb +9 -22
- data/lib/active_support/logger_silence.rb +14 -21
- data/lib/active_support/logger_thread_safe_level.rb +55 -8
- data/lib/active_support/message_encryptor.rb +170 -53
- data/lib/active_support/message_verifier.rb +91 -20
- 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 +24 -78
- data/lib/active_support/multibyte/unicode.rb +21 -352
- data/lib/active_support/multibyte.rb +4 -2
- data/lib/active_support/notifications/fanout.rb +121 -19
- data/lib/active_support/notifications/instrumenter.rb +78 -14
- data/lib/active_support/notifications.rb +80 -12
- data/lib/active_support/number_helper/number_converter.rb +17 -16
- data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -9
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +5 -3
- data/lib/active_support/number_helper/number_to_human_converter.rb +13 -12
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +11 -13
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +5 -4
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +18 -55
- data/lib/active_support/number_helper/rounding_helper.rb +50 -0
- data/lib/active_support/number_helper.rb +45 -16
- data/lib/active_support/option_merger.rb +25 -4
- data/lib/active_support/ordered_hash.rb +6 -4
- data/lib/active_support/ordered_options.rb +23 -9
- data/lib/active_support/parameter_filter.rb +133 -0
- data/lib/active_support/per_thread_registry.rb +7 -5
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +8 -9
- data/lib/active_support/railtie.rb +62 -11
- data/lib/active_support/reloader.rb +12 -11
- data/lib/active_support/rescuable.rb +20 -11
- 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 +12 -3
- data/lib/active_support/subscriber.rb +77 -23
- data/lib/active_support/tagged_logging.rb +52 -17
- data/lib/active_support/test_case.rb +106 -29
- data/lib/active_support/testing/assertions.rb +144 -8
- data/lib/active_support/testing/autorun.rb +5 -10
- 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 +4 -2
- data/lib/active_support/testing/file_fixtures.rb +4 -0
- data/lib/active_support/testing/isolation.rb +19 -24
- data/lib/active_support/testing/method_call_assertions.rb +31 -2
- data/lib/active_support/testing/parallelization/server.rb +78 -0
- data/lib/active_support/testing/parallelization/worker.rb +100 -0
- data/lib/active_support/testing/parallelization.rb +51 -0
- data/lib/active_support/testing/setup_and_teardown.rb +13 -8
- data/lib/active_support/testing/stream.rb +30 -29
- data/lib/active_support/testing/tagged_logging.rb +3 -1
- data/lib/active_support/testing/time_helpers.rb +125 -24
- data/lib/active_support/time.rb +14 -12
- data/lib/active_support/time_with_zone.rb +142 -55
- data/lib/active_support/values/time_zone.rb +160 -53
- data/lib/active_support/version.rb +3 -1
- data/lib/active_support/xml_mini/jdom.rb +115 -114
- data/lib/active_support/xml_mini/libxml.rb +15 -14
- data/lib/active_support/xml_mini/libxmlsax.rb +16 -18
- data/lib/active_support/xml_mini/nokogiri.rb +13 -13
- data/lib/active_support/xml_mini/nokogirisax.rb +15 -16
- data/lib/active_support/xml_mini/rexml.rb +18 -9
- data/lib/active_support/xml_mini.rb +44 -42
- data/lib/active_support.rb +19 -10
- metadata +79 -37
- data/lib/active_support/concurrency/latch.rb +0 -19
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
- data/lib/active_support/core_ext/hash/compact.rb +0 -20
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -29
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
- data/lib/active_support/core_ext/kernel/debugger.rb +0 -3
- data/lib/active_support/core_ext/module/method_transplanting.rb +0 -3
- data/lib/active_support/core_ext/module/qualified_const.rb +0 -70
- 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/core_ext/struct.rb +0 -3
- data/lib/active_support/core_ext/time/marshal.rb +0 -3
- 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.
|
@@ -60,7 +69,7 @@ module ActiveSupport
|
|
60
69
|
super()
|
61
70
|
update(constructor)
|
62
71
|
|
63
|
-
hash = constructor.to_hash
|
72
|
+
hash = constructor.is_a?(Hash) ? constructor : constructor.to_hash
|
64
73
|
self.default = hash.default if hash.default
|
65
74
|
self.default_proc = hash.default_proc if hash.default_proc
|
66
75
|
else
|
@@ -68,25 +77,6 @@ module ActiveSupport
|
|
68
77
|
end
|
69
78
|
end
|
70
79
|
|
71
|
-
def default(*args)
|
72
|
-
arg_key = args.first
|
73
|
-
|
74
|
-
if include?(key = convert_key(arg_key))
|
75
|
-
self[key]
|
76
|
-
else
|
77
|
-
super
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def self.new_from_hash_copying_default(hash)
|
82
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
83
|
-
`ActiveSupport::HashWithIndifferentAccess.new_from_hash_copying_default`
|
84
|
-
has been deprecated, and will be removed in Rails 5.1. The behavior of
|
85
|
-
this method is now identical to the behavior of `.new`.
|
86
|
-
MSG
|
87
|
-
new(hash)
|
88
|
-
end
|
89
|
-
|
90
80
|
def self.[](*args)
|
91
81
|
new.merge!(Hash[*args])
|
92
82
|
end
|
@@ -101,12 +91,12 @@ module ActiveSupport
|
|
101
91
|
#
|
102
92
|
# This value can be later fetched using either +:key+ or <tt>'key'</tt>.
|
103
93
|
def []=(key, value)
|
104
|
-
regular_writer(convert_key(key), convert_value(value,
|
94
|
+
regular_writer(convert_key(key), convert_value(value, conversion: :assignment))
|
105
95
|
end
|
106
96
|
|
107
97
|
alias_method :store, :[]=
|
108
98
|
|
109
|
-
# Updates the receiver in-place, merging in the
|
99
|
+
# Updates the receiver in-place, merging in the hashes passed as arguments:
|
110
100
|
#
|
111
101
|
# hash_1 = ActiveSupport::HashWithIndifferentAccess.new
|
112
102
|
# hash_1[:key] = 'value'
|
@@ -116,7 +106,10 @@ module ActiveSupport
|
|
116
106
|
#
|
117
107
|
# hash_1.update(hash_2) # => {"key"=>"New Value!"}
|
118
108
|
#
|
119
|
-
#
|
109
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
110
|
+
# hash.update({ "a" => 1 }, { "b" => 2 }) # => { "a" => 1, "b" => 2 }
|
111
|
+
#
|
112
|
+
# The arguments can be either an
|
120
113
|
# <tt>ActiveSupport::HashWithIndifferentAccess</tt> or a regular +Hash+.
|
121
114
|
# In either case the merge respects the semantics of indifferent access.
|
122
115
|
#
|
@@ -131,18 +124,15 @@ module ActiveSupport
|
|
131
124
|
# hash_1[:key] = 10
|
132
125
|
# hash_2['key'] = 12
|
133
126
|
# hash_1.update(hash_2) { |key, old, new| old + new } # => {"key"=>22}
|
134
|
-
def update(
|
135
|
-
if
|
136
|
-
|
127
|
+
def update(*other_hashes, &block)
|
128
|
+
if other_hashes.size == 1
|
129
|
+
update_with_single_argument(other_hashes.first, block)
|
137
130
|
else
|
138
|
-
|
139
|
-
|
140
|
-
value = yield(convert_key(key), self[key], value)
|
141
|
-
end
|
142
|
-
regular_writer(convert_key(key), convert_value(value))
|
131
|
+
other_hashes.each do |other_hash|
|
132
|
+
update_with_single_argument(other_hash, block)
|
143
133
|
end
|
144
|
-
self
|
145
134
|
end
|
135
|
+
self
|
146
136
|
end
|
147
137
|
|
148
138
|
alias_method :merge!, :update
|
@@ -161,7 +151,6 @@ module ActiveSupport
|
|
161
151
|
alias_method :has_key?, :key?
|
162
152
|
alias_method :member?, :key?
|
163
153
|
|
164
|
-
|
165
154
|
# Same as <tt>Hash#[]</tt> where the key passed as argument can be
|
166
155
|
# either a string or a symbol:
|
167
156
|
#
|
@@ -175,6 +164,19 @@ module ActiveSupport
|
|
175
164
|
super(convert_key(key))
|
176
165
|
end
|
177
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
|
+
|
178
180
|
# Same as <tt>Hash#fetch</tt> where the key passed as argument can be
|
179
181
|
# either a string or a symbol:
|
180
182
|
#
|
@@ -189,14 +191,55 @@ module ActiveSupport
|
|
189
191
|
super(convert_key(key), *extras)
|
190
192
|
end
|
191
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
|
+
|
192
222
|
# Returns an array of the values at the specified indices:
|
193
223
|
#
|
194
224
|
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
195
225
|
# hash[:a] = 'x'
|
196
226
|
# hash[:b] = 'y'
|
197
227
|
# hash.values_at('a', 'b') # => ["x", "y"]
|
198
|
-
def values_at(*
|
199
|
-
|
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)
|
200
243
|
end
|
201
244
|
|
202
245
|
# Returns a shallow copy of the hash.
|
@@ -205,7 +248,7 @@ module ActiveSupport
|
|
205
248
|
# dup = hash.dup
|
206
249
|
# dup[:a][:c] = 'c'
|
207
250
|
#
|
208
|
-
# hash[:a][:c] # =>
|
251
|
+
# hash[:a][:c] # => "c"
|
209
252
|
# dup[:a][:c] # => "c"
|
210
253
|
def dup
|
211
254
|
self.class.new(self).tap do |new_hash|
|
@@ -216,8 +259,8 @@ module ActiveSupport
|
|
216
259
|
# This method has the same semantics of +update+, except it does not
|
217
260
|
# modify the receiver but rather returns a new hash with indifferent
|
218
261
|
# access with the result of the merge.
|
219
|
-
def merge(
|
220
|
-
|
262
|
+
def merge(*hashes, &block)
|
263
|
+
dup.update(*hashes, &block)
|
221
264
|
end
|
222
265
|
|
223
266
|
# Like +merge+ but the other way around: Merges the receiver into the
|
@@ -229,11 +272,13 @@ module ActiveSupport
|
|
229
272
|
def reverse_merge(other_hash)
|
230
273
|
super(self.class.new(other_hash))
|
231
274
|
end
|
275
|
+
alias_method :with_defaults, :reverse_merge
|
232
276
|
|
233
277
|
# Same semantics as +reverse_merge+ but modifies the receiver in-place.
|
234
278
|
def reverse_merge!(other_hash)
|
235
|
-
|
279
|
+
super(self.class.new(other_hash))
|
236
280
|
end
|
281
|
+
alias_method :with_defaults!, :reverse_merge!
|
237
282
|
|
238
283
|
# Replaces the contents of this hash with other_hash.
|
239
284
|
#
|
@@ -248,6 +293,11 @@ module ActiveSupport
|
|
248
293
|
super(convert_key(key))
|
249
294
|
end
|
250
295
|
|
296
|
+
def except(*keys)
|
297
|
+
slice(*self.keys - keys.map { |key| convert_key(key) })
|
298
|
+
end
|
299
|
+
alias_method :without, :except
|
300
|
+
|
251
301
|
def stringify_keys!; self end
|
252
302
|
def deep_stringify_keys!; self end
|
253
303
|
def stringify_keys; dup end
|
@@ -255,6 +305,7 @@ module ActiveSupport
|
|
255
305
|
undef :symbolize_keys!
|
256
306
|
undef :deep_symbolize_keys!
|
257
307
|
def symbolize_keys; to_hash.symbolize_keys! end
|
308
|
+
alias_method :to_options, :symbolize_keys
|
258
309
|
def deep_symbolize_keys; to_hash.deep_symbolize_keys! end
|
259
310
|
def to_options!; self end
|
260
311
|
|
@@ -268,34 +319,72 @@ module ActiveSupport
|
|
268
319
|
dup.tap { |hash| hash.reject!(*args, &block) }
|
269
320
|
end
|
270
321
|
|
322
|
+
def transform_values(*args, &block)
|
323
|
+
return to_enum(:transform_values) unless block_given?
|
324
|
+
dup.tap { |hash| hash.transform_values!(*args, &block) }
|
325
|
+
end
|
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
|
+
|
350
|
+
def compact
|
351
|
+
dup.tap(&:compact!)
|
352
|
+
end
|
353
|
+
|
271
354
|
# Convert to a regular hash with string keys.
|
272
355
|
def to_hash
|
273
356
|
_new_hash = Hash.new
|
274
357
|
set_defaults(_new_hash)
|
275
358
|
|
276
359
|
each do |key, value|
|
277
|
-
_new_hash[key] = convert_value(value,
|
360
|
+
_new_hash[key] = convert_value(value, conversion: :to_hash)
|
278
361
|
end
|
279
362
|
_new_hash
|
280
363
|
end
|
281
364
|
|
282
|
-
|
283
|
-
|
284
|
-
key
|
365
|
+
private
|
366
|
+
if Symbol.method_defined?(:name)
|
367
|
+
def convert_key(key)
|
368
|
+
key.kind_of?(Symbol) ? key.name : key
|
369
|
+
end
|
370
|
+
else
|
371
|
+
def convert_key(key)
|
372
|
+
key.kind_of?(Symbol) ? key.to_s : key
|
373
|
+
end
|
285
374
|
end
|
286
375
|
|
287
|
-
def convert_value(value,
|
376
|
+
def convert_value(value, conversion: nil)
|
288
377
|
if value.is_a? Hash
|
289
|
-
if
|
378
|
+
if conversion == :to_hash
|
290
379
|
value.to_hash
|
291
380
|
else
|
292
381
|
value.nested_under_indifferent_access
|
293
382
|
end
|
294
383
|
elsif value.is_a?(Array)
|
295
|
-
if
|
384
|
+
if conversion != :assignment || value.frozen?
|
296
385
|
value = value.dup
|
297
386
|
end
|
298
|
-
value.map! { |e| convert_value(e,
|
387
|
+
value.map! { |e| convert_value(e, conversion: conversion) }
|
299
388
|
else
|
300
389
|
value
|
301
390
|
end
|
@@ -308,7 +397,22 @@ module ActiveSupport
|
|
308
397
|
target.default = default
|
309
398
|
end
|
310
399
|
end
|
400
|
+
|
401
|
+
def update_with_single_argument(other_hash, block)
|
402
|
+
if other_hash.is_a? HashWithIndifferentAccess
|
403
|
+
regular_update(other_hash, &block)
|
404
|
+
else
|
405
|
+
other_hash.to_hash.each_pair do |key, value|
|
406
|
+
if block && key?(key)
|
407
|
+
value = block.call(convert_key(key), self[key], value)
|
408
|
+
end
|
409
|
+
regular_writer(convert_key(key), convert_value(value))
|
410
|
+
end
|
411
|
+
end
|
412
|
+
end
|
311
413
|
end
|
312
414
|
end
|
313
415
|
|
416
|
+
# :stopdoc:
|
417
|
+
|
314
418
|
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,8 @@ module I18n
|
|
9
12
|
config.i18n.load_path = []
|
10
13
|
config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
|
11
14
|
|
15
|
+
config.eager_load_namespaces << I18n
|
16
|
+
|
12
17
|
# Set the i18n configuration after initialization since a lot of
|
13
18
|
# configuration is still usually done in application initializers.
|
14
19
|
config.after_initialize do |app|
|
@@ -21,8 +26,6 @@ module I18n
|
|
21
26
|
I18n::Railtie.initialize_i18n(app)
|
22
27
|
end
|
23
28
|
|
24
|
-
protected
|
25
|
-
|
26
29
|
@i18n_inited = false
|
27
30
|
|
28
31
|
# Setup i18n configuration.
|
@@ -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
|
+
self.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
|
@@ -83,14 +92,15 @@ module I18n
|
|
83
92
|
def self.init_fallbacks(fallbacks)
|
84
93
|
include_fallbacks_module
|
85
94
|
|
86
|
-
args =
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
Array
|
91
|
-
|
92
|
-
|
93
|
-
|
95
|
+
args = \
|
96
|
+
case fallbacks
|
97
|
+
when ActiveSupport::OrderedOptions
|
98
|
+
[*(fallbacks[:defaults] || []) << fallbacks[:map]].compact
|
99
|
+
when Hash, Array
|
100
|
+
Array.wrap(fallbacks)
|
101
|
+
else # TrueClass
|
102
|
+
[I18n.default_locale]
|
103
|
+
end
|
94
104
|
|
95
105
|
I18n.fallbacks = I18n::Locale::Fallbacks.new(*args)
|
96
106
|
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,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "concurrent/map"
|
4
|
+
require "active_support/i18n"
|
4
5
|
|
5
6
|
module ActiveSupport
|
6
7
|
module Inflector
|
@@ -43,13 +44,14 @@ module ActiveSupport
|
|
43
44
|
end
|
44
45
|
|
45
46
|
def add(words)
|
46
|
-
|
47
|
-
|
47
|
+
words = words.flatten.map(&:downcase)
|
48
|
+
concat(words)
|
49
|
+
@regex_array += words.map { |word| to_regex(word) }
|
48
50
|
self
|
49
51
|
end
|
50
52
|
|
51
53
|
def uncountable?(str)
|
52
|
-
@regex_array.any? { |regex| regex
|
54
|
+
@regex_array.any? { |regex| regex.match? str }
|
53
55
|
end
|
54
56
|
|
55
57
|
private
|
@@ -62,17 +64,21 @@ module ActiveSupport
|
|
62
64
|
@__instance__[locale] ||= new
|
63
65
|
end
|
64
66
|
|
65
|
-
attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms
|
67
|
+
attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms
|
68
|
+
|
69
|
+
attr_reader :acronyms_camelize_regex, :acronyms_underscore_regex # :nodoc:
|
66
70
|
|
67
71
|
def initialize
|
68
|
-
@plurals, @singulars, @uncountables, @humans, @acronyms
|
72
|
+
@plurals, @singulars, @uncountables, @humans, @acronyms = [], [], Uncountables.new, [], {}
|
73
|
+
define_acronym_regex_patterns
|
69
74
|
end
|
70
75
|
|
71
76
|
# Private, for the test suite.
|
72
77
|
def initialize_dup(orig) # :nodoc:
|
73
|
-
%w(plurals singulars uncountables humans acronyms
|
74
|
-
instance_variable_set("@#{scope}", orig.
|
78
|
+
%w(plurals singulars uncountables humans acronyms).each do |scope|
|
79
|
+
instance_variable_set("@#{scope}", orig.public_send(scope).dup)
|
75
80
|
end
|
81
|
+
define_acronym_regex_patterns
|
76
82
|
end
|
77
83
|
|
78
84
|
# Specifies a new acronym. An acronym must be specified as it will appear
|
@@ -126,7 +132,7 @@ module ActiveSupport
|
|
126
132
|
# camelize 'mcdonald' # => 'McDonald'
|
127
133
|
def acronym(word)
|
128
134
|
@acronyms[word.downcase] = word
|
129
|
-
|
135
|
+
define_acronym_regex_patterns
|
130
136
|
end
|
131
137
|
|
132
138
|
# Specifies a new pluralization rule and its replacement. The rule can
|
@@ -215,12 +221,19 @@ module ActiveSupport
|
|
215
221
|
# clear :plurals
|
216
222
|
def clear(scope = :all)
|
217
223
|
case scope
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
224
|
+
when :all
|
225
|
+
@plurals, @singulars, @uncountables, @humans = [], [], Uncountables.new, []
|
226
|
+
else
|
227
|
+
instance_variable_set "@#{scope}", []
|
222
228
|
end
|
223
229
|
end
|
230
|
+
|
231
|
+
private
|
232
|
+
def define_acronym_regex_patterns
|
233
|
+
@acronym_regex = @acronyms.empty? ? /(?=a)b/ : /#{@acronyms.values.join("|")}/
|
234
|
+
@acronyms_camelize_regex = /^(?:#{@acronym_regex}(?=\b|[A-Z_])|\w)/
|
235
|
+
@acronyms_underscore_regex = /(?:(?<=([A-Za-z\d]))|\b)(#{@acronym_regex})(?=\b|[^a-z])/
|
236
|
+
end
|
224
237
|
end
|
225
238
|
|
226
239
|
# Yields a singleton instance of Inflector::Inflections so you can specify
|