activesupport 7.0.8.7 → 7.2.2.1

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.
Files changed (198) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +143 -459
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -4
  5. data/lib/active_support/actionable_error.rb +3 -1
  6. data/lib/active_support/array_inquirer.rb +3 -1
  7. data/lib/active_support/backtrace_cleaner.rb +39 -7
  8. data/lib/active_support/benchmarkable.rb +1 -0
  9. data/lib/active_support/broadcast_logger.rb +251 -0
  10. data/lib/active_support/builder.rb +1 -1
  11. data/lib/active_support/cache/coder.rb +153 -0
  12. data/lib/active_support/cache/entry.rb +134 -0
  13. data/lib/active_support/cache/file_store.rb +49 -17
  14. data/lib/active_support/cache/mem_cache_store.rb +94 -128
  15. data/lib/active_support/cache/memory_store.rb +80 -25
  16. data/lib/active_support/cache/null_store.rb +6 -0
  17. data/lib/active_support/cache/redis_cache_store.rb +165 -152
  18. data/lib/active_support/cache/serializer_with_fallback.rb +152 -0
  19. data/lib/active_support/cache/strategy/local_cache.rb +29 -14
  20. data/lib/active_support/cache.rb +363 -291
  21. data/lib/active_support/callbacks.rb +118 -134
  22. data/lib/active_support/code_generator.rb +15 -10
  23. data/lib/active_support/concern.rb +4 -2
  24. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +42 -3
  25. data/lib/active_support/concurrency/null_lock.rb +13 -0
  26. data/lib/active_support/configurable.rb +10 -0
  27. data/lib/active_support/core_ext/array/conversions.rb +1 -2
  28. data/lib/active_support/core_ext/array.rb +0 -1
  29. data/lib/active_support/core_ext/class/subclasses.rb +17 -34
  30. data/lib/active_support/core_ext/date/blank.rb +4 -0
  31. data/lib/active_support/core_ext/date/conversions.rb +1 -2
  32. data/lib/active_support/core_ext/date.rb +0 -1
  33. data/lib/active_support/core_ext/date_and_time/calculations.rb +10 -0
  34. data/lib/active_support/core_ext/date_and_time/compatibility.rb +28 -1
  35. data/lib/active_support/core_ext/date_time/blank.rb +4 -0
  36. data/lib/active_support/core_ext/date_time/conversions.rb +2 -2
  37. data/lib/active_support/core_ext/date_time.rb +0 -1
  38. data/lib/active_support/core_ext/digest/uuid.rb +7 -10
  39. data/lib/active_support/core_ext/enumerable.rb +3 -75
  40. data/lib/active_support/core_ext/erb/util.rb +201 -0
  41. data/lib/active_support/core_ext/hash/conversions.rb +1 -1
  42. data/lib/active_support/core_ext/hash/deep_merge.rb +22 -14
  43. data/lib/active_support/core_ext/hash/keys.rb +4 -4
  44. data/lib/active_support/core_ext/module/attr_internal.rb +17 -6
  45. data/lib/active_support/core_ext/module/attribute_accessors.rb +6 -0
  46. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +34 -16
  47. data/lib/active_support/core_ext/module/concerning.rb +6 -6
  48. data/lib/active_support/core_ext/module/delegation.rb +20 -119
  49. data/lib/active_support/core_ext/module/deprecation.rb +12 -12
  50. data/lib/active_support/core_ext/module/introspection.rb +0 -1
  51. data/lib/active_support/core_ext/numeric/bytes.rb +9 -0
  52. data/lib/active_support/core_ext/numeric/conversions.rb +5 -3
  53. data/lib/active_support/core_ext/numeric.rb +0 -1
  54. data/lib/active_support/core_ext/object/blank.rb +45 -1
  55. data/lib/active_support/core_ext/object/deep_dup.rb +16 -0
  56. data/lib/active_support/core_ext/object/inclusion.rb +13 -5
  57. data/lib/active_support/core_ext/object/instance_variables.rb +4 -2
  58. data/lib/active_support/core_ext/object/json.rb +17 -7
  59. data/lib/active_support/core_ext/object/with.rb +46 -0
  60. data/lib/active_support/core_ext/object/with_options.rb +4 -4
  61. data/lib/active_support/core_ext/object.rb +1 -0
  62. data/lib/active_support/core_ext/pathname/blank.rb +20 -0
  63. data/lib/active_support/core_ext/pathname/existence.rb +2 -0
  64. data/lib/active_support/core_ext/pathname.rb +1 -0
  65. data/lib/active_support/core_ext/range/conversions.rb +28 -7
  66. data/lib/active_support/core_ext/range/overlap.rb +40 -0
  67. data/lib/active_support/core_ext/range.rb +1 -2
  68. data/lib/active_support/core_ext/securerandom.rb +1 -5
  69. data/lib/active_support/core_ext/string/conversions.rb +1 -1
  70. data/lib/active_support/core_ext/string/filters.rb +21 -15
  71. data/lib/active_support/core_ext/string/indent.rb +1 -1
  72. data/lib/active_support/core_ext/string/inflections.rb +16 -5
  73. data/lib/active_support/core_ext/string/multibyte.rb +1 -1
  74. data/lib/active_support/core_ext/string/output_safety.rb +34 -177
  75. data/lib/active_support/core_ext/thread/backtrace/location.rb +12 -0
  76. data/lib/active_support/core_ext/time/calculations.rb +36 -30
  77. data/lib/active_support/core_ext/time/compatibility.rb +16 -0
  78. data/lib/active_support/core_ext/time/conversions.rb +1 -3
  79. data/lib/active_support/core_ext/time/zones.rb +4 -4
  80. data/lib/active_support/core_ext/time.rb +0 -1
  81. data/lib/active_support/core_ext.rb +0 -1
  82. data/lib/active_support/current_attributes.rb +53 -46
  83. data/lib/active_support/deep_mergeable.rb +53 -0
  84. data/lib/active_support/delegation.rb +202 -0
  85. data/lib/active_support/dependencies/autoload.rb +9 -16
  86. data/lib/active_support/deprecation/behaviors.rb +65 -42
  87. data/lib/active_support/deprecation/constant_accessor.rb +47 -25
  88. data/lib/active_support/deprecation/deprecators.rb +104 -0
  89. data/lib/active_support/deprecation/disallowed.rb +3 -5
  90. data/lib/active_support/deprecation/method_wrappers.rb +6 -23
  91. data/lib/active_support/deprecation/proxy_wrappers.rb +34 -22
  92. data/lib/active_support/deprecation/reporting.rb +49 -27
  93. data/lib/active_support/deprecation.rb +39 -9
  94. data/lib/active_support/deprecator.rb +7 -0
  95. data/lib/active_support/descendants_tracker.rb +66 -172
  96. data/lib/active_support/duration/iso8601_parser.rb +2 -2
  97. data/lib/active_support/duration/iso8601_serializer.rb +1 -4
  98. data/lib/active_support/duration.rb +13 -7
  99. data/lib/active_support/encrypted_configuration.rb +30 -9
  100. data/lib/active_support/encrypted_file.rb +9 -4
  101. data/lib/active_support/environment_inquirer.rb +22 -2
  102. data/lib/active_support/error_reporter/test_helper.rb +15 -0
  103. data/lib/active_support/error_reporter.rb +160 -36
  104. data/lib/active_support/evented_file_update_checker.rb +0 -1
  105. data/lib/active_support/execution_wrapper.rb +4 -5
  106. data/lib/active_support/file_update_checker.rb +5 -3
  107. data/lib/active_support/fork_tracker.rb +4 -32
  108. data/lib/active_support/gem_version.rb +4 -4
  109. data/lib/active_support/gzip.rb +2 -0
  110. data/lib/active_support/hash_with_indifferent_access.rb +41 -25
  111. data/lib/active_support/html_safe_translation.rb +19 -6
  112. data/lib/active_support/i18n.rb +1 -1
  113. data/lib/active_support/i18n_railtie.rb +20 -13
  114. data/lib/active_support/inflector/inflections.rb +2 -0
  115. data/lib/active_support/inflector/methods.rb +23 -11
  116. data/lib/active_support/inflector/transliterate.rb +3 -1
  117. data/lib/active_support/isolated_execution_state.rb +26 -22
  118. data/lib/active_support/json/decoding.rb +2 -1
  119. data/lib/active_support/json/encoding.rb +25 -43
  120. data/lib/active_support/key_generator.rb +9 -1
  121. data/lib/active_support/lazy_load_hooks.rb +6 -4
  122. data/lib/active_support/locale/en.yml +2 -0
  123. data/lib/active_support/log_subscriber.rb +74 -34
  124. data/lib/active_support/logger.rb +22 -60
  125. data/lib/active_support/logger_thread_safe_level.rb +10 -32
  126. data/lib/active_support/message_encryptor.rb +197 -53
  127. data/lib/active_support/message_encryptors.rb +141 -0
  128. data/lib/active_support/message_pack/cache_serializer.rb +23 -0
  129. data/lib/active_support/message_pack/extensions.rb +305 -0
  130. data/lib/active_support/message_pack/serializer.rb +63 -0
  131. data/lib/active_support/message_pack.rb +50 -0
  132. data/lib/active_support/message_verifier.rb +220 -89
  133. data/lib/active_support/message_verifiers.rb +135 -0
  134. data/lib/active_support/messages/codec.rb +65 -0
  135. data/lib/active_support/messages/metadata.rb +111 -45
  136. data/lib/active_support/messages/rotation_coordinator.rb +93 -0
  137. data/lib/active_support/messages/rotator.rb +34 -32
  138. data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
  139. data/lib/active_support/multibyte/chars.rb +4 -2
  140. data/lib/active_support/multibyte/unicode.rb +9 -37
  141. data/lib/active_support/notifications/fanout.rb +248 -87
  142. data/lib/active_support/notifications/instrumenter.rb +93 -25
  143. data/lib/active_support/notifications.rb +29 -28
  144. data/lib/active_support/number_helper/number_converter.rb +16 -7
  145. data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -6
  146. data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -3
  147. data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -0
  148. data/lib/active_support/number_helper.rb +379 -318
  149. data/lib/active_support/option_merger.rb +2 -2
  150. data/lib/active_support/ordered_hash.rb +3 -3
  151. data/lib/active_support/ordered_options.rb +67 -15
  152. data/lib/active_support/parameter_filter.rb +84 -69
  153. data/lib/active_support/proxy_object.rb +8 -3
  154. data/lib/active_support/railtie.rb +25 -20
  155. data/lib/active_support/reloader.rb +12 -4
  156. data/lib/active_support/rescuable.rb +2 -0
  157. data/lib/active_support/secure_compare_rotator.rb +16 -9
  158. data/lib/active_support/string_inquirer.rb +4 -2
  159. data/lib/active_support/subscriber.rb +10 -27
  160. data/lib/active_support/syntax_error_proxy.rb +60 -0
  161. data/lib/active_support/tagged_logging.rb +64 -25
  162. data/lib/active_support/test_case.rb +156 -7
  163. data/lib/active_support/testing/assertions.rb +28 -12
  164. data/lib/active_support/testing/autorun.rb +0 -2
  165. data/lib/active_support/testing/constant_stubbing.rb +54 -0
  166. data/lib/active_support/testing/deprecation.rb +20 -27
  167. data/lib/active_support/testing/error_reporter_assertions.rb +107 -0
  168. data/lib/active_support/testing/isolation.rb +21 -9
  169. data/lib/active_support/testing/method_call_assertions.rb +7 -8
  170. data/lib/active_support/testing/parallelization/server.rb +3 -0
  171. data/lib/active_support/testing/parallelize_executor.rb +8 -3
  172. data/lib/active_support/testing/setup_and_teardown.rb +2 -0
  173. data/lib/active_support/testing/stream.rb +1 -1
  174. data/lib/active_support/testing/strict_warnings.rb +43 -0
  175. data/lib/active_support/testing/tests_without_assertions.rb +19 -0
  176. data/lib/active_support/testing/time_helpers.rb +38 -16
  177. data/lib/active_support/time_with_zone.rb +12 -18
  178. data/lib/active_support/values/time_zone.rb +25 -14
  179. data/lib/active_support/version.rb +1 -1
  180. data/lib/active_support/xml_mini/jdom.rb +3 -10
  181. data/lib/active_support/xml_mini/nokogiri.rb +1 -1
  182. data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
  183. data/lib/active_support/xml_mini/rexml.rb +1 -1
  184. data/lib/active_support/xml_mini.rb +12 -3
  185. data/lib/active_support.rb +15 -3
  186. metadata +140 -19
  187. data/lib/active_support/core_ext/array/deprecated_conversions.rb +0 -25
  188. data/lib/active_support/core_ext/date/deprecated_conversions.rb +0 -40
  189. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +0 -36
  190. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +0 -60
  191. data/lib/active_support/core_ext/range/deprecated_conversions.rb +0 -36
  192. data/lib/active_support/core_ext/range/include_time_with_zone.rb +0 -5
  193. data/lib/active_support/core_ext/range/overlaps.rb +0 -10
  194. data/lib/active_support/core_ext/time/deprecated_conversions.rb +0 -73
  195. data/lib/active_support/core_ext/uri.rb +0 -5
  196. data/lib/active_support/deprecation/instance_delegator.rb +0 -38
  197. data/lib/active_support/per_thread_registry.rb +0 -65
  198. data/lib/active_support/ruby_features.rb +0 -7
