activesupport 6.0.4.4 → 7.0.4.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.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +257 -532
- data/MIT-LICENSE +1 -1
- data/lib/active_support/actionable_error.rb +1 -1
- data/lib/active_support/array_inquirer.rb +2 -2
- data/lib/active_support/backtrace_cleaner.rb +5 -5
- data/lib/active_support/benchmarkable.rb +3 -3
- data/lib/active_support/cache/file_store.rb +16 -10
- data/lib/active_support/cache/mem_cache_store.rb +163 -42
- data/lib/active_support/cache/memory_store.rb +57 -29
- data/lib/active_support/cache/null_store.rb +10 -2
- data/lib/active_support/cache/redis_cache_store.rb +79 -98
- data/lib/active_support/cache/strategy/local_cache.rb +49 -57
- data/lib/active_support/cache.rb +378 -179
- data/lib/active_support/callbacks.rb +230 -122
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +49 -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 +9 -6
- data/lib/active_support/configuration_file.rb +51 -0
- 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/benchmark.rb +2 -2
- data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
- data/lib/active_support/core_ext/class/attribute.rb +34 -44
- data/lib/active_support/core_ext/class/subclasses.rb +9 -22
- data/lib/active_support/core_ext/date/blank.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +9 -9
- data/lib/active_support/core_ext/date/conversions.rb +16 -15
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/date.rb +1 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +17 -4
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/date_time/blank.rb +1 -1
- data/lib/active_support/core_ext/date_time/conversions.rb +13 -13
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -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 +164 -23
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +2 -3
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +1 -1
- data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
- data/lib/active_support/core_ext/hash/keys.rb +2 -2
- data/lib/active_support/core_ext/hash/slice.rb +3 -2
- 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/load_error.rb +1 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +25 -29
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +26 -13
- data/lib/active_support/core_ext/module/concerning.rb +8 -2
- data/lib/active_support/core_ext/module/delegation.rb +40 -36
- data/lib/active_support/core_ext/module/introspection.rb +1 -25
- data/lib/active_support/core_ext/name_error.rb +23 -2
- data/lib/active_support/core_ext/numeric/conversions.rb +80 -73
- 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 +11 -0
- data/lib/active_support/core_ext/object/json.rb +42 -26
- data/lib/active_support/core_ext/object/to_query.rb +2 -2
- data/lib/active_support/core_ext/object/try.rb +20 -20
- data/lib/active_support/core_ext/object/with_options.rb +20 -1
- 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 +6 -25
- data/lib/active_support/core_ext/range/conversions.rb +8 -8
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/range/each.rb +1 -1
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +4 -20
- 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/regexp.rb +8 -1
- data/lib/active_support/core_ext/securerandom.rb +1 -1
- data/lib/active_support/core_ext/string/access.rb +5 -24
- data/lib/active_support/core_ext/string/conversions.rb +3 -2
- data/lib/active_support/core_ext/string/filters.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +39 -5
- data/lib/active_support/core_ext/string/inquiry.rb +2 -1
- data/lib/active_support/core_ext/string/multibyte.rb +2 -2
- data/lib/active_support/core_ext/string/output_safety.rb +92 -41
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/time/calculations.rb +25 -7
- data/lib/active_support/core_ext/time/conversions.rb +15 -12
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/time/zones.rb +7 -22
- data/lib/active_support/core_ext/time.rb +1 -0
- data/lib/active_support/core_ext/uri.rb +3 -23
- data/lib/active_support/core_ext.rb +2 -1
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +39 -16
- 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 -769
- data/lib/active_support/deprecation/behaviors.rb +23 -7
- data/lib/active_support/deprecation/disallowed.rb +56 -0
- data/lib/active_support/deprecation/instance_delegator.rb +0 -1
- data/lib/active_support/deprecation/method_wrappers.rb +6 -5
- data/lib/active_support/deprecation/proxy_wrappers.rb +4 -4
- data/lib/active_support/deprecation/reporting.rb +50 -7
- data/lib/active_support/deprecation.rb +7 -2
- data/lib/active_support/descendants_tracker.rb +174 -64
- 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 +24 -10
- data/lib/active_support/duration.rb +134 -55
- data/lib/active_support/encrypted_configuration.rb +13 -2
- data/lib/active_support/encrypted_file.rb +32 -3
- data/lib/active_support/environment_inquirer.rb +20 -0
- data/lib/active_support/error_reporter.rb +117 -0
- data/lib/active_support/evented_file_update_checker.rb +72 -138
- 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 +71 -0
- data/lib/active_support/gem_version.rb +3 -3
- data/lib/active_support/hash_with_indifferent_access.rb +51 -25
- 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 +14 -19
- data/lib/active_support/inflector/inflections.rb +24 -9
- data/lib/active_support/inflector/methods.rb +29 -49
- data/lib/active_support/inflector/transliterate.rb +5 -5
- data/lib/active_support/isolated_execution_state.rb +72 -0
- data/lib/active_support/json/decoding.rb +4 -4
- data/lib/active_support/json/encoding.rb +8 -4
- data/lib/active_support/key_generator.rb +23 -6
- data/lib/active_support/lazy_load_hooks.rb +28 -4
- data/lib/active_support/locale/en.yml +8 -4
- data/lib/active_support/log_subscriber/test_helper.rb +2 -2
- data/lib/active_support/log_subscriber.rb +23 -5
- data/lib/active_support/logger.rb +1 -1
- data/lib/active_support/logger_silence.rb +2 -26
- data/lib/active_support/logger_thread_safe_level.rb +34 -21
- data/lib/active_support/message_encryptor.rb +16 -13
- data/lib/active_support/message_verifier.rb +50 -18
- data/lib/active_support/messages/metadata.rb +2 -2
- data/lib/active_support/messages/rotation_configuration.rb +2 -1
- data/lib/active_support/messages/rotator.rb +6 -5
- data/lib/active_support/multibyte/chars.rb +13 -52
- data/lib/active_support/multibyte/unicode.rb +1 -87
- data/lib/active_support/multibyte.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +110 -69
- data/lib/active_support/notifications/instrumenter.rb +37 -29
- data/lib/active_support/notifications.rb +55 -28
- data/lib/active_support/number_helper/number_converter.rb +2 -4
- 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_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +2 -2
- data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +9 -5
- data/lib/active_support/number_helper/rounding_helper.rb +12 -32
- data/lib/active_support/number_helper.rb +29 -16
- data/lib/active_support/option_merger.rb +11 -18
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/ordered_options.rb +9 -3
- data/lib/active_support/parameter_filter.rb +21 -11
- data/lib/active_support/per_thread_registry.rb +6 -1
- data/lib/active_support/rails.rb +1 -4
- data/lib/active_support/railtie.rb +77 -5
- data/lib/active_support/reloader.rb +1 -1
- data/lib/active_support/rescuable.rb +16 -16
- data/lib/active_support/ruby_features.rb +7 -0
- data/lib/active_support/secure_compare_rotator.rb +51 -0
- data/lib/active_support/security_utils.rb +19 -12
- data/lib/active_support/string_inquirer.rb +2 -2
- data/lib/active_support/subscriber.rb +19 -25
- data/lib/active_support/tagged_logging.rb +31 -6
- data/lib/active_support/test_case.rb +13 -21
- data/lib/active_support/testing/assertions.rb +50 -13
- data/lib/active_support/testing/deprecation.rb +52 -1
- data/lib/active_support/testing/isolation.rb +2 -2
- data/lib/active_support/testing/method_call_assertions.rb +5 -5
- data/lib/active_support/testing/parallelization/server.rb +82 -0
- data/lib/active_support/testing/parallelization/worker.rb +103 -0
- data/lib/active_support/testing/parallelization.rb +16 -95
- 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 +53 -5
- data/lib/active_support/time_with_zone.rb +126 -62
- data/lib/active_support/values/time_zone.rb +54 -23
- 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 +9 -2
- data/lib/active_support/xml_mini.rb +5 -4
- data/lib/active_support.rb +29 -1
- metadata +46 -45
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -5
- data/lib/active_support/core_ext/hash/compact.rb +0 -5
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -5
- data/lib/active_support/core_ext/marshal.rb +0 -24
- data/lib/active_support/core_ext/module/reachable.rb +0 -6
- data/lib/active_support/core_ext/numeric/inquiry.rb +0 -5
- data/lib/active_support/core_ext/range/include_range.rb +0 -9
- data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
@@ -4,10 +4,8 @@ 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/kernel/reporting"
|
8
|
-
require "active_support/core_ext/kernel/singleton_class"
|
9
7
|
require "active_support/core_ext/string/filters"
|
10
|
-
require "active_support/
|
8
|
+
require "active_support/core_ext/object/blank"
|
11
9
|
require "thread"
|
12
10
|
|
13
11
|
module ActiveSupport
|
@@ -18,19 +16,19 @@ module ActiveSupport
|
|
18
16
|
# needing to override or redefine methods of the base class.
|
19
17
|
#
|
20
18
|
# Mixing in this module allows you to define the events in the object's
|
21
|
-
# life cycle that will support callbacks (via
|
19
|
+
# life cycle that will support callbacks (via ClassMethods#define_callbacks),
|
22
20
|
# set the instance methods, procs, or callback objects to be called (via
|
23
|
-
#
|
21
|
+
# ClassMethods#set_callback), and run the installed callbacks at the
|
24
22
|
# appropriate times (via +run_callbacks+).
|
25
23
|
#
|
26
24
|
# By default callbacks are halted by throwing +:abort+.
|
27
|
-
# See
|
25
|
+
# See ClassMethods#define_callbacks for details.
|
28
26
|
#
|
29
27
|
# Three kinds of callbacks are supported: before callbacks, run before a
|
30
28
|
# certain event; after callbacks, run after the event; and around callbacks,
|
31
29
|
# blocks that surround the event, triggering it when they yield. Callback code
|
32
30
|
# can be contained in instance methods, procs or lambdas, or callback objects
|
33
|
-
# that respond to certain predetermined methods. See
|
31
|
+
# that respond to certain predetermined methods. See ClassMethods#set_callback
|
34
32
|
# for details.
|
35
33
|
#
|
36
34
|
# class Record
|
@@ -103,32 +101,6 @@ module ActiveSupport
|
|
103
101
|
env = Filters::Environment.new(self, false, nil)
|
104
102
|
next_sequence = callbacks.compile
|
105
103
|
|
106
|
-
invoke_sequence = Proc.new do
|
107
|
-
skipped = nil
|
108
|
-
while true
|
109
|
-
current = next_sequence
|
110
|
-
current.invoke_before(env)
|
111
|
-
if current.final?
|
112
|
-
env.value = !env.halted && (!block_given? || yield)
|
113
|
-
elsif current.skip?(env)
|
114
|
-
(skipped ||= []) << current
|
115
|
-
next_sequence = next_sequence.nested
|
116
|
-
next
|
117
|
-
else
|
118
|
-
next_sequence = next_sequence.nested
|
119
|
-
begin
|
120
|
-
target, block, method, *arguments = current.expand_call_template(env, invoke_sequence)
|
121
|
-
target.send(method, *arguments, &block)
|
122
|
-
ensure
|
123
|
-
next_sequence = current
|
124
|
-
end
|
125
|
-
end
|
126
|
-
current.invoke_after(env)
|
127
|
-
skipped.pop.invoke_after(env) while skipped && skipped.first
|
128
|
-
break env.value
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
104
|
# Common case: no 'around' callbacks defined
|
133
105
|
if next_sequence.final?
|
134
106
|
next_sequence.invoke_before(env)
|
@@ -136,6 +108,33 @@ module ActiveSupport
|
|
136
108
|
next_sequence.invoke_after(env)
|
137
109
|
env.value
|
138
110
|
else
|
111
|
+
invoke_sequence = Proc.new do
|
112
|
+
skipped = nil
|
113
|
+
|
114
|
+
while true
|
115
|
+
current = next_sequence
|
116
|
+
current.invoke_before(env)
|
117
|
+
if current.final?
|
118
|
+
env.value = !env.halted && (!block_given? || yield)
|
119
|
+
elsif current.skip?(env)
|
120
|
+
(skipped ||= []) << current
|
121
|
+
next_sequence = next_sequence.nested
|
122
|
+
next
|
123
|
+
else
|
124
|
+
next_sequence = next_sequence.nested
|
125
|
+
begin
|
126
|
+
target, block, method, *arguments = current.expand_call_template(env, invoke_sequence)
|
127
|
+
target.send(method, *arguments, &block)
|
128
|
+
ensure
|
129
|
+
next_sequence = current
|
130
|
+
end
|
131
|
+
end
|
132
|
+
current.invoke_after(env)
|
133
|
+
skipped.pop.invoke_after(env) while skipped&.first
|
134
|
+
break env.value
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
139
138
|
invoke_sequence.call
|
140
139
|
end
|
141
140
|
end
|
@@ -145,7 +144,7 @@ module ActiveSupport
|
|
145
144
|
# A hook invoked every time a before callback is halted.
|
146
145
|
# This can be overridden in ActiveSupport::Callbacks implementors in order
|
147
146
|
# to provide better debugging/logging.
|
148
|
-
def halted_callback_hook(filter)
|
147
|
+
def halted_callback_hook(filter, name)
|
149
148
|
end
|
150
149
|
|
151
150
|
module Conditionals # :nodoc:
|
@@ -161,17 +160,17 @@ module ActiveSupport
|
|
161
160
|
Environment = Struct.new(:target, :halted, :value)
|
162
161
|
|
163
162
|
class Before
|
164
|
-
def self.build(callback_sequence, user_callback, user_conditions, chain_config, filter)
|
163
|
+
def self.build(callback_sequence, user_callback, user_conditions, chain_config, filter, name)
|
165
164
|
halted_lambda = chain_config[:terminator]
|
166
165
|
|
167
166
|
if user_conditions.any?
|
168
|
-
halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter)
|
167
|
+
halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter, name)
|
169
168
|
else
|
170
|
-
halting(callback_sequence, user_callback, halted_lambda, filter)
|
169
|
+
halting(callback_sequence, user_callback, halted_lambda, filter, name)
|
171
170
|
end
|
172
171
|
end
|
173
172
|
|
174
|
-
def self.halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter)
|
173
|
+
def self.halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter, name)
|
175
174
|
callback_sequence.before do |env|
|
176
175
|
target = env.target
|
177
176
|
value = env.value
|
@@ -181,7 +180,7 @@ module ActiveSupport
|
|
181
180
|
result_lambda = -> { user_callback.call target, value }
|
182
181
|
env.halted = halted_lambda.call(target, result_lambda)
|
183
182
|
if env.halted
|
184
|
-
target.send :halted_callback_hook, filter
|
183
|
+
target.send :halted_callback_hook, filter, name
|
185
184
|
end
|
186
185
|
end
|
187
186
|
|
@@ -190,7 +189,7 @@ module ActiveSupport
|
|
190
189
|
end
|
191
190
|
private_class_method :halting_and_conditional
|
192
191
|
|
193
|
-
def self.halting(callback_sequence, user_callback, halted_lambda, filter)
|
192
|
+
def self.halting(callback_sequence, user_callback, halted_lambda, filter, name)
|
194
193
|
callback_sequence.before do |env|
|
195
194
|
target = env.target
|
196
195
|
value = env.value
|
@@ -199,9 +198,8 @@ module ActiveSupport
|
|
199
198
|
unless halted
|
200
199
|
result_lambda = -> { user_callback.call target, value }
|
201
200
|
env.halted = halted_lambda.call(target, result_lambda)
|
202
|
-
|
203
201
|
if env.halted
|
204
|
-
target.send :halted_callback_hook, filter
|
202
|
+
target.send :halted_callback_hook, filter, name
|
205
203
|
end
|
206
204
|
end
|
207
205
|
|
@@ -279,7 +277,7 @@ module ActiveSupport
|
|
279
277
|
end
|
280
278
|
end
|
281
279
|
|
282
|
-
class Callback
|
280
|
+
class Callback # :nodoc:#
|
283
281
|
def self.build(chain, filter, kind, options)
|
284
282
|
if filter.is_a?(String)
|
285
283
|
raise ArgumentError, <<-MSG.squish
|
@@ -292,21 +290,17 @@ module ActiveSupport
|
|
292
290
|
end
|
293
291
|
|
294
292
|
attr_accessor :kind, :name
|
295
|
-
attr_reader :chain_config
|
293
|
+
attr_reader :chain_config, :filter
|
296
294
|
|
297
295
|
def initialize(name, filter, kind, options, chain_config)
|
298
296
|
@chain_config = chain_config
|
299
297
|
@name = name
|
300
298
|
@kind = kind
|
301
299
|
@filter = filter
|
302
|
-
@
|
303
|
-
@
|
304
|
-
@unless = check_conditionals(Array(options[:unless]))
|
300
|
+
@if = check_conditionals(options[:if])
|
301
|
+
@unless = check_conditionals(options[:unless])
|
305
302
|
end
|
306
303
|
|
307
|
-
def filter; @key; end
|
308
|
-
def raw_filter; @filter; end
|
309
|
-
|
310
304
|
def merge_conditional_options(chain, if_option:, unless_option:)
|
311
305
|
options = {
|
312
306
|
if: @if.dup,
|
@@ -339,7 +333,7 @@ module ActiveSupport
|
|
339
333
|
|
340
334
|
case kind
|
341
335
|
when :before
|
342
|
-
Filters::Before.build(callback_sequence, user_callback.make_lambda, user_conditions, chain_config, @filter)
|
336
|
+
Filters::Before.build(callback_sequence, user_callback.make_lambda, user_conditions, chain_config, @filter, name)
|
343
337
|
when :after
|
344
338
|
Filters::After.build(callback_sequence, user_callback.make_lambda, user_conditions, chain_config)
|
345
339
|
when :around
|
@@ -352,8 +346,14 @@ module ActiveSupport
|
|
352
346
|
end
|
353
347
|
|
354
348
|
private
|
349
|
+
EMPTY_ARRAY = [].freeze
|
350
|
+
private_constant :EMPTY_ARRAY
|
351
|
+
|
355
352
|
def check_conditionals(conditionals)
|
356
|
-
if conditionals.
|
353
|
+
return EMPTY_ARRAY if conditionals.blank?
|
354
|
+
|
355
|
+
conditionals = Array(conditionals)
|
356
|
+
if conditionals.any?(String)
|
357
357
|
raise ArgumentError, <<-MSG.squish
|
358
358
|
Passing string to be evaluated in :if and :unless conditional
|
359
359
|
options is not supported. Pass a symbol for an instance method,
|
@@ -361,16 +361,7 @@ module ActiveSupport
|
|
361
361
|
MSG
|
362
362
|
end
|
363
363
|
|
364
|
-
conditionals
|
365
|
-
end
|
366
|
-
|
367
|
-
def compute_identifier(filter)
|
368
|
-
case filter
|
369
|
-
when ::Proc
|
370
|
-
filter.object_id
|
371
|
-
else
|
372
|
-
filter
|
373
|
-
end
|
364
|
+
conditionals.freeze
|
374
365
|
end
|
375
366
|
|
376
367
|
def conditions_lambdas
|
@@ -381,60 +372,153 @@ module ActiveSupport
|
|
381
372
|
|
382
373
|
# A future invocation of user-supplied code (either as a callback,
|
383
374
|
# or a condition filter).
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
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
|
390
409
|
end
|
391
410
|
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
def expand(target, value, block)
|
406
|
-
result = @arguments.map { |arg|
|
407
|
-
case arg
|
408
|
-
when :value; value
|
409
|
-
when :target; target
|
410
|
-
when :block; block || raise(ArgumentError)
|
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
|
420
|
+
|
421
|
+
def make_lambda
|
422
|
+
lambda do |target, value, &block|
|
423
|
+
(@override_target || target).send(@method_name, target, &block)
|
411
424
|
end
|
412
|
-
|
425
|
+
end
|
426
|
+
|
427
|
+
def inverted_lambda
|
428
|
+
lambda do |target, value, &block|
|
429
|
+
!(@override_target || target).send(@method_name, target, &block)
|
430
|
+
end
|
431
|
+
end
|
432
|
+
end
|
413
433
|
|
414
|
-
|
415
|
-
|
416
|
-
|
434
|
+
class InstanceExec0
|
435
|
+
def initialize(block)
|
436
|
+
@override_block = block
|
437
|
+
end
|
417
438
|
|
418
|
-
|
419
|
-
|
420
|
-
|
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
|
453
|
+
end
|
421
454
|
end
|
422
455
|
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
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
|
429
475
|
end
|
430
476
|
end
|
431
477
|
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
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
|
438
522
|
end
|
439
523
|
end
|
440
524
|
|
@@ -449,21 +533,19 @@ module ActiveSupport
|
|
449
533
|
def self.build(filter, callback)
|
450
534
|
case filter
|
451
535
|
when Symbol
|
452
|
-
new(
|
536
|
+
MethodCall.new(filter)
|
453
537
|
when Conditionals::Value
|
454
|
-
new(filter
|
538
|
+
ProcCall.new(filter)
|
455
539
|
when ::Proc
|
456
540
|
if filter.arity > 1
|
457
|
-
new(
|
541
|
+
InstanceExec2.new(filter)
|
458
542
|
elsif filter.arity > 0
|
459
|
-
new(
|
543
|
+
InstanceExec1.new(filter)
|
460
544
|
else
|
461
|
-
new(
|
545
|
+
InstanceExec0.new(filter)
|
462
546
|
end
|
463
547
|
else
|
464
|
-
|
465
|
-
|
466
|
-
new(filter, method_to_call, [:target], nil)
|
548
|
+
ObjectCall.new(filter, callback.current_scopes.join("_").to_sym)
|
467
549
|
end
|
468
550
|
end
|
469
551
|
end
|
@@ -518,7 +600,7 @@ module ActiveSupport
|
|
518
600
|
end
|
519
601
|
end
|
520
602
|
|
521
|
-
class CallbackChain
|
603
|
+
class CallbackChain # :nodoc:
|
522
604
|
include Enumerable
|
523
605
|
|
524
606
|
attr_reader :name, :config
|
@@ -620,8 +702,8 @@ module ActiveSupport
|
|
620
702
|
|
621
703
|
# This is used internally to append, prepend and skip callbacks to the
|
622
704
|
# CallbackChain.
|
623
|
-
def __update_callbacks(name)
|
624
|
-
([self] +
|
705
|
+
def __update_callbacks(name) # :nodoc:
|
706
|
+
([self] + self.descendants).reverse_each do |target|
|
625
707
|
chain = target.get_callbacks name
|
626
708
|
yield target, chain.dup
|
627
709
|
end
|
@@ -689,10 +771,32 @@ module ActiveSupport
|
|
689
771
|
# <tt>:unless</tt> options may be passed in order to control when the
|
690
772
|
# callback is skipped.
|
691
773
|
#
|
692
|
-
# class Writer <
|
693
|
-
#
|
774
|
+
# class Writer < PersonRecord
|
775
|
+
# attr_accessor :age
|
776
|
+
# skip_callback :save, :before, :saving_message, if: -> { age > 18 }
|
694
777
|
# end
|
695
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
|
+
#
|
696
800
|
# An <tt>ArgumentError</tt> will be raised if the callback has not
|
697
801
|
# already been set (unless the <tt>:raise</tt> option is set to <tt>false</tt>).
|
698
802
|
def skip_callback(name, *filter_list, &block)
|
@@ -723,7 +827,7 @@ module ActiveSupport
|
|
723
827
|
def reset_callbacks(name)
|
724
828
|
callbacks = get_callbacks name
|
725
829
|
|
726
|
-
|
830
|
+
self.descendants.each do |target|
|
727
831
|
chain = target.get_callbacks(name).dup
|
728
832
|
callbacks.each { |c| chain.delete(c) }
|
729
833
|
target.set_callbacks name, chain
|
@@ -816,7 +920,7 @@ module ActiveSupport
|
|
816
920
|
names.each do |name|
|
817
921
|
name = name.to_sym
|
818
922
|
|
819
|
-
([self] +
|
923
|
+
([self] + self.descendants).each do |target|
|
820
924
|
target.set_callbacks name, CallbackChain.new(name, options)
|
821
925
|
end
|
822
926
|
|
@@ -846,7 +950,11 @@ module ActiveSupport
|
|
846
950
|
end
|
847
951
|
|
848
952
|
def set_callbacks(name, callbacks) # :nodoc:
|
849
|
-
|
953
|
+
unless singleton_class.method_defined?(:__callbacks, false)
|
954
|
+
self.__callbacks = __callbacks.dup
|
955
|
+
end
|
956
|
+
self.__callbacks[name.to_sym] = callbacks
|
957
|
+
self.__callbacks
|
850
958
|
end
|
851
959
|
end
|
852
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
|