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
.duplicable
? ? value
.dup
: 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