@@ -31,8 +31,8 @@ module ActiveSupport
31
31
  end
32
32
  end
33
33
 
34
- def respond_to_missing?(*arguments)
35
- @context.respond_to?(*arguments)
34
+ def respond_to_missing?(...)
35
+ @context.respond_to?(...)
36
36
  end
37
37
  end
38
38
  end
@@ -7,7 +7,7 @@ YAML.add_builtin_type("omap") do |type, val|
7
7
  end
8
8
 
9
9
  module ActiveSupport
10
- # DEPRECATED: <tt>ActiveSupport::OrderedHash</tt> implements a hash that preserves
10
+ # DEPRECATED: +ActiveSupport::OrderedHash+ implements a hash that preserves
11
11
  # insertion order.
12
12
  #
13
13
  # oh = ActiveSupport::OrderedHash.new
@@ -17,9 +17,9 @@ module ActiveSupport
17
17
  #
18
18
  # Also, maps the +omap+ feature for YAML files
19
19
  # (See https://yaml.org/type/omap.html) to support ordered items
20
- # when loading from yaml.
20
+ # when loading from YAML.
21
21
  #
22
- # <tt>ActiveSupport::OrderedHash</tt> is namespaced to prevent conflicts
22
+ # +ActiveSupport::OrderedHash+ is namespaced to prevent conflicts
23
23
  # with other implementations.
