activesupport 7.0.8.7 → 7.2.3

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 (203) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +229 -397
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -5
  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 +238 -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 +51 -19
  14. data/lib/active_support/cache/mem_cache_store.rb +98 -134
  15. data/lib/active_support/cache/memory_store.rb +85 -30
  16. data/lib/active_support/cache/null_store.rb +8 -2
  17. data/lib/active_support/cache/redis_cache_store.rb +166 -153
  18. data/lib/active_support/cache/serializer_with_fallback.rb +152 -0
  19. data/lib/active_support/cache/strategy/local_cache.rb +64 -13
  20. data/lib/active_support/cache.rb +364 -292
  21. data/lib/active_support/callbacks.rb +121 -136
  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/benchmark.rb +1 -0
  30. data/lib/active_support/core_ext/class/attribute.rb +2 -2
  31. data/lib/active_support/core_ext/class/subclasses.rb +17 -34
  32. data/lib/active_support/core_ext/date/blank.rb +4 -0
  33. data/lib/active_support/core_ext/date/conversions.rb +1 -2
  34. data/lib/active_support/core_ext/date.rb +0 -1
  35. data/lib/active_support/core_ext/date_and_time/calculations.rb +10 -0
  36. data/lib/active_support/core_ext/date_and_time/compatibility.rb +28 -1
  37. data/lib/active_support/core_ext/date_time/blank.rb +4 -0
  38. data/lib/active_support/core_ext/date_time/conversions.rb +6 -4
  39. data/lib/active_support/core_ext/date_time.rb +0 -1
  40. data/lib/active_support/core_ext/digest/uuid.rb +7 -10
  41. data/lib/active_support/core_ext/enumerable.rb +20 -80
  42. data/lib/active_support/core_ext/erb/util.rb +201 -0
  43. data/lib/active_support/core_ext/hash/conversions.rb +1 -1
  44. data/lib/active_support/core_ext/hash/deep_merge.rb +22 -14
  45. data/lib/active_support/core_ext/hash/keys.rb +4 -4
  46. data/lib/active_support/core_ext/module/attr_internal.rb +17 -6
  47. data/lib/active_support/core_ext/module/attribute_accessors.rb +6 -0
  48. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +34 -16
  49. data/lib/active_support/core_ext/module/concerning.rb +6 -6
  50. data/lib/active_support/core_ext/module/delegation.rb +20 -119
  51. data/lib/active_support/core_ext/module/deprecation.rb +12 -12
  52. data/lib/active_support/core_ext/module/introspection.rb +3 -1
  53. data/lib/active_support/core_ext/numeric/bytes.rb +9 -0
  54. data/lib/active_support/core_ext/numeric/conversions.rb +5 -3
  55. data/lib/active_support/core_ext/numeric.rb +0 -1
  56. data/lib/active_support/core_ext/object/blank.rb +45 -1
  57. data/lib/active_support/core_ext/object/deep_dup.rb +16 -0
  58. data/lib/active_support/core_ext/object/inclusion.rb +13 -5
  59. data/lib/active_support/core_ext/object/instance_variables.rb +4 -2
  60. data/lib/active_support/core_ext/object/json.rb +17 -7
  61. data/lib/active_support/core_ext/object/try.rb +2 -2
  62. data/lib/active_support/core_ext/object/with.rb +46 -0
  63. data/lib/active_support/core_ext/object/with_options.rb +4 -4
  64. data/lib/active_support/core_ext/object.rb +1 -0
  65. data/lib/active_support/core_ext/pathname/blank.rb +20 -0
  66. data/lib/active_support/core_ext/pathname/existence.rb +2 -0
  67. data/lib/active_support/core_ext/pathname.rb +1 -0
  68. data/lib/active_support/core_ext/range/conversions.rb +28 -7
  69. data/lib/active_support/core_ext/range/overlap.rb +40 -0
  70. data/lib/active_support/core_ext/range/sole.rb +17 -0
  71. data/lib/active_support/core_ext/range.rb +2 -2
  72. data/lib/active_support/core_ext/securerandom.rb +24 -12
  73. data/lib/active_support/core_ext/string/conversions.rb +1 -1
  74. data/lib/active_support/core_ext/string/filters.rb +24 -18
  75. data/lib/active_support/core_ext/string/indent.rb +1 -1
  76. data/lib/active_support/core_ext/string/inflections.rb +16 -5
  77. data/lib/active_support/core_ext/string/multibyte.rb +3 -3
  78. data/lib/active_support/core_ext/string/output_safety.rb +34 -177
  79. data/lib/active_support/core_ext/thread/backtrace/location.rb +12 -0
  80. data/lib/active_support/core_ext/time/calculations.rb +36 -30
  81. data/lib/active_support/core_ext/time/compatibility.rb +24 -0
  82. data/lib/active_support/core_ext/time/conversions.rb +1 -3
  83. data/lib/active_support/core_ext/time/zones.rb +4 -4
  84. data/lib/active_support/core_ext/time.rb +0 -1
  85. data/lib/active_support/core_ext.rb +0 -1
  86. data/lib/active_support/current_attributes.rb +60 -46
  87. data/lib/active_support/deep_mergeable.rb +53 -0
  88. data/lib/active_support/delegation.rb +202 -0
  89. data/lib/active_support/dependencies/autoload.rb +9 -16
  90. data/lib/active_support/deprecation/behaviors.rb +65 -42
  91. data/lib/active_support/deprecation/constant_accessor.rb +47 -25
  92. data/lib/active_support/deprecation/deprecators.rb +104 -0
  93. data/lib/active_support/deprecation/disallowed.rb +3 -5
  94. data/lib/active_support/deprecation/method_wrappers.rb +6 -23
  95. data/lib/active_support/deprecation/proxy_wrappers.rb +34 -22
  96. data/lib/active_support/deprecation/reporting.rb +49 -27
  97. data/lib/active_support/deprecation.rb +39 -9
  98. data/lib/active_support/deprecator.rb +7 -0
  99. data/lib/active_support/descendants_tracker.rb +66 -172
  100. data/lib/active_support/duration/iso8601_parser.rb +2 -2
  101. data/lib/active_support/duration/iso8601_serializer.rb +1 -4
  102. data/lib/active_support/duration.rb +13 -7
  103. data/lib/active_support/encrypted_configuration.rb +30 -9
  104. data/lib/active_support/encrypted_file.rb +9 -4
  105. data/lib/active_support/environment_inquirer.rb +22 -2
  106. data/lib/active_support/error_reporter/test_helper.rb +15 -0
  107. data/lib/active_support/error_reporter.rb +163 -36
  108. data/lib/active_support/evented_file_update_checker.rb +0 -1
  109. data/lib/active_support/execution_wrapper.rb +5 -6
  110. data/lib/active_support/file_update_checker.rb +6 -4
  111. data/lib/active_support/fork_tracker.rb +4 -32
  112. data/lib/active_support/gem_version.rb +4 -4
  113. data/lib/active_support/gzip.rb +2 -0
  114. data/lib/active_support/hash_with_indifferent_access.rb +50 -30
  115. data/lib/active_support/html_safe_translation.rb +19 -6
  116. data/lib/active_support/i18n.rb +1 -1
  117. data/lib/active_support/i18n_railtie.rb +20 -13
  118. data/lib/active_support/inflector/inflections.rb +2 -0
  119. data/lib/active_support/inflector/methods.rb +23 -11
  120. data/lib/active_support/inflector/transliterate.rb +3 -1
  121. data/lib/active_support/isolated_execution_state.rb +26 -22
  122. data/lib/active_support/json/decoding.rb +3 -2
  123. data/lib/active_support/json/encoding.rb +48 -48
  124. data/lib/active_support/key_generator.rb +9 -1
  125. data/lib/active_support/lazy_load_hooks.rb +7 -5
  126. data/lib/active_support/locale/en.yml +2 -0
  127. data/lib/active_support/log_subscriber.rb +74 -34
  128. data/lib/active_support/logger.rb +22 -60
  129. data/lib/active_support/logger_thread_safe_level.rb +10 -32
  130. data/lib/active_support/message_encryptor.rb +197 -53
  131. data/lib/active_support/message_encryptors.rb +141 -0
  132. data/lib/active_support/message_pack/cache_serializer.rb +23 -0
  133. data/lib/active_support/message_pack/extensions.rb +305 -0
  134. data/lib/active_support/message_pack/serializer.rb +63 -0
  135. data/lib/active_support/message_pack.rb +50 -0
  136. data/lib/active_support/message_verifier.rb +229 -89
  137. data/lib/active_support/message_verifiers.rb +137 -0
  138. data/lib/active_support/messages/codec.rb +65 -0
  139. data/lib/active_support/messages/metadata.rb +111 -45
  140. data/lib/active_support/messages/rotation_coordinator.rb +93 -0
  141. data/lib/active_support/messages/rotator.rb +38 -31
  142. data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
  143. data/lib/active_support/multibyte/chars.rb +8 -3
  144. data/lib/active_support/multibyte/unicode.rb +9 -37
  145. data/lib/active_support/notifications/fanout.rb +248 -87
  146. data/lib/active_support/notifications/instrumenter.rb +93 -25
  147. data/lib/active_support/notifications.rb +29 -28
  148. data/lib/active_support/number_helper/number_converter.rb +16 -7
  149. data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -6
  150. data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -3
  151. data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -0
  152. data/lib/active_support/number_helper.rb +379 -318
  153. data/lib/active_support/option_merger.rb +2 -2
  154. data/lib/active_support/ordered_hash.rb +3 -3
  155. data/lib/active_support/ordered_options.rb +67 -15
  156. data/lib/active_support/parameter_filter.rb +84 -69
  157. data/lib/active_support/proxy_object.rb +8 -3
  158. data/lib/active_support/railtie.rb +25 -20
  159. data/lib/active_support/reloader.rb +12 -4
  160. data/lib/active_support/rescuable.rb +2 -0
  161. data/lib/active_support/secure_compare_rotator.rb +16 -9
  162. data/lib/active_support/string_inquirer.rb +4 -2
  163. data/lib/active_support/subscriber.rb +10 -27
  164. data/lib/active_support/syntax_error_proxy.rb +60 -0
  165. data/lib/active_support/tagged_logging.rb +64 -25
  166. data/lib/active_support/test_case.rb +156 -7
  167. data/lib/active_support/testing/assertions.rb +28 -12
  168. data/lib/active_support/testing/autorun.rb +0 -2
  169. data/lib/active_support/testing/constant_stubbing.rb +54 -0
  170. data/lib/active_support/testing/deprecation.rb +20 -27
  171. data/lib/active_support/testing/error_reporter_assertions.rb +107 -0
  172. data/lib/active_support/testing/isolation.rb +21 -9
  173. data/lib/active_support/testing/method_call_assertions.rb +7 -8
  174. data/lib/active_support/testing/parallelization/server.rb +18 -2
  175. data/lib/active_support/testing/parallelization/worker.rb +2 -2
  176. data/lib/active_support/testing/parallelization.rb +12 -1
  177. data/lib/active_support/testing/parallelize_executor.rb +8 -3
  178. data/lib/active_support/testing/setup_and_teardown.rb +2 -0
  179. data/lib/active_support/testing/stream.rb +1 -1
  180. data/lib/active_support/testing/tests_without_assertions.rb +19 -0
  181. data/lib/active_support/testing/time_helpers.rb +38 -16
  182. data/lib/active_support/time_with_zone.rb +12 -18
  183. data/lib/active_support/values/time_zone.rb +25 -14
  184. data/lib/active_support/version.rb +1 -1
  185. data/lib/active_support/xml_mini/jdom.rb +3 -10
  186. data/lib/active_support/xml_mini/nokogiri.rb +1 -1
  187. data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
  188. data/lib/active_support/xml_mini/rexml.rb +1 -1
  189. data/lib/active_support/xml_mini.rb +14 -3
  190. data/lib/active_support.rb +15 -3
  191. metadata +142 -24
  192. data/lib/active_support/core_ext/array/deprecated_conversions.rb +0 -25
  193. data/lib/active_support/core_ext/date/deprecated_conversions.rb +0 -40
  194. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +0 -36
  195. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +0 -60
  196. data/lib/active_support/core_ext/range/deprecated_conversions.rb +0 -36
  197. data/lib/active_support/core_ext/range/include_time_with_zone.rb +0 -5
  198. data/lib/active_support/core_ext/range/overlaps.rb +0 -10
  199. data/lib/active_support/core_ext/time/deprecated_conversions.rb +0 -73
  200. data/lib/active_support/core_ext/uri.rb +0 -5
  201. data/lib/active_support/deprecation/instance_delegator.rb +0 -38
  202. data/lib/active_support/per_thread_registry.rb +0 -65
  203. data/lib/active_support/ruby_features.rb +0 -7
