# class Class

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

Note that unlike `class_attribute`, if a subclass changes the value then that would also change the value for parent class. Similarly if parent class changes the value then that would change the value of subclasses too.

    class Person
      cattr_accessor :hair_colors
    end

    Person.hair_colors = [:brown, :black, :blonde, :red]
    Person.hair_colors     # => [:brown, :black, :blonde, :red]
    Person.new.hair_colors # => [:brown, :black, :blonde, :red]

To opt out of the instance writer method, pass :instance_writer => false. To opt out of the instance reader method, pass :instance_reader => false. To opt out of both instance methods, pass :instance_accessor => false.

    class Person
      cattr_accessor :hair_colors, :instance_writer => false, :instance_reader => false
    end

    Person.new.hair_colors = [:brown]  # => NoMethodError
    Person.new.hair_colors             # => NoMethodError

### Public Instance Methods

cattr_accessor(*syms, &blk) click to toggle source

    # File lib/active_support/core_ext/class/attribute_accessors.rb, line 76
    def cattr_accessor(*syms, &blk)
      cattr_reader(*syms)
      cattr_writer(*syms, &blk)
    end

cattr_reader(*syms) click to toggle source

    # File lib/active_support/core_ext/class/attribute_accessors.rb, line 29
      def cattr_reader(*syms)
        options = syms.extract_options!
        syms.each do |sym|
          class_eval("        unless defined? @@#{sym}
              @@#{sym} = nil
            end

            def self.#{sym}
              @@#{sym}
            end
    ", __FILE__, __LINE__ + 1)

          unless options[:instance_reader] == false || options[:instance_accessor] == false
            class_eval("          def #{sym}
                @@#{sym}
              end
    ", __FILE__, __LINE__ + 1)
          end
        end
      end

cattr_writer(*syms) { || ... } click to toggle source

    # File lib/active_support/core_ext/class/attribute_accessors.rb, line 52
      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 || options[:instance_accessor] == false
            class_eval("          def #{sym}=(obj)
                @@#{sym} = obj
              end
    ", __FILE__, __LINE__ + 1)
          end
          self.send("#{sym}=", yield) if block_given?
        end
      end

class_attribute(*attrs) click to toggle source

Declare a class-level attribute whose value is inheritable by subclasses. Subclasses can change their own value and it will not impact parent class.

    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

In the above case as long as Subclass does not assign a value to setting by performing `Subclass.setting = something` , `Subclass.setting` would read value assigned to parent class. Once Subclass assigns a value then the value assigned by Subclass would be returned.

This matches normal Ruby method inheritance: think of writing an attribute on a subclass as overriding the reader method. However, you need to be aware when using `class_attribute` with mutable structures as `Array` or `Hash`. In such cases, you don’t want to do changes in places but use setters:

    Base.setting = []
    Base.setting                # => []
    Subclass.setting            # => []

    # Appending in child changes both parent and child because it is the same object:
    Subclass.setting << :foo
    Base.setting               # => [:foo]
    Subclass.setting           # => [:foo]

    # Use setters to not propagate changes:
    Base.setting = []
    Subclass.setting += [:foo]
    Base.setting               # => []
    Subclass.setting           # => [:foo]

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 reader method, pass :instance_reader => false.

    object.setting          # => NoMethodError
    object.setting?         # => NoMethodError

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

    object.setting = false  # => NoMethodError

    # File lib/active_support/core_ext/class/attribute.rb, line 68
      def class_attribute(*attrs)
        options = attrs.extract_options!
        instance_reader = options.fetch(:instance_reader, true)
        instance_writer = options.fetch(:instance_writer, true)

        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

              if singleton_class?
                class_eval do
                  remove_possible_method(:#{name})
                  def #{name}
                    defined?(@#{name}) ? @#{name} : singleton_class.#{name}
                  end
                end
              end
              val
            end

            if instance_reader
              remove_possible_method :#{name}
              def #{name}
                defined?(@#{name}) ? @#{name} : self.class.#{name}
              end

              def #{name}?
                !!#{name}
              end
            end
    ", __FILE__, __LINE__ + 1

          attr_writer name if instance_writer
        end
      end

duplicable?() click to toggle source

Classes are not duplicable:

    c = Class.new # => #<Class:0x10328fd80>
    c.dup         # => #<Class:0x10328fd80>

Note `dup` returned the same class object.

    # File lib/active_support/core_ext/object/duplicable.rb, line 91
    def duplicable?
      false
    end

superclass_delegating_accessor(name, options = {}) click to toggle source

    # File lib/active_support/core_ext/class/delegating_attributes.rb, line 7
    def superclass_delegating_accessor(name, options = {})
      # Create private _name and _name= methods that can still be used if the public
      # methods are overridden. This allows
      _superclass_delegating_accessor("_#{name}")

      # Generate the public methods name, name=, and name?
      # These methods dispatch to the private _name, and _name= methods, making them
      # overridable
      singleton_class.send(:define_method, name) { send("_#{name}") }
      singleton_class.send(:define_method, "#{name}?") { !!send("_#{name}") }
      singleton_class.send(:define_method, "#{name}=") { |value| send("_#{name}=", value) }

      # If an instance_reader is needed, generate methods for name and name= on the
      # class itself, so instances will be able to see them
      define_method(name) { send("_#{name}") } if options[:instance_reader] != false
      define_method("#{name}?") { !!send("#{name}") } if options[:instance_reader] != false
    end