24
24
  class OrderedHash < ::Hash # :nodoc:
25
25
  def to_yaml_type
@@ -3,6 +3,8 @@
3
3
  require "active_support/core_ext/object/blank"
4
4
 
5
5
  module ActiveSupport
6
+ # = Ordered Options
7
+ #
6
8
  # +OrderedOptions+ inherits from +Hash+ and provides dynamic accessor methods.
7
9
  #
8
10
  # With a +Hash+, key-value pairs are typically managed like this:
@@ -40,18 +42,18 @@ module ActiveSupport
40
42
  super(key.to_sym)
41
43
  end
42
44
 
43
- def method_missing(name, *args)
44
- name_string = +name.to_s
45
- if name_string.chomp!("=")
46
- self[name_string] = args.first
47
- else
48
- bangs = name_string.chomp!("!")
45
+ def dig(key, *identifiers)
46
+ super(key.to_sym, *identifiers)
47
+ end
49
48
 
50
- if bangs
51
- self[name_string].presence || raise(KeyError.new(":#{name_string} is blank"))
52
- else
53
- self[name_string]
54
- end
49
+ def method_missing(method, *args)
50
+ if method.end_with?("=")
51
+ self[method.name.chomp("=")] = args.first
52
+ elsif method.end_with?("!")
53
+ name_string = method.name.chomp("!")
54
+ self[name_string].presence || raise(KeyError.new(":#{name_string} is blank"))
55
+ else
56
+ self[method.name]
55
57
  end
