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
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
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