aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@gmail.com>2010-06-12 09:00:45 +0200
committerJosé Valim <jose.valim@gmail.com>2010-06-12 09:54:18 +0200
commit50ec0d9b2ec864c819cf7b053c756c09b2367379 (patch)
tree4dca43f4dc2755029ad61b768ddbff4b4a815d6c /activesupport/lib
parentf0963e2ab0d39e951d772465ec4c8d07b8a4a3d7 (diff)
downloadrails-50ec0d9b2ec864c819cf7b053c756c09b2367379.tar.gz
rails-50ec0d9b2ec864c819cf7b053c756c09b2367379.tar.bz2
rails-50ec0d9b2ec864c819cf7b053c756c09b2367379.zip
Simplify and optimize callbacks superclass sync.
Diffstat (limited to 'activesupport/lib')
-rw-r--r--activesupport/lib/active_support/callbacks.rb75
1 files changed, 21 insertions, 54 deletions
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb
index ba15043bde..16fdfd04e9 100644
--- a/activesupport/lib/active_support/callbacks.rb
+++ b/activesupport/lib/active_support/callbacks.rb
@@ -1,5 +1,6 @@
require 'active_support/core_ext/array/wrap'
require 'active_support/core_ext/class/inheritable_attributes'
+require 'active_support/core_ext/class/subclasses'
require 'active_support/core_ext/kernel/reporting'
require 'active_support/core_ext/kernel/singleton_class'
@@ -383,21 +384,12 @@ module ActiveSupport
# key. See #define_callbacks for more information.
#
def __define_runner(symbol) #:nodoc:
- send("_update_#{symbol}_superclass_callbacks")
body = send("_#{symbol}_callbacks").compile(nil)
silence_warnings do
undef_method "_run_#{symbol}_callbacks" if method_defined?("_run_#{symbol}_callbacks")
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
def _run_#{symbol}_callbacks(key = nil, &blk)
- @_initialized_#{symbol}_callbacks ||= begin
- if self.class.send("_update_#{symbol}_superclass_callbacks")
- self.class.__define_runner(#{symbol.inspect})
- return _run_#{symbol}_callbacks(key, &blk)
- end
- true
- end
-
if key
name = "_run__\#{self.class.name.hash.abs}__#{symbol}__\#{key.hash.abs}__callbacks"
@@ -432,16 +424,15 @@ module ActiveSupport
# CallbackChain.
#
def __update_callbacks(name, filters = [], block = nil) #:nodoc:
- send("_update_#{name}_superclass_callbacks")
-
type = [:before, :after, :around].include?(filters.first) ? filters.shift : :before
options = filters.last.is_a?(Hash) ? filters.pop : {}
filters.unshift(block) if block
- chain = send("_#{name}_callbacks")
- yield chain, type, filters, options if block_given?
-
- __define_runner(name)
+ ([self] + self.descendents).each do |target|
+ chain = target.send("_#{name}_callbacks")
+ yield chain, type, filters, options
+ target.__define_runner(name)
+ end
end
# Set callbacks for a previously defined callback.
@@ -471,14 +462,18 @@ module ActiveSupport
# is a speed improvement for ActionPack.
#
def set_callback(name, *filter_list, &block)
+ mapped = nil
+
__update_callbacks(name, filter_list, block) do |chain, type, filters, options|
- filters.map! do |filter|
- removed = chain.delete_if {|c| c.matches?(type, filter) }
- send("_removed_#{name}_callbacks").push(*removed)
+ mapped ||= filters.map do |filter|
Callback.new(chain, filter, type, options.dup, self)
end
- options[:prepend] ? chain.unshift(*filters) : chain.push(*filters)
+ filters.each do |filter|
+ chain.delete_if {|c| c.matches?(type, filter) }
+ end
+
+ options[:prepend] ? chain.unshift(*mapped) : chain.push(*mapped)
end
end
@@ -496,7 +491,6 @@ module ActiveSupport
end
chain.delete(filter)
- send("_removed_#{name}_callbacks") << filter
end
end
end
@@ -505,8 +499,14 @@ module ActiveSupport
#
def reset_callbacks(symbol)
callbacks = send("_#{symbol}_callbacks")
+
+ self.descendents.each do |target|
+ chain = target.send("_#{symbol}_callbacks")
+ callbacks.each { |c| chain.delete(c) }
+ target.__define_runner(symbol)
+ end
+
callbacks.clear
- send("_removed_#{symbol}_callbacks").concat(callbacks)
__define_runner(symbol)
end
@@ -559,39 +559,6 @@ module ActiveSupport
extlib_inheritable_reader("_#{callback}_callbacks") do
CallbackChain.new(callback, config)
end
-
- extlib_inheritable_reader("_removed_#{callback}_callbacks") do
- []
- end
-
- class_eval <<-METHOD, __FILE__, __LINE__ + 1
- def self._#{callback}_superclass_callbacks
- if superclass.respond_to?(:_#{callback}_callbacks)
- superclass._#{callback}_callbacks + superclass._#{callback}_superclass_callbacks
- else
- []
- end
- end
-
- def self._update_#{callback}_superclass_callbacks
- changed, index = false, 0
-
- callbacks = (_#{callback}_superclass_callbacks -
- _#{callback}_callbacks) - _removed_#{callback}_callbacks
-
- callbacks.each do |callback|
- if new_index = _#{callback}_callbacks.index(callback)
- index = new_index + 1
- else
- changed = true
- _#{callback}_callbacks.insert(index, callback)
- index = index + 1
- end
- end
- changed
- end
- METHOD
-
__define_runner(callback)
end
end