Skip to content
Browse files

separate filters from source code

  • Loading branch information...
1 parent 6abbc4a commit 8038f7eb10e0168a0f438d443ab69d61cb396ef5 @tenderlove tenderlove committed
Showing with 31 additions and 20 deletions.
  1. +31 −20 activesupport/lib/active_support/callbacks.rb
View
51 activesupport/lib/active_support/callbacks.rb
@@ -92,20 +92,11 @@ class Callback #:nodoc:#
@@_callback_sequence = 0
class Basic < Callback
- def matches?(_kind, _filter)
- super && @filter == _filter
- end
end
class Object < Callback
- def matches?(_kind, _filter)
- return false unless super
-
- if !_filter.is_a?(String)
- @filter.to_s.start_with?(_method_name_for_object_filter(_kind, _filter, false))
- else
- @filter == _filter
- end
+ def duplicates?(other)
+ false
end
end
@@ -127,7 +118,8 @@ def initialize(chain, filter, kind, options, klass)
normalize_options!(options)
@raw_filter, @options = filter, options
- @filter = _compile_filter(filter)
+ @filter = _compile_filter(filter)
+ @source = _compile_source(filter)
recompile_options!
end
@@ -161,7 +153,7 @@ def next_id
end
def matches?(_kind, _filter)
- @kind == _kind
+ @kind == _kind && filter == _filter
end
def duplicates?(other)
@@ -191,7 +183,7 @@ def apply(code)
# This double assignment is to prevent warnings in 1.9.3 as
# the `result` variable is not always used except if the
# terminator code refers to it.
- result = result = #{@filter}
+ result = result = #{@source}
halted = (#{chain.config[:terminator]})
if halted
halted_callback_hook(#{@raw_filter.inspect.inspect})
@@ -203,7 +195,7 @@ def apply(code)
<<-RUBY_EVAL
#{code}
if #{!chain.config[:skip_after_callbacks_if_terminated] || "!halted"} && #{@compiled_options}
- #{@filter}
+ #{@source}
end
RUBY_EVAL
when :around
@@ -238,7 +230,7 @@ def define_conditional_callback
@klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
def #{name}(halted)
if #{@compiled_options} && !halted
- #{@filter} do
+ #{@source} do
yield self
end
else
@@ -256,11 +248,11 @@ def recompile_options!
conditions = ["true"]
unless options[:if].empty?
- conditions << Array(_compile_filter(options[:if]))
+ conditions << Array(_compile_source(options[:if]))
end
unless options[:unless].empty?
- conditions << Array(_compile_filter(options[:unless])).map {|f| "!#{f}"}
+ conditions << Array(_compile_source(options[:unless])).map {|f| "!#{f}"}
end
@compiled_options = conditions.flatten.join(" && ")
@@ -276,6 +268,25 @@ def _method_name_for_object_filter(kind, filter, append_next_id = true)
method_name
end
+ def _compile_filter(filter)
+ case filter
+ when Array
+ filter.map {|f| _compile_filter(f)}
+ when Symbol
+ filter
+ when String
+ "(#{filter})"
+ when Proc
+ method_name = "_callback_#{@kind}_#{next_id}"
+ @klass.send(:define_method, method_name, &filter)
+ return method_name if filter.arity <= 0
+
+ method_name << (filter.arity == 1 ? "(self)" : " self, Proc.new ")
+ else
+ filter
+ end
+ end
+
# Filters support:
#
# Arrays:: Used in conditions. This is used to specify
@@ -296,10 +307,10 @@ def _method_name_for_object_filter(kind, filter, append_next_id = true)
# Objects::
# a method is created that calls the before_foo method
# on the object.
- def _compile_filter(filter)
+ def _compile_source(filter)
case filter
when Array
- filter.map {|f| _compile_filter(f)}
+ filter.map {|f| _compile_source(f)}
when Symbol
filter
when String

0 comments on commit 8038f7e

Please sign in to comment.
Something went wrong with that request. Please try again.