56
58
  end
57
59
 
@@ -68,6 +70,8 @@ module ActiveSupport
68
70
  end
69
71
  end
70
72
 
73
+ # = Inheritable Options
74
+ #
71
75
  # +InheritableOptions+ provides a constructor to build an OrderedOptions
72
76
  # hash inherited from another hash.
73
77
  #
@@ -76,20 +80,68 @@ module ActiveSupport
76
80
  # h = ActiveSupport::InheritableOptions.new({ girl: 'Mary', boy: 'John' })
77
81
  # h.girl # => 'Mary'
78
82
  # h.boy # => 'John'
83
+ #
84
+ # If the existing hash has string keys, call Hash#symbolize_keys on it.
85
+ #
86
+ # h = ActiveSupport::InheritableOptions.new({ 'girl' => 'Mary', 'boy' => 'John' }.symbolize_keys)
87
+ # h.girl # => 'Mary'
88
+ # h.boy # => 'John'
79
89
  class InheritableOptions < OrderedOptions
80
90
  def initialize(parent = nil)
81
- if parent.kind_of?(OrderedOptions)
91
+ @parent = parent
92
+ if @parent.kind_of?(OrderedOptions)
82
93
  # use the faster _get when dealing with OrderedOptions
83
- super() { |h, k| parent._get(k) }
84
- elsif parent
85
- super() { |h, k| parent[k] }
94
+ super() { |h, k| @parent._get(k) }
95
+ elsif @parent
96
+ super() { |h, k| @parent[k] }
86
97
  else
87
98
  super()
99
+ @parent = {}
88
100
  end
89
101
  end
90
102
 
103
+ def to_h
104
+ @parent.merge(self)
105
+ end
106
+
107
+ def ==(other)
108
+ to_h == other.to_h
109
+ end
110
+
111
+ def inspect
112
+ "#<#{self.class.name} #{to_h.inspect}>"
113
+ end
114
+
115
+ def to_s
116
+ to_h.to_s
117
+ end
118
+
119
+ def pretty_print(pp)
120
+ pp.pp_hash(to_h)
121
+ end
122
+
123
+ alias_method :own_key?, :key?
124
+ private :own_key?
125
+
126
+ def key?(key)
127
+ super || @parent.key?(key)
128
+ end
129
+
130
+ def overridden?(key)
131
+ !!(@parent && @parent.key?(key) && own_key?(key.to_sym))
132
+ end
133
+
91
134
  def inheritable_copy
92
135
  self.class.new(self)
93
136
  end
137
+
138
+ def to_a
139
+ entries
140
+ end
141
+
142
+ def each(&block)
143
+ to_h.each(&block)
144
+ self
145
+ end
94
146
  end
95
147
  end
@@ -1,8 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/core_ext/object/duplicable"
4
+ require "active_support/core_ext/array/extract"
4
5
 
5
6
  module ActiveSupport
7
+ # = Active Support Parameter Filter
8
+ #
6
9
  # +ParameterFilter+ replaces values in a <tt>Hash</tt>-like object if their
7
10
  # keys match one of the specified filters.
8
11
  #
@@ -36,6 +39,34 @@ module ActiveSupport
36
39
  class ParameterFilter
37
40
  FILTERED = "[FILTERED]" # :nodoc:
38
41
 