@@ -9,7 +9,9 @@ require "active_support/core_ext/object/blank"
9
9
  require "thread"
10
10
 
11
11
  module ActiveSupport
12
- # Callbacks are code hooks that are run at key points in an object's life cycle.
12
+ # = Active Support \Callbacks
13
+ #
14
+ # \Callbacks are code hooks that are run at key points in an object's life cycle.
13
15
  # The typical use case is to have a base class define a set of callbacks
14
16
  # relevant to the other functionality it supplies, so that subclasses can
15
17
  # install callbacks that enhance or modify the base functionality without
@@ -68,7 +70,7 @@ module ActiveSupport
68
70
  class_attribute :__callbacks, instance_writer: false, default: {}
69
71
  end
70
72
 
71
- CALLBACK_FILTER_TYPES = [:before, :after, :around]
73
+ CALLBACK_FILTER_TYPES = [:before, :after, :around].freeze
72
74
 
73
75
  # Runs the callbacks for the given event.
74
76
  #
@@ -92,14 +94,15 @@ module ActiveSupport
92
94
  # callback can be as noisy as it likes -- but when control has passed
93
95
  # smoothly through and into the supplied block, we want as little evidence
94
96
  # as possible that we were here.
95
- def run_callbacks(kind)
97
+ def run_callbacks(kind, type = nil)
96
98
  callbacks = __callbacks[kind.to_sym]
