Sha256: 4154c8aae27aa2d4dcb9390f0fef36cfd16b5e8e0d0010d10fb8f2d9401588ca

Contents?: true

Size: 1.59 KB

Versions: 1

Compression:

Stored size: 1.59 KB

Contents

require 'usable/config_multi'
require 'usable/config_register'

module Usable
  # 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
  class Config
    include ConfigRegister
    include ConfigMulti

    def initialize
      @spec = OpenStruct.new
      @lazy_loads = Set.new
    end

    def spec
      @spec
    end

    def [](key)
      @spec[key]
    end

    def []=(key, val)
      @spec[key] = val
    end

    def each(&block)
      @spec.to_h.each(&block)
    end

    def to_h
      @lazy_loads.each { |key| @spec[key] = call_spec_method(key) }
      @spec.to_h
    end

    alias to_hash to_h

    def method_missing(key, *args, &block)
      if block
        @lazy_loads << key
        @spec.define_singleton_method(key) { yield }
      else
        key = key.to_s.tr('=', '')
        if args.empty?
          value = @spec[key] ||= call_spec_method(key)
          define_singleton_method(key) { @spec[key] }
          value
        else
          @spec[key] = args.first
        end
      end
    rescue NoMethodError
      super
    end

    def respond_to_missing?(method_name, _private = false)
      method_name.to_s.end_with?('=') || @spec.respond_to?(method_name)
    end

    def freeze
      to_h.each { |key, value| define_singleton_method(key) { value } }
      super
    end

    private

    # @note Handles the case where the value may be defined with a block, in which case it's a method
    def call_spec_method(key)
      @lazy_loads.delete key
      @spec.public_send key
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
usable-3.2.0 lib/usable/config.rb