class Dry::Configurable::Config

@private

def self.create(settings)

def self.create(settings)
  klass = ::Class.new(self)
  settings.each do |setting|
    klass.__send__(:define_method, setting.name) do
      @config[setting.name]
    end
    klass.__send__(:define_method, "#{setting.name}=") do |value|
      @config[setting.name] = setting.processor.call(value)
    end
  end
  klass.new(settings)
end

def [](name)

def [](name)
  raise_unknown_setting_error(name) unless setting?(name)
  public_send(name)
end

def []=(name, value)

def []=(name, value)
  raise_unknown_setting_error(name) unless setting?(name)
  public_send("#{name}=", value)
end

def clone

def clone
  clone = super
  clone.instance_variable_set(:@config, @config.clone)
  clone
end

def dup

def dup
  dup = super
  dup.instance_variable_set(:@config, @config.dup)
  dup
end

def initialize(settings)

def initialize(settings)
  @config = ::Concurrent::Hash.new
  settings.each do |setting|
    if setting.none?
      @config[setting.name] = nil
    else
      public_send("#{setting.name}=", setting.value)
    end
  end
end

def raise_unknown_setting_error(name)

def raise_unknown_setting_error(name)
  raise ArgumentError, "+#{name}+ is not a setting name"
end

def setting?(name)

def setting?(name)
  @config.key?(name.to_sym)
end

def to_h

def to_h
  @config.each_with_object({}) do |tuple, hash|
    key, value = tuple
    if value.kind_of?(::Dry::Configurable::Config)
      hash[key] = value.to_h
    else
      hash[key] = value 
    end
  end
end