diff --git a/activesupport/lib/active_support/concern.rb b/activesupport/lib/active_support/concern.rb index 6781082786e53..d1e03e596cc16 100644 --- a/activesupport/lib/active_support/concern.rb +++ b/activesupport/lib/active_support/concern.rb @@ -1,119 +1,119 @@ -# A typical module looks like this: -# -# module M -# def self.included(base) -# base.send(:extend, ClassMethods) -# base.send(:include, InstanceMethods) -# scope :foo, :conditions => { :created_at => nil } -# end -# -# module ClassMethods -# def cm; puts 'I am a class method'; end -# end -# -# module InstanceMethods -# def im; puts 'I am an instance method'; end -# end -# end -# -# By using ActiveSupport::Concern the above module could instead be written as: -# -# require 'active_support/concern' -# -# module M -# extend ActiveSupport::Concern -# -# included do -# scope :foo, :conditions => { :created_at => nil } -# end -# -# module ClassMethods -# def cm; puts 'I am a class method'; end -# end -# -# module InstanceMethods -# def im; puts 'I am an instance method'; end -# end -# end -# -# Moreover, it gracefully handles module dependencies. Given a Foo module and a Bar module which depends on the former, we would typically write the following: -# -# module Foo -# def self.included(base) -# # Define some :enhanced_method for Host class -# base.class_eval do -# def self.enhanced_method -# # Do enhanced stuff -# end -# end -# end -# end -# -# module Bar -# def self.included(base) -# base.send(:enhanced_method) -# end -# end -# -# class Host -# include Foo # We need to include this dependency for Bar -# include Bar # Bar is the module that Host really needs -# end -# -# But why should Host care about Bar's dependencies, namely Foo? We could try to hide these from Host directly including Foo in Bar: -# -# module Foo -# def self.included(base) -# # Define some :enhanced_method for Host class -# base.class_eval do -# def self.enhanced_method -# # Do enhanced stuff -# end -# end -# end -# end -# -# module Bar -# include Foo -# def self.included(base) -# base.send(:enhanced_method) -# end -# end -# -# class Host -# include Bar -# end -# -# Unfortunately this won't work, since when Foo is included, its base is Bar module, not Host class. -# With ActiveSupport::Concern, module dependencies are properly resolved: -# -# require 'active_support/concern' -# -# module Foo -# extend ActiveSupport::Concern -# included do -# class_eval do -# def self.enhanced_method -# # Do enhanced stuff -# end -# end -# end -# end -# -# module Bar -# extend ActiveSupport::Concern -# include Foo -# -# included do -# self.send(:enhanced_method) -# end -# end -# -# class Host -# include Bar # Host only needs to care about Bar without needing to know about its dependencies -# end -# module ActiveSupport + # A typical module looks like this: + # + # module M + # def self.included(base) + # base.send(:extend, ClassMethods) + # base.send(:include, InstanceMethods) + # scope :foo, :conditions => { :created_at => nil } + # end + # + # module ClassMethods + # def cm; puts 'I am a class method'; end + # end + # + # module InstanceMethods + # def im; puts 'I am an instance method'; end + # end + # end + # + # By using ActiveSupport::Concern the above module could instead be written as: + # + # require 'active_support/concern' + # + # module M + # extend ActiveSupport::Concern + # + # included do + # scope :foo, :conditions => { :created_at => nil } + # end + # + # module ClassMethods + # def cm; puts 'I am a class method'; end + # end + # + # module InstanceMethods + # def im; puts 'I am an instance method'; end + # end + # end + # + # Moreover, it gracefully handles module dependencies. Given a Foo module and a Bar module which depends on the former, we would typically write the following: + # + # module Foo + # def self.included(base) + # # Define some :enhanced_method for Host class + # base.class_eval do + # def self.enhanced_method + # # Do enhanced stuff + # end + # end + # end + # end + # + # module Bar + # def self.included(base) + # base.send(:enhanced_method) + # end + # end + # + # class Host + # include Foo # We need to include this dependency for Bar + # include Bar # Bar is the module that Host really needs + # end + # + # But why should Host care about Bar's dependencies, namely Foo? We could try to hide these from Host directly including Foo in Bar: + # + # module Foo + # def self.included(base) + # # Define some :enhanced_method for Host class + # base.class_eval do + # def self.enhanced_method + # # Do enhanced stuff + # end + # end + # end + # end + # + # module Bar + # include Foo + # def self.included(base) + # base.send(:enhanced_method) + # end + # end + # + # class Host + # include Bar + # end + # + # Unfortunately this won't work, since when Foo is included, its base is Bar module, not Host class. + # With ActiveSupport::Concern, module dependencies are properly resolved: + # + # require 'active_support/concern' + # + # module Foo + # extend ActiveSupport::Concern + # included do + # class_eval do + # def self.enhanced_method + # # Do enhanced stuff + # end + # end + # end + # end + # + # module Bar + # extend ActiveSupport::Concern + # include Foo + # + # included do + # self.send(:enhanced_method) + # end + # end + # + # class Host + # include Bar # Host only needs to care about Bar without needing to know about its dependencies + # end + # module Concern def self.extended(base) base.instance_variable_set("@_dependencies", [])