Module: HasAttributes
- Included in:
- GeoEngineer::Environment, GeoEngineer::Project, GeoEngineer::Provider, GeoEngineer::Resource, GeoEngineer::SubResource, GeoEngineer::Template
- Defined in:
- lib/geoengineer/utils/has_attributes.rb
Overview
HasAttributes allows objects to have arbitrary attributes associated with it.
Instance Method Summary collapse
- #[](key) ⇒ Object
- #[]=(key, val) ⇒ Object
- #assign_attribute(name, args) ⇒ Object
- #assign_block(name, *args, &block) ⇒ Object
- #attribute_missing(name) ⇒ Object
-
#attribute_procs ⇒ Object
Contains the procs used to calculate attributes.
- #attributes ⇒ Object
- #delete(key) ⇒ Object
- #eager_load_attributes ⇒ Object
-
#method_missing(name, *args, &block) ⇒ Object
This method allows attributes to be defined on an instance without explicitly defining which attributes are allowed.
-
#reset_attributes ⇒ Object
For any value that has been lazily calculated, recalculate it.
- #retrieve_attribute(name) ⇒ Object
- #terraform_attribute_ref(k) ⇒ Object
-
#terraform_attributes ⇒ Object
This method creates a set of attributes for terraform to consume.
-
#timeout(*args) ⇒ Object
must override because of Object#timeout.
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object
This method allows attributes to be defined on an instance without explicitly defining which attributes are allowed
The flow is:
-
If the method receives a block, it will pass it to the
assign_blockmethod to be handled. By default this method will throw an error, but can be overridden by the class. -
If the method has one or more argument it will assume it is a setter and store the argument as an attribute.
-
If the method has no arguments it will assume it is a getter and retrieve the value. If the retrieved value is a
Procit will execute it and store the returned value, this will allow for caching expensive calls and only calling if requested
75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/geoengineer/utils/has_attributes.rb', line 75 def method_missing(name, *args, &block) name = name.to_s if block_given? # A class can override a assign_block(name, *args, &block) elsif args.length >= 1 assign_attribute(name, args) elsif args.empty? retrieve_attribute(name) end end |
Instance Method Details
#[](key) ⇒ Object
14 15 16 |
# File 'lib/geoengineer/utils/has_attributes.rb', line 14 def [](key) retrieve_attribute(key.to_s) end |
#[]=(key, val) ⇒ Object
18 19 20 |
# File 'lib/geoengineer/utils/has_attributes.rb', line 18 def []=(key, val) assign_attribute(key.to_s, [val]) end |
#assign_attribute(name, args) ⇒ Object
30 31 32 33 34 35 36 |
# File 'lib/geoengineer/utils/has_attributes.rb', line 30 def assign_attribute(name, args) # this is a setter name = name[0...-1] if name.end_with?"=" val = args.length == 1 ? args[0] : args attribute_procs[name] = val if val.is_a?(Proc) attributes[name] = val end |
#assign_block(name, *args, &block) ⇒ Object
26 27 28 |
# File 'lib/geoengineer/utils/has_attributes.rb', line 26 def assign_block(name, *args, &block) throw "#{self.class.inspect} cannot handle block" end |
#attribute_missing(name) ⇒ Object
60 61 62 |
# File 'lib/geoengineer/utils/has_attributes.rb', line 60 def attribute_missing(name) nil end |
#attribute_procs ⇒ Object
Contains the procs used to calculate attributes
10 11 12 |
# File 'lib/geoengineer/utils/has_attributes.rb', line 10 def attribute_procs @_procs ||= {} end |
#attributes ⇒ Object
5 6 7 |
# File 'lib/geoengineer/utils/has_attributes.rb', line 5 def attributes @_attributes ||= {} end |
#delete(key) ⇒ Object
22 23 24 |
# File 'lib/geoengineer/utils/has_attributes.rb', line 22 def delete(key) attributes.delete(key.to_s) end |
#eager_load_attributes ⇒ Object
55 56 57 58 |
# File 'lib/geoengineer/utils/has_attributes.rb', line 55 def eager_load_attributes attribute_procs.each { |name, function| attributes[name] = function.call() } self end |
#reset_attributes ⇒ Object
For any value that has been lazily calculated, recalculate it
50 51 52 53 |
# File 'lib/geoengineer/utils/has_attributes.rb', line 50 def reset_attributes attribute_procs.each { |name, function| attributes[name] = function } self end |
#retrieve_attribute(name) ⇒ Object
38 39 40 41 42 43 44 45 46 47 |
# File 'lib/geoengineer/utils/has_attributes.rb', line 38 def retrieve_attribute(name) # this is a getter val = if attributes.key?(name) attributes[name] else attribute_missing(name) end return val unless val.is_a?(Proc) attributes[name] = val.call() # cache the value to override the Proc end |
#terraform_attribute_ref(k) ⇒ Object
101 102 103 104 105 106 107 108 109 110 |
# File 'lib/geoengineer/utils/has_attributes.rb', line 101 def terraform_attribute_ref(k) v = retrieve_attribute(k) if v.is_a? GeoEngineer::Resource # convert Resource to reference for terraform v.to_ref elsif v.is_a? Array # map resources if attribute is an array v.map { |vi| vi.is_a?(GeoEngineer::Resource) ? vi.to_ref : vi } else v end end |
#terraform_attributes ⇒ Object
This method creates a set of attributes for terraform to consume
93 94 95 96 97 98 99 |
# File 'lib/geoengineer/utils/has_attributes.rb', line 93 def terraform_attributes attributes .select { |k, v| !k.nil? && !k.start_with?('_') } .map { |k, v| [k, terraform_attribute_ref(k)] } .select { |k, v| !v.nil? } .to_h end |
#timeout(*args) ⇒ Object
must override because of Object#timeout
88 89 90 |
# File 'lib/geoengineer/utils/has_attributes.rb', line 88 def timeout(*args) method_missing(:timeout, *args) end |