activesupport 6.0.6.1 → 7.1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +865 -438
- data/MIT-LICENSE +1 -1
- data/README.rdoc +6 -6
- data/lib/active_support/actionable_error.rb +4 -2
- data/lib/active_support/array_inquirer.rb +4 -2
- data/lib/active_support/backtrace_cleaner.rb +30 -10
- data/lib/active_support/benchmarkable.rb +4 -3
- data/lib/active_support/broadcast_logger.rb +250 -0
- data/lib/active_support/builder.rb +1 -1
- data/lib/active_support/cache/coder.rb +153 -0
- data/lib/active_support/cache/entry.rb +134 -0
- data/lib/active_support/cache/file_store.rb +53 -20
- data/lib/active_support/cache/mem_cache_store.rb +208 -63
- data/lib/active_support/cache/memory_store.rb +120 -38
- data/lib/active_support/cache/null_store.rb +16 -2
- data/lib/active_support/cache/redis_cache_store.rb +201 -208
- data/lib/active_support/cache/serializer_with_fallback.rb +175 -0
- data/lib/active_support/cache/strategy/local_cache.rb +73 -66
- data/lib/active_support/cache.rb +539 -261
- data/lib/active_support/callbacks.rb +273 -142
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +53 -7
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +44 -7
- data/lib/active_support/concurrency/null_lock.rb +13 -0
- data/lib/active_support/concurrency/share_lock.rb +2 -2
- data/lib/active_support/configurable.rb +19 -6
- data/lib/active_support/configuration_file.rb +51 -0
- data/lib/active_support/core_ext/array/access.rb +1 -5
- data/lib/active_support/core_ext/array/conversions.rb +15 -13
- data/lib/active_support/core_ext/array/grouping.rb +6 -6
- data/lib/active_support/core_ext/array/inquiry.rb +2 -2
- data/lib/active_support/core_ext/benchmark.rb +2 -2
- data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
- data/lib/active_support/core_ext/class/attribute.rb +34 -44
- data/lib/active_support/core_ext/class/subclasses.rb +19 -29
- data/lib/active_support/core_ext/date/blank.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +24 -9
- data/lib/active_support/core_ext/date/conversions.rb +18 -16
- data/lib/active_support/core_ext/date_and_time/calculations.rb +27 -4
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/date_time/blank.rb +1 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +4 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +19 -15
- data/lib/active_support/core_ext/digest/uuid.rb +30 -13
- data/lib/active_support/core_ext/enumerable.rb +146 -72
- data/lib/active_support/core_ext/erb/util.rb +196 -0
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +3 -4
- data/lib/active_support/core_ext/hash/deep_merge.rb +22 -14
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +4 -4
- data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
- data/lib/active_support/core_ext/hash/keys.rb +5 -5
- data/lib/active_support/core_ext/hash/slice.rb +3 -2
- data/lib/active_support/core_ext/integer/inflections.rb +12 -12
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
- data/lib/active_support/core_ext/kernel/singleton_class.rb +1 -1
- data/lib/active_support/core_ext/load_error.rb +1 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +31 -29
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +51 -20
- data/lib/active_support/core_ext/module/concerning.rb +14 -8
- data/lib/active_support/core_ext/module/delegation.rb +75 -42
- data/lib/active_support/core_ext/module/deprecation.rb +15 -12
- data/lib/active_support/core_ext/module/introspection.rb +1 -26
- data/lib/active_support/core_ext/name_error.rb +23 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +9 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +82 -73
- data/lib/active_support/core_ext/object/acts_like.rb +29 -5
- data/lib/active_support/core_ext/object/blank.rb +2 -2
- data/lib/active_support/core_ext/object/deep_dup.rb +17 -1
- data/lib/active_support/core_ext/object/duplicable.rb +15 -4
- data/lib/active_support/core_ext/object/inclusion.rb +13 -5
- data/lib/active_support/core_ext/object/instance_variables.rb +22 -12
- data/lib/active_support/core_ext/object/json.rb +52 -28
- data/lib/active_support/core_ext/object/to_query.rb +2 -4
- data/lib/active_support/core_ext/object/try.rb +20 -20
- data/lib/active_support/core_ext/object/with.rb +44 -0
- data/lib/active_support/core_ext/object/with_options.rb +25 -6
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/pathname/blank.rb +16 -0
- data/lib/active_support/core_ext/pathname/existence.rb +23 -0
- data/lib/active_support/core_ext/pathname.rb +4 -0
- data/lib/active_support/core_ext/range/compare_range.rb +6 -25
- data/lib/active_support/core_ext/range/conversions.rb +34 -13
- data/lib/active_support/core_ext/range/each.rb +1 -1
- data/lib/active_support/core_ext/range/overlap.rb +40 -0
- data/lib/active_support/core_ext/range.rb +1 -2
- data/lib/active_support/core_ext/regexp.rb +8 -1
- data/lib/active_support/core_ext/securerandom.rb +25 -13
- data/lib/active_support/core_ext/string/access.rb +5 -24
- data/lib/active_support/core_ext/string/conversions.rb +3 -2
- data/lib/active_support/core_ext/string/filters.rb +21 -15
- data/lib/active_support/core_ext/string/indent.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +51 -10
- data/lib/active_support/core_ext/string/inquiry.rb +2 -1
- data/lib/active_support/core_ext/string/multibyte.rb +2 -2
- data/lib/active_support/core_ext/string/output_safety.rb +85 -194
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
- 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/thread/backtrace/location.rb +12 -0
- data/lib/active_support/core_ext/time/calculations.rb +46 -8
- data/lib/active_support/core_ext/time/conversions.rb +16 -13
- data/lib/active_support/core_ext/time/zones.rb +12 -28
- data/lib/active_support/core_ext.rb +2 -1
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +54 -22
- data/lib/active_support/deep_mergeable.rb +53 -0
- data/lib/active_support/dependencies/autoload.rb +17 -12
- data/lib/active_support/dependencies/interlock.rb +10 -18
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +58 -769
- data/lib/active_support/deprecation/behaviors.rb +77 -38
- data/lib/active_support/deprecation/constant_accessor.rb +5 -4
- data/lib/active_support/deprecation/deprecators.rb +104 -0
- data/lib/active_support/deprecation/disallowed.rb +54 -0
- data/lib/active_support/deprecation/instance_delegator.rb +31 -5
- data/lib/active_support/deprecation/method_wrappers.rb +12 -28
- data/lib/active_support/deprecation/proxy_wrappers.rb +40 -25
- data/lib/active_support/deprecation/reporting.rb +76 -16
- data/lib/active_support/deprecation.rb +36 -4
- data/lib/active_support/deprecator.rb +7 -0
- data/lib/active_support/descendants_tracker.rb +150 -68
- data/lib/active_support/digest.rb +5 -3
- data/lib/active_support/duration/iso8601_parser.rb +3 -3
- data/lib/active_support/duration/iso8601_serializer.rb +24 -12
- data/lib/active_support/duration.rb +136 -56
- data/lib/active_support/encrypted_configuration.rb +72 -9
- data/lib/active_support/encrypted_file.rb +46 -13
- data/lib/active_support/environment_inquirer.rb +40 -0
- data/lib/active_support/error_reporter/test_helper.rb +15 -0
- data/lib/active_support/error_reporter.rb +203 -0
- data/lib/active_support/evented_file_update_checker.rb +86 -137
- 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 +31 -12
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/file_update_checker.rb +4 -2
- data/lib/active_support/fork_tracker.rb +79 -0
- data/lib/active_support/gem_version.rb +5 -5
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +86 -42
- data/lib/active_support/html_safe_translation.rb +53 -0
- data/lib/active_support/i18n.rb +2 -1
- data/lib/active_support/i18n_railtie.rb +29 -27
- data/lib/active_support/inflector/inflections.rb +26 -9
- data/lib/active_support/inflector/methods.rb +54 -64
- data/lib/active_support/inflector/transliterate.rb +7 -5
- data/lib/active_support/isolated_execution_state.rb +76 -0
- data/lib/active_support/json/decoding.rb +6 -5
- data/lib/active_support/json/encoding.rb +31 -45
- data/lib/active_support/key_generator.rb +32 -7
- data/lib/active_support/lazy_load_hooks.rb +33 -7
- data/lib/active_support/locale/en.yml +10 -4
- data/lib/active_support/log_subscriber/test_helper.rb +2 -2
- data/lib/active_support/log_subscriber.rb +101 -32
- data/lib/active_support/logger.rb +9 -60
- data/lib/active_support/logger_silence.rb +2 -26
- data/lib/active_support/logger_thread_safe_level.rb +24 -25
- data/lib/active_support/message_encryptor.rb +205 -58
- data/lib/active_support/message_encryptors.rb +141 -0
- data/lib/active_support/message_pack/cache_serializer.rb +23 -0
- data/lib/active_support/message_pack/extensions.rb +292 -0
- data/lib/active_support/message_pack/serializer.rb +63 -0
- data/lib/active_support/message_pack.rb +50 -0
- data/lib/active_support/message_verifier.rb +237 -86
- data/lib/active_support/message_verifiers.rb +135 -0
- data/lib/active_support/messages/codec.rb +65 -0
- data/lib/active_support/messages/metadata.rb +112 -46
- data/lib/active_support/messages/rotation_configuration.rb +2 -1
- data/lib/active_support/messages/rotation_coordinator.rb +93 -0
- data/lib/active_support/messages/rotator.rb +35 -32
- data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
- data/lib/active_support/multibyte/chars.rb +15 -52
- data/lib/active_support/multibyte/unicode.rb +8 -122
- data/lib/active_support/multibyte.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +310 -105
- data/lib/active_support/notifications/instrumenter.rb +113 -48
- data/lib/active_support/notifications.rb +56 -29
- data/lib/active_support/number_helper/number_converter.rb +15 -8
- data/lib/active_support/number_helper/number_to_currency_converter.rb +11 -6
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_human_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +5 -5
- data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +9 -5
- data/lib/active_support/number_helper/rounding_helper.rb +12 -32
- data/lib/active_support/number_helper.rb +379 -304
- data/lib/active_support/option_merger.rb +11 -18
- data/lib/active_support/ordered_hash.rb +4 -4
- data/lib/active_support/ordered_options.rb +23 -3
- data/lib/active_support/parameter_filter.rb +104 -75
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +1 -4
- data/lib/active_support/railtie.rb +90 -6
- data/lib/active_support/reloader.rb +12 -4
- data/lib/active_support/rescuable.rb +18 -16
- data/lib/active_support/ruby_features.rb +7 -0
- data/lib/active_support/secure_compare_rotator.rb +58 -0
- data/lib/active_support/security_utils.rb +19 -12
- data/lib/active_support/string_inquirer.rb +5 -3
- data/lib/active_support/subscriber.rb +23 -47
- data/lib/active_support/syntax_error_proxy.rb +70 -0
- data/lib/active_support/tagged_logging.rb +84 -23
- data/lib/active_support/test_case.rb +166 -27
- data/lib/active_support/testing/assertions.rb +73 -20
- data/lib/active_support/testing/autorun.rb +0 -2
- data/lib/active_support/testing/constant_stubbing.rb +32 -0
- data/lib/active_support/testing/deprecation.rb +53 -2
- data/lib/active_support/testing/error_reporter_assertions.rb +107 -0
- data/lib/active_support/testing/isolation.rb +30 -29
- data/lib/active_support/testing/method_call_assertions.rb +24 -11
- 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 +16 -95
- data/lib/active_support/testing/parallelize_executor.rb +81 -0
- data/lib/active_support/testing/stream.rb +4 -6
- data/lib/active_support/testing/strict_warnings.rb +39 -0
- data/lib/active_support/testing/tagged_logging.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +89 -19
- data/lib/active_support/time_with_zone.rb +105 -70
- data/lib/active_support/values/time_zone.rb +59 -26
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/jdom.rb +4 -11
- data/lib/active_support/xml_mini/libxml.rb +5 -5
- data/lib/active_support/xml_mini/libxmlsax.rb +1 -1
- data/lib/active_support/xml_mini/nokogiri.rb +5 -5
- data/lib/active_support/xml_mini/nokogirisax.rb +2 -2
- data/lib/active_support/xml_mini/rexml.rb +9 -2
- data/lib/active_support/xml_mini.rb +7 -6
- data/lib/active_support.rb +40 -1
- metadata +127 -40
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -5
- data/lib/active_support/core_ext/hash/compact.rb +0 -5
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -5
- data/lib/active_support/core_ext/marshal.rb +0 -24
- data/lib/active_support/core_ext/module/reachable.rb +0 -6
- data/lib/active_support/core_ext/numeric/inquiry.rb +0 -5
- data/lib/active_support/core_ext/range/include_range.rb +0 -9
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +0 -23
- data/lib/active_support/core_ext/range/overlaps.rb +0 -10
- data/lib/active_support/core_ext/uri.rb +0 -25
- data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
- data/lib/active_support/per_thread_registry.rb +0 -60
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
module ForkTracker # :nodoc:
|
5
|
+
module ModernCoreExt
|
6
|
+
def _fork
|
7
|
+
pid = super
|
8
|
+
if pid == 0
|
9
|
+
ForkTracker.after_fork_callback
|
10
|
+
end
|
11
|
+
pid
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module CoreExt
|
16
|
+
def fork(...)
|
17
|
+
if block_given?
|
18
|
+
super do
|
19
|
+
ForkTracker.check!
|
20
|
+
yield
|
21
|
+
end
|
22
|
+
else
|
23
|
+
unless pid = super
|
24
|
+
ForkTracker.check!
|
25
|
+
end
|
26
|
+
pid
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
module CoreExtPrivate
|
32
|
+
include CoreExt
|
33
|
+
private :fork
|
34
|
+
end
|
35
|
+
|
36
|
+
@pid = Process.pid
|
37
|
+
@callbacks = []
|
38
|
+
|
39
|
+
class << self
|
40
|
+
def after_fork_callback
|
41
|
+
new_pid = Process.pid
|
42
|
+
if @pid != new_pid
|
43
|
+
@callbacks.each(&:call)
|
44
|
+
@pid = new_pid
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
if Process.respond_to?(:_fork) # Ruby 3.1+
|
49
|
+
def check!
|
50
|
+
# We trust the `_fork` callback
|
51
|
+
end
|
52
|
+
else
|
53
|
+
alias_method :check!, :after_fork_callback
|
54
|
+
end
|
55
|
+
|
56
|
+
def hook!
|
57
|
+
if Process.respond_to?(:_fork) # Ruby 3.1+
|
58
|
+
::Process.singleton_class.prepend(ModernCoreExt)
|
59
|
+
elsif Process.respond_to?(:fork)
|
60
|
+
::Object.prepend(CoreExtPrivate) if RUBY_VERSION < "3.0"
|
61
|
+
::Kernel.prepend(CoreExtPrivate)
|
62
|
+
::Kernel.singleton_class.prepend(CoreExt)
|
63
|
+
::Process.singleton_class.prepend(CoreExt)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def after_fork(&block)
|
68
|
+
@callbacks << block
|
69
|
+
block
|
70
|
+
end
|
71
|
+
|
72
|
+
def unregister(callback)
|
73
|
+
@callbacks.delete(callback)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
ActiveSupport::ForkTracker.hook!
|
@@ -1,16 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveSupport
|
4
|
-
# Returns the version of
|
4
|
+
# Returns the currently loaded version of Active Support as a +Gem::Version+.
|
5
5
|
def self.gem_version
|
6
6
|
Gem::Version.new VERSION::STRING
|
7
7
|
end
|
8
8
|
|
9
9
|
module VERSION
|
10
|
-
MAJOR =
|
11
|
-
MINOR =
|
12
|
-
TINY =
|
13
|
-
PRE = "
|
10
|
+
MAJOR = 7
|
11
|
+
MINOR = 1
|
12
|
+
TINY = 3
|
13
|
+
PRE = "2"
|
14
14
|
|
15
15
|
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
|
16
16
|
end
|
data/lib/active_support/gzip.rb
CHANGED
@@ -3,8 +3,11 @@
|
|
3
3
|
require "active_support/core_ext/hash/keys"
|
4
4
|
require "active_support/core_ext/hash/reverse_merge"
|
5
5
|
require "active_support/core_ext/hash/except"
|
6
|
+
require "active_support/core_ext/hash/slice"
|
6
7
|
|
7
8
|
module ActiveSupport
|
9
|
+
# = \Hash With Indifferent Access
|
10
|
+
#
|
8
11
|
# Implements a hash where keys <tt>:foo</tt> and <tt>"foo"</tt> are considered
|
9
12
|
# to be the same.
|
10
13
|
#
|
@@ -36,7 +39,7 @@ module ActiveSupport
|
|
36
39
|
#
|
37
40
|
# but this class is intended for use cases where strings or symbols are the
|
38
41
|
# expected keys and it is convenient to understand both as the same. For
|
39
|
-
# example the +params+ hash in Ruby on Rails.
|
42
|
+
# example the +params+ hash in Ruby on \Rails.
|
40
43
|
#
|
41
44
|
# Note that core extensions define <tt>Hash#with_indifferent_access</tt>:
|
42
45
|
#
|
@@ -44,7 +47,7 @@ module ActiveSupport
|
|
44
47
|
#
|
45
48
|
# which may be handy.
|
46
49
|
#
|
47
|
-
# To access this class outside of Rails, require the core extension with:
|
50
|
+
# To access this class outside of \Rails, require the core extension with:
|
48
51
|
#
|
49
52
|
# require "active_support/core_ext/hash/indifferent_access"
|
50
53
|
#
|
@@ -64,14 +67,16 @@ module ActiveSupport
|
|
64
67
|
self
|
65
68
|
end
|
66
69
|
|
67
|
-
def initialize(constructor =
|
70
|
+
def initialize(constructor = nil)
|
68
71
|
if constructor.respond_to?(:to_hash)
|
69
72
|
super()
|
70
73
|
update(constructor)
|
71
74
|
|
72
|
-
hash = constructor.to_hash
|
75
|
+
hash = constructor.is_a?(Hash) ? constructor : constructor.to_hash
|
73
76
|
self.default = hash.default if hash.default
|
74
77
|
self.default_proc = hash.default_proc if hash.default_proc
|
78
|
+
elsif constructor.nil?
|
79
|
+
super()
|
75
80
|
else
|
76
81
|
super(constructor)
|
77
82
|
end
|
@@ -91,12 +96,12 @@ module ActiveSupport
|
|
91
96
|
#
|
92
97
|
# This value can be later fetched using either +:key+ or <tt>'key'</tt>.
|
93
98
|
def []=(key, value)
|
94
|
-
regular_writer(convert_key(key), convert_value(value,
|
99
|
+
regular_writer(convert_key(key), convert_value(value, conversion: :assignment))
|
95
100
|
end
|
96
101
|
|
97
102
|
alias_method :store, :[]=
|
98
103
|
|
99
|
-
# Updates the receiver in-place, merging in the
|
104
|
+
# Updates the receiver in-place, merging in the hashes passed as arguments:
|
100
105
|
#
|
101
106
|
# hash_1 = ActiveSupport::HashWithIndifferentAccess.new
|
102
107
|
# hash_1[:key] = 'value'
|
@@ -106,11 +111,14 @@ module ActiveSupport
|
|
106
111
|
#
|
107
112
|
# hash_1.update(hash_2) # => {"key"=>"New Value!"}
|
108
113
|
#
|
109
|
-
#
|
110
|
-
#
|
114
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
115
|
+
# hash.update({ "a" => 1 }, { "b" => 2 }) # => { "a" => 1, "b" => 2 }
|
116
|
+
#
|
117
|
+
# The arguments can be either an
|
118
|
+
# +ActiveSupport::HashWithIndifferentAccess+ or a regular +Hash+.
|
111
119
|
# In either case the merge respects the semantics of indifferent access.
|
112
120
|
#
|
113
|
-
# If the argument is a regular hash with keys +:key+ and
|
121
|
+
# If the argument is a regular hash with keys +:key+ and <tt>"key"</tt> only one
|
114
122
|
# of the values end up in the receiver, but which one is unspecified.
|
115
123
|
#
|
116
124
|
# When given a block, the value for duplicated keys will be determined
|
@@ -121,18 +129,15 @@ module ActiveSupport
|
|
121
129
|
# hash_1[:key] = 10
|
122
130
|
# hash_2['key'] = 12
|
123
131
|
# hash_1.update(hash_2) { |key, old, new| old + new } # => {"key"=>22}
|
124
|
-
def update(
|
125
|
-
if
|
126
|
-
|
132
|
+
def update(*other_hashes, &block)
|
133
|
+
if other_hashes.size == 1
|
134
|
+
update_with_single_argument(other_hashes.first, block)
|
127
135
|
else
|
128
|
-
|
129
|
-
|
130
|
-
value = yield(convert_key(key), self[key], value)
|
131
|
-
end
|
132
|
-
regular_writer(convert_key(key), convert_value(value))
|
136
|
+
other_hashes.each do |other_hash|
|
137
|
+
update_with_single_argument(other_hash, block)
|
133
138
|
end
|
134
|
-
self
|
135
139
|
end
|
140
|
+
self
|
136
141
|
end
|
137
142
|
|
138
143
|
alias_method :merge!, :update
|
@@ -215,8 +220,12 @@ module ActiveSupport
|
|
215
220
|
# hash.default # => nil
|
216
221
|
# hash.default('foo') # => 'foo'
|
217
222
|
# hash.default(:foo) # => 'foo'
|
218
|
-
def default(
|
219
|
-
|
223
|
+
def default(key = (no_key = true))
|
224
|
+
if no_key
|
225
|
+
super()
|
226
|
+
else
|
227
|
+
super(convert_key(key))
|
228
|
+
end
|
220
229
|
end
|
221
230
|
|
222
231
|
# Returns an array of the values at the specified indices:
|
@@ -226,7 +235,8 @@ module ActiveSupport
|
|
226
235
|
# hash[:b] = 'y'
|
227
236
|
# hash.values_at('a', 'b') # => ["x", "y"]
|
228
237
|
def values_at(*keys)
|
229
|
-
|
238
|
+
keys.map! { |key| convert_key(key) }
|
239
|
+
super
|
230
240
|
end
|
231
241
|
|
232
242
|
# Returns an array of the values at the specified indices, but also
|
@@ -239,7 +249,8 @@ module ActiveSupport
|
|
239
249
|
# hash.fetch_values('a', 'c') { |key| 'z' } # => ["x", "z"]
|
240
250
|
# hash.fetch_values('a', 'c') # => KeyError: key not found: "c"
|
241
251
|
def fetch_values(*indices, &block)
|
242
|
-
|
252
|
+
indices.map! { |key| convert_key(key) }
|
253
|
+
super
|
243
254
|
end
|
244
255
|
|
245
256
|
# Returns a shallow copy of the hash.
|
@@ -259,8 +270,8 @@ module ActiveSupport
|
|
259
270
|
# This method has the same semantics of +update+, except it does not
|
260
271
|
# modify the receiver but rather returns a new hash with indifferent
|
261
272
|
# access with the result of the merge.
|
262
|
-
def merge(
|
263
|
-
dup.update(
|
273
|
+
def merge(*hashes, &block)
|
274
|
+
dup.update(*hashes, &block)
|
264
275
|
end
|
265
276
|
|
266
277
|
# Like +merge+ but the other way around: Merges the receiver into the
|
@@ -293,8 +304,12 @@ module ActiveSupport
|
|
293
304
|
super(convert_key(key))
|
294
305
|
end
|
295
306
|
|
307
|
+
# Returns a hash with indifferent access that includes everything except given keys.
|
308
|
+
# hash = { a: "x", b: "y", c: 10 }.with_indifferent_access
|
309
|
+
# hash.except(:a, "b") # => {c: 10}.with_indifferent_access
|
310
|
+
# hash # => { a: "x", b: "y", c: 10 }.with_indifferent_access
|
296
311
|
def except(*keys)
|
297
|
-
|
312
|
+
dup.except!(*keys)
|
298
313
|
end
|
299
314
|
alias_method :without, :except
|
300
315
|
|
@@ -319,21 +334,31 @@ module ActiveSupport
|
|
319
334
|
dup.tap { |hash| hash.reject!(*args, &block) }
|
320
335
|
end
|
321
336
|
|
322
|
-
def transform_values(
|
337
|
+
def transform_values(&block)
|
323
338
|
return to_enum(:transform_values) unless block_given?
|
324
|
-
dup.tap { |hash| hash.transform_values!(
|
339
|
+
dup.tap { |hash| hash.transform_values!(&block) }
|
325
340
|
end
|
326
341
|
|
327
|
-
|
328
|
-
|
329
|
-
|
342
|
+
NOT_GIVEN = Object.new # :nodoc:
|
343
|
+
|
344
|
+
def transform_keys(hash = NOT_GIVEN, &block)
|
345
|
+
return to_enum(:transform_keys) if NOT_GIVEN.equal?(hash) && !block_given?
|
346
|
+
dup.tap { |h| h.transform_keys!(hash, &block) }
|
330
347
|
end
|
331
348
|
|
332
|
-
def transform_keys!
|
333
|
-
return
|
334
|
-
|
335
|
-
|
349
|
+
def transform_keys!(hash = NOT_GIVEN, &block)
|
350
|
+
return to_enum(:transform_keys!) if NOT_GIVEN.equal?(hash) && !block_given?
|
351
|
+
|
352
|
+
if hash.nil?
|
353
|
+
super
|
354
|
+
elsif NOT_GIVEN.equal?(hash)
|
355
|
+
keys.each { |key| self[yield(key)] = delete(key) }
|
356
|
+
elsif block_given?
|
357
|
+
keys.each { |key| self[hash[key] || yield(key)] = delete(key) }
|
358
|
+
else
|
359
|
+
keys.each { |key| self[hash[key] || key] = delete(key) }
|
336
360
|
end
|
361
|
+
|
337
362
|
self
|
338
363
|
end
|
339
364
|
|
@@ -357,40 +382,59 @@ module ActiveSupport
|
|
357
382
|
set_defaults(_new_hash)
|
358
383
|
|
359
384
|
each do |key, value|
|
360
|
-
_new_hash[key] = convert_value(value,
|
385
|
+
_new_hash[key] = convert_value(value, conversion: :to_hash)
|
361
386
|
end
|
362
387
|
_new_hash
|
363
388
|
end
|
364
389
|
|
365
390
|
private
|
366
|
-
|
367
|
-
key
|
391
|
+
if Symbol.method_defined?(:name)
|
392
|
+
def convert_key(key)
|
393
|
+
key.kind_of?(Symbol) ? key.name : key
|
394
|
+
end
|
395
|
+
else
|
396
|
+
def convert_key(key)
|
397
|
+
key.kind_of?(Symbol) ? key.to_s : key
|
398
|
+
end
|
368
399
|
end
|
369
400
|
|
370
|
-
def convert_value(value,
|
401
|
+
def convert_value(value, conversion: nil)
|
371
402
|
if value.is_a? Hash
|
372
|
-
if
|
403
|
+
if conversion == :to_hash
|
373
404
|
value.to_hash
|
374
405
|
else
|
375
406
|
value.nested_under_indifferent_access
|
376
407
|
end
|
377
408
|
elsif value.is_a?(Array)
|
378
|
-
if
|
409
|
+
if conversion != :assignment || value.frozen?
|
379
410
|
value = value.dup
|
380
411
|
end
|
381
|
-
value.map! { |e| convert_value(e,
|
412
|
+
value.map! { |e| convert_value(e, conversion: conversion) }
|
382
413
|
else
|
383
414
|
value
|
384
415
|
end
|
385
416
|
end
|
386
417
|
|
387
|
-
def set_defaults(target)
|
418
|
+
def set_defaults(target)
|
388
419
|
if default_proc
|
389
420
|
target.default_proc = default_proc.dup
|
390
421
|
else
|
391
422
|
target.default = default
|
392
423
|
end
|
393
424
|
end
|
425
|
+
|
426
|
+
def update_with_single_argument(other_hash, block)
|
427
|
+
if other_hash.is_a? HashWithIndifferentAccess
|
428
|
+
regular_update(other_hash, &block)
|
429
|
+
else
|
430
|
+
other_hash.to_hash.each_pair do |key, value|
|
431
|
+
if block && key?(key)
|
432
|
+
value = block.call(convert_key(key), self[key], value)
|
433
|
+
end
|
434
|
+
regular_writer(convert_key(key), convert_value(value))
|
435
|
+
end
|
436
|
+
end
|
437
|
+
end
|
394
438
|
end
|
395
439
|
end
|
396
440
|
|
@@ -0,0 +1,53 @@
|
|
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
|
+
|
11
|
+
exception = false
|
12
|
+
exception_handler = ->(*args) do
|
13
|
+
exception = true
|
14
|
+
I18n.exception_handler.call(*args)
|
15
|
+
end
|
16
|
+
translation = I18n.translate(key, **html_safe_options, exception_handler: exception_handler)
|
17
|
+
if exception
|
18
|
+
translation
|
19
|
+
else
|
20
|
+
html_safe_translation(translation)
|
21
|
+
end
|
22
|
+
else
|
23
|
+
I18n.translate(key, **options)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def html_safe_translation_key?(key)
|
29
|
+
/(?:_|\b)html\z/.match?(key)
|
30
|
+
end
|
31
|
+
|
32
|
+
def html_escape_translation_options(options)
|
33
|
+
options.each do |name, value|
|
34
|
+
unless i18n_option?(name) || (name == :count && value.is_a?(Numeric))
|
35
|
+
options[name] = ERB::Util.html_escape(value.to_s)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def i18n_option?(name)
|
41
|
+
(@i18n_option_names ||= I18n::RESERVED_KEYS.to_set).include?(name)
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
def html_safe_translation(translation)
|
46
|
+
if translation.respond_to?(:map)
|
47
|
+
translation.map { |element| element.respond_to?(:html_safe) ? element.html_safe : element }
|
48
|
+
else
|
49
|
+
translation.respond_to?(:html_safe) ? translation.html_safe : translation
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/active_support/i18n.rb
CHANGED
@@ -5,8 +5,9 @@ require "active_support/core_ext/hash/except"
|
|
5
5
|
require "active_support/core_ext/hash/slice"
|
6
6
|
begin
|
7
7
|
require "i18n"
|
8
|
+
require "i18n/backend/fallbacks"
|
8
9
|
rescue LoadError => e
|
9
|
-
|
10
|
+
warn "The i18n gem is not available. Please add it to your Gemfile and run bundle install"
|
10
11
|
raise e
|
11
12
|
end
|
12
13
|
require "active_support/lazy_load_hooks"
|
@@ -12,9 +12,7 @@ module I18n
|
|
12
12
|
config.i18n.load_path = []
|
13
13
|
config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
|
14
14
|
|
15
|
-
|
16
|
-
config.eager_load_namespaces << I18n
|
17
|
-
end
|
15
|
+
config.eager_load_namespaces << I18n
|
18
16
|
|
19
17
|
# Set the i18n configuration after initialization since a lot of
|
20
18
|
# configuration is still usually done in application initializers.
|
@@ -50,8 +48,10 @@ module I18n
|
|
50
48
|
app.config.i18n.load_path.unshift(*value.flat_map(&:existent))
|
51
49
|
when :load_path
|
52
50
|
I18n.load_path += value
|
51
|
+
when :raise_on_missing_translations
|
52
|
+
setup_raise_on_missing_translations_config(app)
|
53
53
|
else
|
54
|
-
I18n.
|
54
|
+
I18n.public_send("#{setting}=", value)
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
@@ -60,21 +60,36 @@ module I18n
|
|
60
60
|
# Restore available locales check so it will take place from now on.
|
61
61
|
I18n.enforce_available_locales = enforce_available_locales
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
I18n.load_path.
|
66
|
-
|
63
|
+
if app.config.reloading_enabled?
|
64
|
+
directories = watched_dirs_with_extensions(reloadable_paths)
|
65
|
+
reloader = app.config.file_watcher.new(I18n.load_path.dup, directories) do
|
66
|
+
I18n.load_path.keep_if { |p| File.exist?(p) }
|
67
|
+
I18n.load_path |= reloadable_paths.flat_map(&:existent)
|
68
|
+
end
|
67
69
|
|
68
|
-
|
70
|
+
app.reloaders << reloader
|
71
|
+
app.reloader.to_run do
|
72
|
+
reloader.execute_if_updated { require_unload_lock! }
|
73
|
+
end
|
74
|
+
reloader.execute
|
69
75
|
end
|
70
76
|
|
71
|
-
|
72
|
-
|
73
|
-
|
77
|
+
@i18n_inited = true
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.setup_raise_on_missing_translations_config(app)
|
81
|
+
ActiveSupport.on_load(:action_view) do
|
82
|
+
ActionView::Helpers::TranslationHelper.raise_on_missing_translations = app.config.i18n.raise_on_missing_translations
|
74
83
|
end
|
75
|
-
reloader.execute
|
76
84
|
|
77
|
-
|
85
|
+
if app.config.i18n.raise_on_missing_translations &&
|
86
|
+
I18n.exception_handler.is_a?(I18n::ExceptionHandler) # Only override the i18n gem's default exception handler.
|
87
|
+
|
88
|
+
I18n.exception_handler = ->(exception, *) {
|
89
|
+
exception = exception.to_exception if exception.is_a?(I18n::MissingTranslation)
|
90
|
+
raise exception
|
91
|
+
}
|
92
|
+
end
|
78
93
|
end
|
79
94
|
|
80
95
|
def self.include_fallbacks_module
|
@@ -94,19 +109,6 @@ module I18n
|
|
94
109
|
[I18n.default_locale]
|
95
110
|
end
|
96
111
|
|
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
|
108
|
-
end
|
109
|
-
|
110
112
|
I18n.fallbacks = I18n::Locale::Fallbacks.new(*args)
|
111
113
|
end
|
112
114
|
|
@@ -2,12 +2,13 @@
|
|
2
2
|
|
3
3
|
require "concurrent/map"
|
4
4
|
require "active_support/i18n"
|
5
|
-
require "active_support/deprecation"
|
6
5
|
|
7
6
|
module ActiveSupport
|
8
7
|
module Inflector
|
9
8
|
extend self
|
10
9
|
|
10
|
+
# = Active Support \Inflections
|
11
|
+
#
|
11
12
|
# A singleton instance of this class is yielded by Inflector.inflections,
|
12
13
|
# which can then be used to specify additional inflection rules. If passed
|
13
14
|
# an optional locale, rules for other languages can be specified. The
|
@@ -17,13 +18,13 @@ module ActiveSupport
|
|
17
18
|
# inflect.plural /^(ox)$/i, '\1\2en'
|
18
19
|
# inflect.singular /^(ox)en/i, '\1'
|
19
20
|
#
|
20
|
-
# inflect.irregular '
|
21
|
+
# inflect.irregular 'cactus', 'cacti'
|
21
22
|
#
|
22
23
|
# inflect.uncountable 'equipment'
|
23
24
|
# end
|
24
25
|
#
|
25
26
|
# New rules are added at the top. So in the example above, the irregular
|
26
|
-
# rule for
|
27
|
+
# rule for cactus will now be the first of the pluralization and
|
27
28
|
# singularization rules that is runs. This guarantees that your rules run
|
28
29
|
# before any of the rules that may already have been loaded.
|
29
30
|
class Inflections
|
@@ -65,6 +66,13 @@ module ActiveSupport
|
|
65
66
|
@__instance__[locale] ||= new
|
66
67
|
end
|
67
68
|
|
69
|
+
def self.instance_or_fallback(locale)
|
70
|
+
I18n.fallbacks[locale].each do |k|
|
71
|
+
return @__instance__[k] if @__instance__.key?(k)
|
72
|
+
end
|
73
|
+
instance(locale)
|
74
|
+
end
|
75
|
+
|
68
76
|
attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms
|
69
77
|
|
70
78
|
attr_reader :acronyms_camelize_regex, :acronyms_underscore_regex # :nodoc:
|
@@ -77,7 +85,7 @@ module ActiveSupport
|
|
77
85
|
# Private, for the test suite.
|
78
86
|
def initialize_dup(orig) # :nodoc:
|
79
87
|
%w(plurals singulars uncountables humans acronyms).each do |scope|
|
80
|
-
instance_variable_set("@#{scope}", orig.
|
88
|
+
instance_variable_set("@#{scope}", orig.public_send(scope).dup)
|
81
89
|
end
|
82
90
|
define_acronym_regex_patterns
|
83
91
|
end
|
@@ -161,7 +169,7 @@ module ActiveSupport
|
|
161
169
|
# regular expressions. You simply pass the irregular in singular and
|
162
170
|
# plural form.
|
163
171
|
#
|
164
|
-
# irregular '
|
172
|
+
# irregular 'cactus', 'cacti'
|
165
173
|
# irregular 'person', 'people'
|
166
174
|
def irregular(singular, plural)
|
167
175
|
@uncountables.delete(singular)
|
@@ -216,15 +224,24 @@ module ActiveSupport
|
|
216
224
|
# Clears the loaded inflections within a given scope (default is
|
217
225
|
# <tt>:all</tt>). Give the scope as a symbol of the inflection type, the
|
218
226
|
# options are: <tt>:plurals</tt>, <tt>:singulars</tt>, <tt>:uncountables</tt>,
|
219
|
-
# <tt>:humans</tt>.
|
227
|
+
# <tt>:humans</tt>, <tt>:acronyms</tt>.
|
220
228
|
#
|
221
229
|
# clear :all
|
222
230
|
# clear :plurals
|
223
231
|
def clear(scope = :all)
|
224
232
|
case scope
|
225
233
|
when :all
|
226
|
-
|
227
|
-
|
234
|
+
clear(:acronyms)
|
235
|
+
clear(:plurals)
|
236
|
+
clear(:singulars)
|
237
|
+
clear(:uncountables)
|
238
|
+
clear(:humans)
|
239
|
+
when :acronyms
|
240
|
+
@acronyms = {}
|
241
|
+
define_acronym_regex_patterns
|
242
|
+
when :uncountables
|
243
|
+
@uncountables = Uncountables.new
|
244
|
+
when :plurals, :singulars, :humans
|
228
245
|
instance_variable_set "@#{scope}", []
|
229
246
|
end
|
230
247
|
end
|
@@ -249,7 +266,7 @@ module ActiveSupport
|
|
249
266
|
if block_given?
|
250
267
|
yield Inflections.instance(locale)
|
251
268
|
else
|
252
|
-
Inflections.
|
269
|
+
Inflections.instance_or_fallback(locale)
|
253
270
|
end
|
254
271
|
end
|
255
272
|
end
|