aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/class_inheritable_attributes.rb
blob: 5ad5a362f6b66f4bc639718f05286bb89e34a4f8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# Allows attributes to be shared within an inheritance hierarchy, but where each descendant gets a copy of
# their parents' attributes, instead of just a pointer to the same. This means that the child can add elements
# to, for example, an array without those additions being shared with either their parent, siblings, or
# children, which is unlike the regular class-level attributes that are shared across the entire hierarchy.
module ClassInheritableAttributes # :nodoc:
  def self.append_features(base)
    super
    base.extend(ClassMethods)
  end
  
  module ClassMethods # :nodoc:
    @@classes ||= {}
    
    def inheritable_attributes
      @@classes[self] ||= {}
    end
    
    def write_inheritable_attribute(key, value)
      inheritable_attributes[key] = value
    end
    
    def write_inheritable_array(key, elements)
      write_inheritable_attribute(key, []) if read_inheritable_attribute(key).nil?
      write_inheritable_attribute(key, read_inheritable_attribute(key) + elements)
    end

    def write_inheritable_hash(key, hash)
      write_inheritable_attribute(key, {}) if read_inheritable_attribute(key).nil?
      write_inheritable_attribute(key, read_inheritable_attribute(key).merge(hash))
    end

    def read_inheritable_attribute(key)
      inheritable_attributes[key]
    end
    
    def reset_inheritable_attributes
      inheritable_attributes.clear
    end

    private 
      def inherited(child)
        @@classes[child] = inheritable_attributes.dup
      end
   
  end
end