42
+ # Precompiles an array of filters that otherwise would be passed directly to
43
+ # #initialize. Depending on the quantity and types of filters,
44
+ # precompilation can improve filtering performance, especially in the case
45
+ # where the ParameterFilter instance itself cannot be retained (but the
46
+ # precompiled filters can be retained).
47
+ #
48
+ # filters = [/foo/, :bar, "nested.baz", /nested\.qux/]
49
+ #
50
+ # precompiled = ActiveSupport::ParameterFilter.precompile_filters(filters)
51
+ # # => [/(?-mix:foo)|(?i:bar)/, /(?i:nested\.baz)|(?-mix:nested\.qux)/]
52
+ #
53
+ # ActiveSupport::ParameterFilter.new(precompiled)
54
+ #
55
+ def self.precompile_filters(filters)
56
+ filters, patterns = filters.partition { |filter| filter.is_a?(Proc) }
57
+
58
+ patterns.map! do |pattern|
59
+ pattern.is_a?(Regexp) ? pattern : "(?i:#{Regexp.escape pattern.to_s})"
60
+ end
61
+
62
+ deep_patterns = patterns.extract! { |pattern| pattern.to_s.include?("\\.") }
63
+
64
+ filters << Regexp.new(patterns.join("|")) if patterns.any?
65
+ filters << Regexp.new(deep_patterns.join("|")) if deep_patterns.any?
66
+
67
+ filters
68
+ end
69
+
39
70
  # Create instance with given filters. Supported type of filters are +String+, +Regexp+, and +Proc+.
40
71
  # Other types of filters are treated as +String+ using +to_s+.
41
72
  # For +Proc+ filters, key, value, and optional original hash is passed to block arguments.
@@ -44,99 +75,83 @@ module ActiveSupport
44
75
  #
45
76
  # * <tt>:mask</tt> - A replaced object when filtered. Defaults to <tt>"[FILTERED]"</tt>.
46
77
  def initialize(filters = [], mask: FILTERED)
47
- @filters = filters
48
78
  @mask = mask
79
+ compile_filters!(filters)
49
80
  end
50
81
 
51
82
  # Mask value of +params+ if key matches one of filters.
52
83
  def filter(params)
53
- compiled_filter.call(params)
84
+ @no_filters ? params.dup : call(params)
54
85
  end
55
86
 
56
87
  # Returns filtered value for given key. For +Proc+ filters, third block argument is not populated.
57
88
  def filter_param(key, value)
58
- @filters.empty? ? value : compiled_filter.value_for_key(key, value)
89
+ @no_filters ? value : value_for_key(key, value)
59
90
  end
60
91
 
61
92
  private
62
- def compiled_filter
63
- @compiled_filter ||= CompiledFilter.compile(@filters, mask: @mask)
64
- end
65
-
66
- class CompiledFilter # :nodoc:
67
- def self.compile(filters, mask:)
68
- return lambda { |params| params.dup } if filters.empty?
69
-
70
- strings, regexps, blocks, deep_regexps, deep_strings = [], [], [], nil, nil
71
-
72
- filters.each do |item|
73
- case item
74
- when Proc
75
- blocks << item
76
- when Regexp
77
- if item.to_s.include?("\\.")
78
- (deep_regexps ||= []) << item
79
- else
80
- regexps << item
81
- end
93
+ def compile_filters!(filters)
94
+ @no_filters = filters.empty?
95
+ return if @no_filters
96
+
97
+ @regexps, strings = [], []
98
+ @deep_regexps, deep_strings = nil, nil
99
+ @blocks = nil
100
+
101
+ filters.each do |item|
102
+ case item
103
+ when Proc
104
+ (@blocks ||= []) << item
105
+ when Regexp
106
+ if item.to_s.include?("\\.")
107
+ (@deep_regexps ||= []) << item
108
+ else
109
+ @regexps << item
110
+ end
111
+ else
112
+ s = Regexp.escape(item.to_s)
113
+ if s.include?("\\.")
114
+ (deep_strings ||= []) << s
82
115
  else
83
- s = Regexp.escape(item.to_s)
84
- if s.include?("\\.")
85
- (deep_strings ||= []) << s
86
- else
87
- strings << s
88
- end
116
+ strings << s
89
117
  end
90
118
  end
91
-
92
- regexps << Regexp.new(strings.join("|"), true) unless strings.empty?
93
- (deep_regexps ||= []) << Regexp.new(deep_strings.join("|"), true) if deep_strings&.any?
94
-
95
- new regexps, deep_regexps, blocks, mask: mask
96
119
  end
97
120
 
98
- attr_reader :regexps, :deep_regexps, :blocks
121
+ @regexps << Regexp.new(strings.join("|"), true) unless strings.empty?
122
+ (@deep_regexps ||= []) << Regexp.new(deep_strings.join("|"), true) if deep_strings
123
+ end
124
+
125
+ def call(params, full_parent_key = nil, original_params = params)
126
+ filtered_params = params.class.new
99
127
 
100
- def initialize(regexps, deep_regexps, blocks, mask:)
101
- @regexps = regexps
102
- @deep_regexps = deep_regexps&.any? ? deep_regexps : nil
103
- @blocks = blocks
104
- @mask = mask
128
+ params.each do |key, value|
129
+ filtered_params[key] = value_for_key(key, value, full_parent_key, original_params)
105
130
  end
106
131
 