97
99
 
98
100
  if callbacks.empty?
99
101
  yield if block_given?
100
102
  else
101
103
  env = Filters::Environment.new(self, false, nil)
102
- next_sequence = callbacks.compile
104
+
105
+ next_sequence = callbacks.compile(type)
103
106
 
104
107
  # Common case: no 'around' callbacks defined
105
108
  if next_sequence.final?
@@ -147,7 +150,7 @@ module ActiveSupport
147
150
  def halted_callback_hook(filter, name)
148
151
  end
149
152
 
150
- module Conditionals # :nodoc:
153
+ module Conditionals # :nodoc: all
151
154
  class Value
152
155
  def initialize(&block)
153
156
  @block = block
@@ -156,128 +159,76 @@ module ActiveSupport
156
159
  end
157
160
  end
158
161
 
159
- module Filters
162
+ module Filters # :nodoc: all
160
163
  Environment = Struct.new(:target, :halted, :value)
161
164
 
162
165
  class Before
163
- def self.build(callback_sequence, user_callback, user_conditions, chain_config, filter, name)
166
+ def initialize(user_callback, user_conditions, chain_config, filter, name)
164
167
  halted_lambda = chain_config[:terminator]
165
-
166
- if user_conditions.any?
167
- halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter, name)
168
- else
169
- halting(callback_sequence, user_callback, halted_lambda, filter, name)
170
- end
168
+ @user_callback, @user_conditions, @halted_lambda, @filter, @name = user_callback, user_conditions, halted_lambda, filter, name
169
+ freeze
171
170
  end
