Class: ActiveSupport::Callbacks::CallTemplate

Inherits:
Object
  • Object
show all
Defined in:
lib/active_support/callbacks.rb

Overview

A future invocation of user-supplied code (either as a callback, or a condition filter).

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(target, method, arguments, block) ⇒ CallTemplate

:nodoc:



370
371
372
373
374
375
# File 'lib/active_support/callbacks.rb', line 370

def initialize(target, method, arguments, block)
  @override_target = target
  @method_name = method
  @arguments = arguments
  @override_block = block
end

Class Method Details

.build(filter, callback) ⇒ Object

Filters support:

Symbols:: A method to call.
Strings:: Some content to evaluate.
Procs::   A proc to call with the object.
Objects:: An object with a <tt>before_foo</tt> method on it to call.

All of these objects are converted into a CallTemplate and handled the same after this point.



435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
# File 'lib/active_support/callbacks.rb', line 435

def self.build(filter, callback)
  case filter
  when Symbol
    new(nil, filter, [], nil)
  when String
    new(nil, :instance_exec, [:value], compile_lambda(filter))
  when Conditionals::Value
    new(filter, :call, [:target, :value], nil)
  when ::Proc
    if filter.arity > 1
      new(nil, :instance_exec, [:target, :block], filter)
    elsif filter.arity > 0
      new(nil, :instance_exec, [:target], filter)
    else
      new(nil, :instance_exec, [], filter)
    end
  else
    method_to_call = callback.current_scopes.join("_")

    new(filter, method_to_call, [:target], nil)
  end
end

.compile_lambda(filter) ⇒ Object



458
459
460
# File 'lib/active_support/callbacks.rb', line 458

def self.compile_lambda(filter)
  eval("lambda { |value| #{filter} }")
end

Instance Method Details

#expand(target, value, block) ⇒ Object

Return the parts needed to make this call, with the given input values.

Returns an array of the form:

[target, block, method, *arguments]

This array can be used as such:

target.send(method, *arguments, &block)

The actual invocation is left up to the caller to minimize call stack pollution.



390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
# File 'lib/active_support/callbacks.rb', line 390

def expand(target, value, block)
  result = @arguments.map { |arg|
    case arg
    when :value; value
    when :target; target
    when :block; block || raise(ArgumentError)
    end
  }

  result.unshift @method_name
  result.unshift @override_block || block
  result.unshift @override_target || target

  # target, block, method, *arguments = result
  # target.send(method, *arguments, &block)
  result
end

#inverted_lambdaObject

Return a lambda that will make this call when given the input values, but then return the boolean inverse of that result.



419
420
421
422
423
424
# File 'lib/active_support/callbacks.rb', line 419

def inverted_lambda
  lambda do |target, value, &block|
    target, block, method, *arguments = expand(target, value, block)
    ! target.send(method, *arguments, &block)
  end
end

#make_lambdaObject

Return a lambda that will make this call when given the input values.



410
411
412
413
414
415
# File 'lib/active_support/callbacks.rb', line 410

def make_lambda
  lambda do |target, value, &block|
    target, block, method, *arguments = expand(target, value, block)
    target.send(method, *arguments, &block)
  end
end