107
- def call(params, parents = [], original_params = params)
108
- filtered_params = params.class.new
109
-
110
- params.each do |key, value|
111
- filtered_params[key] = value_for_key(key, value, parents, original_params)
112
- end
132
+ filtered_params
133
+ end
113
134
 
114
- filtered_params
135
+ def value_for_key(key, value, full_parent_key = nil, original_params = nil)
136
+ if @deep_regexps
137
+ full_key = full_parent_key ? "#{full_parent_key}.#{key}" : key.to_s
115
138
  end
116
139
 
117
- def value_for_key(key, value, parents = [], original_params = nil)
118
- parents.push(key) if deep_regexps
119
- if regexps.any? { |r| r.match?(key.to_s) }
120
- value = @mask
121
- elsif deep_regexps && (joined = parents.join(".")) && deep_regexps.any? { |r| r.match?(joined) }
122
- value = @mask
123
- elsif value.is_a?(Hash)
124
- value = call(value, parents, original_params)
125
- elsif value.is_a?(Array)
126
- # If we don't pop the current parent it will be duplicated as we
127
- # process each array value.
128
- parents.pop if deep_regexps
129
- value = value.map { |v| value_for_key(key, v, parents, original_params) }
130
- # Restore the parent stack after processing the array.
131
- parents.push(key) if deep_regexps
132
- elsif blocks.any?
133
- key = key.dup if key.duplicable?
134
- value = value.dup if value.duplicable?
135
- blocks.each { |b| b.arity == 2 ? b.call(key, value) : b.call(key, value, original_params) }
136
- end
137
- parents.pop if deep_regexps
138
- value
140
+ if @regexps.any? { |r| r.match?(key.to_s) }
141
+ value = @mask
142
+ elsif @deep_regexps&.any? { |r| r.match?(full_key) }
143
+ value = @mask
144
+ elsif value.is_a?(Hash)
145
+ value = call(value, full_key, original_params)
146
+ elsif value.is_a?(Array)
147
+ value = value.map { |v| value_for_key(key, v, full_parent_key, original_params) }
148
+ elsif @blocks
149
+ key = key.dup if key.duplicable?
150
+ value = value.dup if value.duplicable?
151
+ @blocks.each { |b| b.arity == 2 ? b.call(key, value) : b.call(key, value, original_params) }
139
152
  end
153
+
154
+ value
140
155
  end
141
156
  end
142
157
  end
@@ -1,9 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveSupport
4
- # A class with no predefined methods that behaves similarly to Builder's
5
- # BlankSlate. Used for proxy classes.
6
- class ProxyObject < ::BasicObject
4
+ class ProxyObject < ::BasicObject # :nodoc:
7
5
  undef_method :==
8
6
  undef_method :equal?
9
7
 
@@ -11,5 +9,12 @@ module ActiveSupport
11
9
  def raise(*args)
12
10
  ::Object.send(:raise, *args)
13
11
  end
12
+
13
+ def self.inherited(_subclass)
14
+ ::ActiveSupport.deprecator.warn(<<~MSG)
15
+ ActiveSupport::ProxyObject is deprecated and will be removed in Rails 8.0.
16
+ Use Ruby's built-in BasicObject instead.
17
+ MSG
18
+ end
14
19
  end
15
20
  end
@@ -6,10 +6,13 @@ require "active_support/i18n_railtie"
6
6
  module ActiveSupport
7
7
  class Railtie < Rails::Railtie # :nodoc:
8
8
  config.active_support = ActiveSupport::OrderedOptions.new
9
- config.active_support.disable_to_s_conversion = false
10
9
 
11
10
  config.eager_load_namespaces << ActiveSupport
12
11
 
12
+ initializer "active_support.deprecator", before: :load_environment_config do |app|
13
+ app.deprecators[:active_support] = ActiveSupport.deprecator
14
+ end
15
+
13
16
  initializer "active_support.isolation_level" do |app|
14
17
  config.after_initialize do
15
18
  if level = app.config.active_support.delete(:isolation_level)
@@ -18,11 +21,10 @@ module ActiveSupport
18
21
  end
19
22
  end
20
23
 
21
- initializer "active_support.remove_deprecated_time_with_zone_name" do |app|
24
+ initializer "active_support.raise_on_invalid_cache_expiration_time" do |app|
22
25
  config.after_initialize do
23
- if app.config.active_support.remove_deprecated_time_with_zone_name
24
- require "active_support/time_with_zone"
25
- TimeWithZone.singleton_class.remove_method(:name)
26
+ if app.config.active_support.raise_on_invalid_cache_expiration_time
27
+ ActiveSupport::Cache::Store.raise_on_invalid_cache_expiration_time = true
26
28
  end
27
29
  end
28
30
  end
@@ -63,20 +65,20 @@ module ActiveSupport
63
65
 
64
66
  initializer "active_support.deprecation_behavior" do |app|
65
67
  if app.config.active_support.report_deprecations == false