171
+ attr_reader :user_callback, :user_conditions, :halted_lambda, :filter, :name
172
172
 
173
- def self.halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter, name)
174
- callback_sequence.before do |env|
175
- target = env.target
176
- value = env.value
177
- halted = env.halted
173
+ def call(env)
174
+ target = env.target
175
+ value = env.value
176
+ halted = env.halted
178
177
 
179
- if !halted && user_conditions.all? { |c| c.call(target, value) }
180
- result_lambda = -> { user_callback.call target, value }
181
- env.halted = halted_lambda.call(target, result_lambda)
182
- if env.halted
183
- target.send :halted_callback_hook, filter, name
184
- end
178
+ if !halted && user_conditions.all? { |c| c.call(target, value) }
179
+ result_lambda = -> { user_callback.call target, value }
180
+ env.halted = halted_lambda.call(target, result_lambda)
181
+ if env.halted
182
+ target.send :halted_callback_hook, filter, name
185
183
  end
186
-
187
- env
188
184
  end
189
- end
190
- private_class_method :halting_and_conditional
191
-
192
- def self.halting(callback_sequence, user_callback, halted_lambda, filter, name)
193
- callback_sequence.before do |env|
194
- target = env.target
195
- value = env.value
196
- halted = env.halted
197
185
 
198
- unless halted
199
- result_lambda = -> { user_callback.call target, value }
200
- env.halted = halted_lambda.call(target, result_lambda)
201
- if env.halted
202
- target.send :halted_callback_hook, filter, name
203
- end
204
- end
186
+ env
187
+ end
205
188
 
206
- env
207
- end
189
+ def apply(callback_sequence)
190
+ callback_sequence.before(self)
208
191
  end
209
- private_class_method :halting
210
192
  end
211
193
 
212
194
  class After
213
- def self.build(callback_sequence, user_callback, user_conditions, chain_config)
214
- if chain_config[:skip_after_callbacks_if_terminated]
215
- if user_conditions.any?
216
- halting_and_conditional(callback_sequence, user_callback, user_conditions)
217
- else
218
- halting(callback_sequence, user_callback)
219
- end
220
- else
221
- if user_conditions.any?
222
- conditional callback_sequence, user_callback, user_conditions
223
- else
224
- simple callback_sequence, user_callback
225
- end
226
- end
195
+ attr_reader :user_callback, :user_conditions, :halting
196
+ def initialize(user_callback, user_conditions, chain_config)
197
+ halting = chain_config[:skip_after_callbacks_if_terminated]
198
+ @user_callback, @user_conditions, @halting = user_callback, user_conditions, halting
199
+ freeze
227
200
  end
228
201
 
229
- def self.halting_and_conditional(callback_sequence, user_callback, user_conditions)
230
- callback_sequence.after do |env|
231
- target = env.target
232
- value = env.value
233
- halted = env.halted
234
-
235
- if !halted && user_conditions.all? { |c| c.call(target, value) }
236
- user_callback.call target, value
237
- end
202
+ def call(env)
203
+ target = env.target
204
+ value = env.value
205
+ halted = env.halted
238
206
 
