activesupport 4.2.0 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +630 -220
- data/MIT-LICENSE +2 -2
- data/README.rdoc +2 -3
- data/lib/active_support/array_inquirer.rb +44 -0
- data/lib/active_support/backtrace_cleaner.rb +1 -1
- data/lib/active_support/benchmarkable.rb +1 -1
- data/lib/active_support/cache/file_store.rb +36 -22
- data/lib/active_support/cache/mem_cache_store.rb +63 -54
- data/lib/active_support/cache/memory_store.rb +16 -21
- data/lib/active_support/cache/null_store.rb +1 -4
- data/lib/active_support/cache/strategy/local_cache.rb +31 -20
- data/lib/active_support/cache.rb +73 -89
- data/lib/active_support/callbacks.rb +195 -155
- data/lib/active_support/concern.rb +2 -2
- data/lib/active_support/concurrency/latch.rb +7 -15
- data/lib/active_support/concurrency/share_lock.rb +186 -0
- data/lib/active_support/configurable.rb +1 -0
- data/lib/active_support/core_ext/array/access.rb +27 -1
- data/lib/active_support/core_ext/array/conversions.rb +6 -4
- data/lib/active_support/core_ext/array/grouping.rb +9 -18
- data/lib/active_support/core_ext/array/inquiry.rb +17 -0
- data/lib/active_support/core_ext/array/wrap.rb +5 -4
- data/lib/active_support/core_ext/array.rb +1 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -10
- data/lib/active_support/core_ext/class/attribute.rb +10 -9
- data/lib/active_support/core_ext/class/subclasses.rb +3 -4
- data/lib/active_support/core_ext/class.rb +0 -1
- data/lib/active_support/core_ext/date/blank.rb +12 -0
- data/lib/active_support/core_ext/date/calculations.rb +1 -1
- data/lib/active_support/core_ext/date/conversions.rb +13 -6
- data/lib/active_support/core_ext/date.rb +1 -1
- data/lib/active_support/core_ext/date_and_time/calculations.rb +109 -25
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +3 -4
- data/lib/active_support/core_ext/date_time/blank.rb +12 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +36 -10
- data/lib/active_support/core_ext/date_time/compatibility.rb +5 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
- data/lib/active_support/core_ext/date_time.rb +2 -1
- data/lib/active_support/core_ext/enumerable.rb +49 -5
- data/lib/active_support/core_ext/file/atomic.rb +30 -25
- data/lib/active_support/core_ext/hash/conversions.rb +23 -4
- data/lib/active_support/core_ext/hash/deep_merge.rb +1 -1
- data/lib/active_support/core_ext/hash/except.rb +9 -8
- data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +23 -19
- data/lib/active_support/core_ext/hash/slice.rb +1 -1
- data/lib/active_support/core_ext/hash/transform_values.rb +11 -5
- data/lib/active_support/core_ext/integer/time.rb +1 -16
- data/lib/active_support/core_ext/kernel/concern.rb +2 -0
- data/lib/active_support/core_ext/kernel/debugger.rb +3 -10
- data/lib/active_support/core_ext/kernel/reporting.rb +2 -83
- data/lib/active_support/core_ext/kernel.rb +0 -1
- data/lib/active_support/core_ext/load_error.rb +4 -2
- data/lib/active_support/core_ext/marshal.rb +12 -11
- data/lib/active_support/core_ext/module/aliasing.rb +6 -1
- data/lib/active_support/core_ext/module/anonymous.rb +10 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -5
- data/lib/active_support/core_ext/module/attribute_accessors.rb +15 -15
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
- data/lib/active_support/core_ext/module/concerning.rb +4 -4
- data/lib/active_support/core_ext/module/delegation.rb +35 -25
- data/lib/active_support/core_ext/module/deprecation.rb +2 -2
- data/lib/active_support/core_ext/module/introspection.rb +4 -0
- data/lib/active_support/core_ext/module/method_transplanting.rb +3 -11
- data/lib/active_support/core_ext/module/qualified_const.rb +30 -12
- data/lib/active_support/core_ext/module/remove_method.rb +23 -0
- data/lib/active_support/core_ext/module.rb +1 -0
- data/lib/active_support/core_ext/name_error.rb +15 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +20 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +74 -64
- data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
- data/lib/active_support/core_ext/numeric/time.rb +24 -19
- data/lib/active_support/core_ext/numeric.rb +1 -0
- data/lib/active_support/core_ext/object/blank.rb +17 -5
- data/lib/active_support/core_ext/object/deep_dup.rb +10 -3
- data/lib/active_support/core_ext/object/duplicable.rb +8 -13
- data/lib/active_support/core_ext/object/inclusion.rb +2 -2
- data/lib/active_support/core_ext/object/instance_variables.rb +1 -1
- data/lib/active_support/core_ext/object/json.rb +15 -7
- data/lib/active_support/core_ext/object/to_query.rb +1 -1
- data/lib/active_support/core_ext/object/try.rb +68 -22
- data/lib/active_support/core_ext/object/with_options.rb +1 -1
- data/lib/active_support/core_ext/object.rb +0 -1
- data/lib/active_support/core_ext/range/conversions.rb +18 -6
- data/lib/active_support/core_ext/range/each.rb +16 -18
- data/lib/active_support/core_ext/range/include_range.rb +20 -20
- data/lib/active_support/core_ext/securerandom.rb +23 -0
- data/lib/active_support/core_ext/string/access.rb +1 -1
- data/lib/active_support/core_ext/string/behavior.rb +1 -1
- data/lib/active_support/core_ext/string/conversions.rb +4 -3
- data/lib/active_support/core_ext/string/filters.rb +5 -5
- data/lib/active_support/core_ext/string/inflections.rb +32 -5
- data/lib/active_support/core_ext/string/multibyte.rb +11 -7
- data/lib/active_support/core_ext/string/output_safety.rb +18 -16
- data/lib/active_support/core_ext/string/strip.rb +3 -6
- data/lib/active_support/core_ext/struct.rb +3 -6
- data/lib/active_support/core_ext/time/calculations.rb +36 -11
- data/lib/active_support/core_ext/time/compatibility.rb +5 -0
- data/lib/active_support/core_ext/time/conversions.rb +4 -2
- data/lib/active_support/core_ext/time/marshal.rb +2 -29
- data/lib/active_support/core_ext/time/zones.rb +36 -4
- data/lib/active_support/core_ext/time.rb +1 -1
- data/lib/active_support/core_ext/uri.rb +1 -3
- data/lib/active_support/core_ext.rb +2 -1
- data/lib/active_support/dependencies/interlock.rb +51 -0
- data/lib/active_support/dependencies.rb +87 -95
- data/lib/active_support/deprecation/behaviors.rb +16 -2
- data/lib/active_support/deprecation/method_wrappers.rb +42 -16
- data/lib/active_support/deprecation/proxy_wrappers.rb +47 -24
- data/lib/active_support/deprecation/reporting.rb +23 -5
- data/lib/active_support/deprecation.rb +1 -1
- data/lib/active_support/duration/iso8601_parser.rb +122 -0
- data/lib/active_support/duration/iso8601_serializer.rb +51 -0
- data/lib/active_support/duration.rb +55 -10
- data/lib/active_support/evented_file_update_checker.rb +194 -0
- data/lib/active_support/execution_wrapper.rb +117 -0
- data/lib/active_support/executor.rb +6 -0
- data/lib/active_support/file_update_checker.rb +23 -3
- data/lib/active_support/gem_version.rb +3 -3
- data/lib/active_support/hash_with_indifferent_access.rb +46 -13
- data/lib/active_support/i18n_railtie.rb +25 -4
- data/lib/active_support/inflector/inflections.rb +36 -5
- data/lib/active_support/inflector/methods.rb +97 -90
- data/lib/active_support/inflector/transliterate.rb +36 -21
- data/lib/active_support/json/decoding.rb +11 -10
- data/lib/active_support/json/encoding.rb +4 -49
- data/lib/active_support/key_generator.rb +7 -9
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber/test_helper.rb +3 -3
- data/lib/active_support/log_subscriber.rb +1 -1
- data/lib/active_support/logger.rb +50 -1
- data/lib/active_support/logger_silence.rb +8 -4
- data/lib/active_support/logger_thread_safe_level.rb +31 -0
- data/lib/active_support/message_encryptor.rb +4 -4
- data/lib/active_support/message_verifier.rb +70 -8
- data/lib/active_support/multibyte/chars.rb +13 -4
- data/lib/active_support/multibyte/unicode.rb +44 -21
- data/lib/active_support/notifications/fanout.rb +6 -6
- data/lib/active_support/notifications/instrumenter.rb +20 -2
- data/lib/active_support/notifications.rb +2 -2
- data/lib/active_support/number_helper/number_to_currency_converter.rb +7 -9
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +8 -3
- data/lib/active_support/number_helper/number_to_human_converter.rb +6 -4
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -2
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +11 -2
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +30 -25
- data/lib/active_support/number_helper.rb +90 -67
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/ordered_options.rb +15 -1
- data/lib/active_support/per_thread_registry.rb +8 -3
- data/lib/active_support/rails.rb +2 -2
- data/lib/active_support/railtie.rb +6 -1
- data/lib/active_support/reloader.rb +129 -0
- data/lib/active_support/rescuable.rb +93 -47
- data/lib/active_support/security_utils.rb +7 -0
- data/lib/active_support/string_inquirer.rb +1 -1
- data/lib/active_support/subscriber.rb +5 -10
- data/lib/active_support/tagged_logging.rb +3 -1
- data/lib/active_support/test_case.rb +15 -29
- data/lib/active_support/testing/assertions.rb +15 -13
- data/lib/active_support/testing/autorun.rb +8 -1
- data/lib/active_support/testing/deprecation.rb +9 -8
- data/lib/active_support/testing/file_fixtures.rb +34 -0
- data/lib/active_support/testing/isolation.rb +22 -8
- data/lib/active_support/testing/method_call_assertions.rb +41 -0
- data/lib/active_support/testing/stream.rb +42 -0
- data/lib/active_support/testing/time_helpers.rb +13 -10
- data/lib/active_support/time_with_zone.rb +135 -46
- data/lib/active_support/values/time_zone.rb +95 -47
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/xml_mini/jdom.rb +7 -6
- data/lib/active_support/xml_mini/libxml.rb +2 -2
- data/lib/active_support/xml_mini/nokogiri.rb +2 -2
- data/lib/active_support/xml_mini/rexml.rb +7 -8
- data/lib/active_support/xml_mini.rb +22 -14
- data/lib/active_support.rb +20 -6
- metadata +32 -35
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -14
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
- data/lib/active_support/core_ext/date_time/zones.rb +0 -6
- data/lib/active_support/core_ext/object/itself.rb +0 -15
- data/lib/active_support/core_ext/thread.rb +0 -86
@@ -4,6 +4,9 @@ require 'active_support/core_ext/array/extract_options'
|
|
4
4
|
require 'active_support/core_ext/class/attribute'
|
5
5
|
require 'active_support/core_ext/kernel/reporting'
|
6
6
|
require 'active_support/core_ext/kernel/singleton_class'
|
7
|
+
require 'active_support/core_ext/module/attribute_accessors'
|
8
|
+
require 'active_support/core_ext/string/filters'
|
9
|
+
require 'active_support/deprecation'
|
7
10
|
require 'thread'
|
8
11
|
|
9
12
|
module ActiveSupport
|
@@ -64,6 +67,12 @@ module ActiveSupport
|
|
64
67
|
|
65
68
|
CALLBACK_FILTER_TYPES = [:before, :after, :around]
|
66
69
|
|
70
|
+
# If true, Active Record and Active Model callbacks returning +false+ will
|
71
|
+
# halt the entire callback chain and display a deprecation message.
|
72
|
+
# If false, callback chains will only be halted by calling +throw :abort+.
|
73
|
+
# Defaults to +true+.
|
74
|
+
mattr_accessor(:halt_and_display_warning_on_return_false, instance_writer: false) { true }
|
75
|
+
|
67
76
|
# Runs the callbacks for the given event.
|
68
77
|
#
|
69
78
|
# Calls the before and around callbacks in the order they were set, yields
|
@@ -83,9 +92,9 @@ module ActiveSupport
|
|
83
92
|
|
84
93
|
private
|
85
94
|
|
86
|
-
def
|
95
|
+
def __run_callbacks__(callbacks, &block)
|
87
96
|
if callbacks.empty?
|
88
|
-
|
97
|
+
yield if block_given?
|
89
98
|
else
|
90
99
|
runner = callbacks.compile
|
91
100
|
e = Filters::Environment.new(self, false, nil, block)
|
@@ -121,102 +130,75 @@ module ActiveSupport
|
|
121
130
|
ENDING = End.new
|
122
131
|
|
123
132
|
class Before
|
124
|
-
def self.build(
|
133
|
+
def self.build(callback_sequence, user_callback, user_conditions, chain_config, filter)
|
125
134
|
halted_lambda = chain_config[:terminator]
|
126
135
|
|
127
|
-
if
|
128
|
-
halting_and_conditional(
|
129
|
-
elsif chain_config.key? :terminator
|
130
|
-
halting(next_callback, user_callback, halted_lambda, filter)
|
131
|
-
elsif user_conditions.any?
|
132
|
-
conditional(next_callback, user_callback, user_conditions)
|
136
|
+
if user_conditions.any?
|
137
|
+
halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter)
|
133
138
|
else
|
134
|
-
|
139
|
+
halting(callback_sequence, user_callback, halted_lambda, filter)
|
135
140
|
end
|
136
141
|
end
|
137
142
|
|
138
|
-
def self.halting_and_conditional(
|
139
|
-
|
143
|
+
def self.halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter)
|
144
|
+
callback_sequence.before do |env|
|
140
145
|
target = env.target
|
141
146
|
value = env.value
|
142
147
|
halted = env.halted
|
143
148
|
|
144
149
|
if !halted && user_conditions.all? { |c| c.call(target, value) }
|
145
|
-
|
146
|
-
env.halted = halted_lambda.call(target,
|
150
|
+
result_lambda = -> { user_callback.call target, value }
|
151
|
+
env.halted = halted_lambda.call(target, result_lambda)
|
147
152
|
if env.halted
|
148
153
|
target.send :halted_callback_hook, filter
|
149
154
|
end
|
150
155
|
end
|
151
|
-
|
152
|
-
|
156
|
+
|
157
|
+
env
|
158
|
+
end
|
153
159
|
end
|
154
160
|
private_class_method :halting_and_conditional
|
155
161
|
|
156
|
-
def self.halting(
|
157
|
-
|
162
|
+
def self.halting(callback_sequence, user_callback, halted_lambda, filter)
|
163
|
+
callback_sequence.before do |env|
|
158
164
|
target = env.target
|
159
165
|
value = env.value
|
160
166
|
halted = env.halted
|
161
167
|
|
162
168
|
unless halted
|
163
|
-
|
164
|
-
env.halted = halted_lambda.call(target,
|
169
|
+
result_lambda = -> { user_callback.call target, value }
|
170
|
+
env.halted = halted_lambda.call(target, result_lambda)
|
171
|
+
|
165
172
|
if env.halted
|
166
173
|
target.send :halted_callback_hook, filter
|
167
174
|
end
|
168
175
|
end
|
169
|
-
next_callback.call env
|
170
|
-
}
|
171
|
-
end
|
172
|
-
private_class_method :halting
|
173
|
-
|
174
|
-
def self.conditional(next_callback, user_callback, user_conditions)
|
175
|
-
lambda { |env|
|
176
|
-
target = env.target
|
177
|
-
value = env.value
|
178
|
-
|
179
|
-
if user_conditions.all? { |c| c.call(target, value) }
|
180
|
-
user_callback.call target, value
|
181
|
-
end
|
182
|
-
next_callback.call env
|
183
|
-
}
|
184
|
-
end
|
185
|
-
private_class_method :conditional
|
186
176
|
|
187
|
-
|
188
|
-
|
189
|
-
user_callback.call env.target, env.value
|
190
|
-
next_callback.call env
|
191
|
-
}
|
177
|
+
env
|
178
|
+
end
|
192
179
|
end
|
193
|
-
private_class_method :
|
180
|
+
private_class_method :halting
|
194
181
|
end
|
195
182
|
|
196
183
|
class After
|
197
|
-
def self.build(
|
184
|
+
def self.build(callback_sequence, user_callback, user_conditions, chain_config)
|
198
185
|
if chain_config[:skip_after_callbacks_if_terminated]
|
199
|
-
if
|
200
|
-
halting_and_conditional(
|
201
|
-
elsif chain_config.key?(:terminator)
|
202
|
-
halting(next_callback, user_callback)
|
203
|
-
elsif user_conditions.any?
|
204
|
-
conditional next_callback, user_callback, user_conditions
|
186
|
+
if user_conditions.any?
|
187
|
+
halting_and_conditional(callback_sequence, user_callback, user_conditions)
|
205
188
|
else
|
206
|
-
|
189
|
+
halting(callback_sequence, user_callback)
|
207
190
|
end
|
208
191
|
else
|
209
192
|
if user_conditions.any?
|
210
|
-
conditional
|
193
|
+
conditional callback_sequence, user_callback, user_conditions
|
211
194
|
else
|
212
|
-
simple
|
195
|
+
simple callback_sequence, user_callback
|
213
196
|
end
|
214
197
|
end
|
215
198
|
end
|
216
199
|
|
217
|
-
def self.halting_and_conditional(
|
218
|
-
|
219
|
-
env = next_callback.call env
|
200
|
+
def self.halting_and_conditional(callback_sequence, user_callback, user_conditions)
|
201
|
+
callback_sequence.after do |env|
|
220
202
|
target = env.target
|
221
203
|
value = env.value
|
222
204
|
halted = env.halted
|
@@ -224,129 +206,102 @@ module ActiveSupport
|
|
224
206
|
if !halted && user_conditions.all? { |c| c.call(target, value) }
|
225
207
|
user_callback.call target, value
|
226
208
|
end
|
209
|
+
|
227
210
|
env
|
228
|
-
|
211
|
+
end
|
229
212
|
end
|
230
213
|
private_class_method :halting_and_conditional
|
231
214
|
|
232
|
-
def self.halting(
|
233
|
-
|
234
|
-
env = next_callback.call env
|
215
|
+
def self.halting(callback_sequence, user_callback)
|
216
|
+
callback_sequence.after do |env|
|
235
217
|
unless env.halted
|
236
218
|
user_callback.call env.target, env.value
|
237
219
|
end
|
220
|
+
|
238
221
|
env
|
239
|
-
|
222
|
+
end
|
240
223
|
end
|
241
224
|
private_class_method :halting
|
242
225
|
|
243
|
-
def self.conditional(
|
244
|
-
|
245
|
-
env = next_callback.call env
|
226
|
+
def self.conditional(callback_sequence, user_callback, user_conditions)
|
227
|
+
callback_sequence.after do |env|
|
246
228
|
target = env.target
|
247
229
|
value = env.value
|
248
230
|
|
249
231
|
if user_conditions.all? { |c| c.call(target, value) }
|
250
232
|
user_callback.call target, value
|
251
233
|
end
|
234
|
+
|
252
235
|
env
|
253
|
-
|
236
|
+
end
|
254
237
|
end
|
255
238
|
private_class_method :conditional
|
256
239
|
|
257
|
-
def self.simple(
|
258
|
-
|
259
|
-
env = next_callback.call env
|
240
|
+
def self.simple(callback_sequence, user_callback)
|
241
|
+
callback_sequence.after do |env|
|
260
242
|
user_callback.call env.target, env.value
|
243
|
+
|
261
244
|
env
|
262
|
-
|
245
|
+
end
|
263
246
|
end
|
264
247
|
private_class_method :simple
|
265
248
|
end
|
266
249
|
|
267
250
|
class Around
|
268
|
-
def self.build(
|
269
|
-
if
|
270
|
-
halting_and_conditional(
|
271
|
-
elsif chain_config.key? :terminator
|
272
|
-
halting(next_callback, user_callback)
|
273
|
-
elsif user_conditions.any?
|
274
|
-
conditional(next_callback, user_callback, user_conditions)
|
251
|
+
def self.build(callback_sequence, user_callback, user_conditions, chain_config)
|
252
|
+
if user_conditions.any?
|
253
|
+
halting_and_conditional(callback_sequence, user_callback, user_conditions)
|
275
254
|
else
|
276
|
-
|
255
|
+
halting(callback_sequence, user_callback)
|
277
256
|
end
|
278
257
|
end
|
279
258
|
|
280
|
-
def self.halting_and_conditional(
|
281
|
-
|
259
|
+
def self.halting_and_conditional(callback_sequence, user_callback, user_conditions)
|
260
|
+
callback_sequence.around do |env, &run|
|
282
261
|
target = env.target
|
283
262
|
value = env.value
|
284
263
|
halted = env.halted
|
285
264
|
|
286
265
|
if !halted && user_conditions.all? { |c| c.call(target, value) }
|
287
266
|
user_callback.call(target, value) {
|
288
|
-
|
289
|
-
env.value
|
267
|
+
run.call.value
|
290
268
|
}
|
291
269
|
env
|
292
270
|
else
|
293
|
-
|
271
|
+
run.call
|
294
272
|
end
|
295
|
-
|
273
|
+
end
|
296
274
|
end
|
297
275
|
private_class_method :halting_and_conditional
|
298
276
|
|
299
|
-
def self.halting(
|
300
|
-
|
277
|
+
def self.halting(callback_sequence, user_callback)
|
278
|
+
callback_sequence.around do |env, &run|
|
301
279
|
target = env.target
|
302
280
|
value = env.value
|
303
281
|
|
304
282
|
if env.halted
|
305
|
-
|
283
|
+
run.call
|
306
284
|
else
|
307
285
|
user_callback.call(target, value) {
|
308
|
-
|
309
|
-
env.value
|
286
|
+
run.call.value
|
310
287
|
}
|
311
288
|
env
|
312
289
|
end
|
313
|
-
|
290
|
+
end
|
314
291
|
end
|
315
292
|
private_class_method :halting
|
316
|
-
|
317
|
-
def self.conditional(next_callback, user_callback, user_conditions)
|
318
|
-
lambda { |env|
|
319
|
-
target = env.target
|
320
|
-
value = env.value
|
321
|
-
|
322
|
-
if user_conditions.all? { |c| c.call(target, value) }
|
323
|
-
user_callback.call(target, value) {
|
324
|
-
env = next_callback.call env
|
325
|
-
env.value
|
326
|
-
}
|
327
|
-
env
|
328
|
-
else
|
329
|
-
next_callback.call env
|
330
|
-
end
|
331
|
-
}
|
332
|
-
end
|
333
|
-
private_class_method :conditional
|
334
|
-
|
335
|
-
def self.simple(next_callback, user_callback)
|
336
|
-
lambda { |env|
|
337
|
-
user_callback.call(env.target, env.value) {
|
338
|
-
env = next_callback.call env
|
339
|
-
env.value
|
340
|
-
}
|
341
|
-
env
|
342
|
-
}
|
343
|
-
end
|
344
|
-
private_class_method :simple
|
345
293
|
end
|
346
294
|
end
|
347
295
|
|
348
296
|
class Callback #:nodoc:#
|
349
297
|
def self.build(chain, filter, kind, options)
|
298
|
+
if filter.is_a?(String)
|
299
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
300
|
+
Passing string to define callback is deprecated and will be removed
|
301
|
+
in Rails 5.1 without replacement.
|
302
|
+
MSG
|
303
|
+
end
|
304
|
+
|
350
305
|
new chain.name, filter, kind, options, chain.config
|
351
306
|
end
|
352
307
|
|
@@ -366,14 +321,14 @@ module ActiveSupport
|
|
366
321
|
def filter; @key; end
|
367
322
|
def raw_filter; @filter; end
|
368
323
|
|
369
|
-
def
|
324
|
+
def merge_conditional_options(chain, if_option:, unless_option:)
|
370
325
|
options = {
|
371
326
|
:if => @if.dup,
|
372
327
|
:unless => @unless.dup
|
373
328
|
}
|
374
329
|
|
375
|
-
options[:if].concat Array(
|
376
|
-
options[:unless].concat Array(
|
330
|
+
options[:if].concat Array(unless_option)
|
331
|
+
options[:unless].concat Array(if_option)
|
377
332
|
|
378
333
|
self.class.build chain, @filter, @kind, options
|
379
334
|
end
|
@@ -392,17 +347,17 @@ module ActiveSupport
|
|
392
347
|
end
|
393
348
|
|
394
349
|
# Wraps code with filter
|
395
|
-
def apply(
|
350
|
+
def apply(callback_sequence)
|
396
351
|
user_conditions = conditions_lambdas
|
397
352
|
user_callback = make_lambda @filter
|
398
353
|
|
399
354
|
case kind
|
400
355
|
when :before
|
401
|
-
Filters::Before.build(
|
356
|
+
Filters::Before.build(callback_sequence, user_callback, user_conditions, chain_config, @filter)
|
402
357
|
when :after
|
403
|
-
Filters::After.build(
|
358
|
+
Filters::After.build(callback_sequence, user_callback, user_conditions, chain_config)
|
404
359
|
when :around
|
405
|
-
Filters::Around.build(
|
360
|
+
Filters::Around.build(callback_sequence, user_callback, user_conditions, chain_config)
|
406
361
|
end
|
407
362
|
end
|
408
363
|
|
@@ -467,6 +422,42 @@ module ActiveSupport
|
|
467
422
|
end
|
468
423
|
end
|
469
424
|
|
425
|
+
# Execute before and after filters in a sequence instead of
|
426
|
+
# chaining them with nested lambda calls, see:
|
427
|
+
# https://github.com/rails/rails/issues/18011
|
428
|
+
class CallbackSequence
|
429
|
+
def initialize(&call)
|
430
|
+
@call = call
|
431
|
+
@before = []
|
432
|
+
@after = []
|
433
|
+
end
|
434
|
+
|
435
|
+
def before(&before)
|
436
|
+
@before.unshift(before)
|
437
|
+
self
|
438
|
+
end
|
439
|
+
|
440
|
+
def after(&after)
|
441
|
+
@after.push(after)
|
442
|
+
self
|
443
|
+
end
|
444
|
+
|
445
|
+
def around(&around)
|
446
|
+
CallbackSequence.new do |arg|
|
447
|
+
around.call(arg) {
|
448
|
+
self.call(arg)
|
449
|
+
}
|
450
|
+
end
|
451
|
+
end
|
452
|
+
|
453
|
+
def call(arg)
|
454
|
+
@before.each { |b| b.call(arg) }
|
455
|
+
value = @call.call(arg)
|
456
|
+
@after.each { |a| a.call(arg) }
|
457
|
+
value
|
458
|
+
end
|
459
|
+
end
|
460
|
+
|
470
461
|
# An Array with a compile method.
|
471
462
|
class CallbackChain #:nodoc:#
|
472
463
|
include Enumerable
|
@@ -476,7 +467,8 @@ module ActiveSupport
|
|
476
467
|
def initialize(name, config)
|
477
468
|
@name = name
|
478
469
|
@config = {
|
479
|
-
:
|
470
|
+
scope: [:kind],
|
471
|
+
terminator: default_terminator
|
480
472
|
}.merge!(config)
|
481
473
|
@chain = []
|
482
474
|
@callbacks = nil
|
@@ -511,8 +503,9 @@ module ActiveSupport
|
|
511
503
|
|
512
504
|
def compile
|
513
505
|
@callbacks || @mutex.synchronize do
|
514
|
-
|
515
|
-
|
506
|
+
final_sequence = CallbackSequence.new { |env| Filters::ENDING.call(env) }
|
507
|
+
@callbacks ||= @chain.reverse.inject(final_sequence) do |callback_sequence, callback|
|
508
|
+
callback.apply callback_sequence
|
516
509
|
end
|
517
510
|
end
|
518
511
|
end
|
@@ -546,6 +539,17 @@ module ActiveSupport
|
|
546
539
|
@callbacks = nil
|
547
540
|
@chain.delete_if { |c| callback.duplicates?(c) }
|
548
541
|
end
|
542
|
+
|
543
|
+
def default_terminator
|
544
|
+
Proc.new do |target, result_lambda|
|
545
|
+
terminate = true
|
546
|
+
catch(:abort) do
|
547
|
+
result_lambda.call if result_lambda.is_a?(Proc)
|
548
|
+
terminate = false
|
549
|
+
end
|
550
|
+
terminate
|
551
|
+
end
|
552
|
+
end
|
549
553
|
end
|
550
554
|
|
551
555
|
module ClassMethods
|
@@ -567,18 +571,18 @@ module ActiveSupport
|
|
567
571
|
|
568
572
|
# Install a callback for the given event.
|
569
573
|
#
|
570
|
-
# set_callback :save, :before, :
|
571
|
-
# set_callback :save, :after, :
|
574
|
+
# set_callback :save, :before, :before_method
|
575
|
+
# set_callback :save, :after, :after_method, if: :condition
|
572
576
|
# set_callback :save, :around, ->(r, block) { stuff; result = block.call; stuff }
|
573
577
|
#
|
574
|
-
# The second
|
578
|
+
# The second argument indicates whether the callback is to be run +:before+,
|
575
579
|
# +:after+, or +:around+ the event. If omitted, +:before+ is assumed. This
|
576
580
|
# means the first example above can also be written as:
|
577
581
|
#
|
578
|
-
# set_callback :save, :
|
582
|
+
# set_callback :save, :before_method
|
579
583
|
#
|
580
584
|
# The callback can be specified as a symbol naming an instance method; as a
|
581
|
-
# proc, lambda, or block; as a string to be instance evaluated; or as an
|
585
|
+
# proc, lambda, or block; as a string to be instance evaluated(deprecated); or as an
|
582
586
|
# object that responds to a certain method determined by the <tt>:scope</tt>
|
583
587
|
# argument to +define_callbacks+.
|
584
588
|
#
|
@@ -594,10 +598,12 @@ module ActiveSupport
|
|
594
598
|
#
|
595
599
|
# ===== Options
|
596
600
|
#
|
597
|
-
# * <tt>:if</tt> - A symbol
|
598
|
-
#
|
599
|
-
#
|
600
|
-
#
|
601
|
+
# * <tt>:if</tt> - A symbol, a string or an array of symbols and strings,
|
602
|
+
# each naming an instance method or a proc; the callback will be called
|
603
|
+
# only when they all return a true value.
|
604
|
+
# * <tt>:unless</tt> - A symbol, a string or an array of symbols and
|
605
|
+
# strings, each naming an instance method or a proc; the callback will
|
606
|
+
# be called only when they all return a false value.
|
601
607
|
# * <tt>:prepend</tt> - If +true+, the callback will be prepended to the
|
602
608
|
# existing chain rather than appended.
|
603
609
|
def set_callback(name, *filter_list, &block)
|
@@ -620,19 +626,27 @@ module ActiveSupport
|
|
620
626
|
# class Writer < Person
|
621
627
|
# skip_callback :validate, :before, :check_membership, if: -> { self.age > 18 }
|
622
628
|
# end
|
629
|
+
#
|
630
|
+
# An <tt>ArgumentError</tt> will be raised if the callback has not
|
631
|
+
# already been set (unless the <tt>:raise</tt> option is set to <tt>false</tt>).
|
623
632
|
def skip_callback(name, *filter_list, &block)
|
624
633
|
type, filters, options = normalize_callback_params(filter_list, block)
|
634
|
+
options[:raise] = true unless options.key?(:raise)
|
625
635
|
|
626
636
|
__update_callbacks(name) do |target, chain|
|
627
637
|
filters.each do |filter|
|
628
|
-
|
638
|
+
callback = chain.find {|c| c.matches?(type, filter) }
|
639
|
+
|
640
|
+
if !callback && options[:raise]
|
641
|
+
raise ArgumentError, "#{type.to_s.capitalize} #{name} callback #{filter.inspect} has not been defined"
|
642
|
+
end
|
629
643
|
|
630
|
-
if
|
631
|
-
|
632
|
-
chain.insert(chain.index(
|
644
|
+
if callback && (options.key?(:if) || options.key?(:unless))
|
645
|
+
new_callback = callback.merge_conditional_options(chain, if_option: options[:if], unless_option: options[:unless])
|
646
|
+
chain.insert(chain.index(callback), new_callback)
|
633
647
|
end
|
634
648
|
|
635
|
-
chain.delete(
|
649
|
+
chain.delete(callback)
|
636
650
|
end
|
637
651
|
target.set_callbacks name, chain
|
638
652
|
end
|
@@ -659,21 +673,23 @@ module ActiveSupport
|
|
659
673
|
# ===== Options
|
660
674
|
#
|
661
675
|
# * <tt>:terminator</tt> - Determines when a before filter will halt the
|
662
|
-
# callback chain, preventing following
|
663
|
-
# the event from being triggered.
|
664
|
-
#
|
665
|
-
#
|
676
|
+
# callback chain, preventing following before and around callbacks from
|
677
|
+
# being called and the event from being triggered.
|
678
|
+
# This should be a lambda to be executed.
|
679
|
+
# The current object and the result lambda of the callback will be provided
|
680
|
+
# to the terminator lambda.
|
666
681
|
#
|
667
|
-
# define_callbacks :validate, terminator: ->(target,
|
682
|
+
# define_callbacks :validate, terminator: ->(target, result_lambda) { result_lambda.call == false }
|
668
683
|
#
|
669
684
|
# In this example, if any before validate callbacks returns +false+,
|
670
|
-
#
|
671
|
-
#
|
685
|
+
# any successive before and around callback is not executed.
|
686
|
+
#
|
687
|
+
# The default terminator halts the chain when a callback throws +:abort+.
|
672
688
|
#
|
673
689
|
# * <tt>:skip_after_callbacks_if_terminated</tt> - Determines if after
|
674
690
|
# callbacks should be terminated by the <tt>:terminator</tt> option. By
|
675
|
-
# default after callbacks executed no matter if callback chain was
|
676
|
-
# terminated or not.
|
691
|
+
# default after callbacks are executed no matter if callback chain was
|
692
|
+
# terminated or not. This option makes sense only when <tt>:terminator</tt>
|
677
693
|
# option is specified.
|
678
694
|
#
|
679
695
|
# * <tt>:scope</tt> - Indicates which methods should be executed when an
|
@@ -726,12 +742,12 @@ module ActiveSupport
|
|
726
742
|
options = names.extract_options!
|
727
743
|
|
728
744
|
names.each do |name|
|
729
|
-
class_attribute "_#{name}_callbacks"
|
745
|
+
class_attribute "_#{name}_callbacks", instance_writer: false
|
730
746
|
set_callbacks name, CallbackChain.new(name, options)
|
731
747
|
|
732
748
|
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
733
749
|
def _run_#{name}_callbacks(&block)
|
734
|
-
|
750
|
+
__run_callbacks__(_#{name}_callbacks, &block)
|
735
751
|
end
|
736
752
|
RUBY
|
737
753
|
end
|
@@ -739,13 +755,37 @@ module ActiveSupport
|
|
739
755
|
|
740
756
|
protected
|
741
757
|
|
742
|
-
def get_callbacks(name)
|
758
|
+
def get_callbacks(name) # :nodoc:
|
743
759
|
send "_#{name}_callbacks"
|
744
760
|
end
|
745
761
|
|
746
|
-
def set_callbacks(name, callbacks)
|
762
|
+
def set_callbacks(name, callbacks) # :nodoc:
|
747
763
|
send "_#{name}_callbacks=", callbacks
|
748
764
|
end
|
765
|
+
|
766
|
+
def deprecated_false_terminator # :nodoc:
|
767
|
+
Proc.new do |target, result_lambda|
|
768
|
+
terminate = true
|
769
|
+
catch(:abort) do
|
770
|
+
result = result_lambda.call if result_lambda.is_a?(Proc)
|
771
|
+
if Callbacks.halt_and_display_warning_on_return_false && result == false
|
772
|
+
display_deprecation_warning_for_false_terminator
|
773
|
+
else
|
774
|
+
terminate = false
|
775
|
+
end
|
776
|
+
end
|
777
|
+
terminate
|
778
|
+
end
|
779
|
+
end
|
780
|
+
|
781
|
+
private
|
782
|
+
|
783
|
+
def display_deprecation_warning_for_false_terminator
|
784
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
785
|
+
Returning `false` in Active Record and Active Model callbacks will not implicitly halt a callback chain in Rails 5.1.
|
786
|
+
To explicitly halt the callback chain, please use `throw :abort` instead.
|
787
|
+
MSG
|
788
|
+
end
|
749
789
|
end
|
750
790
|
end
|
751
791
|
end
|
@@ -114,7 +114,7 @@ module ActiveSupport
|
|
114
114
|
return false
|
115
115
|
else
|
116
116
|
return false if base < self
|
117
|
-
@_dependencies.each { |dep| base.
|
117
|
+
@_dependencies.each { |dep| base.include(dep) }
|
118
118
|
super
|
119
119
|
base.extend const_get(:ClassMethods) if const_defined?(:ClassMethods)
|
120
120
|
base.class_eval(&@_included_block) if instance_variable_defined?(:@_included_block)
|
@@ -132,7 +132,7 @@ module ActiveSupport
|
|
132
132
|
end
|
133
133
|
|
134
134
|
def class_methods(&class_methods_module_definition)
|
135
|
-
mod = const_defined?(:ClassMethods) ?
|
135
|
+
mod = const_defined?(:ClassMethods, false) ?
|
136
136
|
const_get(:ClassMethods) :
|
137
137
|
const_set(:ClassMethods, Module.new)
|
138
138
|
|
@@ -1,26 +1,18 @@
|
|
1
|
-
require '
|
2
|
-
require 'monitor'
|
1
|
+
require 'concurrent/atomic/count_down_latch'
|
3
2
|
|
4
3
|
module ActiveSupport
|
5
4
|
module Concurrency
|
6
|
-
class Latch
|
5
|
+
class Latch < Concurrent::CountDownLatch
|
6
|
+
|
7
7
|
def initialize(count = 1)
|
8
|
-
|
9
|
-
|
10
|
-
@cv = @lock.new_cond
|
8
|
+
ActiveSupport::Deprecation.warn("ActiveSupport::Concurrency::Latch is deprecated. Please use Concurrent::CountDownLatch instead.")
|
9
|
+
super(count)
|
11
10
|
end
|
12
11
|
|
13
|
-
|
14
|
-
@lock.synchronize do
|
15
|
-
@count -= 1 if @count > 0
|
16
|
-
@cv.broadcast if @count.zero?
|
17
|
-
end
|
18
|
-
end
|
12
|
+
alias_method :release, :count_down
|
19
13
|
|
20
14
|
def await
|
21
|
-
|
22
|
-
@cv.wait_while { @count > 0 }
|
23
|
-
end
|
15
|
+
wait(nil)
|
24
16
|
end
|
25
17
|
end
|
26
18
|
end
|