class Usable::Config

Store and manage configuration settings. Keep methods to a minimum since this class relies on method_missing to read and write to the underlying @spec object

Public Class Methods

new(attributes = {}) click to toggle source

@todo Maybe keep a list of all attributes (lazy and regular)? e.g @attributes = Set.new attributes.keys.map(&:to_s)

# File lib/usable/config.rb, line 12
def initialize(attributes = {})
  @spec = OpenStruct.new(attributes)
  @lazy_loads = Set.new
end

Public Instance Methods

[](key) click to toggle source
# File lib/usable/config.rb, line 21
def [](key)
  @spec[key]
end
[]=(key, val) click to toggle source
# File lib/usable/config.rb, line 25
def []=(key, val)
  @spec[key] = val
end
each(&block) click to toggle source
# File lib/usable/config.rb, line 29
def each(&block)
  @spec.to_h.each(&block)
end
freeze() click to toggle source
Calls superclass method
# File lib/usable/config.rb, line 91
def freeze
  to_h.each { |key, value| define_singleton_method(key) { value } }
  @spec.freeze
  super
end
include?(key) click to toggle source
# File lib/usable/config.rb, line 58
def include?(key)
  !!@spec[key] || @lazy_loads.include?(key.to_sym)
end
inspect() click to toggle source
# File lib/usable/config.rb, line 97
def inspect
  nested, locals = @spec.to_h.partition { |_, value| value.is_a?(Usable::Config) }
  nested.map! { |key, _| [key, '{...}'] }
  locals.concat nested
  locals.map! { |key, v| %(@#{key}=#{v.inspect}) }
  vars = locals.any? ? ' ' + locals.join(', ') : ''
  "<Usable::Config:0x00#{(object_id << 1).to_s(16)}#{vars}>"
end
Also aliased as: to_s
marshal_dump()
Alias for: to_h
merge(other) click to toggle source
# File lib/usable/config.rb, line 46
def merge(other)
  to_h.merge(other)
end
merge!(other) click to toggle source

@param other [Hash] to update ourselves with

# File lib/usable/config.rb, line 51
def merge!(other)
  other.each do |key, val|
    @spec[key] = val
  end
  self
end
method_missing(key, *args, &block) click to toggle source
Calls superclass method
# File lib/usable/config.rb, line 62
def method_missing(key, *args, &block)
  if block
    @lazy_loads << key
    @spec.define_singleton_method(key, &block)
  else
    # Needs to be a symbol so we can consistently access @lazy_loads
    key = key.to_s.tr('=', '').to_sym
    if args.empty?
      if @spec[key]
        # Cleanup, just in case we loaded it another way (e.g. combining with another usable config)
        @lazy_loads.delete key
      else
        @spec[key] = call_spec_method(key) unless frozen?
      end
      # Define method so we don't hit method missing again
      define_singleton_method(key) { @spec[key] } unless frozen?
      @spec[key]
    else
      @spec[key] = args.first
    end
  end
rescue NoMethodError
  super
end
respond_to_missing?(method_name, _private = false) click to toggle source
# File lib/usable/config.rb, line 87
def respond_to_missing?(method_name, _private = false)
  method_name.to_s.end_with?('=') || @spec.respond_to?(method_name)
end
spec() click to toggle source
# File lib/usable/config.rb, line 17
def spec
  @spec
end
to_h() click to toggle source

@note The @spec could already be set in cases where the config was merged with another

For example, a usable module defines a default with a block, and when mounting the module
the same usable option is overridden as an options hash (usable mod, key: 'val')
# File lib/usable/config.rb, line 36
def to_h
  @lazy_loads.each { |key| @spec[key] ||= @spec.public_send(key) }
  @lazy_loads.clear
  @spec.to_h
end
Also aliased as: to_hash, marshal_dump
to_hash()
Alias for: to_h
to_s()
Alias for: inspect

Private Instance Methods

call_spec_method(key) click to toggle source

@note Handles the case where the value may be defined with a block, in which case it's a method

# File lib/usable/config.rb, line 111
def call_spec_method(key)
  @lazy_loads.delete key
  @spec.public_send key
end