Module: FPM::Cookery::InheritableAttr
- Included in:
- BaseRecipe
- Defined in:
- lib/fpm/cookery/inheritable_attr.rb
Overview
Provides inheritance of class-level attributes. Attributes are cloned from the superclass, except for non-clonable attributes, which are assigned directly.
This module will automatically define class methods for keeping track of inheritable attributes, as follows:
+attr_rw+ => +klass.scalar_attrs+
+attr_rw_list+ => +klass.list_attrs+
+attr_rw_hash+ => +klass.hash_attrs+
+attr_rw_path+ => +klass.path_attrs+
Defined Under Namespace
Classes: DeepClone
Class Method Summary collapse
Instance Method Summary collapse
-
#attr_rw(*attrs) ⇒ Object
Create ‘scalar’ (i.e. non-collection) attributes.
-
#attr_rw_hash(*attrs) ⇒ Object
Create
Hash
-style attributes. -
#attr_rw_list(*attrs) ⇒ Object
Create list-style attributes, backed by Arrays.
-
#attr_rw_path(*attrs) ⇒ Object
Create methods for attributes representing paths.
-
#register_attrs(type, *attrs) ⇒ Object
Adds a list of attributes keyed to the
type
key of an internal hash tracking class attributes.
Class Method Details
.extended(klass) ⇒ Object
194 195 196 197 198 |
# File 'lib/fpm/cookery/inheritable_attr.rb', line 194 def extended(klass) # Inject the +attr_registry+ attribute into any class that extends # this module. klass.attr_rw_hash(:attr_registry) end |
.inherit_for(klass, name) ⇒ Object
189 190 191 192 |
# File 'lib/fpm/cookery/inheritable_attr.rb', line 189 def inherit_for(klass, name) return unless klass.superclass.respond_to?(name) DeepClone.(klass.superclass.send(name)) end |
Instance Method Details
#attr_rw(*attrs) ⇒ Object
Create ‘scalar’ (i.e. non-collection) attributes.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/fpm/cookery/inheritable_attr.rb', line 85 def attr_rw(*attrs) attrs.each do |attr| class_eval %Q{ def self.#{attr}(value = nil) if value.nil? return @#{attr} if instance_variable_defined?(:@#{attr}) @#{attr} = InheritableAttr.inherit_for(self, :#{attr}) else @#{attr} = value end end def #{attr} self.class.#{attr} end } end register_attrs(:scalar, *attrs) end |
#attr_rw_hash(*attrs) ⇒ Object
Create Hash
-style attributes. Supports both hash and argument assignment:
attr_method[:attr1] = xxxx
attr_method :xxxx=>1, :yyyy=>2
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/fpm/cookery/inheritable_attr.rb', line 141 def attr_rw_hash(*attrs) attrs.each do |attr| class_eval %Q{ def self.#{attr}(args = {}) unless instance_variable_defined?(:@#{attr}) @#{attr} = InheritableAttr.inherit_for(self, :#{attr}) end (@#{attr} ||= {}).merge!(args) end def #{attr} self.class.#{attr} end } end register_attrs(:hash, *attrs) end |
#attr_rw_list(*attrs) ⇒ Object
Create list-style attributes, backed by Arrays. nil
entries will be filtered, non-unique entries will be culled to one instance only, and the list will be flattened.
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/fpm/cookery/inheritable_attr.rb', line 109 def attr_rw_list(*attrs) attrs.each do |attr| class_eval %Q{ def self.#{attr}(*list) unless instance_variable_defined?(:@#{attr}) @#{attr} = InheritableAttr.inherit_for(self, :#{attr}) end @#{attr} ||= [] unless list.empty? @#{attr} << list @#{attr}.flatten! @#{attr}.uniq! end @#{attr} end def #{attr} self.class.#{attr} end } end register_attrs(:list, *attrs) end |
#attr_rw_path(*attrs) ⇒ Object
Create methods for attributes representing paths. Arguments to writer methods will be converted to FPM::Cookery::Path
objects.
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/fpm/cookery/inheritable_attr.rb', line 163 def attr_rw_path(*attrs) attrs.each do |attr| class_eval %Q{ def self.#{attr} return @#{attr} if instance_variable_defined?(:@#{attr}) @#{attr} = InheritableAttr.inherit_for(self, :#{attr}) end def self.#{attr}=(value) @#{attr} = FPM::Cookery::Path.new(value) end def #{attr}=(value) self.class.#{attr} = value end def #{attr}(path = nil) self.class.#{attr}(path) end } end register_attrs(:path, *attrs) end |
#register_attrs(type, *attrs) ⇒ Object
Adds a list of attributes keyed to the type
key of an internal hash tracking class attributes. Also defines the method “#{type}_attrs”, which will return the list of attribute names keyed to type
.
74 75 76 77 78 79 80 81 82 |
# File 'lib/fpm/cookery/inheritable_attr.rb', line 74 def register_attrs(type, *attrs) (attr_registry[type] ||= []).concat(attrs) unless respond_to?(type_reader = :"#{type}_attrs") (class << self ; self ; end).send(:define_method, type_reader) do attr_registry.fetch(type, []).dup end end end |