239
- env
207
+ if (!halted || !@halting) && user_conditions.all? { |c| c.call(target, value) }
208
+ user_callback.call target, value
240
209
  end
241
- end
242
- private_class_method :halting_and_conditional
243
210
 
244
- def self.halting(callback_sequence, user_callback)
245
- callback_sequence.after do |env|
246
- unless env.halted
247
- user_callback.call env.target, env.value
248
- end
249
-
250
- env
251
- end
211
+ env
252
212
  end
253
- private_class_method :halting
254
-
255
- def self.conditional(callback_sequence, user_callback, user_conditions)
256
- callback_sequence.after do |env|
257
- target = env.target
258
- value = env.value
259
213
 
260
- if user_conditions.all? { |c| c.call(target, value) }
261
- user_callback.call target, value
262
- end
263
-
264
- env
265
- end
214
+ def apply(callback_sequence)
215
+ callback_sequence.after(self)
266
216
  end
267
- private_class_method :conditional
217
+ end
268
218
 
269
- def self.simple(callback_sequence, user_callback)
270
- callback_sequence.after do |env|
271
- user_callback.call env.target, env.value
219
+ class Around
220
+ def initialize(user_callback, user_conditions)
221
+ @user_callback, @user_conditions = user_callback, user_conditions
222
+ freeze
223
+ end
272
224
 
273
- env
274
- end
225
+ def apply(callback_sequence)
226
+ callback_sequence.around(@user_callback, @user_conditions)
275
227
  end
276
- private_class_method :simple
277
228
  end
278
229
  end
279
230
 
280
- class Callback # :nodoc:#
231
+ class Callback # :nodoc:
281
232
  def self.build(chain, filter, kind, options)
282
233
  if filter.is_a?(String)
283
234
  raise ArgumentError, <<-MSG.squish
@@ -299,6 +250,8 @@ module ActiveSupport
299
250
  @filter = filter
300
251
  @if = check_conditionals(options[:if])
301
252
  @unless = check_conditionals(options[:unless])
253
+
254
+ compiled
302
255
  end
303
256
 
304
257
  def merge_conditional_options(chain, if_option:, unless_option:)
@@ -326,19 +279,26 @@ module ActiveSupport
326
279
  end
327
280
  end
328
281
 
282
+ def compiled
283
+ @compiled ||=
284
+ begin
285
+ user_conditions = conditions_lambdas
286
+ user_callback = CallTemplate.build(@filter, self)
287
+
288
+ case kind
289
+ when :before
290
+ Filters::Before.new(user_callback.make_lambda, user_conditions, chain_config, @filter, name)
291
+ when :after
292
+ Filters::After.new(user_callback.make_lambda, user_conditions, chain_config)
293
+ when :around
294
+ Filters::Around.new(user_callback, user_conditions)
295
+ end
296
+ end
297
+ end
298
+
329
299
  # Wraps code with filter
330
300
  def apply(callback_sequence)
331
- user_conditions = conditions_lambdas
332
- user_callback = CallTemplate.build(@filter, self)
333
-
334
- case kind
335
- when :before
336
- Filters::Before.build(callback_sequence, user_callback.make_lambda, user_conditions, chain_config, @filter, name)
337
- when :after
338
- Filters::After.build(callback_sequence, user_callback.make_lambda, user_conditions, chain_config)
339
- when :around
340
- callback_sequence.around(user_callback, user_conditions)
341
- end
301
+ compiled.apply(callback_sequence)
342
302
  end
343
303
 
344
304
  def current_scopes
@@ -365,14 +325,16 @@ module ActiveSupport
365
325
  end
366
326
 
367
327
  def conditions_lambdas
368
- @if.map { |c| CallTemplate.build(c, self).make_lambda } +
328
+ conditions =
329
+ @if.map { |c| CallTemplate.build(c, self).make_lambda } +
369
330
  @unless.map { |c| CallTemplate.build(c, self).inverted_lambda }
331
+ conditions.empty? ? EMPTY_ARRAY : conditions
370
332
  end
371
333
  end
372
334
 
373
335
  # A future invocation of user-supplied code (either as a callback,
374
336
  # or a condition filter).
375
- module CallTemplate # :nodoc:
337
+ module CallTemplate # :nodoc: all
376
338
  class MethodCall
377
339
  def initialize(method)
378
340
  @method_name = method
@@ -537,9 +499,10 @@ module ActiveSupport
537
499
  when Conditionals::Value
538
500
  ProcCall.new(filter)
539
501
  when ::Proc
540
- if filter.arity > 1
502
+ case filter.arity
503
+ when 2
541
504
  InstanceExec2.new(filter)
542
- elsif filter.arity > 0
505
+ when 1, -2
543
506
  InstanceExec1.new(filter)
544
507
  else
545
508
  InstanceExec0.new(filter)
