module HasAttributes

HasAttributes allows objects to have arbitrary attributes associated with it.

Public Instance Methods

[](key) click to toggle source
# File lib/geoengineer/utils/has_attributes.rb, line 14
def [](key)
  retrieve_attribute(key.to_s)
end
[]=(key, val) click to toggle source
# File lib/geoengineer/utils/has_attributes.rb, line 18
def []=(key, val)
  assign_attribute(key.to_s, [val])
end
assign_attribute(name, args) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# File lib/geoengineer/utils/has_attributes.rb, line 60
def attribute_missing(name)
  nil
end
attribute_procs() click to toggle source

Contains the procs used to calculate attributes

# File lib/geoengineer/utils/has_attributes.rb, line 10
def attribute_procs
  @_procs ||= {}
end
attributes() click to toggle source
# File lib/geoengineer/utils/has_attributes.rb, line 5
def attributes
  @_attributes ||= {}
end
delete(key) click to toggle source
# File lib/geoengineer/utils/has_attributes.rb, line 22
def delete(key)
  attributes.delete(key.to_s)
end
eager_load_attributes() click to toggle source
# File lib/geoengineer/utils/has_attributes.rb, line 55
def eager_load_attributes
  attribute_procs.each { |name, function| attributes[name] = function.call() }
  self
end
method_missing(name, *args, &block) click to toggle source

This method allows attributes to be defined on an instance without explicitly defining which attributes are allowed

The flow is:

  1. If the method receives a block, it will pass it to the `assign_block` method to be handled. By default this method will throw an error, but can be overridden by the class.

  2. If the method has one or more argument it will assume it is a setter and store the argument as an attribute.

  3. If the method has no arguments it will assume it is a getter and retrieve the value. If the retrieved value is a `Proc` it will execute it and store the returned value, this will allow for caching expensive calls and only calling if requested

# 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
reset_attributes() click to toggle source

For any value that has been lazily calculated, recalculate it

# 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) click to toggle source
# 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) click to toggle source
# 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() click to toggle source

This method creates a set of attributes for terraform to consume

# 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) click to toggle source

must override because of Object#timeout

# File lib/geoengineer/utils/has_attributes.rb, line 88
def timeout(*args)
  method_missing(:timeout, *args)
end