66
- ActiveSupport::Deprecation.silenced = true
67
- ActiveSupport::Deprecation.behavior = :silence
68
- ActiveSupport::Deprecation.disallowed_behavior = :silence
68
+ app.deprecators.silenced = true
69
+ app.deprecators.behavior = :silence
70
+ app.deprecators.disallowed_behavior = :silence
69
71
  else
70
72
  if deprecation = app.config.active_support.deprecation
71
- ActiveSupport::Deprecation.behavior = deprecation
73
+ app.deprecators.behavior = deprecation
72
74
  end
73
75
 
74
76
  if disallowed_deprecation = app.config.active_support.disallowed_deprecation
75
- ActiveSupport::Deprecation.disallowed_behavior = disallowed_deprecation
77
+ app.deprecators.disallowed_behavior = disallowed_deprecation
76
78
  end
77
79
 
78
80
  if disallowed_warnings = app.config.active_support.disallowed_deprecation_warnings
79
- ActiveSupport::Deprecation.disallowed_warnings = disallowed_warnings
81
+ app.deprecators.disallowed_warnings = disallowed_warnings
80
82
  end
81
83
  end
82
84
  end
@@ -87,10 +89,11 @@ module ActiveSupport
87
89
  begin
88
90
  TZInfo::DataSource.get
89
91
  rescue TZInfo::DataSourceNotFound => e
90
- raise e.exception "tzinfo-data is not present. Please add gem 'tzinfo-data' to your Gemfile and run bundle install"
92
+ raise e.exception('tzinfo-data is not present. Please add gem "tzinfo-data" to your Gemfile and run bundle install')
91
93
  end
92
94
  require "active_support/core_ext/time/zones"
93
95
  Time.zone_default = Time.find_zone!(app.config.time_zone)
96
+ config.eager_load_namespaces << TZInfo
94
97
  end
95
98
 
96
99
  # Sets the default week start
@@ -113,10 +116,6 @@ module ActiveSupport
113
116
  end
114
117
  end
115
118
 
116
- initializer "active_support.set_error_reporter" do |app|
117
- ActiveSupport.error_reporter = app.executor.error_reporter
118
- end
119
-
120
119
  initializer "active_support.set_configs" do |app|
121
120
  app.config.active_support.each do |k, v|
122
121
  k = "#{k}="
@@ -140,13 +139,19 @@ module ActiveSupport
140
139
  end
141
140
  end
142
141
 
143
- initializer "active_support.set_rfc4122_namespaced_uuids" do |app|
142
+ initializer "active_support.set_default_message_serializer" do |app|
144
143
  config.after_initialize do
145
- if app.config.active_support.use_rfc4122_namespaced_uuids
146
- require "active_support/core_ext/digest"
147
- ::Digest::UUID.use_rfc4122_namespaced_uuids = app.config.active_support.use_rfc4122_namespaced_uuids
144
+ if message_serializer = app.config.active_support.message_serializer
145
+ ActiveSupport::Messages::Codec.default_serializer = message_serializer
148
146
  end
149
147
  end
150
148
  end
149
+
150
+ initializer "active_support.set_use_message_serializer_for_metadata" do |app|
151
+ config.after_initialize do
152
+ ActiveSupport::Messages::Metadata.use_message_serializer_for_metadata =
153
+ app.config.active_support.use_message_serializer_for_metadata
154
+ end
155
+ end
151
156
  end
152
157
  end
@@ -4,7 +4,8 @@ require "active_support/execution_wrapper"
4
4
  require "active_support/executor"
5
5
 
6
6
  module ActiveSupport
7
- #--
7
+ # = Active Support \Reloader
8
+ #
8
9
  # This class defines several callbacks:
9
10
  #
10
11
  # to_prepare -- Run once at application startup, and also from
@@ -67,9 +68,16 @@ module ActiveSupport
67
68
  end
68
69
 
69
70
  # Run the supplied block as a work unit, reloading code as needed
70
- def self.wrap
71
- executor.wrap do
72
- super
71
+ def self.wrap(**kwargs)
72
+ return yield if active?
73
+
74
+ executor.wrap(**kwargs) do
75
+ instance = run!
76
+ begin
77
+ yield
78
+ ensure
79
+ instance.complete!
80
+ end
73
81
  end
74
82
  end
75
83
 
@@ -5,6 +5,8 @@ require "active_support/core_ext/class/attribute"
5
5
  require "active_support/core_ext/string/inflections"
6
6
 
7
7
  module ActiveSupport
8
+ # = Active Support \Rescuable
9
+ #
8
10
  # Rescuable module adds support for easier exception handling.
9
11
  module Rescuable
10
12
  extend Concern
@@ -4,6 +4,8 @@ require "active_support/security_utils"
4
4
  require "active_support/messages/rotator"
5
5
 
6
6
  module ActiveSupport
7
+ # = Secure Compare Rotator
8
+ #
7
9
  # The ActiveSupport::SecureCompareRotator is a wrapper around ActiveSupport::SecurityUtils.secure_compare
8
10
  # and allows you to rotate a previously defined value to a new one.
9
11
  #
@@ -29,23 +31,28 @@ module ActiveSupport
29
31
  # end
