@@ -150,7 +150,7 @@ def run_callbacks(kind, type = nil)
150
150
def halted_callback_hook ( filter , name )
151
151
end
152
152
153
- module Conditionals # :nodoc:
153
+ module Conditionals # :nodoc: all
154
154
class Value
155
155
def initialize ( &block )
156
156
@block = block
@@ -159,128 +159,76 @@ def call(target, value); @block.call(value); end
159
159
end
160
160
end
161
161
162
- module Filters
162
+ module Filters # :nodoc: all
163
163
Environment = Struct . new ( :target , :halted , :value )
164
164
165
165
class Before
166
- def self . build ( callback_sequence , user_callback , user_conditions , chain_config , filter , name )
166
+ def initialize ( user_callback , user_conditions , chain_config , filter , name )
167
167
halted_lambda = chain_config [ :terminator ]
168
-
169
- if user_conditions . any?
170
- halting_and_conditional ( callback_sequence , user_callback , user_conditions , halted_lambda , filter , name )
171
- else
172
- halting ( callback_sequence , user_callback , halted_lambda , filter , name )
173
- end
168
+ @user_callback , @user_conditions , @halted_lambda , @filter , @name = user_callback , user_conditions , halted_lambda , filter , name
169
+ freeze
174
170
end
171
+ attr_reader :user_callback , :user_conditions , :halted_lambda , :filter , :name
175
172
176
- def self . halting_and_conditional ( callback_sequence , user_callback , user_conditions , halted_lambda , filter , name )
177
- callback_sequence . before do |env |
178
- target = env . target
179
- value = env . value
180
- halted = env . halted
173
+ def call ( env )
174
+ target = env . target
175
+ value = env . value
176
+ halted = env . halted
181
177
182
- if !halted && user_conditions . all? { |c | c . call ( target , value ) }
183
- result_lambda = -> { user_callback . call target , value }
184
- env . halted = halted_lambda . call ( target , result_lambda )
185
- if env . halted
186
- target . send :halted_callback_hook , filter , name
187
- end
178
+ if !halted && user_conditions . all? { |c | c . call ( target , value ) }
179
+ result_lambda = -> { user_callback . call target , value }
180
+ env . halted = halted_lambda . call ( target , result_lambda )
181
+ if env . halted
182
+ target . send :halted_callback_hook , filter , name
188
183
end
189
-
190
- env
191
184
end
192
- end
193
- private_class_method :halting_and_conditional
194
-
195
- def self . halting ( callback_sequence , user_callback , halted_lambda , filter , name )
196
- callback_sequence . before do |env |
197
- target = env . target
198
- value = env . value
199
- halted = env . halted
200
185
201
- unless halted
202
- result_lambda = -> { user_callback . call target , value }
203
- env . halted = halted_lambda . call ( target , result_lambda )
204
- if env . halted
205
- target . send :halted_callback_hook , filter , name
206
- end
207
- end
186
+ env
187
+ end
208
188
209
- env
210
- end
189
+ def apply ( callback_sequence )
190
+ callback_sequence . before ( self )
211
191
end
212
- private_class_method :halting
213
192
end
214
193
215
194
class After
216
- def self . build ( callback_sequence , user_callback , user_conditions , chain_config )
217
- if chain_config [ :skip_after_callbacks_if_terminated ]
218
- if user_conditions . any?
219
- halting_and_conditional ( callback_sequence , user_callback , user_conditions )
220
- else
221
- halting ( callback_sequence , user_callback )
222
- end
223
- else
224
- if user_conditions . any?
225
- conditional callback_sequence , user_callback , user_conditions
226
- else
227
- simple callback_sequence , user_callback
228
- end
229
- end
195
+ attr_reader :user_callback , :user_conditions , :halting
196
+ def initialize ( user_callback , user_conditions , chain_config )
197
+ halting = chain_config [ :skip_after_callbacks_if_terminated ]
198
+ @user_callback , @user_conditions , @halting = user_callback , user_conditions , halting
199
+ freeze
230
200
end
231
201
232
- def self . halting_and_conditional ( callback_sequence , user_callback , user_conditions )
233
- callback_sequence . after do |env |
234
- target = env . target
235
- value = env . value
236
- halted = env . halted
237
-
238
- if !halted && user_conditions . all? { |c | c . call ( target , value ) }
239
- user_callback . call target , value
240
- end
202
+ def call ( env )
203
+ target = env . target
204
+ value = env . value
205
+ halted = env . halted
241
206
242
- env
207
+ if ( !halted || !@halting ) && user_conditions . all? { |c | c . call ( target , value ) }
208
+ user_callback . call target , value
243
209
end
244
- end
245
- private_class_method :halting_and_conditional
246
-
247
- def self . halting ( callback_sequence , user_callback )
248
- callback_sequence . after do |env |
249
- unless env . halted
250
- user_callback . call env . target , env . value
251
- end
252
210
253
- env
254
- end
211
+ env
255
212
end
256
- private_class_method :halting
257
-
258
- def self . conditional ( callback_sequence , user_callback , user_conditions )
259
- callback_sequence . after do |env |
260
- target = env . target
261
- value = env . value
262
213
263
- if user_conditions . all? { |c | c . call ( target , value ) }
264
- user_callback . call target , value
265
- end
266
-
267
- env
268
- end
214
+ def apply ( callback_sequence )
215
+ callback_sequence . after ( self )
269
216
end
270
- private_class_method :conditional
217
+ end
271
218
272
- def self . simple ( callback_sequence , user_callback )
273
- callback_sequence . after do |env |
274
- user_callback . call env . target , env . value
219
+ class Around
220
+ def initialize ( user_callback , user_conditions )
221
+ @user_callback , @user_conditions = user_callback , user_conditions
222
+ freeze
223
+ end
275
224
276
- env
277
- end
225
+ def apply ( callback_sequence )
226
+ callback_sequence . around ( @user_callback , @user_conditions )
278
227
end
279
- private_class_method :simple
280
228
end
281
229
end
282
230
283
- class Callback # :nodoc:#
231
+ class Callback # :nodoc:
284
232
def self . build ( chain , filter , kind , options )
285
233
if filter . is_a? ( String )
286
234
raise ArgumentError , <<-MSG . squish
@@ -329,19 +277,26 @@ def duplicates?(other)
329
277
end
330
278
end
331
279
280
+ def compiled
281
+ @compiled ||=
282
+ begin
283
+ user_conditions = conditions_lambdas
284
+ user_callback = CallTemplate . build ( @filter , self )
285
+
286
+ case kind
287
+ when :before
288
+ Filters ::Before . new ( user_callback . make_lambda , user_conditions , chain_config , @filter , name )
289
+ when :after
290
+ Filters ::After . new ( user_callback . make_lambda , user_conditions , chain_config )
291
+ when :around
292
+ Filters ::Around . new ( user_callback , user_conditions )
293
+ end
294
+ end
295
+ end
296
+
332
297
# Wraps code with filter
333
298
def apply ( callback_sequence )
334
- user_conditions = conditions_lambdas
335
- user_callback = CallTemplate . build ( @filter , self )
336
-
337
- case kind
338
- when :before
339
- Filters ::Before . build ( callback_sequence , user_callback . make_lambda , user_conditions , chain_config , @filter , name )
340
- when :after
341
- Filters ::After . build ( callback_sequence , user_callback . make_lambda , user_conditions , chain_config )
342
- when :around
343
- callback_sequence . around ( user_callback , user_conditions )
344
- end
299
+ compiled . apply ( callback_sequence )
345
300
end
346
301
347
302
def current_scopes
@@ -368,14 +323,16 @@ def check_conditionals(conditionals)
368
323
end
369
324
370
325
def conditions_lambdas
371
- @if . map { |c | CallTemplate . build ( c , self ) . make_lambda } +
326
+ conditions =
327
+ @if . map { |c | CallTemplate . build ( c , self ) . make_lambda } +
372
328
@unless . map { |c | CallTemplate . build ( c , self ) . inverted_lambda }
329
+ conditions . empty? ? EMPTY_ARRAY : conditions
373
330
end
374
331
end
375
332
376
333
# A future invocation of user-supplied code (either as a callback,
377
334
# or a condition filter).
378
- module CallTemplate # :nodoc:
335
+ module CallTemplate # :nodoc: all
379
336
class MethodCall
380
337
def initialize ( method )
381
338
@method_name = method
@@ -562,16 +519,18 @@ def initialize(nested = nil, call_template = nil, user_conditions = nil)
562
519
@call_template = call_template
563
520
@user_conditions = user_conditions
564
521
565
- @before = [ ]
566
- @after = [ ]
522
+ @before = nil
523
+ @after = nil
567
524
end
568
525
569
- def before ( &before )
526
+ def before ( before )
527
+ @before ||= [ ]
570
528
@before . unshift ( before )
571
529
self
572
530
end
573
531
574
- def after ( &after )
532
+ def after ( after )
533
+ @after ||= [ ]
575
534
@after . push ( after )
576
535
self
577
536
end
@@ -595,11 +554,11 @@ def expand_call_template(arg, block)
595
554
end
596
555
597
556
def invoke_before ( arg )
598
- @before . each { |b | b . call ( arg ) }
557
+ @before & .each { |b | b . call ( arg ) }
599
558
end
600
559
601
560
def invoke_after ( arg )
602
- @after . each { |a | a . call ( arg ) }
561
+ @after & .each { |a | a . call ( arg ) }
603
562
end
604
563
end
605
564
0 commit comments