class ActiveSupport::Callbacks::CallTemplate

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

def self.build(filter, callback)

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

Objects:: An object with a before_foo method on it to call.
Procs:: A proc to call with the object.
Symbols:: A method to call.

Filters support:
def self.build(filter, callback)
  case filter
  when Symbol
    new(nil, filter, [], nil)
  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

def expand(target, value, block)

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

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

This array can be used as such:

[target, block, method, *arguments]

Returns an array of the form:

input values.
Return the parts needed to make this call, with the given
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

def initialize(target, method, arguments, block)

:nodoc:
or a condition filter).
A future invocation of user-supplied code (either as a callback,
def initialize(target, method, arguments, block)
  @override_target = target
  @method_name = method
  @arguments = arguments
  @override_block = block
end

def inverted_lambda

values, but then return the boolean inverse of that result.
Return a lambda that will make this call when given the input
def inverted_lambda
  lambda do |target, value, &block|
    target, block, method, *arguments = expand(target, value, block)
    ! target.send(method, *arguments, &block)
  end
end

def make_lambda

values.
Return a lambda that will make this call when given the input
def make_lambda
  lambda do |target, value, &block|
    target, block, method, *arguments = expand(target, value, block)
    target.send(method, *arguments, &block)
  end
end