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.
# File lib/active_support/core_ext/class/attribute_accessors.rb, line 57 def cattr_accessor(*syms) cattr_reader(*syms) cattr_writer(*syms) end
# File 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
# File 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
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 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
# File 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
# File 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 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 end end
# File lib/active_support/core_ext/class/delegating_attributes.rb, line 33 def superclass_delegating_writer(*names) names.each do |name| class_eval def self.#{name}=(value) # def self.only_writer=(value) @#{name} = value # @only_writer = value end # end end end
Generated with the Darkfish Rdoc Generator 2.