@@ -559,16 +522,18 @@ module ActiveSupport
559
522
  @call_template = call_template
560
523
  @user_conditions = user_conditions
561
524
 
562
- @before = []
563
- @after = []
525
+ @before = nil
526
+ @after = nil
564
527
  end
565
528
 
566
- def before(&before)
529
+ def before(before)
530
+ @before ||= []
567
531
  @before.unshift(before)
568
532
  self
569
533
  end
570
534
 
571
- def after(&after)
535
+ def after(after)
536
+ @after ||= []
572
537
  @after.push(after)
573
538
  self
574
539
  end
@@ -592,11 +557,11 @@ module ActiveSupport
592
557
  end
593
558
 
594
559
  def invoke_before(arg)
595
- @before.each { |b| b.call(arg) }
560
+ @before&.each { |b| b.call(arg) }
596
561
  end
597
562
 
598
563
  def invoke_after(arg)
599
- @after.each { |a| a.call(arg) }
564
+ @after&.each { |a| a.call(arg) }
600
565
  end
601
566
  end
602
567
 
@@ -612,7 +577,8 @@ module ActiveSupport
612
577
  terminator: default_terminator
613
578
  }.merge!(config)
614
579
  @chain = []
615
- @callbacks = nil
580
+ @all_callbacks = nil
581
+ @single_callbacks = {}
616
582
  @mutex = Mutex.new
617
583
  end
618
584
 
@@ -621,32 +587,45 @@ module ActiveSupport
621
587
  def empty?; @chain.empty?; end
622
588
 
623
589
  def insert(index, o)
624
- @callbacks = nil
590
+ @all_callbacks = nil
591
+ @single_callbacks.clear
625
592
  @chain.insert(index, o)
626
593
  end
627
594
 
628
595
  def delete(o)
629
- @callbacks = nil
596
+ @all_callbacks = nil
597
+ @single_callbacks.clear
630
598
  @chain.delete(o)
631
599
  end
632
600
 
633
601
  def clear
634
- @callbacks = nil
602
+ @all_callbacks = nil
603
+ @single_callbacks.clear
635
604
  @chain.clear
636
605
  self
637
606
  end
638
607
 
639
608
  def initialize_copy(other)
640
- @callbacks = nil
609
+ @all_callbacks = nil
610
+ @single_callbacks = {}
641
611
  @chain = other.chain.dup
642
612
  @mutex = Mutex.new
643
613
  end
644
614
 
645
- def compile
646
- @callbacks || @mutex.synchronize do
647
- final_sequence = CallbackSequence.new
648
- @callbacks ||= @chain.reverse.inject(final_sequence) do |callback_sequence, callback|
649
- callback.apply callback_sequence
615
+ def compile(type)
616
+ if type.nil?
617
+ @all_callbacks || @mutex.synchronize do
618
+ final_sequence = CallbackSequence.new
619
+ @all_callbacks ||= @chain.reverse.inject(final_sequence) do |callback_sequence, callback|
620
+ callback.apply(callback_sequence)
621
+ end
622
+ end
623
+ else
624
+ @single_callbacks[type] || @mutex.synchronize do
625
+ final_sequence = CallbackSequence.new
626
+ @single_callbacks[type] ||= @chain.reverse.inject(final_sequence) do |callback_sequence, callback|
627
+ type == callback.kind ? callback.apply(callback_sequence) : callback_sequence
628
+ end
650
629
  end
651
630
  end
652
631
  end
@@ -664,19 +643,22 @@ module ActiveSupport
664
643
 
665
644
  private
666
645
  def append_one(callback)
667
- @callbacks = nil
646
+ @all_callbacks = nil
647
+ @single_callbacks.clear
668
648
  remove_duplicates(callback)
669
649
  @chain.push(callback)
670
650
  end
671
651
 
672
652
  def prepend_one(callback)
673
- @callbacks = nil
653
+ @all_callbacks = nil
654
+ @single_callbacks.clear
674
655
  remove_duplicates(callback)
675
656
  @chain.unshift(callback)
676
657
  end
677
658
 
678
659
  def remove_duplicates(callback)
679
- @callbacks = nil
660
+ @all_callbacks = nil
661
+ @single_callbacks.clear
680
662
  @chain.delete_if { |c| callback.duplicates?(c) }
681
663
  end
682
664
 
@@ -703,7 +685,7 @@ module ActiveSupport
703
685
  # This is used internally to append, prepend and skip callbacks to the
704
686
  # CallbackChain.
705
687
  def __update_callbacks(name) # :nodoc:
706
- ([self] + self.descendants).reverse_each do |target|
688
+ self.descendants.prepend(self).reverse_each do |target|
707
689
  chain = target.get_callbacks name
708
690
  yield target, chain.dup
709
691
  end
@@ -723,7 +705,7 @@ module ActiveSupport
723
705
  #
