activesupport 5.2.4.3 → 7.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +244 -459
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -3
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/array_inquirer.rb +2 -2
- data/lib/active_support/backtrace_cleaner.rb +31 -5
- data/lib/active_support/benchmarkable.rb +3 -3
- data/lib/active_support/cache/file_store.rb +47 -41
- data/lib/active_support/cache/mem_cache_store.rb +151 -40
- data/lib/active_support/cache/memory_store.rb +68 -34
- data/lib/active_support/cache/null_store.rb +16 -3
- data/lib/active_support/cache/redis_cache_store.rb +103 -101
- data/lib/active_support/cache/strategy/local_cache.rb +56 -64
- data/lib/active_support/cache.rb +333 -116
- data/lib/active_support/callbacks.rb +244 -128
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +72 -5
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +16 -0
- data/lib/active_support/concurrency/share_lock.rb +2 -3
- data/lib/active_support/configurable.rb +15 -16
- data/lib/active_support/configuration_file.rb +51 -0
- data/lib/active_support/core_ext/array/access.rb +15 -7
- data/lib/active_support/core_ext/array/conversions.rb +18 -17
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
- data/lib/active_support/core_ext/array/extract.rb +21 -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 +2 -1
- 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 +32 -47
- 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 +15 -14
- 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 +41 -51
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +0 -1
- data/lib/active_support/core_ext/date_time/blank.rb +1 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
- data/lib/active_support/core_ext/date_time/conversions.rb +13 -14
- 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 +241 -76
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +3 -4
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +2 -2
- data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
- data/lib/active_support/core_ext/hash/keys.rb +2 -31
- data/lib/active_support/core_ext/hash/slice.rb +6 -27
- data/lib/active_support/core_ext/hash.rb +1 -2
- data/lib/active_support/core_ext/integer/multiple.rb +1 -1
- 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/kernel.rb +0 -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 +32 -39
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +35 -28
- data/lib/active_support/core_ext/module/concerning.rb +8 -2
- data/lib/active_support/core_ext/module/delegation.rb +70 -33
- data/lib/active_support/core_ext/module/introspection.rb +16 -15
- data/lib/active_support/core_ext/module/redefine_method.rb +8 -17
- data/lib/active_support/core_ext/module.rb +0 -1
- data/lib/active_support/core_ext/name_error.rb +23 -2
- data/lib/active_support/core_ext/numeric/conversions.rb +132 -129
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
- data/lib/active_support/core_ext/numeric.rb +1 -1
- data/lib/active_support/core_ext/object/acts_like.rb +29 -5
- data/lib/active_support/core_ext/object/blank.rb +3 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
- data/lib/active_support/core_ext/object/duplicable.rb +14 -110
- data/lib/active_support/core_ext/object/json.rb +44 -27
- data/lib/active_support/core_ext/object/to_query.rb +2 -2
- data/lib/active_support/core_ext/object/try.rb +24 -14
- 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 +23 -27
- data/lib/active_support/core_ext/range/conversions.rb +32 -30
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/range/each.rb +1 -2
- 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 -5
- data/lib/active_support/core_ext/securerandom.rb +23 -3
- data/lib/active_support/core_ext/string/access.rb +5 -16
- data/lib/active_support/core_ext/string/conversions.rb +3 -2
- data/lib/active_support/core_ext/string/filters.rb +42 -1
- data/lib/active_support/core_ext/string/inflections.rb +46 -7
- data/lib/active_support/core_ext/string/inquiry.rb +2 -1
- data/lib/active_support/core_ext/string/multibyte.rb +6 -5
- data/lib/active_support/core_ext/string/output_safety.rb +129 -20
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
- data/lib/active_support/core_ext/string/strip.rb +3 -1
- 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 +59 -10
- 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 -22
- 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 +47 -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 +60 -715
- data/lib/active_support/deprecation/behaviors.rb +21 -5
- 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 +18 -23
- data/lib/active_support/deprecation/proxy_wrappers.rb +31 -8
- data/lib/active_support/deprecation/reporting.rb +50 -7
- data/lib/active_support/deprecation.rb +7 -2
- data/lib/active_support/descendants_tracker.rb +190 -34
- data/lib/active_support/digest.rb +5 -3
- data/lib/active_support/duration/iso8601_parser.rb +5 -7
- data/lib/active_support/duration/iso8601_serializer.rb +27 -15
- data/lib/active_support/duration.rb +149 -67
- data/lib/active_support/encrypted_configuration.rb +12 -5
- data/lib/active_support/encrypted_file.rb +23 -5
- 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 +85 -122
- 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 +44 -21
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/file_update_checker.rb +0 -1
- data/lib/active_support/fork_tracker.rb +71 -0
- data/lib/active_support/gem_version.rb +5 -5
- data/lib/active_support/hash_with_indifferent_access.rb +73 -43
- data/lib/active_support/html_safe_translation.rb +43 -0
- data/lib/active_support/i18n.rb +2 -0
- data/lib/active_support/i18n_railtie.rb +15 -8
- data/lib/active_support/inflector/inflections.rb +25 -14
- data/lib/active_support/inflector/methods.rb +38 -71
- data/lib/active_support/inflector/transliterate.rb +47 -18
- data/lib/active_support/isolated_execution_state.rb +72 -0
- data/lib/active_support/json/decoding.rb +25 -26
- data/lib/active_support/json/encoding.rb +14 -6
- data/lib/active_support/key_generator.rb +23 -38
- data/lib/active_support/lazy_load_hooks.rb +19 -5
- data/lib/active_support/locale/en.rb +33 -0
- 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 +51 -11
- data/lib/active_support/logger.rb +6 -22
- data/lib/active_support/logger_silence.rb +11 -19
- data/lib/active_support/logger_thread_safe_level.rb +45 -10
- data/lib/active_support/message_encryptor.rb +20 -19
- data/lib/active_support/message_verifier.rb +53 -21
- data/lib/active_support/messages/metadata.rb +13 -4
- data/lib/active_support/messages/rotation_configuration.rb +2 -1
- data/lib/active_support/messages/rotator.rb +10 -9
- data/lib/active_support/multibyte/chars.rb +17 -76
- data/lib/active_support/multibyte/unicode.rb +7 -331
- data/lib/active_support/multibyte.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +163 -37
- data/lib/active_support/notifications/instrumenter.rb +90 -11
- data/lib/active_support/notifications.rb +88 -30
- data/lib/active_support/number_helper/number_converter.rb +6 -9
- data/lib/active_support/number_helper/number_to_currency_converter.rb +12 -12
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +4 -3
- data/lib/active_support/number_helper/number_to_human_converter.rb +4 -3
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +5 -4
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +3 -2
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +12 -7
- data/lib/active_support/number_helper/rounding_helper.rb +12 -32
- data/lib/active_support/number_helper.rb +36 -12
- data/lib/active_support/option_merger.rb +15 -4
- data/lib/active_support/ordered_hash.rb +2 -2
- data/lib/active_support/ordered_options.rb +14 -4
- data/lib/active_support/parameter_filter.rb +138 -0
- data/lib/active_support/per_thread_registry.rb +6 -1
- data/lib/active_support/rails.rb +1 -10
- data/lib/active_support/railtie.rb +77 -5
- data/lib/active_support/reloader.rb +5 -6
- data/lib/active_support/rescuable.rb +8 -8
- 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 -3
- data/lib/active_support/subscriber.rb +79 -46
- data/lib/active_support/tagged_logging.rb +58 -9
- data/lib/active_support/test_case.rb +79 -0
- data/lib/active_support/testing/assertions.rb +62 -11
- data/lib/active_support/testing/deprecation.rb +52 -2
- data/lib/active_support/testing/file_fixtures.rb +2 -0
- data/lib/active_support/testing/isolation.rb +4 -4
- data/lib/active_support/testing/method_call_assertions.rb +32 -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 +55 -0
- data/lib/active_support/testing/parallelize_executor.rb +76 -0
- data/lib/active_support/testing/stream.rb +4 -7
- data/lib/active_support/testing/tagged_logging.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +60 -14
- data/lib/active_support/time_with_zone.rb +139 -64
- data/lib/active_support/values/time_zone.rb +66 -30
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/jdom.rb +3 -4
- data/lib/active_support/xml_mini/libxml.rb +7 -7
- data/lib/active_support/xml_mini/libxmlsax.rb +5 -5
- data/lib/active_support/xml_mini/nokogiri.rb +6 -6
- data/lib/active_support/xml_mini/nokogirisax.rb +4 -4
- data/lib/active_support/xml_mini/rexml.rb +11 -4
- data/lib/active_support/xml_mini.rb +7 -14
- data/lib/active_support.rb +30 -1
- metadata +64 -35
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -9
- data/lib/active_support/core_ext/hash/compact.rb +0 -29
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -32
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
- data/lib/active_support/core_ext/marshal.rb +0 -24
- data/lib/active_support/core_ext/module/reachable.rb +0 -11
- data/lib/active_support/core_ext/numeric/inquiry.rb +0 -28
- data/lib/active_support/core_ext/range/include_range.rb +0 -3
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -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,16 +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
|
#
|
24
|
+
# By default callbacks are halted by throwing +:abort+.
|
25
|
+
# See ClassMethods#define_callbacks for details.
|
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
|
@@ -100,32 +101,6 @@ module ActiveSupport
|
|
100
101
|
env = Filters::Environment.new(self, false, nil)
|
101
102
|
next_sequence = callbacks.compile
|
102
103
|
|
103
|
-
invoke_sequence = Proc.new do
|
104
|
-
skipped = nil
|
105
|
-
while true
|
106
|
-
current = next_sequence
|
107
|
-
current.invoke_before(env)
|
108
|
-
if current.final?
|
109
|
-
env.value = !env.halted && (!block_given? || yield)
|
110
|
-
elsif current.skip?(env)
|
111
|
-
(skipped ||= []) << current
|
112
|
-
next_sequence = next_sequence.nested
|
113
|
-
next
|
114
|
-
else
|
115
|
-
next_sequence = next_sequence.nested
|
116
|
-
begin
|
117
|
-
target, block, method, *arguments = current.expand_call_template(env, invoke_sequence)
|
118
|
-
target.send(method, *arguments, &block)
|
119
|
-
ensure
|
120
|
-
next_sequence = current
|
121
|
-
end
|
122
|
-
end
|
123
|
-
current.invoke_after(env)
|
124
|
-
skipped.pop.invoke_after(env) while skipped && skipped.first
|
125
|
-
break env.value
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
104
|
# Common case: no 'around' callbacks defined
|
130
105
|
if next_sequence.final?
|
131
106
|
next_sequence.invoke_before(env)
|
@@ -133,17 +108,43 @@ module ActiveSupport
|
|
133
108
|
next_sequence.invoke_after(env)
|
134
109
|
env.value
|
135
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
|
+
|
136
138
|
invoke_sequence.call
|
137
139
|
end
|
138
140
|
end
|
139
141
|
end
|
140
142
|
|
141
143
|
private
|
142
|
-
|
143
144
|
# A hook invoked every time a before callback is halted.
|
144
145
|
# This can be overridden in ActiveSupport::Callbacks implementors in order
|
145
146
|
# to provide better debugging/logging.
|
146
|
-
def halted_callback_hook(filter)
|
147
|
+
def halted_callback_hook(filter, name)
|
147
148
|
end
|
148
149
|
|
149
150
|
module Conditionals # :nodoc:
|
@@ -159,17 +160,17 @@ module ActiveSupport
|
|
159
160
|
Environment = Struct.new(:target, :halted, :value)
|
160
161
|
|
161
162
|
class Before
|
162
|
-
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)
|
163
164
|
halted_lambda = chain_config[:terminator]
|
164
165
|
|
165
166
|
if user_conditions.any?
|
166
|
-
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)
|
167
168
|
else
|
168
|
-
halting(callback_sequence, user_callback, halted_lambda, filter)
|
169
|
+
halting(callback_sequence, user_callback, halted_lambda, filter, name)
|
169
170
|
end
|
170
171
|
end
|
171
172
|
|
172
|
-
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)
|
173
174
|
callback_sequence.before do |env|
|
174
175
|
target = env.target
|
175
176
|
value = env.value
|
@@ -179,7 +180,7 @@ module ActiveSupport
|
|
179
180
|
result_lambda = -> { user_callback.call target, value }
|
180
181
|
env.halted = halted_lambda.call(target, result_lambda)
|
181
182
|
if env.halted
|
182
|
-
target.send :halted_callback_hook, filter
|
183
|
+
target.send :halted_callback_hook, filter, name
|
183
184
|
end
|
184
185
|
end
|
185
186
|
|
@@ -188,7 +189,7 @@ module ActiveSupport
|
|
188
189
|
end
|
189
190
|
private_class_method :halting_and_conditional
|
190
191
|
|
191
|
-
def self.halting(callback_sequence, user_callback, halted_lambda, filter)
|
192
|
+
def self.halting(callback_sequence, user_callback, halted_lambda, filter, name)
|
192
193
|
callback_sequence.before do |env|
|
193
194
|
target = env.target
|
194
195
|
value = env.value
|
@@ -197,9 +198,8 @@ module ActiveSupport
|
|
197
198
|
unless halted
|
198
199
|
result_lambda = -> { user_callback.call target, value }
|
199
200
|
env.halted = halted_lambda.call(target, result_lambda)
|
200
|
-
|
201
201
|
if env.halted
|
202
|
-
target.send :halted_callback_hook, filter
|
202
|
+
target.send :halted_callback_hook, filter, name
|
203
203
|
end
|
204
204
|
end
|
205
205
|
|
@@ -277,7 +277,7 @@ module ActiveSupport
|
|
277
277
|
end
|
278
278
|
end
|
279
279
|
|
280
|
-
class Callback
|
280
|
+
class Callback # :nodoc:#
|
281
281
|
def self.build(chain, filter, kind, options)
|
282
282
|
if filter.is_a?(String)
|
283
283
|
raise ArgumentError, <<-MSG.squish
|
@@ -290,21 +290,17 @@ module ActiveSupport
|
|
290
290
|
end
|
291
291
|
|
292
292
|
attr_accessor :kind, :name
|
293
|
-
attr_reader :chain_config
|
293
|
+
attr_reader :chain_config, :filter
|
294
294
|
|
295
295
|
def initialize(name, filter, kind, options, chain_config)
|
296
296
|
@chain_config = chain_config
|
297
297
|
@name = name
|
298
298
|
@kind = kind
|
299
299
|
@filter = filter
|
300
|
-
@
|
301
|
-
@
|
302
|
-
@unless = check_conditionals(Array(options[:unless]))
|
300
|
+
@if = check_conditionals(options[:if])
|
301
|
+
@unless = check_conditionals(options[:unless])
|
303
302
|
end
|
304
303
|
|
305
|
-
def filter; @key; end
|
306
|
-
def raw_filter; @filter; end
|
307
|
-
|
308
304
|
def merge_conditional_options(chain, if_option:, unless_option:)
|
309
305
|
options = {
|
310
306
|
if: @if.dup,
|
@@ -337,7 +333,7 @@ module ActiveSupport
|
|
337
333
|
|
338
334
|
case kind
|
339
335
|
when :before
|
340
|
-
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)
|
341
337
|
when :after
|
342
338
|
Filters::After.build(callback_sequence, user_callback.make_lambda, user_conditions, chain_config)
|
343
339
|
when :around
|
@@ -350,8 +346,14 @@ module ActiveSupport
|
|
350
346
|
end
|
351
347
|
|
352
348
|
private
|
349
|
+
EMPTY_ARRAY = [].freeze
|
350
|
+
private_constant :EMPTY_ARRAY
|
351
|
+
|
353
352
|
def check_conditionals(conditionals)
|
354
|
-
if conditionals.
|
353
|
+
return EMPTY_ARRAY if conditionals.blank?
|
354
|
+
|
355
|
+
conditionals = Array(conditionals)
|
356
|
+
if conditionals.any?(String)
|
355
357
|
raise ArgumentError, <<-MSG.squish
|
356
358
|
Passing string to be evaluated in :if and :unless conditional
|
357
359
|
options is not supported. Pass a symbol for an instance method,
|
@@ -359,16 +361,7 @@ module ActiveSupport
|
|
359
361
|
MSG
|
360
362
|
end
|
361
363
|
|
362
|
-
conditionals
|
363
|
-
end
|
364
|
-
|
365
|
-
def compute_identifier(filter)
|
366
|
-
case filter
|
367
|
-
when ::Proc
|
368
|
-
filter.object_id
|
369
|
-
else
|
370
|
-
filter
|
371
|
-
end
|
364
|
+
conditionals.freeze
|
372
365
|
end
|
373
366
|
|
374
367
|
def conditions_lambdas
|
@@ -379,60 +372,153 @@ module ActiveSupport
|
|
379
372
|
|
380
373
|
# A future invocation of user-supplied code (either as a callback,
|
381
374
|
# or a condition filter).
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
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
|
388
409
|
end
|
389
410
|
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
def expand(target, value, block)
|
404
|
-
result = @arguments.map { |arg|
|
405
|
-
case arg
|
406
|
-
when :value; value
|
407
|
-
when :target; target
|
408
|
-
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)
|
409
424
|
end
|
410
|
-
|
425
|
+
end
|
411
426
|
|
412
|
-
|
413
|
-
|
414
|
-
|
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
|
415
433
|
|
416
|
-
|
417
|
-
|
418
|
-
|
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
|
453
|
+
end
|
419
454
|
end
|
420
455
|
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
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
|
427
475
|
end
|
428
476
|
end
|
429
477
|
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
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
|
436
522
|
end
|
437
523
|
end
|
438
524
|
|
@@ -447,21 +533,19 @@ module ActiveSupport
|
|
447
533
|
def self.build(filter, callback)
|
448
534
|
case filter
|
449
535
|
when Symbol
|
450
|
-
new(
|
536
|
+
MethodCall.new(filter)
|
451
537
|
when Conditionals::Value
|
452
|
-
new(filter
|
538
|
+
ProcCall.new(filter)
|
453
539
|
when ::Proc
|
454
540
|
if filter.arity > 1
|
455
|
-
new(
|
541
|
+
InstanceExec2.new(filter)
|
456
542
|
elsif filter.arity > 0
|
457
|
-
new(
|
543
|
+
InstanceExec1.new(filter)
|
458
544
|
else
|
459
|
-
new(
|
545
|
+
InstanceExec0.new(filter)
|
460
546
|
end
|
461
547
|
else
|
462
|
-
|
463
|
-
|
464
|
-
new(filter, method_to_call, [:target], nil)
|
548
|
+
ObjectCall.new(filter, callback.current_scopes.join("_").to_sym)
|
465
549
|
end
|
466
550
|
end
|
467
551
|
end
|
@@ -497,9 +581,7 @@ module ActiveSupport
|
|
497
581
|
arg.halted || !@user_conditions.all? { |c| c.call(arg.target, arg.value) }
|
498
582
|
end
|
499
583
|
|
500
|
-
|
501
|
-
@nested
|
502
|
-
end
|
584
|
+
attr_reader :nested
|
503
585
|
|
504
586
|
def final?
|
505
587
|
!@call_template
|
@@ -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
|
@@ -578,10 +660,9 @@ module ActiveSupport
|
|
578
660
|
end
|
579
661
|
|
580
662
|
protected
|
581
|
-
|
663
|
+
attr_reader :chain
|
582
664
|
|
583
665
|
private
|
584
|
-
|
585
666
|
def append_one(callback)
|
586
667
|
@callbacks = nil
|
587
668
|
remove_duplicates(callback)
|
@@ -621,8 +702,8 @@ module ActiveSupport
|
|
621
702
|
|
622
703
|
# This is used internally to append, prepend and skip callbacks to the
|
623
704
|
# CallbackChain.
|
624
|
-
def __update_callbacks(name)
|
625
|
-
([self] +
|
705
|
+
def __update_callbacks(name) # :nodoc:
|
706
|
+
([self] + self.descendants).reverse_each do |target|
|
626
707
|
chain = target.get_callbacks name
|
627
708
|
yield target, chain.dup
|
628
709
|
end
|
@@ -659,9 +740,17 @@ module ActiveSupport
|
|
659
740
|
# * <tt>:if</tt> - A symbol or an array of symbols, each naming an instance
|
660
741
|
# method or a proc; the callback will be called only when they all return
|
661
742
|
# a true value.
|
743
|
+
#
|
744
|
+
# If a proc is given, its body is evaluated in the context of the
|
745
|
+
# current object. It can also optionally accept the current object as
|
746
|
+
# an argument.
|
662
747
|
# * <tt>:unless</tt> - A symbol or an array of symbols, each naming an
|
663
748
|
# instance method or a proc; the callback will be called only when they
|
664
749
|
# all return a false value.
|
750
|
+
#
|
751
|
+
# If a proc is given, its body is evaluated in the context of the
|
752
|
+
# current object. It can also optionally accept the current object as
|
753
|
+
# an argument.
|
665
754
|
# * <tt>:prepend</tt> - If +true+, the callback will be prepended to the
|
666
755
|
# existing chain rather than appended.
|
667
756
|
def set_callback(name, *filter_list, &block)
|
@@ -682,10 +771,32 @@ module ActiveSupport
|
|
682
771
|
# <tt>:unless</tt> options may be passed in order to control when the
|
683
772
|
# callback is skipped.
|
684
773
|
#
|
685
|
-
# class Writer <
|
686
|
-
#
|
774
|
+
# class Writer < PersonRecord
|
775
|
+
# attr_accessor :age
|
776
|
+
# skip_callback :save, :before, :saving_message, if: -> { age > 18 }
|
687
777
|
# end
|
688
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
|
+
#
|
689
800
|
# An <tt>ArgumentError</tt> will be raised if the callback has not
|
690
801
|
# already been set (unless the <tt>:raise</tt> option is set to <tt>false</tt>).
|
691
802
|
def skip_callback(name, *filter_list, &block)
|
@@ -716,7 +827,7 @@ module ActiveSupport
|
|
716
827
|
def reset_callbacks(name)
|
717
828
|
callbacks = get_callbacks name
|
718
829
|
|
719
|
-
|
830
|
+
self.descendants.each do |target|
|
720
831
|
chain = target.get_callbacks(name).dup
|
721
832
|
callbacks.each { |c| chain.delete(c) }
|
722
833
|
target.set_callbacks name, chain
|
@@ -809,7 +920,9 @@ module ActiveSupport
|
|
809
920
|
names.each do |name|
|
810
921
|
name = name.to_sym
|
811
922
|
|
812
|
-
|
923
|
+
([self] + self.descendants).each do |target|
|
924
|
+
target.set_callbacks name, CallbackChain.new(name, options)
|
925
|
+
end
|
813
926
|
|
814
927
|
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
815
928
|
def _run_#{name}_callbacks(&block)
|
@@ -832,13 +945,16 @@ module ActiveSupport
|
|
832
945
|
end
|
833
946
|
|
834
947
|
protected
|
835
|
-
|
836
948
|
def get_callbacks(name) # :nodoc:
|
837
949
|
__callbacks[name.to_sym]
|
838
950
|
end
|
839
951
|
|
840
952
|
def set_callbacks(name, callbacks) # :nodoc:
|
841
|
-
|
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
|
842
958
|
end
|
843
959
|
end
|
844
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
|