Class Index [+]

Quicksearch

ActiveSupport::Concern

A typical module looks like this:

  module M
    def self.included(base)
      base.extend ClassMethods
      scope :disabled, where(:disabled => true)
    end

    module ClassMethods
      ...
    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 :disabled, where(:disabled => true)
    end

    module ClassMethods
      ...
    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)
      base.class_eval do
        def self.method_injected_by_foo
          ...
        end
      end
    end
  end

  module Bar
    def self.included(base)
      base.method_injected_by_foo
    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 Bar
    include Foo 
    def self.included(base)
      base.method_injected_by_foo
    end
  end

  class Host
    include Bar
  end

Unfortunately this won’t work, since when Foo is included, its base is the Bar module, not the 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.method_injected_by_foo
          ...
        end
      end
    end
  end

  module Bar
    extend ActiveSupport::Concern
    include Foo

    included do
      self.method_injected_by_foo
    end
  end

  class Host
    include Bar # works, Bar takes care now of its dependencies
  end

Public Class Methods

extended(base) click to toggle source
     # File lib/active_support/concern.rb, line 101
101:     def self.extended(base)
102:       base.instance_variable_set("@_dependencies", [])
103:     end

Public Instance Methods

append_features(base) click to toggle source
     # File lib/active_support/concern.rb, line 105
105:     def append_features(base)
106:       if base.instance_variable_defined?("@_dependencies")
107:         base.instance_variable_get("@_dependencies") << self
108:         return false
109:       else
110:         return false if base < self
111:         @_dependencies.each { |dep| base.send(:include, dep) }
112:         super
113:         base.extend const_get("ClassMethods") if const_defined?("ClassMethods")
114:         if const_defined?("InstanceMethods")
115:           base.send :include, const_get("InstanceMethods")
116:           ActiveSupport::Deprecation.warn "The InstanceMethods module inside ActiveSupport::Concern will be "              "no longer included automatically. Please define instance methods directly in #{self} instead.", caller
117:         end
118:         base.class_eval(&@_included_block) if instance_variable_defined?("@_included_block")
119:       end
120:     end
included(base = nil, &block) click to toggle source
     # File lib/active_support/concern.rb, line 123
123:     def included(base = nil, &block)
124:       if base.nil?
125:         @_included_block = block
126:       else
127:         super
128:       end
129:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.