724
706
  # The callback can be specified as a symbol naming an instance method; as a
725
707
  # proc, lambda, or block; or as an object that responds to a certain method
726
- # determined by the <tt>:scope</tt> argument to +define_callbacks+.
708
+ # determined by the <tt>:scope</tt> argument to #define_callbacks.
727
709
  #
728
710
  # If a proc, lambda, or block is given, its body is evaluated in the context
729
711
  # of the current object. It can also optionally accept the current object as
@@ -767,10 +749,13 @@ module ActiveSupport
767
749
  end
768
750
  end
769
751
 
770
- # Skip a previously set callback. Like +set_callback+, <tt>:if</tt> or
752
+ # Skip a previously set callback. Like #set_callback, <tt>:if</tt> or
771
753
  # <tt>:unless</tt> options may be passed in order to control when the
772
754
  # callback is skipped.
773
755
  #
756
+ # Note: this example uses +PersonRecord+ and +#saving_message+, which you
757
+ # can see defined here[rdoc-ref:ActiveSupport::Callbacks]
758
+ #
774
759
  # class Writer < PersonRecord
775
760
  # attr_accessor :age
776
761
  # skip_callback :save, :before, :saving_message, if: -> { age > 18 }
@@ -913,7 +898,7 @@ module ActiveSupport
913
898
  # <tt>!</tt>, <tt>?</tt> or <tt>=</tt>.
914
899
  #
915
900
  # Calling +define_callbacks+ multiple times with the same +names+ will
916
- # overwrite previous callbacks registered with +set_callback+.
901
+ # overwrite previous callbacks registered with #set_callback.
917
902
  def define_callbacks(*names)
918
903
  options = names.extract_options!
919
904
 
@@ -9,16 +9,19 @@ module ActiveSupport
9
9
  @cache = METHOD_CACHES[namespace]
10
10
  @sources = []
11
11
  @methods = {}
12
+ @canonical_methods = {}
12
13
  end
13
14
 
14
- def define_cached_method(name, as: name)
15
- name = name.to_sym
16
- as = as.to_sym
17
- @methods.fetch(name) do
18
- unless @cache.method_defined?(as)
15
+ def define_cached_method(canonical_name, as: nil)
16
+ canonical_name = canonical_name.to_sym
17
+ as = (as || canonical_name).to_sym
18
+
19
+ @methods.fetch(as) do
20
+ unless @cache.method_defined?(canonical_name) || @canonical_methods[canonical_name]
19
21
  yield @sources
20
22
  end
21
- @methods[name] = as
23
+ @canonical_methods[canonical_name] = true
24
+ @methods[as] = canonical_name
22
25
  end
23
26
  end
24
27
 
@@ -26,8 +29,10 @@ module ActiveSupport
26
29
  unless @sources.empty?
27
30
  @cache.module_eval("# frozen_string_literal: true\n" + @sources.join(";"), path, line)
28
31
  end
29
- @methods.each do |name, as|
30
- owner.define_method(name, @cache.instance_method(as))
32
+ @canonical_methods.clear
33
+
34
+ @methods.each do |as, canonical_name|
35
+ owner.define_method(as, @cache.instance_method(canonical_name))
31
36
  end
32
37
  end
33
38
  end
@@ -52,8 +57,8 @@ module ActiveSupport
52
57
  @namespaces = Hash.new { |h, k| h[k] = MethodSet.new(k) }
53
58
  end
54
59
 
55
- def define_cached_method(name, namespace:, as: name, &block)
56
- @namespaces[namespace].define_cached_method(name, as: as, &block)
60
+ def define_cached_method(canonical_name, namespace:, as: nil, &block)
61
+ @namespaces[namespace].define_cached_method(canonical_name, as: as, &block)
57
62
  end
58
63
 
59
64
  def execute
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveSupport
4
+ # = Active Support \Concern
5
+ #
4
6
  # A typical module looks like this:
5
7
  #
6
8
  # module M
@@ -16,7 +18,7 @@ module ActiveSupport
16
18
  # end
17
19
  # end
18
20
  #
19
- # By using <tt>ActiveSupport::Concern</tt> the above module could instead be
21
+ # By using +ActiveSupport::Concern+ the above module could instead be
20
22
  # written as:
21
23
  #
22
24
  # require "active_support/concern"
@@ -73,7 +75,7 @@ module ActiveSupport
73
75
  # end
74
76
  #
75
77
  # Unfortunately this won't work, since when +Foo+ is included, its <tt>base</tt>
76
- # is the +Bar+ module, not the +Host+ class. With <tt>ActiveSupport::Concern</tt>,
78
+ # is the +Bar+ module, not the +Host+ class. With +ActiveSupport::Concern+,
77
79
  # module dependencies are properly resolved:
78
80
  #
