diff options
Diffstat (limited to 'activesupport/lib')
-rw-r--r-- | activesupport/lib/active_support/core_ext/class/attribute.rb | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/activesupport/lib/active_support/core_ext/class/attribute.rb b/activesupport/lib/active_support/core_ext/class/attribute.rb index af8202ae2c..bfa57fe1f7 100644 --- a/activesupport/lib/active_support/core_ext/class/attribute.rb +++ b/activesupport/lib/active_support/core_ext/class/attribute.rb @@ -18,17 +18,34 @@ class Class # Subclass.setting # => false # Base.setting # => true # - # In the above case as long as Subclass does not assign a value to setting - # by performing <tt>Subclass.setting = _something_ </tt>, <tt>Subclass.setting</tt> - # would read value assigned to parent class. Once Subclass assigns a value then - # the value assigned by Subclass would be returned. + # In the above case as long as Subclass does not assign a value to setting + # by performing <tt>Subclass.setting = _something_ </tt>, <tt>Subclass.setting</tt> + # 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. + # 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 + # Subclass.setting? # => false # # Instances may overwrite the class value in the same way: # @@ -41,11 +58,7 @@ class Class # # To opt out of the instance writer method, pass :instance_writer => false. # - # class Base - # class_attribute :setting, :instance_write => false - # end - # - # Base.new.setting = false # => NoMethodError + # object.setting = false # => NoMethodError def class_attribute(*attrs) instance_writer = !attrs.last.is_a?(Hash) || attrs.pop[:instance_writer] |