Extends the class object with class and instance accessors for class attributes, just like the native attr* accessors for instance attributes.

class Person
  cattr_accessor :hair_colors
end
Person.hair_colors = [:brown, :black, :blonde, :red]

These class attributes behave something like the class inheritable accessors. But instead of copying the hash over at the time the subclass is first defined, the accessors simply delegate to their superclass unless they have been given a specific value. This stops the strange situation where values set after class definition don't get applied to subclasses.

Methods
C
S
Instance Public methods
cattr_accessor(*syms)
# File activesupport/lib/active_support/core_ext/class/attribute_accessors.rb, line 57
def cattr_accessor(*syms)
  cattr_reader(*syms)
  cattr_writer(*syms)
end
cattr_reader(*syms)
# File activesupport/lib/active_support/core_ext/class/attribute_accessors.rb, line 10
  def cattr_reader(*syms)
    options = syms.extract_options!
    syms.each do |sym|
      next if sym.is_a?(Hash)
      class_eval("        unless defined? @@#{sym}
          @@#{sym} = nil
        end
        def self.#{sym}
          @@#{sym}
        end
", __FILE__, __LINE__ + 1)
      unless options[:instance_reader] == false
        class_eval("          def #{sym}
            @@#{sym}
          end
", __FILE__, __LINE__ + 1)
      end
    end
  end
cattr_writer(*syms)
# File activesupport/lib/active_support/core_ext/class/attribute_accessors.rb, line 34
  def cattr_writer(*syms)
    options = syms.extract_options!
    syms.each do |sym|
      class_eval("        unless defined? @@#{sym}
          @@#{sym} = nil
        end
        def self.#{sym}=(obj)
          @@#{sym} = obj
        end
", __FILE__, __LINE__ + 1)
      unless options[:instance_writer] == false
        class_eval("          def #{sym}=(obj)
            @@#{sym} = obj
          end
", __FILE__, __LINE__ + 1)
      end
    end
  end
class_attribute(*attrs)

Declare a class-level attribute whose value is inheritable and overwritable by subclasses:

class Base
  class_attribute :setting
end
class Subclass < Base
end
Base.setting = true
Subclass.setting            # => true
Subclass.setting = false
Subclass.setting            # => false
Base.setting                # => true

This matches normal Ruby method inheritance: think of writing an attribute on a subclass as overriding the reader method.

For convenience, a query method is defined as well:

Subclass.setting?           # => false

Instances may overwrite the class value in the same way:

Base.setting = true
object = Base.new
object.setting          # => true
object.setting = false
object.setting          # => false
Base.setting            # => true

To opt out of the instance writer method, pass :instance_writer => false.

object.setting = false  # => NoMethodError
# File activesupport/lib/active_support/core_ext/class/attribute.rb, line 40
  def class_attribute(*attrs)
    instance_writer = !attrs.last.is_a?(Hash) || attrs.pop[:instance_writer]
    attrs.each do |name|
      class_eval "        def self.#{name}() nil end
        def self.#{name}?() !!#{name} end
        def self.#{name}=(val)
          singleton_class.class_eval do
            remove_possible_method(:#{name})
            define_method(:#{name}) { val }
          end
        end
        def #{name}
          defined?(@#{name}) ? @#{name} : singleton_class.#{name}
        end
        def #{name}?
          !!#{name}
        end
", __FILE__, __LINE__ + 1
      attr_writer name if instance_writer
    end
  end
superclass_delegating_accessor(*names)
# File activesupport/lib/active_support/core_ext/class/delegating_attributes.rb, line 43
def superclass_delegating_accessor(*names)
  superclass_delegating_reader(*names)
  superclass_delegating_writer(*names)
end
superclass_delegating_reader(*names)
# File activesupport/lib/active_support/core_ext/class/delegating_attributes.rb, line 8
def superclass_delegating_reader(*names)
  class_name_to_stop_searching_on = self.superclass.name.blank? ? "Object" : self.superclass.name
  names.each do |name|
    class_eval <<-EOS
    def self.#{name}                                            # def self.only_reader
      if defined?(@#{name})                                     #   if defined?(@only_reader)
        @#{name}                                                #     @only_reader
      elsif superclass < #{class_name_to_stop_searching_on} &&  #   elsif superclass < Object &&
            superclass.respond_to?(:#{name})                    #         superclass.respond_to?(:only_reader)
        superclass.#{name}                                      #     superclass.only_reader
      end                                                       #   end
    end                                                         # end
    def #{name}                                                 # def only_reader
      self.class.#{name}                                        #   self.class.only_reader
    end                                                         # end
    def self.#{name}?                                           # def self.only_reader?
      !!#{name}                                                 #   !!only_reader
    end                                                         # end
    def #{name}?                                                # def only_reader?
      !!#{name}                                                 #   !!only_reader
    end                                                         # end
    EOS
  end
end
superclass_delegating_writer(*names)
# File activesupport/lib/active_support/core_ext/class/delegating_attributes.rb, line 33
def superclass_delegating_writer(*names)
  names.each do |name|
    class_eval <<-EOS
      def self.#{name}=(value)  # def self.only_writer=(value)
        @#{name} = value        #   @only_writer = value
      end                       # end
    EOS
  end
end