30
32
  class SecureCompareRotator
31
33
  include SecurityUtils
32
- prepend Messages::Rotator
33
34
 
34
35
  InvalidMatch = Class.new(StandardError)
35
36
 
36
- def initialize(value, **_options)
37
+ def initialize(value, on_rotation: nil)
37
38
  @value = value
39
+ @rotate_values = []
40
+ @on_rotation = on_rotation
38
41
  end
39
42
 
40
- def secure_compare!(other_value, on_rotation: @on_rotation)
41
- secure_compare(@value, other_value) ||
42
- run_rotations(on_rotation) { |wrapper| wrapper.secure_compare!(other_value) } ||
43
- raise(InvalidMatch)
43
+ def rotate(previous_value)
44
+ @rotate_values << previous_value
44
45
  end
45
46
 
46
- private
47
- def build_rotation(previous_value, _options)
48
- self.class.new(previous_value)
47
+ def secure_compare!(other_value, on_rotation: @on_rotation)
48
+ if secure_compare(@value, other_value)
49
+ true
50
+ elsif @rotate_values.any? { |value| secure_compare(value, other_value) }
51
+ on_rotation&.call
52
+ true
53
+ else
54
+ raise InvalidMatch
49
55
  end
56
+ end
50
57
  end
51
58
  end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveSupport
4
+ # = \String Inquirer
5
+ #
4
6
  # Wrapping a string in this class gives you a prettier way to test
5
7
  # for equality. The value returned by <tt>Rails.env</tt> is wrapped
6
8
  # in a StringInquirer object, so instead of calling this:
@@ -11,7 +13,7 @@ module ActiveSupport
11
13
  #
12
14
  # Rails.env.production?
13
15
  #
14
- # == Instantiating a new StringInquirer
16
+ # == Instantiating a new \StringInquirer
15
17
  #
16
18
  # vehicle = ActiveSupport::StringInquirer.new('car')
17
19
  # vehicle.car? # => true
@@ -22,7 +24,7 @@ module ActiveSupport
22
24
  method_name.end_with?("?") || super
23
25
  end
24
26
 
25
- def method_missing(method_name, *arguments)
27
+ def method_missing(method_name, ...)
26
28
  if method_name.end_with?("?")
27
29
  self == method_name[0..-2]
28
30
  else
@@ -3,7 +3,9 @@
3
3
  require "active_support/notifications"
4
4
 
5
5
  module ActiveSupport
6
- # ActiveSupport::Subscriber is an object set to consume
6
+ # = Active Support \Subscriber
7
+ #
8
+ # +ActiveSupport::Subscriber+ is an object set to consume
7
9
  # ActiveSupport::Notifications. The subscriber dispatches notifications to
8
10
  # a registered object based on its given namespace.
9
11
  #
@@ -20,9 +22,9 @@ module ActiveSupport
20
22
  # end
21
23
  # end
22
24
  #
23
- # After configured, whenever a "sql.active_record" notification is published,
24
- # it will properly dispatch the event (ActiveSupport::Notifications::Event) to
25
- # the +sql+ method.
25
+ # After configured, whenever a <tt>"sql.active_record"</tt> notification is
26
+ # published, it will properly dispatch the event
27
+ # (ActiveSupport::Notifications::Event) to the +sql+ method.
26
28
  #
27
29
  # We can detach a subscriber as well:
28
30
  #
@@ -65,6 +67,7 @@ module ActiveSupport
65
67
 
66
68
  # Adds event subscribers for all new methods added to the class.
67
69
  def method_added(event)
70
+ super
68
71
  # Only public methods are added as subscribers, and only if a notifier
69
72
  # has been set up. This means that subscribers will only be set up for
70
73
  # classes that call #attach_to.
@@ -126,38 +129,18 @@ module ActiveSupport
126
129
  attr_reader :patterns # :nodoc:
127
130
 
128
131
  def initialize
129
- @queue_key = [self.class.name, object_id].join "-"
130
132
  @patterns = {}
131
133
  super
132
134
  end
133
135
 
134
- def start(name, id, payload)
135
- event = ActiveSupport::Notifications::Event.new(name, nil, nil, id, payload)
136
- event.start!
137
- parent = event_stack.last
138
- parent << event if parent
139
-
140
- event_stack.push event
141
- end
142
-
143
- def finish(name, id, payload)
144
- event = event_stack.pop
145
- event.finish!
146
- event.payload.merge!(payload)
147
-
148
- method = name.split(".").first
136
+ def call(event)
137
+ method = event.name[0, event.name.index(".")]
149
138
  send(method, event)
150
139
  end
151
140
 
152
141
  def publish_event(event) # :nodoc:
153
- method = event.name.split(".").first
142
+ method = event.name[0, event.name.index(".")]
154
143
  send(method, event)
155
144
  end
156
-
157
- private
158
- def event_stack
159
- registry = ActiveSupport::IsolatedExecutionState[:active_support_subscriber_queue_registry] ||= {}
160
- registry[@queue_key] ||= []
161
- end
162
145
  end
163
146
  end