activesupport 6.1.4.1 → 7.0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +325 -395
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -2
- data/lib/active_support/actionable_error.rb +1 -1
- data/lib/active_support/array_inquirer.rb +0 -2
- data/lib/active_support/backtrace_cleaner.rb +2 -2
- data/lib/active_support/benchmarkable.rb +2 -2
- data/lib/active_support/cache/file_store.rb +15 -9
- data/lib/active_support/cache/mem_cache_store.rb +148 -37
- data/lib/active_support/cache/memory_store.rb +24 -16
- data/lib/active_support/cache/null_store.rb +10 -2
- data/lib/active_support/cache/redis_cache_store.rb +68 -85
- data/lib/active_support/cache/strategy/local_cache.rb +38 -61
- data/lib/active_support/cache.rb +299 -147
- data/lib/active_support/callbacks.rb +184 -85
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +5 -5
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +2 -4
- data/lib/active_support/concurrency/share_lock.rb +2 -2
- data/lib/active_support/configurable.rb +8 -5
- data/lib/active_support/configuration_file.rb +1 -1
- data/lib/active_support/core_ext/array/access.rb +1 -5
- data/lib/active_support/core_ext/array/conversions.rb +13 -12
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
- data/lib/active_support/core_ext/array/grouping.rb +6 -6
- data/lib/active_support/core_ext/array/inquiry.rb +2 -2
- data/lib/active_support/core_ext/array.rb +1 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
- data/lib/active_support/core_ext/class/subclasses.rb +25 -17
- data/lib/active_support/core_ext/date/blank.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +24 -9
- data/lib/active_support/core_ext/date/conversions.rb +14 -14
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +40 -0
- data/lib/active_support/core_ext/date.rb +1 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +4 -4
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -1
- data/lib/active_support/core_ext/date_time/blank.rb +1 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +4 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +13 -13
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +36 -0
- data/lib/active_support/core_ext/date_time.rb +1 -0
- data/lib/active_support/core_ext/digest/uuid.rb +39 -13
- data/lib/active_support/core_ext/enumerable.rb +112 -38
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +0 -1
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +3 -3
- data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
- data/lib/active_support/core_ext/hash/keys.rb +4 -4
- data/lib/active_support/core_ext/integer/inflections.rb +12 -12
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
- data/lib/active_support/core_ext/kernel/singleton_class.rb +1 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +2 -0
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +19 -10
- data/lib/active_support/core_ext/module/delegation.rb +2 -8
- data/lib/active_support/core_ext/name_error.rb +2 -8
- data/lib/active_support/core_ext/numeric/conversions.rb +80 -77
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
- data/lib/active_support/core_ext/numeric.rb +1 -0
- data/lib/active_support/core_ext/object/acts_like.rb +29 -5
- data/lib/active_support/core_ext/object/blank.rb +2 -2
- data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
- data/lib/active_support/core_ext/object/duplicable.rb +15 -4
- data/lib/active_support/core_ext/object/json.rb +30 -25
- data/lib/active_support/core_ext/object/to_query.rb +2 -4
- data/lib/active_support/core_ext/object/try.rb +20 -20
- data/lib/active_support/core_ext/object/with_options.rb +21 -2
- data/lib/active_support/core_ext/pathname/existence.rb +21 -0
- data/lib/active_support/core_ext/pathname.rb +3 -0
- data/lib/active_support/core_ext/range/compare_range.rb +0 -25
- data/lib/active_support/core_ext/range/conversions.rb +8 -8
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +36 -0
- data/lib/active_support/core_ext/range/each.rb +1 -1
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +3 -26
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/range.rb +1 -1
- data/lib/active_support/core_ext/securerandom.rb +1 -1
- data/lib/active_support/core_ext/string/conversions.rb +2 -2
- data/lib/active_support/core_ext/string/filters.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +1 -5
- data/lib/active_support/core_ext/string/inquiry.rb +1 -1
- data/lib/active_support/core_ext/string/output_safety.rb +94 -38
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +0 -8
- data/lib/active_support/core_ext/time/calculations.rb +13 -8
- data/lib/active_support/core_ext/time/conversions.rb +13 -12
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +73 -0
- data/lib/active_support/core_ext/time/zones.rb +10 -26
- data/lib/active_support/core_ext/time.rb +1 -0
- data/lib/active_support/core_ext/uri.rb +3 -27
- data/lib/active_support/core_ext.rb +1 -0
- data/lib/active_support/current_attributes.rb +31 -14
- data/lib/active_support/dependencies/interlock.rb +10 -18
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +58 -788
- data/lib/active_support/deprecation/behaviors.rb +8 -5
- data/lib/active_support/deprecation/disallowed.rb +3 -3
- data/lib/active_support/deprecation/method_wrappers.rb +3 -3
- data/lib/active_support/deprecation/proxy_wrappers.rb +2 -2
- data/lib/active_support/deprecation.rb +2 -2
- data/lib/active_support/descendants_tracker.rb +174 -68
- data/lib/active_support/digest.rb +5 -3
- data/lib/active_support/duration/iso8601_parser.rb +3 -3
- data/lib/active_support/duration/iso8601_serializer.rb +9 -1
- data/lib/active_support/duration.rb +81 -51
- data/lib/active_support/encrypted_configuration.rb +45 -3
- data/lib/active_support/encrypted_file.rb +21 -10
- data/lib/active_support/environment_inquirer.rb +1 -1
- data/lib/active_support/error_reporter.rb +117 -0
- data/lib/active_support/evented_file_update_checker.rb +20 -7
- data/lib/active_support/execution_context/test_helper.rb +13 -0
- data/lib/active_support/execution_context.rb +53 -0
- data/lib/active_support/execution_wrapper.rb +43 -21
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/fork_tracker.rb +19 -12
- data/lib/active_support/gem_version.rb +5 -5
- data/lib/active_support/hash_with_indifferent_access.rb +3 -1
- data/lib/active_support/html_safe_translation.rb +43 -0
- data/lib/active_support/i18n.rb +1 -0
- data/lib/active_support/i18n_railtie.rb +1 -1
- data/lib/active_support/inflector/inflections.rb +23 -7
- data/lib/active_support/inflector/methods.rb +29 -55
- data/lib/active_support/inflector/transliterate.rb +1 -1
- data/lib/active_support/isolated_execution_state.rb +72 -0
- data/lib/active_support/json/encoding.rb +3 -3
- data/lib/active_support/key_generator.rb +22 -5
- data/lib/active_support/lazy_load_hooks.rb +28 -4
- data/lib/active_support/locale/en.yml +1 -1
- data/lib/active_support/log_subscriber/test_helper.rb +2 -2
- data/lib/active_support/log_subscriber.rb +15 -5
- data/lib/active_support/logger_thread_safe_level.rb +4 -13
- data/lib/active_support/message_encryptor.rb +12 -6
- data/lib/active_support/message_verifier.rb +46 -14
- data/lib/active_support/messages/metadata.rb +2 -2
- data/lib/active_support/multibyte/chars.rb +10 -11
- data/lib/active_support/multibyte/unicode.rb +0 -12
- data/lib/active_support/multibyte.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +91 -65
- data/lib/active_support/notifications/instrumenter.rb +32 -15
- data/lib/active_support/notifications.rb +23 -23
- data/lib/active_support/number_helper/number_converter.rb +1 -3
- data/lib/active_support/number_helper/number_to_currency_converter.rb +11 -6
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -1
- data/lib/active_support/number_helper/rounding_helper.rb +1 -5
- data/lib/active_support/number_helper.rb +4 -5
- data/lib/active_support/option_merger.rb +10 -18
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/ordered_options.rb +1 -1
- data/lib/active_support/parameter_filter.rb +20 -11
- data/lib/active_support/per_thread_registry.rb +5 -0
- data/lib/active_support/railtie.rb +69 -19
- data/lib/active_support/reloader.rb +1 -1
- data/lib/active_support/rescuable.rb +12 -12
- data/lib/active_support/ruby_features.rb +7 -0
- data/lib/active_support/secure_compare_rotator.rb +2 -2
- data/lib/active_support/string_inquirer.rb +0 -2
- data/lib/active_support/subscriber.rb +7 -18
- data/lib/active_support/tagged_logging.rb +2 -2
- data/lib/active_support/test_case.rb +13 -21
- data/lib/active_support/testing/assertions.rb +36 -6
- data/lib/active_support/testing/deprecation.rb +52 -1
- data/lib/active_support/testing/isolation.rb +30 -29
- data/lib/active_support/testing/method_call_assertions.rb +5 -5
- data/lib/active_support/testing/parallelization/server.rb +4 -0
- data/lib/active_support/testing/parallelization/worker.rb +3 -0
- data/lib/active_support/testing/parallelization.rb +4 -0
- data/lib/active_support/testing/parallelize_executor.rb +76 -0
- data/lib/active_support/testing/stream.rb +3 -5
- data/lib/active_support/testing/tagged_logging.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +13 -2
- data/lib/active_support/time_with_zone.rb +43 -22
- data/lib/active_support/values/time_zone.rb +35 -14
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/jdom.rb +1 -1
- data/lib/active_support/xml_mini/libxml.rb +5 -5
- data/lib/active_support/xml_mini/libxmlsax.rb +1 -1
- data/lib/active_support/xml_mini/nokogiri.rb +4 -4
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
- data/lib/active_support/xml_mini/rexml.rb +1 -1
- data/lib/active_support/xml_mini.rb +5 -4
- data/lib/active_support.rb +17 -1
- metadata +26 -23
- data/lib/active_support/core_ext/marshal.rb +0 -26
- data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
@@ -5,6 +5,7 @@ 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
7
|
require "active_support/core_ext/string/filters"
|
8
|
+
require "active_support/core_ext/object/blank"
|
8
9
|
require "thread"
|
9
10
|
|
10
11
|
module ActiveSupport
|
@@ -15,19 +16,19 @@ module ActiveSupport
|
|
15
16
|
# needing to override or redefine methods of the base class.
|
16
17
|
#
|
17
18
|
# Mixing in this module allows you to define the events in the object's
|
18
|
-
# life cycle that will support callbacks (via
|
19
|
+
# life cycle that will support callbacks (via ClassMethods#define_callbacks),
|
19
20
|
# set the instance methods, procs, or callback objects to be called (via
|
20
|
-
#
|
21
|
+
# ClassMethods#set_callback), and run the installed callbacks at the
|
21
22
|
# appropriate times (via +run_callbacks+).
|
22
23
|
#
|
23
24
|
# By default callbacks are halted by throwing +:abort+.
|
24
|
-
# See
|
25
|
+
# See ClassMethods#define_callbacks for details.
|
25
26
|
#
|
26
27
|
# Three kinds of callbacks are supported: before callbacks, run before a
|
27
28
|
# certain event; after callbacks, run after the event; and around callbacks,
|
28
29
|
# blocks that surround the event, triggering it when they yield. Callback code
|
29
30
|
# can be contained in instance methods, procs or lambdas, or callback objects
|
30
|
-
# that respond to certain predetermined methods. See
|
31
|
+
# that respond to certain predetermined methods. See ClassMethods#set_callback
|
31
32
|
# for details.
|
32
33
|
#
|
33
34
|
# class Record
|
@@ -276,7 +277,7 @@ module ActiveSupport
|
|
276
277
|
end
|
277
278
|
end
|
278
279
|
|
279
|
-
class Callback
|
280
|
+
class Callback # :nodoc:#
|
280
281
|
def self.build(chain, filter, kind, options)
|
281
282
|
if filter.is_a?(String)
|
282
283
|
raise ArgumentError, <<-MSG.squish
|
@@ -289,21 +290,17 @@ module ActiveSupport
|
|
289
290
|
end
|
290
291
|
|
291
292
|
attr_accessor :kind, :name
|
292
|
-
attr_reader :chain_config
|
293
|
+
attr_reader :chain_config, :filter
|
293
294
|
|
294
295
|
def initialize(name, filter, kind, options, chain_config)
|
295
296
|
@chain_config = chain_config
|
296
297
|
@name = name
|
297
298
|
@kind = kind
|
298
299
|
@filter = filter
|
299
|
-
@key = compute_identifier filter
|
300
300
|
@if = check_conditionals(options[:if])
|
301
301
|
@unless = check_conditionals(options[:unless])
|
302
302
|
end
|
303
303
|
|
304
|
-
def filter; @key; end
|
305
|
-
def raw_filter; @filter; end
|
306
|
-
|
307
304
|
def merge_conditional_options(chain, if_option:, unless_option:)
|
308
305
|
options = {
|
309
306
|
if: @if.dup,
|
@@ -356,7 +353,7 @@ module ActiveSupport
|
|
356
353
|
return EMPTY_ARRAY if conditionals.blank?
|
357
354
|
|
358
355
|
conditionals = Array(conditionals)
|
359
|
-
if conditionals.any?
|
356
|
+
if conditionals.any?(String)
|
360
357
|
raise ArgumentError, <<-MSG.squish
|
361
358
|
Passing string to be evaluated in :if and :unless conditional
|
362
359
|
options is not supported. Pass a symbol for an instance method,
|
@@ -367,15 +364,6 @@ module ActiveSupport
|
|
367
364
|
conditionals.freeze
|
368
365
|
end
|
369
366
|
|
370
|
-
def compute_identifier(filter)
|
371
|
-
case filter
|
372
|
-
when ::Proc
|
373
|
-
filter.object_id
|
374
|
-
else
|
375
|
-
filter
|
376
|
-
end
|
377
|
-
end
|
378
|
-
|
379
367
|
def conditions_lambdas
|
380
368
|
@if.map { |c| CallTemplate.build(c, self).make_lambda } +
|
381
369
|
@unless.map { |c| CallTemplate.build(c, self).inverted_lambda }
|
@@ -384,56 +372,153 @@ module ActiveSupport
|
|
384
372
|
|
385
373
|
# A future invocation of user-supplied code (either as a callback,
|
386
374
|
# or a condition filter).
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
375
|
+
module CallTemplate # :nodoc:
|
376
|
+
class MethodCall
|
377
|
+
def initialize(method)
|
378
|
+
@method_name = method
|
379
|
+
end
|
380
|
+
|
381
|
+
# Return the parts needed to make this call, with the given
|
382
|
+
# input values.
|
383
|
+
#
|
384
|
+
# Returns an array of the form:
|
385
|
+
#
|
386
|
+
# [target, block, method, *arguments]
|
387
|
+
#
|
388
|
+
# This array can be used as such:
|
389
|
+
#
|
390
|
+
# target.send(method, *arguments, &block)
|
391
|
+
#
|
392
|
+
# The actual invocation is left up to the caller to minimize
|
393
|
+
# call stack pollution.
|
394
|
+
def expand(target, value, block)
|
395
|
+
[target, block, @method_name]
|
396
|
+
end
|
397
|
+
|
398
|
+
def make_lambda
|
399
|
+
lambda do |target, value, &block|
|
400
|
+
target.send(@method_name, &block)
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
def inverted_lambda
|
405
|
+
lambda do |target, value, &block|
|
406
|
+
!target.send(@method_name, &block)
|
407
|
+
end
|
408
|
+
end
|
393
409
|
end
|
394
410
|
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
# target.send(method, *arguments, &block)
|
405
|
-
#
|
406
|
-
# The actual invocation is left up to the caller to minimize
|
407
|
-
# call stack pollution.
|
408
|
-
def expand(target, value, block)
|
409
|
-
expanded = [@override_target || target, @override_block || block, @method_name]
|
411
|
+
class ObjectCall
|
412
|
+
def initialize(target, method)
|
413
|
+
@override_target = target
|
414
|
+
@method_name = method
|
415
|
+
end
|
416
|
+
|
417
|
+
def expand(target, value, block)
|
418
|
+
[@override_target || target, block, @method_name, target]
|
419
|
+
end
|
410
420
|
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
when :target then expanded << target
|
415
|
-
when :block then expanded << (block || raise(ArgumentError))
|
421
|
+
def make_lambda
|
422
|
+
lambda do |target, value, &block|
|
423
|
+
(@override_target || target).send(@method_name, target, &block)
|
416
424
|
end
|
417
425
|
end
|
418
426
|
|
419
|
-
|
427
|
+
def inverted_lambda
|
428
|
+
lambda do |target, value, &block|
|
429
|
+
!(@override_target || target).send(@method_name, target, &block)
|
430
|
+
end
|
431
|
+
end
|
420
432
|
end
|
421
433
|
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
434
|
+
class InstanceExec0
|
435
|
+
def initialize(block)
|
436
|
+
@override_block = block
|
437
|
+
end
|
438
|
+
|
439
|
+
def expand(target, value, block)
|
440
|
+
[target, @override_block, :instance_exec]
|
441
|
+
end
|
442
|
+
|
443
|
+
def make_lambda
|
444
|
+
lambda do |target, value, &block|
|
445
|
+
target.instance_exec(&@override_block)
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
449
|
+
def inverted_lambda
|
450
|
+
lambda do |target, value, &block|
|
451
|
+
!target.instance_exec(&@override_block)
|
452
|
+
end
|
428
453
|
end
|
429
454
|
end
|
430
455
|
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
456
|
+
class InstanceExec1
|
457
|
+
def initialize(block)
|
458
|
+
@override_block = block
|
459
|
+
end
|
460
|
+
|
461
|
+
def expand(target, value, block)
|
462
|
+
[target, @override_block, :instance_exec, target]
|
463
|
+
end
|
464
|
+
|
465
|
+
def make_lambda
|
466
|
+
lambda do |target, value, &block|
|
467
|
+
target.instance_exec(target, &@override_block)
|
468
|
+
end
|
469
|
+
end
|
470
|
+
|
471
|
+
def inverted_lambda
|
472
|
+
lambda do |target, value, &block|
|
473
|
+
!target.instance_exec(target, &@override_block)
|
474
|
+
end
|
475
|
+
end
|
476
|
+
end
|
477
|
+
|
478
|
+
class InstanceExec2
|
479
|
+
def initialize(block)
|
480
|
+
@override_block = block
|
481
|
+
end
|
482
|
+
|
483
|
+
def expand(target, value, block)
|
484
|
+
raise ArgumentError unless block
|
485
|
+
[target, @override_block || block, :instance_exec, target, block]
|
486
|
+
end
|
487
|
+
|
488
|
+
def make_lambda
|
489
|
+
lambda do |target, value, &block|
|
490
|
+
raise ArgumentError unless block
|
491
|
+
target.instance_exec(target, block, &@override_block)
|
492
|
+
end
|
493
|
+
end
|
494
|
+
|
495
|
+
def inverted_lambda
|
496
|
+
lambda do |target, value, &block|
|
497
|
+
raise ArgumentError unless block
|
498
|
+
!target.instance_exec(target, block, &@override_block)
|
499
|
+
end
|
500
|
+
end
|
501
|
+
end
|
502
|
+
|
503
|
+
class ProcCall
|
504
|
+
def initialize(target)
|
505
|
+
@override_target = target
|
506
|
+
end
|
507
|
+
|
508
|
+
def expand(target, value, block)
|
509
|
+
[@override_target || target, block, :call, target, value]
|
510
|
+
end
|
511
|
+
|
512
|
+
def make_lambda
|
513
|
+
lambda do |target, value, &block|
|
514
|
+
(@override_target || target).call(target, value, &block)
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
def inverted_lambda
|
519
|
+
lambda do |target, value, &block|
|
520
|
+
!(@override_target || target).call(target, value, &block)
|
521
|
+
end
|
437
522
|
end
|
438
523
|
end
|
439
524
|
|
@@ -448,21 +533,19 @@ module ActiveSupport
|
|
448
533
|
def self.build(filter, callback)
|
449
534
|
case filter
|
450
535
|
when Symbol
|
451
|
-
new(
|
536
|
+
MethodCall.new(filter)
|
452
537
|
when Conditionals::Value
|
453
|
-
new(filter
|
538
|
+
ProcCall.new(filter)
|
454
539
|
when ::Proc
|
455
540
|
if filter.arity > 1
|
456
|
-
new(
|
541
|
+
InstanceExec2.new(filter)
|
457
542
|
elsif filter.arity > 0
|
458
|
-
new(
|
543
|
+
InstanceExec1.new(filter)
|
459
544
|
else
|
460
|
-
new(
|
545
|
+
InstanceExec0.new(filter)
|
461
546
|
end
|
462
547
|
else
|
463
|
-
|
464
|
-
|
465
|
-
new(filter, method_to_call, [:target], nil)
|
548
|
+
ObjectCall.new(filter, callback.current_scopes.join("_").to_sym)
|
466
549
|
end
|
467
550
|
end
|
468
551
|
end
|
@@ -517,7 +600,7 @@ module ActiveSupport
|
|
517
600
|
end
|
518
601
|
end
|
519
602
|
|
520
|
-
class CallbackChain
|
603
|
+
class CallbackChain # :nodoc:
|
521
604
|
include Enumerable
|
522
605
|
|
523
606
|
attr_reader :name, :config
|
@@ -619,8 +702,8 @@ module ActiveSupport
|
|
619
702
|
|
620
703
|
# This is used internally to append, prepend and skip callbacks to the
|
621
704
|
# CallbackChain.
|
622
|
-
def __update_callbacks(name)
|
623
|
-
([self] +
|
705
|
+
def __update_callbacks(name) # :nodoc:
|
706
|
+
([self] + self.descendants).reverse_each do |target|
|
624
707
|
chain = target.get_callbacks name
|
625
708
|
yield target, chain.dup
|
626
709
|
end
|
@@ -688,10 +771,32 @@ module ActiveSupport
|
|
688
771
|
# <tt>:unless</tt> options may be passed in order to control when the
|
689
772
|
# callback is skipped.
|
690
773
|
#
|
691
|
-
# class Writer <
|
692
|
-
#
|
774
|
+
# class Writer < PersonRecord
|
775
|
+
# attr_accessor :age
|
776
|
+
# skip_callback :save, :before, :saving_message, if: -> { age > 18 }
|
693
777
|
# end
|
694
778
|
#
|
779
|
+
# When if option returns true, callback is skipped.
|
780
|
+
#
|
781
|
+
# writer = Writer.new
|
782
|
+
# writer.age = 20
|
783
|
+
# writer.save
|
784
|
+
#
|
785
|
+
# Output:
|
786
|
+
# - save
|
787
|
+
# saved
|
788
|
+
#
|
789
|
+
# When if option returns false, callback is NOT skipped.
|
790
|
+
#
|
791
|
+
# young_writer = Writer.new
|
792
|
+
# young_writer.age = 17
|
793
|
+
# young_writer.save
|
794
|
+
#
|
795
|
+
# Output:
|
796
|
+
# saving...
|
797
|
+
# - save
|
798
|
+
# saved
|
799
|
+
#
|
695
800
|
# An <tt>ArgumentError</tt> will be raised if the callback has not
|
696
801
|
# already been set (unless the <tt>:raise</tt> option is set to <tt>false</tt>).
|
697
802
|
def skip_callback(name, *filter_list, &block)
|
@@ -722,7 +827,7 @@ module ActiveSupport
|
|
722
827
|
def reset_callbacks(name)
|
723
828
|
callbacks = get_callbacks name
|
724
829
|
|
725
|
-
|
830
|
+
self.descendants.each do |target|
|
726
831
|
chain = target.get_callbacks(name).dup
|
727
832
|
callbacks.each { |c| chain.delete(c) }
|
728
833
|
target.set_callbacks name, chain
|
@@ -815,7 +920,7 @@ module ActiveSupport
|
|
815
920
|
names.each do |name|
|
816
921
|
name = name.to_sym
|
817
922
|
|
818
|
-
([self] +
|
923
|
+
([self] + self.descendants).each do |target|
|
819
924
|
target.set_callbacks name, CallbackChain.new(name, options)
|
820
925
|
end
|
821
926
|
|
@@ -844,18 +949,12 @@ module ActiveSupport
|
|
844
949
|
__callbacks[name.to_sym]
|
845
950
|
end
|
846
951
|
|
847
|
-
|
848
|
-
|
849
|
-
self.__callbacks = __callbacks.
|
850
|
-
end
|
851
|
-
else # Ruby 2.6 and newer
|
852
|
-
def set_callbacks(name, callbacks) # :nodoc:
|
853
|
-
unless singleton_class.method_defined?(:__callbacks, false)
|
854
|
-
self.__callbacks = __callbacks.dup
|
855
|
-
end
|
856
|
-
self.__callbacks[name.to_sym] = callbacks
|
857
|
-
self.__callbacks
|
952
|
+
def set_callbacks(name, callbacks) # :nodoc:
|
953
|
+
unless singleton_class.method_defined?(:__callbacks, false)
|
954
|
+
self.__callbacks = __callbacks.dup
|
858
955
|
end
|
956
|
+
self.__callbacks[name.to_sym] = callbacks
|
957
|
+
self.__callbacks
|
859
958
|
end
|
860
959
|
end
|
861
960
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
class CodeGenerator # :nodoc:
|
5
|
+
class MethodSet
|
6
|
+
METHOD_CACHES = Hash.new { |h, k| h[k] = Module.new }
|
7
|
+
|
8
|
+
def initialize(namespace)
|
9
|
+
@cache = METHOD_CACHES[namespace]
|
10
|
+
@sources = []
|
11
|
+
@methods = {}
|
12
|
+
end
|
13
|
+
|
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)
|
19
|
+
yield @sources
|
20
|
+
end
|
21
|
+
@methods[name] = as
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def apply(owner, path, line)
|
26
|
+
unless @sources.empty?
|
27
|
+
@cache.module_eval("# frozen_string_literal: true\n" + @sources.join(";"), path, line)
|
28
|
+
end
|
29
|
+
@methods.each do |name, as|
|
30
|
+
owner.define_method(name, @cache.instance_method(as))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class << self
|
36
|
+
def batch(owner, path, line)
|
37
|
+
if owner.is_a?(CodeGenerator)
|
38
|
+
yield owner
|
39
|
+
else
|
40
|
+
instance = new(owner, path, line)
|
41
|
+
result = yield instance
|
42
|
+
instance.execute
|
43
|
+
result
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def initialize(owner, path, line)
|
49
|
+
@owner = owner
|
50
|
+
@path = path
|
51
|
+
@line = line
|
52
|
+
@namespaces = Hash.new { |h, k| h[k] = MethodSet.new(k) }
|
53
|
+
end
|
54
|
+
|
55
|
+
def define_cached_method(name, namespace:, as: name, &block)
|
56
|
+
@namespaces[namespace].define_cached_method(name, as: as, &block)
|
57
|
+
end
|
58
|
+
|
59
|
+
def execute
|
60
|
+
@namespaces.each_value do |method_set|
|
61
|
+
method_set.apply(@owner, @path, @line - 1)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -108,23 +108,23 @@ module ActiveSupport
|
|
108
108
|
#
|
109
109
|
# <tt>prepend</tt> is also used for any dependencies.
|
110
110
|
module Concern
|
111
|
-
class MultipleIncludedBlocks < StandardError
|
111
|
+
class MultipleIncludedBlocks < StandardError # :nodoc:
|
112
112
|
def initialize
|
113
113
|
super "Cannot define multiple 'included' blocks for a Concern"
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
117
|
-
class MultiplePrependBlocks < StandardError
|
117
|
+
class MultiplePrependBlocks < StandardError # :nodoc:
|
118
118
|
def initialize
|
119
119
|
super "Cannot define multiple 'prepended' blocks for a Concern"
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
123
|
-
def self.extended(base)
|
123
|
+
def self.extended(base) # :nodoc:
|
124
124
|
base.instance_variable_set(:@_dependencies, [])
|
125
125
|
end
|
126
126
|
|
127
|
-
def append_features(base)
|
127
|
+
def append_features(base) # :nodoc:
|
128
128
|
if base.instance_variable_defined?(:@_dependencies)
|
129
129
|
base.instance_variable_get(:@_dependencies) << self
|
130
130
|
false
|
@@ -137,7 +137,7 @@ module ActiveSupport
|
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
140
|
-
def prepend_features(base)
|
140
|
+
def prepend_features(base) # :nodoc:
|
141
141
|
if base.instance_variable_defined?(:@_dependencies)
|
142
142
|
base.instance_variable_get(:@_dependencies).unshift self
|
143
143
|
false
|
@@ -17,14 +17,12 @@ module ActiveSupport
|
|
17
17
|
ActiveSupport::Dependencies.interlock.permit_concurrent_loads { super }
|
18
18
|
end
|
19
19
|
|
20
|
-
def synchronize
|
20
|
+
def synchronize(&block)
|
21
21
|
Thread.handle_interrupt(EXCEPTION_NEVER) do
|
22
22
|
mon_enter
|
23
23
|
|
24
24
|
begin
|
25
|
-
Thread.handle_interrupt(EXCEPTION_IMMEDIATE)
|
26
|
-
yield
|
27
|
-
end
|
25
|
+
Thread.handle_interrupt(EXCEPTION_IMMEDIATE, &block)
|
28
26
|
ensure
|
29
27
|
mon_exit
|
30
28
|
end
|
@@ -215,9 +215,9 @@ module ActiveSupport
|
|
215
215
|
@waiting.any? { |t, (p, _)| compatible.include?(p) && @waiting.all? { |t2, (_, c2)| t == t2 || c2.include?(p) } }
|
216
216
|
end
|
217
217
|
|
218
|
-
def wait_for(method)
|
218
|
+
def wait_for(method, &block)
|
219
219
|
@sleeping[Thread.current] = method
|
220
|
-
@cv.wait_while
|
220
|
+
@cv.wait_while(&block)
|
221
221
|
ensure
|
222
222
|
@sleeping.delete Thread.current
|
223
223
|
end
|
@@ -5,7 +5,7 @@ require "active_support/ordered_options"
|
|
5
5
|
|
6
6
|
module ActiveSupport
|
7
7
|
# Configurable provides a <tt>config</tt> method to store and retrieve
|
8
|
-
# configuration options as an
|
8
|
+
# configuration options as an OrderedOptions.
|
9
9
|
module Configurable
|
10
10
|
extend ActiveSupport::Concern
|
11
11
|
|
@@ -94,17 +94,19 @@ module ActiveSupport
|
|
94
94
|
# User.new.allowed_access = true # => NoMethodError
|
95
95
|
# User.new.allowed_access # => NoMethodError
|
96
96
|
#
|
97
|
-
# Also you can pass a block to set up the attribute with a default value.
|
97
|
+
# Also you can pass <tt>default</tt> or a block to set up the attribute with a default value.
|
98
98
|
#
|
99
99
|
# class User
|
100
100
|
# include ActiveSupport::Configurable
|
101
|
+
# config_accessor :allowed_access, default: false
|
101
102
|
# config_accessor :hair_colors do
|
102
103
|
# [:brown, :black, :blonde, :red]
|
103
104
|
# end
|
104
105
|
# end
|
105
106
|
#
|
107
|
+
# User.allowed_access # => false
|
106
108
|
# User.hair_colors # => [:brown, :black, :blonde, :red]
|
107
|
-
def config_accessor(*names, instance_reader: true, instance_writer: true, instance_accessor: true) # :doc:
|
109
|
+
def config_accessor(*names, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil) # :doc:
|
108
110
|
names.each do |name|
|
109
111
|
raise NameError.new("invalid config attribute name") unless /\A[_A-Za-z]\w*\z/.match?(name)
|
110
112
|
|
@@ -118,13 +120,14 @@ module ActiveSupport
|
|
118
120
|
class_eval reader, __FILE__, reader_line if instance_reader
|
119
121
|
class_eval writer, __FILE__, writer_line if instance_writer
|
120
122
|
end
|
121
|
-
|
123
|
+
|
124
|
+
send("#{name}=", block_given? ? yield : default)
|
122
125
|
end
|
123
126
|
end
|
124
127
|
private :config_accessor
|
125
128
|
end
|
126
129
|
|
127
|
-
# Reads and writes attributes from a configuration
|
130
|
+
# Reads and writes attributes from a configuration OrderedOptions.
|
128
131
|
#
|
129
132
|
# require "active_support/configurable"
|
130
133
|
#
|
@@ -38,7 +38,7 @@ module ActiveSupport
|
|
38
38
|
|
39
39
|
File.read(content_path).tap do |content|
|
40
40
|
if content.include?("\u00A0")
|
41
|
-
warn "
|
41
|
+
warn "#{content_path} contains invisible non-breaking spaces, you may want to remove those"
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/xml_mini"
|
4
3
|
require "active_support/core_ext/hash/keys"
|
5
4
|
require "active_support/core_ext/string/inflections"
|
6
5
|
require "active_support/core_ext/object/to_param"
|
@@ -16,12 +15,12 @@ class Array
|
|
16
15
|
#
|
17
16
|
# ==== Options
|
18
17
|
#
|
19
|
-
# * <tt>:words_connector</tt> - The sign or word used to join the
|
20
|
-
# in arrays with
|
21
|
-
# * <tt>:two_words_connector</tt> - The sign or word used to join the elements
|
22
|
-
# in arrays with two elements (default: " and ").
|
18
|
+
# * <tt>:words_connector</tt> - The sign or word used to join all but the last
|
19
|
+
# element in arrays with three or more elements (default: ", ").
|
23
20
|
# * <tt>:last_word_connector</tt> - The sign or word used to join the last element
|
24
21
|
# in arrays with three or more elements (default: ", and ").
|
22
|
+
# * <tt>:two_words_connector</tt> - The sign or word used to join the elements
|
23
|
+
# in arrays with two elements (default: " and ").
|
25
24
|
# * <tt>:locale</tt> - If +i18n+ is available, you can set a locale and use
|
26
25
|
# the connector options defined on the 'support.array' namespace in the
|
27
26
|
# corresponding dictionary file.
|
@@ -66,7 +65,7 @@ class Array
|
|
66
65
|
two_words_connector: " and ",
|
67
66
|
last_word_connector: ", and "
|
68
67
|
}
|
69
|
-
if defined?(I18n)
|
68
|
+
if options[:locale] != false && defined?(I18n)
|
70
69
|
i18n_connectors = I18n.translate(:'support.array', locale: options[:locale], default: {})
|
71
70
|
default_connectors.merge!(i18n_connectors)
|
72
71
|
end
|
@@ -87,10 +86,12 @@ class Array
|
|
87
86
|
# Extends <tt>Array#to_s</tt> to convert a collection of elements into a
|
88
87
|
# comma separated id list if <tt>:db</tt> argument is given as the format.
|
89
88
|
#
|
90
|
-
#
|
91
|
-
#
|
92
|
-
#
|
93
|
-
|
89
|
+
# This method is aliased to <tt>to_formatted_s</tt>.
|
90
|
+
#
|
91
|
+
# Blog.all.to_fs(:db) # => "1,2,3"
|
92
|
+
# Blog.none.to_fs(:db) # => "null"
|
93
|
+
# [1,2].to_fs # => "[1, 2]"
|
94
|
+
def to_fs(format = :default)
|
94
95
|
case format
|
95
96
|
when :db
|
96
97
|
if empty?
|
@@ -102,8 +103,8 @@ class Array
|
|
102
103
|
to_default_s
|
103
104
|
end
|
104
105
|
end
|
106
|
+
alias_method :to_formatted_s, :to_fs
|
105
107
|
alias_method :to_default_s, :to_s
|
106
|
-
alias_method :to_s, :to_formatted_s
|
107
108
|
|
108
109
|
# Returns a string that represents the array in XML by invoking +to_xml+
|
109
110
|
# on each element. Active Record collections delegate their representation
|
@@ -187,7 +188,7 @@ class Array
|
|
187
188
|
options[:indent] ||= 2
|
188
189
|
options[:builder] ||= Builder::XmlMarkup.new(indent: options[:indent])
|
189
190
|
options[:root] ||= \
|
190
|
-
if first.class != Hash && all?
|
191
|
+
if first.class != Hash && all?(first.class)
|
191
192
|
underscored = ActiveSupport::Inflector.underscore(first.class.name)
|
192
193
|
ActiveSupport::Inflector.pluralize(underscored).tr("/", "_")
|
193
194
|
else
|