提交 ae44bf7c 编写于 作者: J Josh Kalderimis 提交者: José Valim

bye bye extlib_inheritable_*, AS callbacks now using class_attribute

Signed-off-by: NJosé Valim <jose.valim@gmail.com>
上级 43e2e10f
require 'active_support/descendants_tracker'
require 'active_support/core_ext/array/wrap'
require 'active_support/core_ext/class/inheritable_attributes'
require 'active_support/core_ext/class/attribute'
require 'active_support/core_ext/kernel/reporting'
require 'active_support/core_ext/kernel/singleton_class'
......@@ -437,7 +437,7 @@ def __update_callbacks(name, filters = [], block = nil) #:nodoc:
([self] + ActiveSupport::DescendantsTracker.descendants(self)).each do |target|
chain = target.send("_#{name}_callbacks")
yield chain, type, filters, options
yield target, chain.dup, type, filters, options
target.__define_runner(name)
end
end
......@@ -473,7 +473,7 @@ def __update_callbacks(name, filters = [], block = nil) #:nodoc:
def set_callback(name, *filter_list, &block)
mapped = nil
__update_callbacks(name, filter_list, block) do |chain, type, filters, options|
__update_callbacks(name, filter_list, block) do |target, chain, type, filters, options|
mapped ||= filters.map do |filter|
Callback.new(chain, filter, type, options.dup, self)
end
......@@ -483,6 +483,8 @@ def set_callback(name, *filter_list, &block)
end
options[:prepend] ? chain.unshift(*(mapped.reverse)) : chain.push(*mapped)
target.send("_#{name}_callbacks=", chain)
end
end
......@@ -493,7 +495,7 @@ def set_callback(name, *filter_list, &block)
# end
#
def skip_callback(name, *filter_list, &block)
__update_callbacks(name, filter_list, block) do |chain, type, filters, options|
__update_callbacks(name, filter_list, block) do |target, chain, type, filters, options|
filters.each do |filter|
filter = chain.find {|c| c.matches?(type, filter) }
......@@ -505,6 +507,7 @@ def skip_callback(name, *filter_list, &block)
chain.delete(filter)
end
target.send("_#{name}_callbacks=", chain)
end
end
......@@ -514,12 +517,14 @@ def reset_callbacks(symbol)
callbacks = send("_#{symbol}_callbacks")
ActiveSupport::DescendantsTracker.descendants(self).each do |target|
chain = target.send("_#{symbol}_callbacks")
chain = target.send("_#{symbol}_callbacks").dup
callbacks.each { |c| chain.delete(c) }
target.send("_#{symbol}_callbacks=", chain)
target.__define_runner(symbol)
end
callbacks.clear
self.send("_#{symbol}_callbacks=", callbacks.dup.clear)
__define_runner(symbol)
end
......@@ -589,9 +594,8 @@ def reset_callbacks(symbol)
def define_callbacks(*callbacks)
config = callbacks.last.is_a?(Hash) ? callbacks.pop : {}
callbacks.each do |callback|
extlib_inheritable_reader("_#{callback}_callbacks") do
CallbackChain.new(callback, config)
end
class_attribute "_#{callback}_callbacks"
send("_#{callback}_callbacks=", CallbackChain.new(callback, config))
__define_runner(callback)
end
end
......
......@@ -169,86 +169,3 @@ def inherited_with_inheritable_attributes(child)
alias inherited_without_inheritable_attributes inherited
alias inherited inherited_with_inheritable_attributes
end
class Class
# Defines class-level inheritable attribute reader. Attributes are available to subclasses,
# each subclass has a copy of parent's attribute.
#
# @param *syms<Array[#to_s]> Array of attributes to define inheritable reader for.
# @return <Array[#to_s]> Array of attributes converted into inheritable_readers.
#
# @api public
#
# @todo Do we want to block instance_reader via :instance_reader => false
# @todo It would be preferable that we do something with a Hash passed in
# (error out or do the same as other methods above) instead of silently
# moving on). In particular, this makes the return value of this function
# less useful.
def extlib_inheritable_reader(*ivars, &block)
options = ivars.extract_options!
ivars.each do |ivar|
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
def self.#{ivar}
return @#{ivar} if self.object_id == #{self.object_id} || defined?(@#{ivar})
ivar = superclass.#{ivar}
return nil if ivar.nil? && !#{self}.instance_variable_defined?("@#{ivar}")
@#{ivar} = ivar.duplicable? ? ivar.dup : ivar
end
RUBY
unless options[:instance_reader] == false
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{ivar}
self.class.#{ivar}
end
RUBY
end
instance_variable_set(:"@#{ivar}", yield) if block_given?
end
end
# Defines class-level inheritable attribute writer. Attributes are available to subclasses,
# each subclass has a copy of parent's attribute.
#
# @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to
# define inheritable writer for.
# @option syms :instance_writer<Boolean> if true, instance-level inheritable attribute writer is defined.
# @return <Array[#to_s]> An Array of the attributes that were made into inheritable writers.
#
# @api public
#
# @todo We need a style for class_eval <<-HEREDOC. I'd like to make it
# class_eval(<<-RUBY, __FILE__, __LINE__), but we should codify it somewhere.
def extlib_inheritable_writer(*ivars)
options = ivars.extract_options!
ivars.each do |ivar|
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
def self.#{ivar}=(obj)
@#{ivar} = obj
end
RUBY
unless options[:instance_writer] == false
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{ivar}=(obj) self.class.#{ivar} = obj end
RUBY
end
self.send("#{ivar}=", yield) if block_given?
end
end
# Defines class-level inheritable attribute accessor. Attributes are available to subclasses,
# each subclass has a copy of parent's attribute.
#
# @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to
# define inheritable accessor for.
# @option syms :instance_writer<Boolean> if true, instance-level inheritable attribute writer is defined.
# @return <Array[#to_s]> An Array of attributes turned into inheritable accessors.
#
# @api public
def extlib_inheritable_accessor(*syms, &block)
extlib_inheritable_reader(*syms)
extlib_inheritable_writer(*syms, &block)
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册