activesupport 7.1.6 → 8.1.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +256 -1133
- data/README.rdoc +1 -1
- data/lib/active_support/array_inquirer.rb +1 -1
- data/lib/active_support/backtrace_cleaner.rb +81 -3
- data/lib/active_support/benchmark.rb +21 -0
- data/lib/active_support/benchmarkable.rb +3 -2
- data/lib/active_support/broadcast_logger.rb +65 -78
- data/lib/active_support/cache/file_store.rb +29 -14
- data/lib/active_support/cache/mem_cache_store.rb +42 -102
- data/lib/active_support/cache/memory_store.rb +11 -6
- data/lib/active_support/cache/null_store.rb +2 -2
- data/lib/active_support/cache/redis_cache_store.rb +58 -46
- data/lib/active_support/cache/serializer_with_fallback.rb +0 -23
- data/lib/active_support/cache/strategy/local_cache.rb +72 -27
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +7 -7
- data/lib/active_support/cache.rb +146 -86
- data/lib/active_support/callbacks.rb +102 -126
- data/lib/active_support/class_attribute.rb +33 -0
- data/lib/active_support/code_generator.rb +9 -0
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +8 -62
- data/lib/active_support/concurrency/share_lock.rb +0 -1
- data/lib/active_support/concurrency/thread_monitor.rb +55 -0
- data/lib/active_support/configurable.rb +34 -0
- data/lib/active_support/configuration_file.rb +15 -6
- data/lib/active_support/continuous_integration.rb +145 -0
- data/lib/active_support/core_ext/array/conversions.rb +3 -5
- data/lib/active_support/core_ext/array.rb +7 -7
- data/lib/active_support/core_ext/benchmark.rb +4 -14
- data/lib/active_support/core_ext/big_decimal.rb +1 -1
- data/lib/active_support/core_ext/class/attribute.rb +26 -19
- data/lib/active_support/core_ext/class/subclasses.rb +15 -35
- data/lib/active_support/core_ext/class.rb +2 -2
- data/lib/active_support/core_ext/date/blank.rb +4 -0
- data/lib/active_support/core_ext/date/conversions.rb +2 -2
- data/lib/active_support/core_ext/date.rb +5 -5
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -9
- data/lib/active_support/core_ext/date_time/blank.rb +4 -0
- data/lib/active_support/core_ext/date_time/compatibility.rb +3 -5
- data/lib/active_support/core_ext/date_time/conversions.rb +4 -6
- data/lib/active_support/core_ext/date_time.rb +5 -5
- data/lib/active_support/core_ext/digest/uuid.rb +6 -0
- data/lib/active_support/core_ext/digest.rb +1 -1
- data/lib/active_support/core_ext/enumerable.rb +25 -8
- data/lib/active_support/core_ext/erb/util.rb +10 -5
- data/lib/active_support/core_ext/file.rb +1 -1
- data/lib/active_support/core_ext/hash/deep_merge.rb +1 -0
- data/lib/active_support/core_ext/hash/except.rb +0 -12
- data/lib/active_support/core_ext/hash/keys.rb +4 -4
- data/lib/active_support/core_ext/hash.rb +8 -8
- data/lib/active_support/core_ext/integer.rb +3 -3
- data/lib/active_support/core_ext/kernel.rb +3 -3
- data/lib/active_support/core_ext/module/attr_internal.rb +16 -6
- data/lib/active_support/core_ext/module/delegation.rb +20 -163
- data/lib/active_support/core_ext/module/deprecation.rb +1 -4
- data/lib/active_support/core_ext/module/introspection.rb +3 -0
- data/lib/active_support/core_ext/module.rb +11 -11
- data/lib/active_support/core_ext/numeric/conversions.rb +3 -3
- data/lib/active_support/core_ext/numeric.rb +3 -3
- data/lib/active_support/core_ext/object/blank.rb +45 -1
- data/lib/active_support/core_ext/object/instance_variables.rb +11 -19
- data/lib/active_support/core_ext/object/json.rb +24 -11
- data/lib/active_support/core_ext/object/to_query.rb +7 -1
- data/lib/active_support/core_ext/object/try.rb +2 -2
- data/lib/active_support/core_ext/object/with.rb +5 -3
- data/lib/active_support/core_ext/object.rb +13 -13
- data/lib/active_support/core_ext/pathname/blank.rb +4 -0
- data/lib/active_support/core_ext/pathname.rb +2 -2
- data/lib/active_support/core_ext/range/overlap.rb +4 -4
- data/lib/active_support/core_ext/range/sole.rb +17 -0
- data/lib/active_support/core_ext/range.rb +4 -4
- data/lib/active_support/core_ext/securerandom.rb +4 -4
- data/lib/active_support/core_ext/string/conversions.rb +1 -1
- data/lib/active_support/core_ext/string/filters.rb +4 -4
- data/lib/active_support/core_ext/string/multibyte.rb +13 -4
- data/lib/active_support/core_ext/string/output_safety.rb +19 -19
- data/lib/active_support/core_ext/string.rb +13 -13
- data/lib/active_support/core_ext/symbol.rb +1 -1
- data/lib/active_support/core_ext/thread/backtrace/location.rb +2 -7
- data/lib/active_support/core_ext/time/calculations.rb +25 -30
- data/lib/active_support/core_ext/time/compatibility.rb +2 -3
- data/lib/active_support/core_ext/time/conversions.rb +2 -2
- data/lib/active_support/core_ext/time/zones.rb +1 -1
- data/lib/active_support/core_ext/time.rb +5 -5
- data/lib/active_support/core_ext.rb +1 -2
- data/lib/active_support/current_attributes/test_helper.rb +2 -2
- data/lib/active_support/current_attributes.rb +58 -50
- data/lib/active_support/delegation.rb +200 -0
- data/lib/active_support/dependencies/autoload.rb +0 -12
- data/lib/active_support/dependencies/interlock.rb +11 -5
- data/lib/active_support/dependencies.rb +6 -2
- data/lib/active_support/deprecation/constant_accessor.rb +47 -26
- data/lib/active_support/deprecation/proxy_wrappers.rb +9 -12
- data/lib/active_support/deprecation/reporting.rb +5 -17
- data/lib/active_support/deprecation.rb +8 -5
- data/lib/active_support/descendants_tracker.rb +9 -87
- data/lib/active_support/duration/iso8601_parser.rb +2 -2
- data/lib/active_support/duration/iso8601_serializer.rb +1 -2
- data/lib/active_support/duration.rb +25 -16
- data/lib/active_support/editor.rb +70 -0
- data/lib/active_support/encrypted_configuration.rb +20 -2
- data/lib/active_support/encrypted_file.rb +1 -1
- data/lib/active_support/error_reporter.rb +121 -6
- data/lib/active_support/event_reporter/test_helper.rb +32 -0
- data/lib/active_support/event_reporter.rb +592 -0
- data/lib/active_support/evented_file_update_checker.rb +5 -3
- data/lib/active_support/execution_context.rb +64 -7
- data/lib/active_support/execution_wrapper.rb +1 -2
- data/lib/active_support/file_update_checker.rb +9 -7
- data/lib/active_support/fork_tracker.rb +2 -38
- data/lib/active_support/gem_version.rb +2 -2
- data/lib/active_support/gzip.rb +1 -0
- data/lib/active_support/hash_with_indifferent_access.rb +66 -45
- data/lib/active_support/html_safe_translation.rb +3 -0
- data/lib/active_support/i18n_railtie.rb +19 -11
- data/lib/active_support/inflector/inflections.rb +31 -15
- data/lib/active_support/inflector/transliterate.rb +6 -8
- data/lib/active_support/isolated_execution_state.rb +12 -17
- data/lib/active_support/json/decoding.rb +6 -4
- data/lib/active_support/json/encoding.rb +157 -21
- data/lib/active_support/lazy_load_hooks.rb +1 -1
- data/lib/active_support/log_subscriber.rb +2 -18
- data/lib/active_support/logger.rb +15 -2
- data/lib/active_support/logger_thread_safe_level.rb +4 -9
- data/lib/active_support/message_encryptors.rb +54 -2
- data/lib/active_support/message_pack/extensions.rb +20 -2
- data/lib/active_support/message_verifier.rb +21 -0
- data/lib/active_support/message_verifiers.rb +57 -3
- data/lib/active_support/messages/rotation_coordinator.rb +9 -0
- data/lib/active_support/messages/rotator.rb +10 -0
- data/lib/active_support/multibyte/chars.rb +14 -4
- data/lib/active_support/multibyte.rb +4 -0
- data/lib/active_support/notifications/fanout.rb +68 -50
- data/lib/active_support/notifications/instrumenter.rb +22 -19
- data/lib/active_support/notifications.rb +28 -27
- data/lib/active_support/number_helper/number_converter.rb +2 -2
- data/lib/active_support/number_helper.rb +22 -0
- data/lib/active_support/option_merger.rb +2 -2
- data/lib/active_support/ordered_options.rb +53 -15
- data/lib/active_support/railtie.rb +36 -20
- data/lib/active_support/string_inquirer.rb +1 -1
- data/lib/active_support/structured_event_subscriber.rb +99 -0
- data/lib/active_support/subscriber.rb +1 -5
- data/lib/active_support/syntax_error_proxy.rb +3 -0
- data/lib/active_support/tagged_logging.rb +5 -1
- data/lib/active_support/test_case.rb +63 -6
- data/lib/active_support/testing/assertions.rb +113 -27
- data/lib/active_support/testing/constant_stubbing.rb +30 -8
- data/lib/active_support/testing/deprecation.rb +5 -12
- data/lib/active_support/testing/error_reporter_assertions.rb +18 -1
- data/lib/active_support/testing/event_reporter_assertions.rb +227 -0
- data/lib/active_support/testing/isolation.rb +19 -9
- data/lib/active_support/testing/method_call_assertions.rb +2 -16
- data/lib/active_support/testing/notification_assertions.rb +92 -0
- data/lib/active_support/testing/parallelization/server.rb +18 -2
- data/lib/active_support/testing/parallelization/worker.rb +4 -2
- data/lib/active_support/testing/parallelization.rb +25 -1
- data/lib/active_support/testing/tests_without_assertions.rb +19 -0
- data/lib/active_support/testing/time_helpers.rb +11 -6
- data/lib/active_support/time_with_zone.rb +39 -26
- data/lib/active_support/values/time_zone.rb +26 -17
- data/lib/active_support/xml_mini.rb +14 -4
- data/lib/active_support.rb +22 -9
- metadata +31 -17
- data/lib/active_support/core_ext/range/each.rb +0 -24
- data/lib/active_support/deprecation/instance_delegator.rb +0 -65
- data/lib/active_support/proxy_object.rb +0 -17
- data/lib/active_support/ruby_features.rb +0 -7
- data/lib/active_support/testing/strict_warnings.rb +0 -39
|
@@ -4,9 +4,9 @@ require "active_support/concern"
|
|
|
4
4
|
require "active_support/descendants_tracker"
|
|
5
5
|
require "active_support/core_ext/array/extract_options"
|
|
6
6
|
require "active_support/core_ext/class/attribute"
|
|
7
|
+
require "active_support/core_ext/module/redefine_method"
|
|
7
8
|
require "active_support/core_ext/string/filters"
|
|
8
9
|
require "active_support/core_ext/object/blank"
|
|
9
|
-
require "thread"
|
|
10
10
|
|
|
11
11
|
module ActiveSupport
|
|
12
12
|
# = Active Support \Callbacks
|
|
@@ -67,7 +67,7 @@ module ActiveSupport
|
|
|
67
67
|
|
|
68
68
|
included do
|
|
69
69
|
extend ActiveSupport::DescendantsTracker
|
|
70
|
-
class_attribute :__callbacks, instance_writer: false, default: {}
|
|
70
|
+
class_attribute :__callbacks, instance_writer: false, instance_predicate: false, default: {}
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
CALLBACK_FILTER_TYPES = [:before, :after, :around].freeze
|
|
@@ -150,7 +150,7 @@ module ActiveSupport
|
|
|
150
150
|
def halted_callback_hook(filter, name)
|
|
151
151
|
end
|
|
152
152
|
|
|
153
|
-
module Conditionals # :nodoc:
|
|
153
|
+
module Conditionals # :nodoc: all
|
|
154
154
|
class Value
|
|
155
155
|
def initialize(&block)
|
|
156
156
|
@block = block
|
|
@@ -159,128 +159,76 @@ module ActiveSupport
|
|
|
159
159
|
end
|
|
160
160
|
end
|
|
161
161
|
|
|
162
|
-
module Filters
|
|
162
|
+
module Filters # :nodoc: all
|
|
163
163
|
Environment = Struct.new(:target, :halted, :value)
|
|
164
164
|
|
|
165
165
|
class Before
|
|
166
|
-
def
|
|
166
|
+
def initialize(user_callback, user_conditions, chain_config, filter, name)
|
|
167
167
|
halted_lambda = chain_config[:terminator]
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter, name)
|
|
171
|
-
else
|
|
172
|
-
halting(callback_sequence, user_callback, halted_lambda, filter, name)
|
|
173
|
-
end
|
|
168
|
+
@user_callback, @user_conditions, @halted_lambda, @filter, @name = user_callback, user_conditions, halted_lambda, filter, name
|
|
169
|
+
freeze
|
|
174
170
|
end
|
|
171
|
+
attr_reader :user_callback, :user_conditions, :halted_lambda, :filter, :name
|
|
175
172
|
|
|
176
|
-
def
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
halted = env.halted
|
|
173
|
+
def call(env)
|
|
174
|
+
target = env.target
|
|
175
|
+
value = env.value
|
|
176
|
+
halted = env.halted
|
|
181
177
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
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
|
|
188
183
|
end
|
|
189
|
-
|
|
190
|
-
env
|
|
191
184
|
end
|
|
192
|
-
end
|
|
193
|
-
private_class_method :halting_and_conditional
|
|
194
|
-
|
|
195
|
-
def self.halting(callback_sequence, user_callback, halted_lambda, filter, name)
|
|
196
|
-
callback_sequence.before do |env|
|
|
197
|
-
target = env.target
|
|
198
|
-
value = env.value
|
|
199
|
-
halted = env.halted
|
|
200
185
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
env.halted = halted_lambda.call(target, result_lambda)
|
|
204
|
-
if env.halted
|
|
205
|
-
target.send :halted_callback_hook, filter, name
|
|
206
|
-
end
|
|
207
|
-
end
|
|
186
|
+
env
|
|
187
|
+
end
|
|
208
188
|
|
|
209
|
-
|
|
210
|
-
|
|
189
|
+
def apply(callback_sequence)
|
|
190
|
+
callback_sequence.before(self)
|
|
211
191
|
end
|
|
212
|
-
private_class_method :halting
|
|
213
192
|
end
|
|
214
193
|
|
|
215
194
|
class After
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
halting(callback_sequence, user_callback)
|
|
222
|
-
end
|
|
223
|
-
else
|
|
224
|
-
if user_conditions.any?
|
|
225
|
-
conditional callback_sequence, user_callback, user_conditions
|
|
226
|
-
else
|
|
227
|
-
simple callback_sequence, user_callback
|
|
228
|
-
end
|
|
229
|
-
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
|
|
230
200
|
end
|
|
231
201
|
|
|
232
|
-
def
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
halted = env.halted
|
|
237
|
-
|
|
238
|
-
if !halted && user_conditions.all? { |c| c.call(target, value) }
|
|
239
|
-
user_callback.call target, value
|
|
240
|
-
end
|
|
202
|
+
def call(env)
|
|
203
|
+
target = env.target
|
|
204
|
+
value = env.value
|
|
205
|
+
halted = env.halted
|
|
241
206
|
|
|
242
|
-
|
|
207
|
+
if (!halted || !@halting) && user_conditions.all? { |c| c.call(target, value) }
|
|
208
|
+
user_callback.call target, value
|
|
243
209
|
end
|
|
244
|
-
end
|
|
245
|
-
private_class_method :halting_and_conditional
|
|
246
|
-
|
|
247
|
-
def self.halting(callback_sequence, user_callback)
|
|
248
|
-
callback_sequence.after do |env|
|
|
249
|
-
unless env.halted
|
|
250
|
-
user_callback.call env.target, env.value
|
|
251
|
-
end
|
|
252
210
|
|
|
253
|
-
|
|
254
|
-
end
|
|
211
|
+
env
|
|
255
212
|
end
|
|
256
|
-
private_class_method :halting
|
|
257
|
-
|
|
258
|
-
def self.conditional(callback_sequence, user_callback, user_conditions)
|
|
259
|
-
callback_sequence.after do |env|
|
|
260
|
-
target = env.target
|
|
261
|
-
value = env.value
|
|
262
|
-
|
|
263
|
-
if user_conditions.all? { |c| c.call(target, value) }
|
|
264
|
-
user_callback.call target, value
|
|
265
|
-
end
|
|
266
213
|
|
|
267
|
-
|
|
268
|
-
|
|
214
|
+
def apply(callback_sequence)
|
|
215
|
+
callback_sequence.after(self)
|
|
269
216
|
end
|
|
270
|
-
|
|
217
|
+
end
|
|
271
218
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
219
|
+
class Around
|
|
220
|
+
def initialize(user_callback, user_conditions)
|
|
221
|
+
@user_callback, @user_conditions = user_callback, user_conditions
|
|
222
|
+
freeze
|
|
223
|
+
end
|
|
275
224
|
|
|
276
|
-
|
|
277
|
-
|
|
225
|
+
def apply(callback_sequence)
|
|
226
|
+
callback_sequence.around(@user_callback, @user_conditions)
|
|
278
227
|
end
|
|
279
|
-
private_class_method :simple
|
|
280
228
|
end
|
|
281
229
|
end
|
|
282
230
|
|
|
283
|
-
class Callback # :nodoc
|
|
231
|
+
class Callback # :nodoc:
|
|
284
232
|
def self.build(chain, filter, kind, options)
|
|
285
233
|
if filter.is_a?(String)
|
|
286
234
|
raise ArgumentError, <<-MSG.squish
|
|
@@ -302,6 +250,8 @@ module ActiveSupport
|
|
|
302
250
|
@filter = filter
|
|
303
251
|
@if = check_conditionals(options[:if])
|
|
304
252
|
@unless = check_conditionals(options[:unless])
|
|
253
|
+
|
|
254
|
+
compiled
|
|
305
255
|
end
|
|
306
256
|
|
|
307
257
|
def merge_conditional_options(chain, if_option:, unless_option:)
|
|
@@ -329,19 +279,26 @@ module ActiveSupport
|
|
|
329
279
|
end
|
|
330
280
|
end
|
|
331
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
|
+
|
|
332
299
|
# Wraps code with filter
|
|
333
300
|
def apply(callback_sequence)
|
|
334
|
-
|
|
335
|
-
user_callback = CallTemplate.build(@filter, self)
|
|
336
|
-
|
|
337
|
-
case kind
|
|
338
|
-
when :before
|
|
339
|
-
Filters::Before.build(callback_sequence, user_callback.make_lambda, user_conditions, chain_config, @filter, name)
|
|
340
|
-
when :after
|
|
341
|
-
Filters::After.build(callback_sequence, user_callback.make_lambda, user_conditions, chain_config)
|
|
342
|
-
when :around
|
|
343
|
-
callback_sequence.around(user_callback, user_conditions)
|
|
344
|
-
end
|
|
301
|
+
compiled.apply(callback_sequence)
|
|
345
302
|
end
|
|
346
303
|
|
|
347
304
|
def current_scopes
|
|
@@ -368,14 +325,16 @@ module ActiveSupport
|
|
|
368
325
|
end
|
|
369
326
|
|
|
370
327
|
def conditions_lambdas
|
|
371
|
-
|
|
328
|
+
conditions =
|
|
329
|
+
@if.map { |c| CallTemplate.build(c, self).make_lambda } +
|
|
372
330
|
@unless.map { |c| CallTemplate.build(c, self).inverted_lambda }
|
|
331
|
+
conditions.empty? ? EMPTY_ARRAY : conditions
|
|
373
332
|
end
|
|
374
333
|
end
|
|
375
334
|
|
|
376
335
|
# A future invocation of user-supplied code (either as a callback,
|
|
377
336
|
# or a condition filter).
|
|
378
|
-
module CallTemplate # :nodoc:
|
|
337
|
+
module CallTemplate # :nodoc: all
|
|
379
338
|
class MethodCall
|
|
380
339
|
def initialize(method)
|
|
381
340
|
@method_name = method
|
|
@@ -540,9 +499,10 @@ module ActiveSupport
|
|
|
540
499
|
when Conditionals::Value
|
|
541
500
|
ProcCall.new(filter)
|
|
542
501
|
when ::Proc
|
|
543
|
-
|
|
502
|
+
case filter.arity
|
|
503
|
+
when 2
|
|
544
504
|
InstanceExec2.new(filter)
|
|
545
|
-
|
|
505
|
+
when 1, -2
|
|
546
506
|
InstanceExec1.new(filter)
|
|
547
507
|
else
|
|
548
508
|
InstanceExec0.new(filter)
|
|
@@ -562,16 +522,18 @@ module ActiveSupport
|
|
|
562
522
|
@call_template = call_template
|
|
563
523
|
@user_conditions = user_conditions
|
|
564
524
|
|
|
565
|
-
@before =
|
|
566
|
-
@after =
|
|
525
|
+
@before = nil
|
|
526
|
+
@after = nil
|
|
567
527
|
end
|
|
568
528
|
|
|
569
|
-
def before(
|
|
529
|
+
def before(before)
|
|
530
|
+
@before ||= []
|
|
570
531
|
@before.unshift(before)
|
|
571
532
|
self
|
|
572
533
|
end
|
|
573
534
|
|
|
574
|
-
def after(
|
|
535
|
+
def after(after)
|
|
536
|
+
@after ||= []
|
|
575
537
|
@after.push(after)
|
|
576
538
|
self
|
|
577
539
|
end
|
|
@@ -595,11 +557,11 @@ module ActiveSupport
|
|
|
595
557
|
end
|
|
596
558
|
|
|
597
559
|
def invoke_before(arg)
|
|
598
|
-
@before
|
|
560
|
+
@before&.each { |b| b.call(arg) }
|
|
599
561
|
end
|
|
600
562
|
|
|
601
563
|
def invoke_after(arg)
|
|
602
|
-
@after
|
|
564
|
+
@after&.each { |a| a.call(arg) }
|
|
603
565
|
end
|
|
604
566
|
end
|
|
605
567
|
|
|
@@ -612,7 +574,7 @@ module ActiveSupport
|
|
|
612
574
|
@name = name
|
|
613
575
|
@config = {
|
|
614
576
|
scope: [:kind],
|
|
615
|
-
terminator:
|
|
577
|
+
terminator: DEFAULT_TERMINATOR
|
|
616
578
|
}.merge!(config)
|
|
617
579
|
@chain = []
|
|
618
580
|
@all_callbacks = nil
|
|
@@ -700,8 +662,8 @@ module ActiveSupport
|
|
|
700
662
|
@chain.delete_if { |c| callback.duplicates?(c) }
|
|
701
663
|
end
|
|
702
664
|
|
|
703
|
-
|
|
704
|
-
|
|
665
|
+
class DefaultTerminator # :nodoc:
|
|
666
|
+
def call(target, result_lambda)
|
|
705
667
|
terminate = true
|
|
706
668
|
catch(:abort) do
|
|
707
669
|
result_lambda.call
|
|
@@ -710,6 +672,7 @@ module ActiveSupport
|
|
|
710
672
|
terminate
|
|
711
673
|
end
|
|
712
674
|
end
|
|
675
|
+
DEFAULT_TERMINATOR = DefaultTerminator.new.freeze
|
|
713
676
|
end
|
|
714
677
|
|
|
715
678
|
module ClassMethods
|
|
@@ -943,12 +906,13 @@ module ActiveSupport
|
|
|
943
906
|
names.each do |name|
|
|
944
907
|
name = name.to_sym
|
|
945
908
|
|
|
946
|
-
([self] + self.descendants).each do |target|
|
|
947
|
-
target.set_callbacks name, CallbackChain.new(name, options)
|
|
948
|
-
end
|
|
949
|
-
|
|
950
909
|
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
951
|
-
def _run_#{name}_callbacks
|
|
910
|
+
def _run_#{name}_callbacks
|
|
911
|
+
yield if block_given?
|
|
912
|
+
end
|
|
913
|
+
silence_redefinition_of_method(:_run_#{name}_callbacks)
|
|
914
|
+
|
|
915
|
+
def _run_#{name}_callbacks!(&block)
|
|
952
916
|
run_callbacks #{name.inspect}, &block
|
|
953
917
|
end
|
|
954
918
|
|
|
@@ -964,6 +928,10 @@ module ActiveSupport
|
|
|
964
928
|
__callbacks[#{name.inspect}]
|
|
965
929
|
end
|
|
966
930
|
RUBY
|
|
931
|
+
|
|
932
|
+
([self] + self.descendants).each do |target|
|
|
933
|
+
target.set_callbacks name, CallbackChain.new(name, options)
|
|
934
|
+
end
|
|
967
935
|
end
|
|
968
936
|
end
|
|
969
937
|
|
|
@@ -973,9 +941,17 @@ module ActiveSupport
|
|
|
973
941
|
end
|
|
974
942
|
|
|
975
943
|
def set_callbacks(name, callbacks) # :nodoc:
|
|
976
|
-
|
|
944
|
+
# HACK: We're making assumption on how `class_attribute` is implemented
|
|
945
|
+
# to save constantly duping the callback hash. If this desync with class_attribute
|
|
946
|
+
# we'll lose the optimization, but won't cause an actual behavior bug.
|
|
947
|
+
unless singleton_class.private_method_defined?(:__class_attr__callbacks, false)
|
|
977
948
|
self.__callbacks = __callbacks.dup
|
|
978
949
|
end
|
|
950
|
+
name = name.to_sym
|
|
951
|
+
callbacks_was = self.__callbacks[name.to_sym]
|
|
952
|
+
if (callbacks_was.nil? || callbacks_was.empty?) && !callbacks.empty?
|
|
953
|
+
alias_method("_run_#{name}_callbacks", "_run_#{name}_callbacks!")
|
|
954
|
+
end
|
|
979
955
|
self.__callbacks[name.to_sym] = callbacks
|
|
980
956
|
self.__callbacks
|
|
981
957
|
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveSupport
|
|
4
|
+
module ClassAttribute # :nodoc:
|
|
5
|
+
class << self
|
|
6
|
+
def redefine(owner, name, namespaced_name, value)
|
|
7
|
+
if owner.singleton_class?
|
|
8
|
+
if owner.attached_object.is_a?(Module)
|
|
9
|
+
redefine_method(owner, namespaced_name, private: true) { value }
|
|
10
|
+
else
|
|
11
|
+
redefine_method(owner, name) { value }
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
redefine_method(owner.singleton_class, namespaced_name, private: true) { value }
|
|
16
|
+
|
|
17
|
+
redefine_method(owner.singleton_class, "#{namespaced_name}=", private: true) do |new_value|
|
|
18
|
+
if owner.equal?(self)
|
|
19
|
+
value = new_value
|
|
20
|
+
else
|
|
21
|
+
::ActiveSupport::ClassAttribute.redefine(self, name, namespaced_name, new_value)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def redefine_method(owner, name, private: false, &block)
|
|
27
|
+
owner.silence_redefinition_of_method(name)
|
|
28
|
+
owner.define_method(name, &block)
|
|
29
|
+
owner.send(:private, name) if private
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -55,6 +55,11 @@ module ActiveSupport
|
|
|
55
55
|
@path = path
|
|
56
56
|
@line = line
|
|
57
57
|
@namespaces = Hash.new { |h, k| h[k] = MethodSet.new(k) }
|
|
58
|
+
@sources = []
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def class_eval
|
|
62
|
+
yield @sources
|
|
58
63
|
end
|
|
59
64
|
|
|
60
65
|
def define_cached_method(canonical_name, namespace:, as: nil, &block)
|
|
@@ -65,6 +70,10 @@ module ActiveSupport
|
|
|
65
70
|
@namespaces.each_value do |method_set|
|
|
66
71
|
method_set.apply(@owner, @path, @line - 1)
|
|
67
72
|
end
|
|
73
|
+
|
|
74
|
+
unless @sources.empty?
|
|
75
|
+
@owner.class_eval("# frozen_string_literal: true\n" + @sources.join(";"), @path, @line - 1)
|
|
76
|
+
end
|
|
68
77
|
end
|
|
69
78
|
end
|
|
70
79
|
end
|
|
@@ -4,69 +4,15 @@ require "monitor"
|
|
|
4
4
|
|
|
5
5
|
module ActiveSupport
|
|
6
6
|
module Concurrency
|
|
7
|
-
module LoadInterlockAwareMonitorMixin # :nodoc:
|
|
8
|
-
EXCEPTION_NEVER = { Exception => :never }.freeze
|
|
9
|
-
EXCEPTION_IMMEDIATE = { Exception => :immediate }.freeze
|
|
10
|
-
private_constant :EXCEPTION_NEVER, :EXCEPTION_IMMEDIATE
|
|
11
|
-
|
|
12
|
-
# Enters an exclusive section, but allows dependency loading while blocked
|
|
13
|
-
def mon_enter
|
|
14
|
-
mon_try_enter ||
|
|
15
|
-
ActiveSupport::Dependencies.interlock.permit_concurrent_loads { super }
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def synchronize(&block)
|
|
19
|
-
Thread.handle_interrupt(EXCEPTION_NEVER) do
|
|
20
|
-
mon_enter
|
|
21
|
-
|
|
22
|
-
begin
|
|
23
|
-
Thread.handle_interrupt(EXCEPTION_IMMEDIATE, &block)
|
|
24
|
-
ensure
|
|
25
|
-
mon_exit
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
7
|
# A monitor that will permit dependency loading while blocked waiting for
|
|
31
8
|
# the lock.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
|
9
|
+
LoadInterlockAwareMonitor = ActiveSupport::Deprecation::DeprecatedConstantProxy.new(
|
|
10
|
+
"ActiveSupport::Concurrency::LoadInterlockAwareMonitor",
|
|
11
|
+
"::Monitor",
|
|
12
|
+
ActiveSupport.deprecator,
|
|
13
|
+
message: "ActiveSupport::Concurrency::LoadInterlockAwareMonitor is deprecated and will be " \
|
|
14
|
+
"removed in Rails 9.0. Use Monitor directly instead, as the loading interlock is " \
|
|
15
|
+
"no longer used."
|
|
16
|
+
)
|
|
71
17
|
end
|
|
72
18
|
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveSupport
|
|
4
|
+
module Concurrency
|
|
5
|
+
class ThreadMonitor # :nodoc:
|
|
6
|
+
EXCEPTION_NEVER = { Exception => :never }.freeze
|
|
7
|
+
EXCEPTION_IMMEDIATE = { Exception => :immediate }.freeze
|
|
8
|
+
private_constant :EXCEPTION_NEVER, :EXCEPTION_IMMEDIATE
|
|
9
|
+
|
|
10
|
+
def initialize
|
|
11
|
+
@owner = nil
|
|
12
|
+
@count = 0
|
|
13
|
+
@mutex = Mutex.new
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def synchronize(&block)
|
|
17
|
+
Thread.handle_interrupt(EXCEPTION_NEVER) do
|
|
18
|
+
mon_enter
|
|
19
|
+
|
|
20
|
+
begin
|
|
21
|
+
Thread.handle_interrupt(EXCEPTION_IMMEDIATE, &block)
|
|
22
|
+
ensure
|
|
23
|
+
mon_exit
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
def mon_try_enter
|
|
30
|
+
if @owner != Thread.current
|
|
31
|
+
return false unless @mutex.try_lock
|
|
32
|
+
@owner = Thread.current
|
|
33
|
+
end
|
|
34
|
+
@count += 1
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def mon_enter
|
|
38
|
+
@mutex.lock if @owner != Thread.current
|
|
39
|
+
@owner = Thread.current
|
|
40
|
+
@count += 1
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def mon_exit
|
|
44
|
+
unless @owner == Thread.current
|
|
45
|
+
raise ThreadError, "current thread not owner"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
@count -= 1
|
|
49
|
+
return unless @count == 0
|
|
50
|
+
@owner = nil
|
|
51
|
+
@mutex.unlock
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
ActiveSupport.deprecator.warn <<~MSG
|
|
4
|
+
ActiveSupport::Configurable is deprecated without replacement, and will be removed in Rails 8.2.
|
|
5
|
+
|
|
6
|
+
You can emulate the previous behavior with `class_attribute`.
|
|
7
|
+
MSG
|
|
8
|
+
|
|
3
9
|
require "active_support/concern"
|
|
4
10
|
require "active_support/ordered_options"
|
|
5
11
|
|
|
@@ -27,6 +33,19 @@ module ActiveSupport
|
|
|
27
33
|
end
|
|
28
34
|
|
|
29
35
|
module ClassMethods
|
|
36
|
+
# Reads and writes attributes from a configuration OrderedOptions.
|
|
37
|
+
#
|
|
38
|
+
# require "active_support/configurable"
|
|
39
|
+
#
|
|
40
|
+
# class User
|
|
41
|
+
# include ActiveSupport::Configurable
|
|
42
|
+
# end
|
|
43
|
+
#
|
|
44
|
+
# User.config.allowed_access = true
|
|
45
|
+
# User.config.level = 1
|
|
46
|
+
#
|
|
47
|
+
# User.config.allowed_access # => true
|
|
48
|
+
# User.config.level # => 1
|
|
30
49
|
def config
|
|
31
50
|
@_config ||= if respond_to?(:superclass) && superclass.respond_to?(:config)
|
|
32
51
|
superclass.config.inheritable_copy
|
|
@@ -36,6 +55,21 @@ module ActiveSupport
|
|
|
36
55
|
end
|
|
37
56
|
end
|
|
38
57
|
|
|
58
|
+
# Configure values from within the passed block.
|
|
59
|
+
#
|
|
60
|
+
# require "active_support/configurable"
|
|
61
|
+
#
|
|
62
|
+
# class User
|
|
63
|
+
# include ActiveSupport::Configurable
|
|
64
|
+
# end
|
|
65
|
+
#
|
|
66
|
+
# User.allowed_access # => nil
|
|
67
|
+
#
|
|
68
|
+
# User.configure do |config|
|
|
69
|
+
# config.allowed_access = true
|
|
70
|
+
# end
|
|
71
|
+
#
|
|
72
|
+
# User.allowed_access # => true
|
|
39
73
|
def configure
|
|
40
74
|
yield config
|
|
41
75
|
end
|
|
@@ -19,11 +19,20 @@ module ActiveSupport
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def parse(context: nil, **options)
|
|
22
|
-
source = render(context)
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
source = @content.include?("<%") ? render(context) : @content
|
|
23
|
+
|
|
24
|
+
if source == @content
|
|
25
|
+
if YAML.respond_to?(:unsafe_load)
|
|
26
|
+
YAML.unsafe_load_file(@content_path, **options) || {}
|
|
27
|
+
else
|
|
28
|
+
YAML.load_file(@content_path, **options) || {}
|
|
29
|
+
end
|
|
25
30
|
else
|
|
26
|
-
YAML.
|
|
31
|
+
if YAML.respond_to?(:unsafe_load)
|
|
32
|
+
YAML.unsafe_load(source, **options) || {}
|
|
33
|
+
else
|
|
34
|
+
YAML.load(source, **options) || {}
|
|
35
|
+
end
|
|
27
36
|
end
|
|
28
37
|
rescue Psych::SyntaxError => error
|
|
29
38
|
raise "YAML syntax error occurred while parsing #{@content_path}. " \
|
|
@@ -33,8 +42,7 @@ module ActiveSupport
|
|
|
33
42
|
|
|
34
43
|
private
|
|
35
44
|
def read(content_path)
|
|
36
|
-
require "yaml"
|
|
37
|
-
require "erb"
|
|
45
|
+
require "yaml" unless defined?(YAML)
|
|
38
46
|
|
|
39
47
|
File.read(content_path).tap do |content|
|
|
40
48
|
if content.include?("\u00A0")
|
|
@@ -44,6 +52,7 @@ module ActiveSupport
|
|
|
44
52
|
end
|
|
45
53
|
|
|
46
54
|
def render(context)
|
|
55
|
+
require "erb" unless defined?(ERB)
|
|
47
56
|
erb = ERB.new(@content).tap { |e| e.filename = @content_path }
|
|
48
57
|
context ? erb.result(context) : erb.result
|
|
49
58
|
end
|