activesupport 7.1.4.1 → 7.2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +127 -1129
- data/lib/active_support/array_inquirer.rb +1 -1
- data/lib/active_support/backtrace_cleaner.rb +10 -3
- data/lib/active_support/broadcast_logger.rb +18 -18
- data/lib/active_support/cache/file_store.rb +15 -10
- data/lib/active_support/cache/mem_cache_store.rb +16 -74
- data/lib/active_support/cache/memory_store.rb +2 -1
- data/lib/active_support/cache/redis_cache_store.rb +16 -13
- data/lib/active_support/cache/serializer_with_fallback.rb +0 -23
- data/lib/active_support/cache.rb +60 -68
- data/lib/active_support/callbacks.rb +74 -113
- data/lib/active_support/core_ext/array/conversions.rb +0 -2
- data/lib/active_support/core_ext/class/subclasses.rb +15 -35
- data/lib/active_support/core_ext/date/blank.rb +4 -0
- data/lib/active_support/core_ext/date/conversions.rb +0 -2
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +28 -1
- data/lib/active_support/core_ext/date_time/blank.rb +4 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +0 -4
- data/lib/active_support/core_ext/digest/uuid.rb +6 -0
- data/lib/active_support/core_ext/erb/util.rb +5 -0
- data/lib/active_support/core_ext/hash/keys.rb +4 -4
- data/lib/active_support/core_ext/module/attr_internal.rb +17 -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/numeric/conversions.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 +6 -4
- data/lib/active_support/core_ext/object/with.rb +5 -3
- data/lib/active_support/core_ext/pathname/blank.rb +4 -0
- data/lib/active_support/core_ext/range/overlap.rb +1 -1
- data/lib/active_support/core_ext/securerandom.rb +8 -24
- data/lib/active_support/core_ext/string/conversions.rb +1 -1
- data/lib/active_support/core_ext/string/filters.rb +1 -1
- data/lib/active_support/core_ext/string/multibyte.rb +1 -1
- data/lib/active_support/core_ext/string/output_safety.rb +0 -7
- data/lib/active_support/core_ext/time/calculations.rb +18 -28
- data/lib/active_support/core_ext/time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/time/conversions.rb +0 -2
- data/lib/active_support/core_ext/time/zones.rb +1 -1
- data/lib/active_support/core_ext.rb +0 -1
- data/lib/active_support/current_attributes.rb +38 -40
- data/lib/active_support/delegation.rb +202 -0
- data/lib/active_support/dependencies/autoload.rb +0 -12
- 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 +9 -4
- 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 +11 -6
- data/lib/active_support/encrypted_file.rb +1 -1
- data/lib/active_support/error_reporter.rb +41 -3
- data/lib/active_support/evented_file_update_checker.rb +0 -1
- data/lib/active_support/execution_wrapper.rb +0 -1
- data/lib/active_support/file_update_checker.rb +1 -1
- data/lib/active_support/fork_tracker.rb +2 -38
- data/lib/active_support/gem_version.rb +2 -2
- data/lib/active_support/hash_with_indifferent_access.rb +6 -8
- data/lib/active_support/html_safe_translation.rb +3 -0
- data/lib/active_support/log_subscriber.rb +0 -12
- data/lib/active_support/logger.rb +15 -2
- data/lib/active_support/logger_thread_safe_level.rb +0 -8
- data/lib/active_support/message_pack/extensions.rb +15 -2
- data/lib/active_support/message_verifier.rb +12 -0
- data/lib/active_support/multibyte/chars.rb +2 -2
- data/lib/active_support/notifications/fanout.rb +4 -7
- data/lib/active_support/notifications/instrumenter.rb +21 -18
- data/lib/active_support/notifications.rb +28 -27
- data/lib/active_support/number_helper/number_converter.rb +2 -2
- data/lib/active_support/option_merger.rb +2 -2
- data/lib/active_support/ordered_options.rb +53 -15
- data/lib/active_support/proxy_object.rb +8 -5
- data/lib/active_support/railtie.rb +4 -11
- data/lib/active_support/string_inquirer.rb +1 -1
- data/lib/active_support/subscriber.rb +1 -0
- data/lib/active_support/tagged_logging.rb +0 -1
- data/lib/active_support/test_case.rb +3 -1
- data/lib/active_support/testing/assertions.rb +4 -4
- data/lib/active_support/testing/constant_stubbing.rb +30 -8
- data/lib/active_support/testing/deprecation.rb +5 -12
- data/lib/active_support/testing/isolation.rb +20 -8
- data/lib/active_support/testing/method_call_assertions.rb +2 -16
- data/lib/active_support/testing/parallelization/server.rb +3 -0
- data/lib/active_support/testing/strict_warnings.rb +8 -4
- data/lib/active_support/testing/tests_without_assertions.rb +19 -0
- data/lib/active_support/testing/time_helpers.rb +3 -3
- data/lib/active_support/time_with_zone.rb +8 -4
- data/lib/active_support/values/time_zone.rb +7 -7
- data/lib/active_support/xml_mini.rb +11 -2
- data/lib/active_support.rb +2 -1
- metadata +49 -15
- data/lib/active_support/deprecation/instance_delegator.rb +0 -65
- data/lib/active_support/ruby_features.rb +0 -7
data/lib/active_support/cache.rb
CHANGED
@@ -52,7 +52,7 @@ module ActiveSupport
|
|
52
52
|
autoload :LocalCache, "active_support/cache/strategy/local_cache"
|
53
53
|
end
|
54
54
|
|
55
|
-
@format_version =
|
55
|
+
@format_version = 7.0
|
56
56
|
|
57
57
|
class << self
|
58
58
|
attr_accessor :format_version
|
@@ -86,13 +86,7 @@ module ActiveSupport
|
|
86
86
|
case store
|
87
87
|
when Symbol
|
88
88
|
options = parameters.extract_options!
|
89
|
-
|
90
|
-
# see https://github.com/rails/rails/pull/41522#discussion_r581186602
|
91
|
-
if options.empty?
|
92
|
-
retrieve_store_class(store).new(*parameters)
|
93
|
-
else
|
94
|
-
retrieve_store_class(store).new(*parameters, **options)
|
95
|
-
end
|
89
|
+
retrieve_store_class(store).new(*parameters, **options)
|
96
90
|
when Array
|
97
91
|
lookup_store(*store)
|
98
92
|
when nil
|
@@ -166,7 +160,7 @@ module ActiveSupport
|
|
166
160
|
# cache = ActiveSupport::Cache::MemoryStore.new
|
167
161
|
#
|
168
162
|
# cache.read('city') # => nil
|
169
|
-
# cache.write('city', "Duckburgh")
|
163
|
+
# cache.write('city', "Duckburgh") # => true
|
170
164
|
# cache.read('city') # => "Duckburgh"
|
171
165
|
#
|
172
166
|
# cache.write('not serializable', Proc.new {}) # => TypeError
|
@@ -206,24 +200,6 @@ module ActiveSupport
|
|
206
200
|
def retrieve_pool_options(options)
|
207
201
|
if options.key?(:pool)
|
208
202
|
pool_options = options.delete(:pool)
|
209
|
-
elsif options.key?(:pool_size) || options.key?(:pool_timeout)
|
210
|
-
pool_options = {}
|
211
|
-
|
212
|
-
if options.key?(:pool_size)
|
213
|
-
ActiveSupport.deprecator.warn(<<~MSG)
|
214
|
-
Using :pool_size is deprecated and will be removed in Rails 7.2.
|
215
|
-
Use `pool: { size: #{options[:pool_size].inspect} }` instead.
|
216
|
-
MSG
|
217
|
-
pool_options[:size] = options.delete(:pool_size)
|
218
|
-
end
|
219
|
-
|
220
|
-
if options.key?(:pool_timeout)
|
221
|
-
ActiveSupport.deprecator.warn(<<~MSG)
|
222
|
-
Using :pool_timeout is deprecated and will be removed in Rails 7.2.
|
223
|
-
Use `pool: { timeout: #{options[:pool_timeout].inspect} }` instead.
|
224
|
-
MSG
|
225
|
-
pool_options[:timeout] = options.delete(:pool_timeout)
|
226
|
-
end
|
227
203
|
else
|
228
204
|
pool_options = true
|
229
205
|
end
|
@@ -344,7 +320,7 @@ module ActiveSupport
|
|
344
320
|
|
345
321
|
# Silences the logger within a block.
|
346
322
|
def mute
|
347
|
-
previous_silence, @silence =
|
323
|
+
previous_silence, @silence = @silence, true
|
348
324
|
yield
|
349
325
|
ensure
|
350
326
|
@silence = previous_silence
|
@@ -411,31 +387,47 @@ module ActiveSupport
|
|
411
387
|
# has elapsed.
|
412
388
|
#
|
413
389
|
# # Set all values to expire after one minute.
|
414
|
-
# cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 1
|
390
|
+
# cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 1)
|
415
391
|
#
|
416
|
-
# cache.write(
|
392
|
+
# cache.write("foo", "original value")
|
417
393
|
# val_1 = nil
|
418
394
|
# val_2 = nil
|
419
|
-
#
|
395
|
+
# p cache.read("foo") # => "original value"
|
420
396
|
#
|
421
|
-
#
|
422
|
-
#
|
397
|
+
# sleep 1 # wait until the cache expires
|
398
|
+
#
|
399
|
+
# t1 = Thread.new do
|
400
|
+
# # fetch does the following:
|
401
|
+
# # 1. gets an recent expired entry
|
402
|
+
# # 2. extends the expiry by 2 seconds (race_condition_ttl)
|
403
|
+
# # 3. regenerates the new value
|
404
|
+
# val_1 = cache.fetch("foo", race_condition_ttl: 2) do
|
423
405
|
# sleep 1
|
424
|
-
#
|
406
|
+
# "new value 1"
|
425
407
|
# end
|
426
408
|
# end
|
427
409
|
#
|
428
|
-
#
|
429
|
-
#
|
430
|
-
#
|
431
|
-
#
|
410
|
+
# # Wait until t1 extends the expiry of the entry
|
411
|
+
# # but before generating the new value
|
412
|
+
# sleep 0.1
|
413
|
+
#
|
414
|
+
# val_2 = cache.fetch("foo", race_condition_ttl: 2) do
|
415
|
+
# # This block won't be executed because t1 extended the expiry
|
416
|
+
# "new value 2"
|
432
417
|
# end
|
433
418
|
#
|
434
|
-
#
|
435
|
-
#
|
436
|
-
#
|
437
|
-
#
|
438
|
-
#
|
419
|
+
# t1.join
|
420
|
+
#
|
421
|
+
# p val_1 # => "new value 1"
|
422
|
+
# p val_2 # => "oritinal value"
|
423
|
+
# p cache.fetch("foo") # => "new value 1"
|
424
|
+
#
|
425
|
+
# # The entry requires 3 seconds to expire (expires_in + race_condition_ttl)
|
426
|
+
# # We have waited 2 seconds already (sleep(1) + t1.join) thus we need to wait 1
|
427
|
+
# # more second to see the entry expire.
|
428
|
+
# sleep 1
|
429
|
+
#
|
430
|
+
# p cache.fetch("foo") # => nil
|
439
431
|
#
|
440
432
|
# ==== Dynamic Options
|
441
433
|
#
|
@@ -456,7 +448,7 @@ module ActiveSupport
|
|
456
448
|
|
457
449
|
entry = nil
|
458
450
|
unless options[:force]
|
459
|
-
instrument(:read,
|
451
|
+
instrument(:read, key, options) do |payload|
|
460
452
|
cached_entry = read_entry(key, **options, event: payload)
|
461
453
|
entry = handle_expired_entry(cached_entry, key, options)
|
462
454
|
if entry
|
@@ -478,7 +470,7 @@ module ActiveSupport
|
|
478
470
|
if entry
|
479
471
|
get_entry_value(entry, name, options)
|
480
472
|
else
|
481
|
-
save_block_result_to_cache(name, options, &block)
|
473
|
+
save_block_result_to_cache(name, key, options, &block)
|
482
474
|
end
|
483
475
|
elsif options && options[:force]
|
484
476
|
raise ArgumentError, "Missing block: Calling `Cache#fetch` with `force: true` requires a block."
|
@@ -508,7 +500,7 @@ module ActiveSupport
|
|
508
500
|
key = normalize_key(name, options)
|
509
501
|
version = normalize_version(name, options)
|
510
502
|
|
511
|
-
instrument(:read,
|
503
|
+
instrument(:read, key, options) do |payload|
|
512
504
|
entry = read_entry(key, **options, event: payload)
|
513
505
|
|
514
506
|
if entry
|
@@ -605,14 +597,14 @@ module ActiveSupport
|
|
605
597
|
options = names.extract_options!
|
606
598
|
options = merged_options(options)
|
607
599
|
|
608
|
-
|
600
|
+
writes = {}
|
601
|
+
ordered = instrument_multi :read_multi, names, options do |payload|
|
609
602
|
if options[:force]
|
610
603
|
reads = {}
|
611
604
|
else
|
612
605
|
reads = read_multi_entries(names, **options)
|
613
606
|
end
|
614
607
|
|
615
|
-
writes = {}
|
616
608
|
ordered = names.index_with do |name|
|
617
609
|
reads.fetch(name) { writes[name] = yield(name) }
|
618
610
|
end
|
@@ -621,15 +613,20 @@ module ActiveSupport
|
|
621
613
|
payload[:hits] = reads.keys
|
622
614
|
payload[:super_operation] = :fetch_multi
|
623
615
|
|
624
|
-
write_multi(writes, options)
|
625
|
-
|
626
616
|
ordered
|
627
617
|
end
|
618
|
+
|
619
|
+
write_multi(writes, options)
|
620
|
+
|
621
|
+
ordered
|
628
622
|
end
|
629
623
|
|
630
624
|
# Writes the value to the cache with the key. The value must be supported
|
631
625
|
# by the +coder+'s +dump+ and +load+ methods.
|
632
626
|
#
|
627
|
+
# Returns +true+ if the write succeeded, +nil+ if there was an error talking
|
628
|
+
# to the cache backend, or +false+ if the write failed for another reason.
|
629
|
+
#
|
633
630
|
# By default, cache entries larger than 1kB are compressed. Compression
|
634
631
|
# allows more data to be stored in the same memory footprint, leading to
|
635
632
|
# fewer cache evictions and higher hit rates.
|
@@ -662,10 +659,11 @@ module ActiveSupport
|
|
662
659
|
# Other options will be handled by the specific cache store implementation.
|
663
660
|
def write(name, value, options = nil)
|
664
661
|
options = merged_options(options)
|
662
|
+
key = normalize_key(name, options)
|
665
663
|
|
666
|
-
instrument(:write,
|
664
|
+
instrument(:write, key, options) do
|
667
665
|
entry = Entry.new(value, **options.merge(version: normalize_version(name, options)))
|
668
|
-
write_entry(
|
666
|
+
write_entry(key, entry, **options)
|
669
667
|
end
|
670
668
|
end
|
671
669
|
|
@@ -675,9 +673,10 @@ module ActiveSupport
|
|
675
673
|
# Options are passed to the underlying cache implementation.
|
676
674
|
def delete(name, options = nil)
|
677
675
|
options = merged_options(options)
|
676
|
+
key = normalize_key(name, options)
|
678
677
|
|
679
|
-
instrument(:delete,
|
680
|
-
delete_entry(
|
678
|
+
instrument(:delete, key, options) do
|
679
|
+
delete_entry(key, **options)
|
681
680
|
end
|
682
681
|
end
|
683
682
|
|
@@ -691,7 +690,7 @@ module ActiveSupport
|
|
691
690
|
options = merged_options(options)
|
692
691
|
names.map! { |key| normalize_key(key, options) }
|
693
692
|
|
694
|
-
instrument_multi
|
693
|
+
instrument_multi(:delete_multi, names, options) do
|
695
694
|
delete_multi_entries(names, **options)
|
696
695
|
end
|
697
696
|
end
|
@@ -701,9 +700,10 @@ module ActiveSupport
|
|
701
700
|
# Options are passed to the underlying cache implementation.
|
702
701
|
def exist?(name, options = nil)
|
703
702
|
options = merged_options(options)
|
703
|
+
key = normalize_key(name, options)
|
704
704
|
|
705
|
-
instrument(:exist?,
|
706
|
-
entry = read_entry(
|
705
|
+
instrument(:exist?, key) do |payload|
|
706
|
+
entry = read_entry(key, **options, event: payload)
|
707
707
|
(entry && !entry.expired? && !entry.mismatched?(normalize_version(name, options))) || false
|
708
708
|
end
|
709
709
|
end
|
@@ -761,14 +761,6 @@ module ActiveSupport
|
|
761
761
|
private
|
762
762
|
def default_serializer
|
763
763
|
case Cache.format_version
|
764
|
-
when 6.1
|
765
|
-
ActiveSupport.deprecator.warn <<~EOM
|
766
|
-
Support for `config.active_support.cache_format_version = 6.1` has been deprecated and will be removed in Rails 7.2.
|
767
|
-
|
768
|
-
Check the Rails upgrade guide at https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#new-activesupport-cache-serialization-format
|
769
|
-
for more information on how to upgrade.
|
770
|
-
EOM
|
771
|
-
Cache::SerializerWithFallback[:marshal_6_1]
|
772
764
|
when 7.0
|
773
765
|
Cache::SerializerWithFallback[:marshal_7_0]
|
774
766
|
when 7.1
|
@@ -1016,7 +1008,7 @@ module ActiveSupport
|
|
1016
1008
|
if multi
|
1017
1009
|
": #{payload[:key].size} key(s) specified"
|
1018
1010
|
elsif payload[:key]
|
1019
|
-
": #{
|
1011
|
+
": #{payload[:key]}"
|
1020
1012
|
end
|
1021
1013
|
|
1022
1014
|
debug_options = " (#{options.inspect})" unless options.blank?
|
@@ -1053,10 +1045,10 @@ module ActiveSupport
|
|
1053
1045
|
entry.value
|
1054
1046
|
end
|
1055
1047
|
|
1056
|
-
def save_block_result_to_cache(name, options)
|
1048
|
+
def save_block_result_to_cache(name, key, options)
|
1057
1049
|
options = options.dup
|
1058
1050
|
|
1059
|
-
result = instrument(:generate,
|
1051
|
+
result = instrument(:generate, key, options) do
|
1060
1052
|
yield(name, WriteOptions.new(options))
|
1061
1053
|
end
|
1062
1054
|
|
@@ -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
213
|
|
263
|
-
|
264
|
-
|
265
|
-
end
|
266
|
-
|
267
|
-
env
|
268
|
-
end
|
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
|
@@ -562,16 +521,18 @@ module ActiveSupport
|
|
562
521
|
@call_template = call_template
|
563
522
|
@user_conditions = user_conditions
|
564
523
|
|
565
|
-
@before =
|
566
|
-
@after =
|
524
|
+
@before = nil
|
525
|
+
@after = nil
|
567
526
|
end
|
568
527
|
|
569
|
-
def before(
|
528
|
+
def before(before)
|
529
|
+
@before ||= []
|
570
530
|
@before.unshift(before)
|
571
531
|
self
|
572
532
|
end
|
573
533
|
|
574
|
-
def after(
|
534
|
+
def after(after)
|
535
|
+
@after ||= []
|
575
536
|
@after.push(after)
|
576
537
|
self
|
577
538
|
end
|
@@ -595,11 +556,11 @@ module ActiveSupport
|
|
595
556
|
end
|
596
557
|
|
597
558
|
def invoke_before(arg)
|
598
|
-
@before
|
559
|
+
@before&.each { |b| b.call(arg) }
|
599
560
|
end
|
600
561
|
|
601
562
|
def invoke_after(arg)
|
602
|
-
@after
|
563
|
+
@after&.each { |a| a.call(arg) }
|
603
564
|
end
|
604
565
|
end
|
605
566
|
|
@@ -104,8 +104,6 @@ class Array
|
|
104
104
|
end
|
105
105
|
end
|
106
106
|
alias_method :to_formatted_s, :to_fs
|
107
|
-
alias_method :to_default_s, :to_s
|
108
|
-
deprecate to_default_s: :to_s, deprecator: ActiveSupport.deprecator
|
109
107
|
|
110
108
|
# Returns a string that represents the array in XML by invoking +to_xml+
|
111
109
|
# on each element. Active Record collections delegate their representation
|
@@ -1,43 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/ruby_features"
|
4
3
|
require "active_support/descendants_tracker"
|
5
4
|
|
6
5
|
class Class
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
subclasses.concat(subclasses.flat_map(&:descendants))
|
23
|
-
end
|
24
|
-
else
|
25
|
-
def descendants
|
26
|
-
ObjectSpace.each_object(singleton_class).reject do |k|
|
27
|
-
k.singleton_class? || k == self
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
# Returns an array with the direct children of +self+.
|
32
|
-
#
|
33
|
-
# class Foo; end
|
34
|
-
# class Bar < Foo; end
|
35
|
-
# class Baz < Bar; end
|
36
|
-
#
|
37
|
-
# Foo.subclasses # => [Bar]
|
38
|
-
def subclasses
|
39
|
-
descendants.select { |descendant| descendant.superclass == self }
|
40
|
-
end
|
6
|
+
# Returns an array with all classes that are < than its receiver.
|
7
|
+
#
|
8
|
+
# class C; end
|
9
|
+
# C.descendants # => []
|
10
|
+
#
|
11
|
+
# class B < C; end
|
12
|
+
# C.descendants # => [B]
|
13
|
+
#
|
14
|
+
# class A < B; end
|
15
|
+
# C.descendants # => [B, A]
|
16
|
+
#
|
17
|
+
# class D < C; end
|
18
|
+
# C.descendants # => [B, A, D]
|
19
|
+
def descendants
|
20
|
+
subclasses.concat(subclasses.flat_map(&:descendants))
|
41
21
|
end
|
42
22
|
|
43
23
|
prepend ActiveSupport::DescendantsTracker::ReloadedClassesFiltering
|
@@ -56,8 +56,6 @@ class Date
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
alias_method :to_formatted_s, :to_fs
|
59
|
-
alias_method :to_default_s, :to_s
|
60
|
-
deprecate to_default_s: :to_s, deprecator: ActiveSupport.deprecator
|
61
59
|
|
62
60
|
# Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005"
|
63
61
|
def readable_inspect
|