1 # Retain for backward compatibility. Methods are now included in Class.
2 module ClassInheritableAttributes # :nodoc:
5 # Allows attributes to be shared within an inheritance hierarchy, but where each descendant gets a copy of
6 # their parents' attributes, instead of just a pointer to the same. This means that the child can add elements
7 # to, for example, an array without those additions being shared with either their parent, siblings, or
8 # children, which is unlike the regular class-level attributes that are shared across the entire hierarchy.
10 def class_inheritable_reader(*syms)
12 next if sym.is_a?(Hash)
15 read_inheritable_attribute(:#{sym})
25 def class_inheritable_writer(*syms)
26 options = syms.extract_options!
30 write_inheritable_attribute(:#{sym}, obj)
35 self.class.#{sym} = obj
37 " unless options[:instance_writer] == false }
42 def class_inheritable_array_writer(*syms)
43 options = syms.extract_options!
47 write_inheritable_array(:#{sym}, obj)
52 self.class.#{sym} = obj
54 " unless options[:instance_writer] == false }
59 def class_inheritable_hash_writer(*syms)
60 options = syms.extract_options!
64 write_inheritable_hash(:#{sym}, obj)
69 self.class.#{sym} = obj
71 " unless options[:instance_writer] == false }
76 def class_inheritable_accessor(*syms)
77 class_inheritable_reader(*syms)
78 class_inheritable_writer(*syms)
81 def class_inheritable_array(*syms)
82 class_inheritable_reader(*syms)
83 class_inheritable_array_writer(*syms)
86 def class_inheritable_hash(*syms)
87 class_inheritable_reader(*syms)
88 class_inheritable_hash_writer(*syms)
91 def inheritable_attributes
92 @inheritable_attributes ||= EMPTY_INHERITABLE_ATTRIBUTES
95 def write_inheritable_attribute(key, value)
96 if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
97 @inheritable_attributes = {}
99 inheritable_attributes[key] = value
102 def write_inheritable_array(key, elements)
103 write_inheritable_attribute(key, []) if read_inheritable_attribute(key).nil?
104 write_inheritable_attribute(key, read_inheritable_attribute(key) + elements)
107 def write_inheritable_hash(key, hash)
108 write_inheritable_attribute(key, {}) if read_inheritable_attribute(key).nil?
109 write_inheritable_attribute(key, read_inheritable_attribute(key).merge(hash))
112 def read_inheritable_attribute(key)
113 inheritable_attributes[key]
116 def reset_inheritable_attributes
117 @inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
121 # Prevent this constant from being created multiple times
122 EMPTY_INHERITABLE_ATTRIBUTES = {}.freeze unless const_defined?(:EMPTY_INHERITABLE_ATTRIBUTES)
124 def inherited_with_inheritable_attributes(child)
125 inherited_without_inheritable_attributes(child) if respond_to?(:inherited_without_inheritable_attributes)
127 if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
128 new_inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
130 new_inheritable_attributes = inheritable_attributes.inject({}) do |memo, (key, value)|
131 memo.update(key => (value.dup rescue value))
135 child.instance_variable_set('@inheritable_attributes', new_inheritable_attributes)
138 alias inherited_without_inheritable_attributes inherited
139 alias inherited inherited_with_inheritable_attributes