class ActiveSupport::Callbacks::Callback
:nodoc:#
def self.build(chain, filter, kind, options)
def self.build(chain, filter, kind, options) new chain.name, filter, kind, options, chain.config end
def apply(callback_sequence)
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)
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