activesupport 7.0.8.7 → 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 +143 -459
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -4
- data/lib/active_support/actionable_error.rb +3 -1
- data/lib/active_support/array_inquirer.rb +3 -1
- data/lib/active_support/backtrace_cleaner.rb +39 -7
- data/lib/active_support/benchmarkable.rb +1 -0
- data/lib/active_support/broadcast_logger.rb +251 -0
- data/lib/active_support/builder.rb +1 -1
- data/lib/active_support/cache/coder.rb +153 -0
- data/lib/active_support/cache/entry.rb +134 -0
- data/lib/active_support/cache/file_store.rb +49 -17
- data/lib/active_support/cache/mem_cache_store.rb +94 -128
- data/lib/active_support/cache/memory_store.rb +80 -25
- data/lib/active_support/cache/null_store.rb +6 -0
- data/lib/active_support/cache/redis_cache_store.rb +165 -152
- data/lib/active_support/cache/serializer_with_fallback.rb +152 -0
- data/lib/active_support/cache/strategy/local_cache.rb +29 -14
- data/lib/active_support/cache.rb +363 -291
- data/lib/active_support/callbacks.rb +118 -134
- data/lib/active_support/code_generator.rb +15 -10
- data/lib/active_support/concern.rb +4 -2
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +42 -3
- data/lib/active_support/concurrency/null_lock.rb +13 -0
- data/lib/active_support/configurable.rb +10 -0
- data/lib/active_support/core_ext/array/conversions.rb +1 -2
- data/lib/active_support/core_ext/array.rb +0 -1
- data/lib/active_support/core_ext/class/subclasses.rb +17 -34
- data/lib/active_support/core_ext/date/blank.rb +4 -0
- data/lib/active_support/core_ext/date/conversions.rb +1 -2
- data/lib/active_support/core_ext/date.rb +0 -1
- data/lib/active_support/core_ext/date_and_time/calculations.rb +10 -0
- 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 +2 -2
- data/lib/active_support/core_ext/date_time.rb +0 -1
- data/lib/active_support/core_ext/digest/uuid.rb +7 -10
- data/lib/active_support/core_ext/enumerable.rb +3 -75
- data/lib/active_support/core_ext/erb/util.rb +201 -0
- data/lib/active_support/core_ext/hash/conversions.rb +1 -1
- data/lib/active_support/core_ext/hash/deep_merge.rb +22 -14
- 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/attribute_accessors.rb +6 -0
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +34 -16
- data/lib/active_support/core_ext/module/concerning.rb +6 -6
- data/lib/active_support/core_ext/module/delegation.rb +20 -119
- data/lib/active_support/core_ext/module/deprecation.rb +12 -12
- data/lib/active_support/core_ext/module/introspection.rb +0 -1
- data/lib/active_support/core_ext/numeric/bytes.rb +9 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +5 -3
- data/lib/active_support/core_ext/numeric.rb +0 -1
- data/lib/active_support/core_ext/object/blank.rb +45 -1
- data/lib/active_support/core_ext/object/deep_dup.rb +16 -0
- data/lib/active_support/core_ext/object/inclusion.rb +13 -5
- data/lib/active_support/core_ext/object/instance_variables.rb +4 -2
- data/lib/active_support/core_ext/object/json.rb +17 -7
- data/lib/active_support/core_ext/object/with.rb +46 -0
- data/lib/active_support/core_ext/object/with_options.rb +4 -4
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/pathname/blank.rb +20 -0
- data/lib/active_support/core_ext/pathname/existence.rb +2 -0
- data/lib/active_support/core_ext/pathname.rb +1 -0
- data/lib/active_support/core_ext/range/conversions.rb +28 -7
- data/lib/active_support/core_ext/range/overlap.rb +40 -0
- data/lib/active_support/core_ext/range.rb +1 -2
- data/lib/active_support/core_ext/securerandom.rb +1 -5
- data/lib/active_support/core_ext/string/conversions.rb +1 -1
- data/lib/active_support/core_ext/string/filters.rb +21 -15
- data/lib/active_support/core_ext/string/indent.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +16 -5
- data/lib/active_support/core_ext/string/multibyte.rb +1 -1
- data/lib/active_support/core_ext/string/output_safety.rb +34 -177
- data/lib/active_support/core_ext/thread/backtrace/location.rb +12 -0
- data/lib/active_support/core_ext/time/calculations.rb +36 -30
- data/lib/active_support/core_ext/time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/time/conversions.rb +1 -3
- data/lib/active_support/core_ext/time/zones.rb +4 -4
- data/lib/active_support/core_ext/time.rb +0 -1
- data/lib/active_support/core_ext.rb +0 -1
- data/lib/active_support/current_attributes.rb +53 -46
- data/lib/active_support/deep_mergeable.rb +53 -0
- data/lib/active_support/delegation.rb +202 -0
- data/lib/active_support/dependencies/autoload.rb +9 -16
- data/lib/active_support/deprecation/behaviors.rb +65 -42
- data/lib/active_support/deprecation/constant_accessor.rb +47 -25
- data/lib/active_support/deprecation/deprecators.rb +104 -0
- data/lib/active_support/deprecation/disallowed.rb +3 -5
- data/lib/active_support/deprecation/method_wrappers.rb +6 -23
- data/lib/active_support/deprecation/proxy_wrappers.rb +34 -22
- data/lib/active_support/deprecation/reporting.rb +49 -27
- data/lib/active_support/deprecation.rb +39 -9
- data/lib/active_support/deprecator.rb +7 -0
- data/lib/active_support/descendants_tracker.rb +66 -172
- data/lib/active_support/duration/iso8601_parser.rb +2 -2
- data/lib/active_support/duration/iso8601_serializer.rb +1 -4
- data/lib/active_support/duration.rb +13 -7
- data/lib/active_support/encrypted_configuration.rb +30 -9
- data/lib/active_support/encrypted_file.rb +9 -4
- data/lib/active_support/environment_inquirer.rb +22 -2
- data/lib/active_support/error_reporter/test_helper.rb +15 -0
- data/lib/active_support/error_reporter.rb +160 -36
- data/lib/active_support/evented_file_update_checker.rb +0 -1
- data/lib/active_support/execution_wrapper.rb +4 -5
- data/lib/active_support/file_update_checker.rb +5 -3
- data/lib/active_support/fork_tracker.rb +4 -32
- data/lib/active_support/gem_version.rb +4 -4
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +41 -25
- data/lib/active_support/html_safe_translation.rb +19 -6
- data/lib/active_support/i18n.rb +1 -1
- data/lib/active_support/i18n_railtie.rb +20 -13
- data/lib/active_support/inflector/inflections.rb +2 -0
- data/lib/active_support/inflector/methods.rb +23 -11
- data/lib/active_support/inflector/transliterate.rb +3 -1
- data/lib/active_support/isolated_execution_state.rb +26 -22
- data/lib/active_support/json/decoding.rb +2 -1
- data/lib/active_support/json/encoding.rb +25 -43
- data/lib/active_support/key_generator.rb +9 -1
- data/lib/active_support/lazy_load_hooks.rb +6 -4
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber.rb +74 -34
- data/lib/active_support/logger.rb +22 -60
- data/lib/active_support/logger_thread_safe_level.rb +10 -32
- data/lib/active_support/message_encryptor.rb +197 -53
- data/lib/active_support/message_encryptors.rb +141 -0
- data/lib/active_support/message_pack/cache_serializer.rb +23 -0
- data/lib/active_support/message_pack/extensions.rb +305 -0
- data/lib/active_support/message_pack/serializer.rb +63 -0
- data/lib/active_support/message_pack.rb +50 -0
- data/lib/active_support/message_verifier.rb +220 -89
- data/lib/active_support/message_verifiers.rb +135 -0
- data/lib/active_support/messages/codec.rb +65 -0
- data/lib/active_support/messages/metadata.rb +111 -45
- data/lib/active_support/messages/rotation_coordinator.rb +93 -0
- data/lib/active_support/messages/rotator.rb +34 -32
- data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
- data/lib/active_support/multibyte/chars.rb +4 -2
- data/lib/active_support/multibyte/unicode.rb +9 -37
- data/lib/active_support/notifications/fanout.rb +248 -87
- data/lib/active_support/notifications/instrumenter.rb +93 -25
- data/lib/active_support/notifications.rb +29 -28
- data/lib/active_support/number_helper/number_converter.rb +16 -7
- data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -6
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -3
- data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -0
- data/lib/active_support/number_helper.rb +379 -318
- data/lib/active_support/option_merger.rb +2 -2
- data/lib/active_support/ordered_hash.rb +3 -3
- data/lib/active_support/ordered_options.rb +67 -15
- data/lib/active_support/parameter_filter.rb +84 -69
- data/lib/active_support/proxy_object.rb +8 -3
- data/lib/active_support/railtie.rb +25 -20
- data/lib/active_support/reloader.rb +12 -4
- data/lib/active_support/rescuable.rb +2 -0
- data/lib/active_support/secure_compare_rotator.rb +16 -9
- data/lib/active_support/string_inquirer.rb +4 -2
- data/lib/active_support/subscriber.rb +10 -27
- data/lib/active_support/syntax_error_proxy.rb +60 -0
- data/lib/active_support/tagged_logging.rb +64 -25
- data/lib/active_support/test_case.rb +156 -7
- data/lib/active_support/testing/assertions.rb +28 -12
- data/lib/active_support/testing/autorun.rb +0 -2
- data/lib/active_support/testing/constant_stubbing.rb +54 -0
- data/lib/active_support/testing/deprecation.rb +20 -27
- data/lib/active_support/testing/error_reporter_assertions.rb +107 -0
- data/lib/active_support/testing/isolation.rb +21 -9
- data/lib/active_support/testing/method_call_assertions.rb +7 -8
- data/lib/active_support/testing/parallelization/server.rb +3 -0
- data/lib/active_support/testing/parallelize_executor.rb +8 -3
- data/lib/active_support/testing/setup_and_teardown.rb +2 -0
- data/lib/active_support/testing/stream.rb +1 -1
- data/lib/active_support/testing/strict_warnings.rb +43 -0
- data/lib/active_support/testing/tests_without_assertions.rb +19 -0
- data/lib/active_support/testing/time_helpers.rb +38 -16
- data/lib/active_support/time_with_zone.rb +12 -18
- data/lib/active_support/values/time_zone.rb +25 -14
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/jdom.rb +3 -10
- data/lib/active_support/xml_mini/nokogiri.rb +1 -1
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
- data/lib/active_support/xml_mini/rexml.rb +1 -1
- data/lib/active_support/xml_mini.rb +12 -3
- data/lib/active_support.rb +15 -3
- metadata +140 -19
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +0 -25
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +0 -40
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +0 -36
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +0 -60
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +0 -36
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +0 -5
- data/lib/active_support/core_ext/range/overlaps.rb +0 -10
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +0 -73
- data/lib/active_support/core_ext/uri.rb +0 -5
- data/lib/active_support/deprecation/instance_delegator.rb +0 -38
- data/lib/active_support/per_thread_registry.rb +0 -65
- data/lib/active_support/ruby_features.rb +0 -7
@@ -9,7 +9,9 @@ require "active_support/core_ext/object/blank"
|
|
9
9
|
require "thread"
|
10
10
|
|
11
11
|
module ActiveSupport
|
12
|
-
#
|
12
|
+
# = Active Support \Callbacks
|
13
|
+
#
|
14
|
+
# \Callbacks are code hooks that are run at key points in an object's life cycle.
|
13
15
|
# The typical use case is to have a base class define a set of callbacks
|
14
16
|
# relevant to the other functionality it supplies, so that subclasses can
|
15
17
|
# install callbacks that enhance or modify the base functionality without
|
@@ -68,7 +70,7 @@ module ActiveSupport
|
|
68
70
|
class_attribute :__callbacks, instance_writer: false, default: {}
|
69
71
|
end
|
70
72
|
|
71
|
-
CALLBACK_FILTER_TYPES = [:before, :after, :around]
|
73
|
+
CALLBACK_FILTER_TYPES = [:before, :after, :around].freeze
|
72
74
|
|
73
75
|
# Runs the callbacks for the given event.
|
74
76
|
#
|
@@ -92,14 +94,15 @@ module ActiveSupport
|
|
92
94
|
# callback can be as noisy as it likes -- but when control has passed
|
93
95
|
# smoothly through and into the supplied block, we want as little evidence
|
94
96
|
# as possible that we were here.
|
95
|
-
def run_callbacks(kind)
|
97
|
+
def run_callbacks(kind, type = nil)
|
96
98
|
callbacks = __callbacks[kind.to_sym]
|
97
99
|
|
98
100
|
if callbacks.empty?
|
99
101
|
yield if block_given?
|
100
102
|
else
|
101
103
|
env = Filters::Environment.new(self, false, nil)
|
102
|
-
|
104
|
+
|
105
|
+
next_sequence = callbacks.compile(type)
|
103
106
|
|
104
107
|
# Common case: no 'around' callbacks defined
|
105
108
|
if next_sequence.final?
|
@@ -147,7 +150,7 @@ module ActiveSupport
|
|
147
150
|
def halted_callback_hook(filter, name)
|
148
151
|
end
|
149
152
|
|
150
|
-
module Conditionals # :nodoc:
|
153
|
+
module Conditionals # :nodoc: all
|
151
154
|
class Value
|
152
155
|
def initialize(&block)
|
153
156
|
@block = block
|
@@ -156,128 +159,76 @@ module ActiveSupport
|
|
156
159
|
end
|
157
160
|
end
|
158
161
|
|
159
|
-
module Filters
|
162
|
+
module Filters # :nodoc: all
|
160
163
|
Environment = Struct.new(:target, :halted, :value)
|
161
164
|
|
162
165
|
class Before
|
163
|
-
def
|
166
|
+
def initialize(user_callback, user_conditions, chain_config, filter, name)
|
164
167
|
halted_lambda = chain_config[:terminator]
|
165
|
-
|
166
|
-
|
167
|
-
halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter, name)
|
168
|
-
else
|
169
|
-
halting(callback_sequence, user_callback, halted_lambda, filter, name)
|
170
|
-
end
|
168
|
+
@user_callback, @user_conditions, @halted_lambda, @filter, @name = user_callback, user_conditions, halted_lambda, filter, name
|
169
|
+
freeze
|
171
170
|
end
|
171
|
+
attr_reader :user_callback, :user_conditions, :halted_lambda, :filter, :name
|
172
172
|
|
173
|
-
def
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
halted = env.halted
|
173
|
+
def call(env)
|
174
|
+
target = env.target
|
175
|
+
value = env.value
|
176
|
+
halted = env.halted
|
178
177
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
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
|
185
183
|
end
|
186
|
-
|
187
|
-
env
|
188
184
|
end
|
189
|
-
end
|
190
|
-
private_class_method :halting_and_conditional
|
191
|
-
|
192
|
-
def self.halting(callback_sequence, user_callback, halted_lambda, filter, name)
|
193
|
-
callback_sequence.before do |env|
|
194
|
-
target = env.target
|
195
|
-
value = env.value
|
196
|
-
halted = env.halted
|
197
185
|
|
198
|
-
|
199
|
-
|
200
|
-
env.halted = halted_lambda.call(target, result_lambda)
|
201
|
-
if env.halted
|
202
|
-
target.send :halted_callback_hook, filter, name
|
203
|
-
end
|
204
|
-
end
|
186
|
+
env
|
187
|
+
end
|
205
188
|
|
206
|
-
|
207
|
-
|
189
|
+
def apply(callback_sequence)
|
190
|
+
callback_sequence.before(self)
|
208
191
|
end
|
209
|
-
private_class_method :halting
|
210
192
|
end
|
211
193
|
|
212
194
|
class After
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
halting(callback_sequence, user_callback)
|
219
|
-
end
|
220
|
-
else
|
221
|
-
if user_conditions.any?
|
222
|
-
conditional callback_sequence, user_callback, user_conditions
|
223
|
-
else
|
224
|
-
simple callback_sequence, user_callback
|
225
|
-
end
|
226
|
-
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
|
227
200
|
end
|
228
201
|
|
229
|
-
def
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
halted = env.halted
|
234
|
-
|
235
|
-
if !halted && user_conditions.all? { |c| c.call(target, value) }
|
236
|
-
user_callback.call target, value
|
237
|
-
end
|
202
|
+
def call(env)
|
203
|
+
target = env.target
|
204
|
+
value = env.value
|
205
|
+
halted = env.halted
|
238
206
|
|
239
|
-
|
207
|
+
if (!halted || !@halting) && user_conditions.all? { |c| c.call(target, value) }
|
208
|
+
user_callback.call target, value
|
240
209
|
end
|
241
|
-
end
|
242
|
-
private_class_method :halting_and_conditional
|
243
210
|
|
244
|
-
|
245
|
-
callback_sequence.after do |env|
|
246
|
-
unless env.halted
|
247
|
-
user_callback.call env.target, env.value
|
248
|
-
end
|
249
|
-
|
250
|
-
env
|
251
|
-
end
|
211
|
+
env
|
252
212
|
end
|
253
|
-
private_class_method :halting
|
254
|
-
|
255
|
-
def self.conditional(callback_sequence, user_callback, user_conditions)
|
256
|
-
callback_sequence.after do |env|
|
257
|
-
target = env.target
|
258
|
-
value = env.value
|
259
213
|
|
260
|
-
|
261
|
-
|
262
|
-
end
|
263
|
-
|
264
|
-
env
|
265
|
-
end
|
214
|
+
def apply(callback_sequence)
|
215
|
+
callback_sequence.after(self)
|
266
216
|
end
|
267
|
-
|
217
|
+
end
|
268
218
|
|
269
|
-
|
270
|
-
|
271
|
-
|
219
|
+
class Around
|
220
|
+
def initialize(user_callback, user_conditions)
|
221
|
+
@user_callback, @user_conditions = user_callback, user_conditions
|
222
|
+
freeze
|
223
|
+
end
|
272
224
|
|
273
|
-
|
274
|
-
|
225
|
+
def apply(callback_sequence)
|
226
|
+
callback_sequence.around(@user_callback, @user_conditions)
|
275
227
|
end
|
276
|
-
private_class_method :simple
|
277
228
|
end
|
278
229
|
end
|
279
230
|
|
280
|
-
class Callback # :nodoc
|
231
|
+
class Callback # :nodoc:
|
281
232
|
def self.build(chain, filter, kind, options)
|
282
233
|
if filter.is_a?(String)
|
283
234
|
raise ArgumentError, <<-MSG.squish
|
@@ -299,6 +250,8 @@ module ActiveSupport
|
|
299
250
|
@filter = filter
|
300
251
|
@if = check_conditionals(options[:if])
|
301
252
|
@unless = check_conditionals(options[:unless])
|
253
|
+
|
254
|
+
compiled
|
302
255
|
end
|
303
256
|
|
304
257
|
def merge_conditional_options(chain, if_option:, unless_option:)
|
@@ -326,19 +279,26 @@ module ActiveSupport
|
|
326
279
|
end
|
327
280
|
end
|
328
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
|
+
|
329
299
|
# Wraps code with filter
|
330
300
|
def apply(callback_sequence)
|
331
|
-
|
332
|
-
user_callback = CallTemplate.build(@filter, self)
|
333
|
-
|
334
|
-
case kind
|
335
|
-
when :before
|
336
|
-
Filters::Before.build(callback_sequence, user_callback.make_lambda, user_conditions, chain_config, @filter, name)
|
337
|
-
when :after
|
338
|
-
Filters::After.build(callback_sequence, user_callback.make_lambda, user_conditions, chain_config)
|
339
|
-
when :around
|
340
|
-
callback_sequence.around(user_callback, user_conditions)
|
341
|
-
end
|
301
|
+
compiled.apply(callback_sequence)
|
342
302
|
end
|
343
303
|
|
344
304
|
def current_scopes
|
@@ -365,14 +325,16 @@ module ActiveSupport
|
|
365
325
|
end
|
366
326
|
|
367
327
|
def conditions_lambdas
|
368
|
-
|
328
|
+
conditions =
|
329
|
+
@if.map { |c| CallTemplate.build(c, self).make_lambda } +
|
369
330
|
@unless.map { |c| CallTemplate.build(c, self).inverted_lambda }
|
331
|
+
conditions.empty? ? EMPTY_ARRAY : conditions
|
370
332
|
end
|
371
333
|
end
|
372
334
|
|
373
335
|
# A future invocation of user-supplied code (either as a callback,
|
374
336
|
# or a condition filter).
|
375
|
-
module CallTemplate # :nodoc:
|
337
|
+
module CallTemplate # :nodoc: all
|
376
338
|
class MethodCall
|
377
339
|
def initialize(method)
|
378
340
|
@method_name = method
|
@@ -559,16 +521,18 @@ module ActiveSupport
|
|
559
521
|
@call_template = call_template
|
560
522
|
@user_conditions = user_conditions
|
561
523
|
|
562
|
-
@before =
|
563
|
-
@after =
|
524
|
+
@before = nil
|
525
|
+
@after = nil
|
564
526
|
end
|
565
527
|
|
566
|
-
def before(
|
528
|
+
def before(before)
|
529
|
+
@before ||= []
|
567
530
|
@before.unshift(before)
|
568
531
|
self
|
569
532
|
end
|
570
533
|
|
571
|
-
def after(
|
534
|
+
def after(after)
|
535
|
+
@after ||= []
|
572
536
|
@after.push(after)
|
573
537
|
self
|
574
538
|
end
|
@@ -592,11 +556,11 @@ module ActiveSupport
|
|
592
556
|
end
|
593
557
|
|
594
558
|
def invoke_before(arg)
|
595
|
-
@before
|
559
|
+
@before&.each { |b| b.call(arg) }
|
596
560
|
end
|
597
561
|
|
598
562
|
def invoke_after(arg)
|
599
|
-
@after
|
563
|
+
@after&.each { |a| a.call(arg) }
|
600
564
|
end
|
601
565
|
end
|
602
566
|
|
@@ -612,7 +576,8 @@ module ActiveSupport
|
|
612
576
|
terminator: default_terminator
|
613
577
|
}.merge!(config)
|
614
578
|
@chain = []
|
615
|
-
@
|
579
|
+
@all_callbacks = nil
|
580
|
+
@single_callbacks = {}
|
616
581
|
@mutex = Mutex.new
|
617
582
|
end
|
618
583
|
|
@@ -621,32 +586,45 @@ module ActiveSupport
|
|
621
586
|
def empty?; @chain.empty?; end
|
622
587
|
|
623
588
|
def insert(index, o)
|
624
|
-
@
|
589
|
+
@all_callbacks = nil
|
590
|
+
@single_callbacks.clear
|
625
591
|
@chain.insert(index, o)
|
626
592
|
end
|
627
593
|
|
628
594
|
def delete(o)
|
629
|
-
@
|
595
|
+
@all_callbacks = nil
|
596
|
+
@single_callbacks.clear
|
630
597
|
@chain.delete(o)
|
631
598
|
end
|
632
599
|
|
633
600
|
def clear
|
634
|
-
@
|
601
|
+
@all_callbacks = nil
|
602
|
+
@single_callbacks.clear
|
635
603
|
@chain.clear
|
636
604
|
self
|
637
605
|
end
|
638
606
|
|
639
607
|
def initialize_copy(other)
|
640
|
-
@
|
608
|
+
@all_callbacks = nil
|
609
|
+
@single_callbacks = {}
|
641
610
|
@chain = other.chain.dup
|
642
611
|
@mutex = Mutex.new
|
643
612
|
end
|
644
613
|
|
645
|
-
def compile
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
614
|
+
def compile(type)
|
615
|
+
if type.nil?
|
616
|
+
@all_callbacks || @mutex.synchronize do
|
617
|
+
final_sequence = CallbackSequence.new
|
618
|
+
@all_callbacks ||= @chain.reverse.inject(final_sequence) do |callback_sequence, callback|
|
619
|
+
callback.apply(callback_sequence)
|
620
|
+
end
|
621
|
+
end
|
622
|
+
else
|
623
|
+
@single_callbacks[type] || @mutex.synchronize do
|
624
|
+
final_sequence = CallbackSequence.new
|
625
|
+
@single_callbacks[type] ||= @chain.reverse.inject(final_sequence) do |callback_sequence, callback|
|
626
|
+
type == callback.kind ? callback.apply(callback_sequence) : callback_sequence
|
627
|
+
end
|
650
628
|
end
|
651
629
|
end
|
652
630
|
end
|
@@ -664,19 +642,22 @@ module ActiveSupport
|
|
664
642
|
|
665
643
|
private
|
666
644
|
def append_one(callback)
|
667
|
-
@
|
645
|
+
@all_callbacks = nil
|
646
|
+
@single_callbacks.clear
|
668
647
|
remove_duplicates(callback)
|
669
648
|
@chain.push(callback)
|
670
649
|
end
|
671
650
|
|
672
651
|
def prepend_one(callback)
|
673
|
-
@
|
652
|
+
@all_callbacks = nil
|
653
|
+
@single_callbacks.clear
|
674
654
|
remove_duplicates(callback)
|
675
655
|
@chain.unshift(callback)
|
676
656
|
end
|
677
657
|
|
678
658
|
def remove_duplicates(callback)
|
679
|
-
@
|
659
|
+
@all_callbacks = nil
|
660
|
+
@single_callbacks.clear
|
680
661
|
@chain.delete_if { |c| callback.duplicates?(c) }
|
681
662
|
end
|
682
663
|
|
@@ -703,7 +684,7 @@ module ActiveSupport
|
|
703
684
|
# This is used internally to append, prepend and skip callbacks to the
|
704
685
|
# CallbackChain.
|
705
686
|
def __update_callbacks(name) # :nodoc:
|
706
|
-
|
687
|
+
self.descendants.prepend(self).reverse_each do |target|
|
707
688
|
chain = target.get_callbacks name
|
708
689
|
yield target, chain.dup
|
709
690
|
end
|
@@ -723,7 +704,7 @@ module ActiveSupport
|
|
723
704
|
#
|
724
705
|
# The callback can be specified as a symbol naming an instance method; as a
|
725
706
|
# proc, lambda, or block; or as an object that responds to a certain method
|
726
|
-
# determined by the <tt>:scope</tt> argument to
|
707
|
+
# determined by the <tt>:scope</tt> argument to #define_callbacks.
|
727
708
|
#
|
728
709
|
# If a proc, lambda, or block is given, its body is evaluated in the context
|
729
710
|
# of the current object. It can also optionally accept the current object as
|
@@ -767,10 +748,13 @@ module ActiveSupport
|
|
767
748
|
end
|
768
749
|
end
|
769
750
|
|
770
|
-
# Skip a previously set callback. Like
|
751
|
+
# Skip a previously set callback. Like #set_callback, <tt>:if</tt> or
|
771
752
|
# <tt>:unless</tt> options may be passed in order to control when the
|
772
753
|
# callback is skipped.
|
773
754
|
#
|
755
|
+
# Note: this example uses +PersonRecord+ and +#saving_message+, which you
|
756
|
+
# can see defined here[rdoc-ref:ActiveSupport::Callbacks]
|
757
|
+
#
|
774
758
|
# class Writer < PersonRecord
|
775
759
|
# attr_accessor :age
|
776
760
|
# skip_callback :save, :before, :saving_message, if: -> { age > 18 }
|
@@ -913,7 +897,7 @@ module ActiveSupport
|
|
913
897
|
# <tt>!</tt>, <tt>?</tt> or <tt>=</tt>.
|
914
898
|
#
|
915
899
|
# Calling +define_callbacks+ multiple times with the same +names+ will
|
916
|
-
# overwrite previous callbacks registered with
|
900
|
+
# overwrite previous callbacks registered with #set_callback.
|
917
901
|
def define_callbacks(*names)
|
918
902
|
options = names.extract_options!
|
919
903
|
|
@@ -9,16 +9,19 @@ module ActiveSupport
|
|
9
9
|
@cache = METHOD_CACHES[namespace]
|
10
10
|
@sources = []
|
11
11
|
@methods = {}
|
12
|
+
@canonical_methods = {}
|
12
13
|
end
|
13
14
|
|
14
|
-
def define_cached_method(
|
15
|
-
|
16
|
-
as = as.to_sym
|
17
|
-
|
18
|
-
|
15
|
+
def define_cached_method(canonical_name, as: nil)
|
16
|
+
canonical_name = canonical_name.to_sym
|
17
|
+
as = (as || canonical_name).to_sym
|
18
|
+
|
19
|
+
@methods.fetch(as) do
|
20
|
+
unless @cache.method_defined?(canonical_name) || @canonical_methods[canonical_name]
|
19
21
|
yield @sources
|
20
22
|
end
|
21
|
-
@
|
23
|
+
@canonical_methods[canonical_name] = true
|
24
|
+
@methods[as] = canonical_name
|
22
25
|
end
|
23
26
|
end
|
24
27
|
|
@@ -26,8 +29,10 @@ module ActiveSupport
|
|
26
29
|
unless @sources.empty?
|
27
30
|
@cache.module_eval("# frozen_string_literal: true\n" + @sources.join(";"), path, line)
|
28
31
|
end
|
29
|
-
@
|
30
|
-
|
32
|
+
@canonical_methods.clear
|
33
|
+
|
34
|
+
@methods.each do |as, canonical_name|
|
35
|
+
owner.define_method(as, @cache.instance_method(canonical_name))
|
31
36
|
end
|
32
37
|
end
|
33
38
|
end
|
@@ -52,8 +57,8 @@ module ActiveSupport
|
|
52
57
|
@namespaces = Hash.new { |h, k| h[k] = MethodSet.new(k) }
|
53
58
|
end
|
54
59
|
|
55
|
-
def define_cached_method(
|
56
|
-
@namespaces[namespace].define_cached_method(
|
60
|
+
def define_cached_method(canonical_name, namespace:, as: nil, &block)
|
61
|
+
@namespaces[namespace].define_cached_method(canonical_name, as: as, &block)
|
57
62
|
end
|
58
63
|
|
59
64
|
def execute
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveSupport
|
4
|
+
# = Active Support \Concern
|
5
|
+
#
|
4
6
|
# A typical module looks like this:
|
5
7
|
#
|
6
8
|
# module M
|
@@ -16,7 +18,7 @@ module ActiveSupport
|
|
16
18
|
# end
|
17
19
|
# end
|
18
20
|
#
|
19
|
-
# By using
|
21
|
+
# By using +ActiveSupport::Concern+ the above module could instead be
|
20
22
|
# written as:
|
21
23
|
#
|
22
24
|
# require "active_support/concern"
|
@@ -73,7 +75,7 @@ module ActiveSupport
|
|
73
75
|
# end
|
74
76
|
#
|
75
77
|
# Unfortunately this won't work, since when +Foo+ is included, its <tt>base</tt>
|
76
|
-
# is the +Bar+ module, not the +Host+ class. With
|
78
|
+
# is the +Bar+ module, not the +Host+ class. With +ActiveSupport::Concern+,
|
77
79
|
# module dependencies are properly resolved:
|
78
80
|
#
|
79
81
|
# require "active_support/concern"
|
@@ -4,9 +4,7 @@ require "monitor"
|
|
4
4
|
|
5
5
|
module ActiveSupport
|
6
6
|
module Concurrency
|
7
|
-
|
8
|
-
# the lock.
|
9
|
-
class LoadInterlockAwareMonitor < Monitor
|
7
|
+
module LoadInterlockAwareMonitorMixin # :nodoc:
|
10
8
|
EXCEPTION_NEVER = { Exception => :never }.freeze
|
11
9
|
EXCEPTION_IMMEDIATE = { Exception => :immediate }.freeze
|
12
10
|
private_constant :EXCEPTION_NEVER, :EXCEPTION_IMMEDIATE
|
@@ -29,5 +27,46 @@ module ActiveSupport
|
|
29
27
|
end
|
30
28
|
end
|
31
29
|
end
|
30
|
+
# A monitor that will permit dependency loading while blocked waiting for
|
31
|
+
# the lock.
|
32
|
+
class LoadInterlockAwareMonitor < Monitor
|
33
|
+
include LoadInterlockAwareMonitorMixin
|
34
|
+
end
|
35
|
+
|
36
|
+
class ThreadLoadInterlockAwareMonitor # :nodoc:
|
37
|
+
prepend LoadInterlockAwareMonitorMixin
|
38
|
+
|
39
|
+
def initialize
|
40
|
+
@owner = nil
|
41
|
+
@count = 0
|
42
|
+
@mutex = Mutex.new
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
def mon_try_enter
|
47
|
+
if @owner != Thread.current
|
48
|
+
return false unless @mutex.try_lock
|
49
|
+
@owner = Thread.current
|
50
|
+
end
|
51
|
+
@count += 1
|
52
|
+
end
|
53
|
+
|
54
|
+
def mon_enter
|
55
|
+
@mutex.lock if @owner != Thread.current
|
56
|
+
@owner = Thread.current
|
57
|
+
@count += 1
|
58
|
+
end
|
59
|
+
|
60
|
+
def mon_exit
|
61
|
+
unless @owner == Thread.current
|
62
|
+
raise ThreadError, "current thread not owner"
|
63
|
+
end
|
64
|
+
|
65
|
+
@count -= 1
|
66
|
+
return unless @count == 0
|
67
|
+
@owner = nil
|
68
|
+
@mutex.unlock
|
69
|
+
end
|
70
|
+
end
|
32
71
|
end
|
33
72
|
end
|
@@ -4,6 +4,8 @@ require "active_support/concern"
|
|
4
4
|
require "active_support/ordered_options"
|
5
5
|
|
6
6
|
module ActiveSupport
|
7
|
+
# = Active Support \Configurable
|
8
|
+
#
|
7
9
|
# Configurable provides a <tt>config</tt> method to store and retrieve
|
8
10
|
# configuration options as an OrderedOptions.
|
9
11
|
module Configurable
|
@@ -125,6 +127,14 @@ module ActiveSupport
|
|
125
127
|
end
|
126
128
|
end
|
127
129
|
private :config_accessor
|
130
|
+
|
131
|
+
private
|
132
|
+
def inherited(subclass)
|
133
|
+
super
|
134
|
+
subclass.class_eval do
|
135
|
+
@_config = nil
|
136
|
+
end
|
137
|
+
end
|
128
138
|
end
|
129
139
|
|
130
140
|
# Reads and writes attributes from a configuration OrderedOptions.
|
@@ -100,11 +100,10 @@ class Array
|
|
100
100
|
collect(&:id).join(",")
|
101
101
|
end
|
102
102
|
else
|
103
|
-
|
103
|
+
to_s
|
104
104
|
end
|
105
105
|
end
|
106
106
|
alias_method :to_formatted_s, :to_fs
|
107
|
-
alias_method :to_default_s, :to_s
|
108
107
|
|
109
108
|
# Returns a string that represents the array in XML by invoking +to_xml+
|
110
109
|
# on each element. Active Record collections delegate their representation
|
@@ -3,7 +3,6 @@
|
|
3
3
|
require "active_support/core_ext/array/wrap"
|
4
4
|
require "active_support/core_ext/array/access"
|
5
5
|
require "active_support/core_ext/array/conversions"
|
6
|
-
require "active_support/core_ext/array/deprecated_conversions" unless ENV["RAILS_DISABLE_DEPRECATED_TO_S_CONVERSION"]
|
7
6
|
require "active_support/core_ext/array/extract"
|
8
7
|
require "active_support/core_ext/array/extract_options"
|
9
8
|
require "active_support/core_ext/array/grouping"
|