Module: GollyUtils::AttrDeclarative
- Included in:
- Object
- Defined in:
- lib/golly-utils/attr_declarative.rb
Overview
Creates instance accessors much like attr_accessor with the following additional properties:
- Default values can be specified.
- Defaults can be overridden in subclasses.
- Values can be declared, failing-fast on typos.
- Explicit declaration of an attribute value can be required and enforced. (Optional)
i.e. if an attribute is read before a value has been specified, then an error will be thrown.
Attributes ending in ? or ! will have said suffix removed in the instance variable, and writer method names.
Instance Method Summary collapse
-
#attr_declarative(first, *args) ⇒ nil
Declares one or more attributes.
Instance Method Details
#attr_declarative(hash_of_names_to_defaults) ⇒ nil #attr_declarative(*names, options = {}) ⇒ nil
Declares one or more attributes.
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 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 136 137 138 139 140 |
# File 'lib/golly-utils/attr_declarative.rb', line 89 def attr_declarative(first,*args) # Parse args names= ([first] + args).flatten.uniq = names.last.is_a?(Hash) ? names.pop.clone : {} # Accept <name>: <default> syntax if names.empty? and not .empty? .each do |name,default| attr_declarative name, default: default end return nil end # Validate options default= .delete :default required= (.has_key? :required) ? .delete(:required): false raise "Unknown options: #{.keys}" unless .empty? # Create attributes names.each do |name| raise "Invalid attribute name: #{name.inspect}" unless name.is_a?(String) or name.is_a?(Symbol) safe_name= name.to_s.sub /[!?]$/, '' dvar= "@__gu_attr_decl_#{safe_name}_default" ivar= "@#{safe_name}" meth_w= "#{safe_name}=" meth_r= name class_eval <<-EOB def #{meth_w}(value) #{ivar} = value end def #{meth_r} if instance_variable_defined? :#{ivar} #{ivar} elsif d= ::GollyUtils::AttrDeclarative.get_default(:#{dvar}, self.class) #{ivar}= d else #{required ? %[raise "Attribute '#{name}' required by #{self} but not set in #\{self.class}."] : 'nil'} end end def self.#{meth_r}(value) instance_variable_set :#{dvar}, value end EOB instance_variable_set dvar.to_sym, default unless default.nil? end nil end |