lib/active_support/callbacks.rb in activesupport-7.0.0.alpha2 vs lib/active_support/callbacks.rb in activesupport-7.0.0.rc1
- old
+ new
@@ -370,63 +370,160 @@
end
end
# A future invocation of user-supplied code (either as a callback,
# or a condition filter).
- class CallTemplate # :nodoc:
- def initialize(target, method, arguments, block)
- @override_target = target
- @method_name = method
- @arguments = arguments
- @override_block = block
+ module CallTemplate # :nodoc:
+ class MethodCall
+ def initialize(method)
+ @method_name = method
+ end
+
+ # Return the parts needed to make this call, with the given
+ # input values.
+ #
+ # Returns an array of the form:
+ #
+ # [target, block, method, *arguments]
+ #
+ # This array can be used as such:
+ #
+ # target.send(method, *arguments, &block)
+ #
+ # The actual invocation is left up to the caller to minimize
+ # call stack pollution.
+ def expand(target, value, block)
+ [target, block, @method_name]
+ end
+
+ def make_lambda
+ lambda do |target, value, &block|
+ target.send(@method_name, &block)
+ end
+ end
+
+ def inverted_lambda
+ lambda do |target, value, &block|
+ !target.send(@method_name, &block)
+ end
+ end
end
- # Return the parts needed to make this call, with the given
- # input values.
- #
- # Returns an array of the form:
- #
- # [target, block, method, *arguments]
- #
- # This array can be used as such:
- #
- # target.send(method, *arguments, &block)
- #
- # The actual invocation is left up to the caller to minimize
- # call stack pollution.
- def expand(target, value, block)
- expanded = [@override_target || target, @override_block || block, @method_name]
+ class ObjectCall
+ def initialize(target, method)
+ @override_target = target
+ @method_name = method
+ end
- @arguments.each do |arg|
- case arg
- when :value then expanded << value
- when :target then expanded << target
- when :block then expanded << (block || raise(ArgumentError))
+ def expand(target, value, block)
+ [@override_target || target, block, @method_name, target]
+ end
+
+ def make_lambda
+ lambda do |target, value, &block|
+ (@override_target || target).send(@method_name, target, &block)
end
end
- expanded
+ def inverted_lambda
+ lambda do |target, value, &block|
+ !(@override_target || target).send(@method_name, target, &block)
+ end
+ end
end
- # Return a lambda that will make this call when given the input
- # values.
- def make_lambda
- lambda do |target, value, &block|
- target, block, method, *arguments = expand(target, value, block)
- target.send(method, *arguments, &block)
+ class InstanceExec0
+ def initialize(block)
+ @override_block = block
end
+
+ def expand(target, value, block)
+ [target, @override_block, :instance_exec]
+ end
+
+ def make_lambda
+ lambda do |target, value, &block|
+ target.instance_exec(&@override_block)
+ end
+ end
+
+ def inverted_lambda
+ lambda do |target, value, &block|
+ !target.instance_exec(&@override_block)
+ end
+ end
end
- # Return a lambda that will make this call when given the input
- # values, but then return the boolean inverse of that result.
- def inverted_lambda
- lambda do |target, value, &block|
- target, block, method, *arguments = expand(target, value, block)
- ! target.send(method, *arguments, &block)
+ class InstanceExec1
+ def initialize(block)
+ @override_block = block
end
+
+ def expand(target, value, block)
+ [target, @override_block, :instance_exec, target]
+ end
+
+ def make_lambda
+ lambda do |target, value, &block|
+ target.instance_exec(target, &@override_block)
+ end
+ end
+
+ def inverted_lambda
+ lambda do |target, value, &block|
+ !target.instance_exec(target, &@override_block)
+ end
+ end
end
+ class InstanceExec2
+ def initialize(block)
+ @override_block = block
+ end
+
+ def expand(target, value, block)
+ raise ArgumentError unless block
+ [target, @override_block || block, :instance_exec, target, block]
+ end
+
+ def make_lambda
+ lambda do |target, value, &block|
+ raise ArgumentError unless block
+ target.instance_exec(target, block, &@override_block)
+ end
+ end
+
+ def inverted_lambda
+ lambda do |target, value, &block|
+ raise ArgumentError unless block
+ !target.instance_exec(target, block, &@override_block)
+ end
+ end
+ end
+
+ class ProcCall
+ def initialize(target)
+ @override_target = target
+ end
+
+ def expand(target, value, block)
+ [@override_target || target, block, :call, target, value]
+ end
+
+ def make_lambda
+ lambda do |target, value, &block|
+ (@override_target || target).call(target, value, &block)
+ end
+ end
+
+ def inverted_lambda
+ lambda do |target, value, &block|
+ !(@override_target || target).call(target, value, &block)
+ end
+ end
+ end
+
# Filters support:
#
# Symbols:: A method to call.
# Procs:: A proc to call with the object.
# Objects:: An object with a <tt>before_foo</tt> method on it to call.
@@ -434,25 +531,23 @@
# All of these objects are converted into a CallTemplate and handled
# the same after this point.
def self.build(filter, callback)
case filter
when Symbol
- new(nil, filter, [], nil)
+ MethodCall.new(filter)
when Conditionals::Value
- new(filter, :call, [:target, :value], nil)
+ ProcCall.new(filter)
when ::Proc
if filter.arity > 1
- new(nil, :instance_exec, [:target, :block], filter)
+ InstanceExec2.new(filter)
elsif filter.arity > 0
- new(nil, :instance_exec, [:target], filter)
+ InstanceExec1.new(filter)
else
- new(nil, :instance_exec, [], filter)
+ InstanceExec0.new(filter)
end
else
- method_to_call = callback.current_scopes.join("_")
-
- new(filter, method_to_call, [:target], nil)
+ ObjectCall.new(filter, callback.current_scopes.join("_").to_sym)
end
end
end
# Execute before and after filters in a sequence instead of
@@ -606,11 +701,11 @@
end
# This is used internally to append, prepend and skip callbacks to the
# CallbackChain.
def __update_callbacks(name) # :nodoc:
- ([self] + ActiveSupport::DescendantsTracker.descendants(self)).reverse_each do |target|
+ ([self] + self.descendants).reverse_each do |target|
chain = target.get_callbacks name
yield target, chain.dup
end
end
@@ -730,11 +825,11 @@
# Remove all set callbacks for the given event.
def reset_callbacks(name)
callbacks = get_callbacks name
- ActiveSupport::DescendantsTracker.descendants(self).each do |target|
+ self.descendants.each do |target|
chain = target.get_callbacks(name).dup
callbacks.each { |c| chain.delete(c) }
target.set_callbacks name, chain
end
@@ -823,10 +918,10 @@
options = names.extract_options!
names.each do |name|
name = name.to_sym
- ([self] + ActiveSupport::DescendantsTracker.descendants(self)).each do |target|
+ ([self] + self.descendants).each do |target|
target.set_callbacks name, CallbackChain.new(name, options)
end
module_eval <<-RUBY, __FILE__, __LINE__ + 1
def _run_#{name}_callbacks(&block)