class ActiveSupport::Callbacks::Callback

:nodoc:#

def self.build(chain, filter, kind, options)

:nodoc:#
def self.build(chain, filter, kind, options)
  new chain.name, filter, kind, options, chain.config
end

def apply(callback_sequence)

Wraps code with filter
def apply(callback_sequence)
  user_conditions = conditions_lambdas
  user_callback = make_lambda @filter
  case kind
  when :before
    Filters::Before.build(callback_sequence, user_callback, user_conditions, chain_config, @filter)
  when :after
    Filters::After.build(callback_sequence, user_callback, user_conditions, chain_config)
  when :around
    Filters::Around.build(callback_sequence, user_callback, user_conditions, chain_config)
  end
end

def compute_identifier(filter)

def compute_identifier(filter)
  case filter
  when String, ::Proc
    filter.object_id
  else
    filter
  end
end

def conditions_lambdas

def conditions_lambdas
  @if.map { |c| make_lambda c } +
    @unless.map { |c| invert_lambda make_lambda c }
end

def duplicates?(other)

def duplicates?(other)
  case @filter
  when Symbol, String
    matches?(other.kind, other.filter)
  else
    false
  end
end

def filter; @key; end

def filter; @key; end

def initialize(name, filter, kind, options, chain_config)

def initialize(name, filter, kind, options, chain_config)
  @chain_config  = chain_config
  @name    = name
  @kind    = kind
  @filter  = filter
  @key     = compute_identifier filter
  @if      = Array(options[:if])
  @unless  = Array(options[:unless])
end

def invert_lambda(l)

def invert_lambda(l)
  lambda { |*args, &blk| !l.call(*args, &blk) }
end

def make_lambda(filter)

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

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

Filters support:
def make_lambda(filter)
  case filter
  when Symbol
    lambda { |target, _, &blk| target.send filter, &blk }
  when String
    l = eval "lambda { |value| #{filter} }"
    lambda { |target, value| target.instance_exec(value, &l) }
  when Conditionals::Value then filter
  when ::Proc
    if filter.arity > 1
      return lambda { |target, _, &block|
        raise ArgumentError unless block
        target.instance_exec(target, block, &filter)
      }
    end
    if filter.arity <= 0
      lambda { |target, _| target.instance_exec(&filter) }
    else
      lambda { |target, _| target.instance_exec(target, &filter) }
    end
  else
    scopes = Array(chain_config[:scope])
    method_to_call = scopes.map{ |s| public_send(s) }.join("_")
    lambda { |target, _, &blk|
      filter.public_send method_to_call, target, &blk
    }
  end
end

def matches?(_kind, _filter)

def matches?(_kind, _filter)
  @kind == _kind && filter == _filter
end

def merge(chain, new_options)

def merge(chain, new_options)
  options = {
    :if     => @if.dup,
    :unless => @unless.dup
  }
  options[:if].concat     Array(new_options.fetch(:unless, []))
  options[:unless].concat Array(new_options.fetch(:if, []))
  self.class.build chain, @filter, @kind, options
end

def raw_filter; @filter; end

def raw_filter; @filter; end