79
81
  # require "active_support/concern"
@@ -4,9 +4,7 @@ require "monitor"
4
4
 
5
5
  module ActiveSupport
6
6
  module Concurrency
7
- # A monitor that will permit dependency loading while blocked waiting for
8
- # the lock.
9
- class LoadInterlockAwareMonitor < Monitor
7
+ module LoadInterlockAwareMonitorMixin # :nodoc:
10
8
  EXCEPTION_NEVER = { Exception => :never }.freeze
11
9
  EXCEPTION_IMMEDIATE = { Exception => :immediate }.freeze
12
10
  private_constant :EXCEPTION_NEVER, :EXCEPTION_IMMEDIATE
@@ -29,5 +27,46 @@ module ActiveSupport
29
27
  end
30
28
  end
31
29
  end
30
+ # A monitor that will permit dependency loading while blocked waiting for
31
+ # the lock.
32
+ class LoadInterlockAwareMonitor < Monitor
33
+ include LoadInterlockAwareMonitorMixin
34
+ end
35
+
36
+ class ThreadLoadInterlockAwareMonitor # :nodoc:
37
+ prepend LoadInterlockAwareMonitorMixin
38
+
39
+ def initialize
40
+ @owner = nil
41
+ @count = 0
42
+ @mutex = Mutex.new
43
+ end
44
+
45
+ private
46
+ def mon_try_enter
47
+ if @owner != Thread.current
48
+ return false unless @mutex.try_lock
49
+ @owner = Thread.current
50
+ end
51
+ @count += 1
52
+ end
53
+
54
+ def mon_enter
55
+ @mutex.lock if @owner != Thread.current
56
+ @owner = Thread.current
57
+ @count += 1
58
+ end
59
+
60
+ def mon_exit
61
+ unless @owner == Thread.current
62
+ raise ThreadError, "current thread not owner"
63
+ end
64
+
65
+ @count -= 1
66
+ return unless @count == 0
67
+ @owner = nil
68
+ @mutex.unlock
69
+ end
70
+ end
32
71
  end
33
72
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ module Concurrency
5
+ module NullLock # :nodoc:
6
+ extend self
7
+
8
+ def synchronize
9
+ yield
10
+ end
11
+ end
12
+ end
13
+ end
@@ -4,6 +4,8 @@ require "active_support/concern"
4
4
  require "active_support/ordered_options"
5
5
 
6
6
  module ActiveSupport
7
+ # = Active Support \Configurable
8
+ #
7
9
  # Configurable provides a <tt>config</tt> method to store and retrieve
8
10
  # configuration options as an OrderedOptions.
9
11
  module Configurable
@@ -125,6 +127,14 @@ module ActiveSupport
125
127
  end
126
128
  end
127
129
  private :config_accessor
130
+
131
+ private
132
+ def inherited(subclass)
133
+ super
134
+ subclass.class_eval do
135
+ @_config = nil
136
+ end
137
+ end
128
138
  end
129
139
 
130
140
  # Reads and writes attributes from a configuration OrderedOptions.
@@ -100,11 +100,10 @@ class Array
100
100
  collect(&:id).join(",")
101
101
  end
102
102
  else
103
- to_default_s
103
+ to_s
104
104
  end
105
105
  end
106
106
  alias_method :to_formatted_s, :to_fs
107
- alias_method :to_default_s, :to_s
108
107
 
109
108
  # Returns a string that represents the array in XML by invoking +to_xml+
110
109
  # on each element. Active Record collections delegate their representation
@@ -3,7 +3,6 @@
3
3
  require "active_support/core_ext/array/wrap"
4
4
  require "active_support/core_ext/array/access"
5
5
  require "active_support/core_ext/array/conversions"
6
- require "active_support/core_ext/array/deprecated_conversions" unless ENV["RAILS_DISABLE_DEPRECATED_TO_S_CONVERSION"]
7
6
  require "active_support/core_ext/array/extract"
8
7
  require "active_support/core_ext/array/extract_options"
9
8
  require "active_support/core_ext/array/grouping"
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "benchmark"
4
+ return if Benchmark.respond_to?(:ms)
4
5
 
5
6
  class << Benchmark
6
7
  # Benchmark realtime in milliseconds.
@@ -83,8 +83,8 @@ class Class
83
83
  #
84
84
  # class_attribute :settings, default: {}
85
85
  def class_attribute(*attrs, instance_accessor: true,
86
- instance_reader: instance_accessor, instance_writer: instance_accessor, instance_predicate: true, default: nil)
87
-
86
+ instance_reader: instance_accessor, instance_writer: instance_accessor, instance_predicate: true, default: nil
87
+ )
88
88
  class_methods, methods = [], []
89
89
  attrs.each do |name|
90
90
  unless name.is_a?(Symbol) || name.is_a?(String)