Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package rubygem-dry-configurable for 
openSUSE:Factory checked in at 2022-10-12 18:25:06
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-dry-configurable (Old)
 and      /work/SRC/openSUSE:Factory/.rubygem-dry-configurable.new.2275 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "rubygem-dry-configurable"

Wed Oct 12 18:25:06 2022 rev:6 rq:1010052 version:0.16.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/rubygem-dry-configurable/rubygem-dry-configurable.changes
        2022-08-09 15:26:35.461323227 +0200
+++ 
/work/SRC/openSUSE:Factory/.rubygem-dry-configurable.new.2275/rubygem-dry-configurable.changes
      2022-10-12 18:26:53.757981019 +0200
@@ -1,0 +2,40 @@
+Mon Oct 10 13:03:10 UTC 2022 - Stephan Kulow <[email protected]>
+
+updated to version 0.16.0
+ see installed CHANGELOG.md
+
+  ## 0.16.0 2022-10-08
+  
+  
+  ### Added
+  
+  - Support for custom config classes via `config_class:` option (#136 by 
@solnic)
+  
+    ```ruby
+    extend Dry::Configurable(config_class: MyConfig)
+    ```
+  
+    Your config class should inherit from `Dry::Configurable::Config`.
+  - Return `Dry::Core::Constants::Undefined` (instead of nil) as the value for 
non-configured settings via a `default_undefined: true` option (#141 by 
@timriley)
+  
+    ```ruby
+    extend Dry::Configurable(default_undefined: true)
+    ```
+  
+    You must opt into this feature via the `default_undefined: true` option. 
Non-configured setting values are still `nil` by default.
+  
+  ### Fixed
+  
+  - Remove exec bit from version.rb (#139 by @Fryguy)
+  
+  ### Changed
+  
+  - Improve memory usage by separating setting definitions from config values 
(#138 by @timriley)
+  
+    Your usage of dry-configurable may be impacted if you have been accessing 
objects from `_settings` or the internals of `Dry::Configurable::Config`. 
`_settings` now returns `Dry::Configurable::Setting` instances, which contain 
only the details from the setting's definition. Setting _values_ remain in 
`Dry::Configurable::Config`.
+  - Use Zeitwerk to speed up load time (#135 by @solnic)
+  
+  [Compare 
v0.15.0...v0.16.0](https://github.com/dry-rb/dry-configurable/compare/v0.15.0...v0.16.0)
+  
+
+-------------------------------------------------------------------

Old:
----
  dry-configurable-0.15.0.gem

New:
----
  dry-configurable-0.16.0.gem

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ rubygem-dry-configurable.spec ++++++
--- /var/tmp/diff_new_pack.scBEVz/_old  2022-10-12 18:26:54.349982322 +0200
+++ /var/tmp/diff_new_pack.scBEVz/_new  2022-10-12 18:26:54.353982331 +0200
@@ -24,7 +24,7 @@
 #
 
 Name:           rubygem-dry-configurable
-Version:        0.15.0
+Version:        0.16.0
 Release:        0
 %define mod_name dry-configurable
 %define mod_full_name %{mod_name}-%{version}

++++++ dry-configurable-0.15.0.gem -> dry-configurable-0.16.0.gem ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/CHANGELOG.md new/CHANGELOG.md
--- old/CHANGELOG.md    2022-04-21 09:30:01.000000000 +0200
+++ new/CHANGELOG.md    2022-10-08 01:24:53.000000000 +0200
@@ -1,5 +1,38 @@
 <!--- DO NOT EDIT THIS FILE - IT'S AUTOMATICALLY GENERATED VIA DEVTOOLS --->
 
+## 0.16.0 2022-10-08
+
+
+### Added
+
+- Support for custom config classes via `config_class:` option (#136 by 
@solnic)
+
+  ```ruby
+  extend Dry::Configurable(config_class: MyConfig)
+  ```
+
+  Your config class should inherit from `Dry::Configurable::Config`.
+- Return `Dry::Core::Constants::Undefined` (instead of nil) as the value for 
non-configured settings via a `default_undefined: true` option (#141 by 
@timriley)
+
+  ```ruby
+  extend Dry::Configurable(default_undefined: true)
+  ```
+
+  You must opt into this feature via the `default_undefined: true` option. 
Non-configured setting values are still `nil` by default.
+
+### Fixed
+
+- Remove exec bit from version.rb (#139 by @Fryguy)
+
+### Changed
+
+- Improve memory usage by separating setting definitions from config values 
(#138 by @timriley)
+
+  Your usage of dry-configurable may be impacted if you have been accessing 
objects from `_settings` or the internals of `Dry::Configurable::Config`. 
`_settings` now returns `Dry::Configurable::Setting` instances, which contain 
only the details from the setting's definition. Setting _values_ remain in 
`Dry::Configurable::Config`.
+- Use Zeitwerk to speed up load time (#135 by @solnic)
+
+[Compare 
v0.15.0...v0.16.0](https://github.com/dry-rb/dry-configurable/compare/v0.15.0...v0.16.0)
+
 ## 0.15.0 2022-04-21
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/LICENSE new/LICENSE
--- old/LICENSE 2022-04-21 09:30:01.000000000 +0200
+++ new/LICENSE 2022-10-08 01:24:53.000000000 +0200
@@ -1,6 +1,6 @@
 The MIT License (MIT)
 
-Copyright (c) 2015-2021 dry-rb team
+Copyright (c) 2015-2022 dry-rb team
 
 Permission is hereby granted, free of charge, to any person obtaining a copy of
 this software and associated documentation files (the "Software"), to deal in
Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dry-configurable.gemspec new/dry-configurable.gemspec
--- old/dry-configurable.gemspec        2022-04-21 09:30:01.000000000 +0200
+++ new/dry-configurable.gemspec        2022-10-08 01:24:53.000000000 +0200
@@ -29,8 +29,8 @@
   spec.required_ruby_version = ">= 2.7.0"
 
   # to update dependencies edit project.yml
-  spec.add_runtime_dependency "concurrent-ruby", "~> 1.0"
   spec.add_runtime_dependency "dry-core", "~> 0.6"
+  spec.add_runtime_dependency "zeitwerk", "~> 2.6"
 
   spec.add_development_dependency "bundler"
   spec.add_development_dependency "rake"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dry/configurable/class_methods.rb 
new/lib/dry/configurable/class_methods.rb
--- old/lib/dry/configurable/class_methods.rb   2022-04-21 09:30:01.000000000 
+0200
+++ new/lib/dry/configurable/class_methods.rb   2022-10-08 01:24:53.000000000 
+0200
@@ -2,11 +2,6 @@
 
 require "set"
 
-require "dry/configurable/constants"
-require "dry/configurable/dsl"
-require "dry/configurable/methods"
-require "dry/configurable/settings"
-
 module Dry
   module Configurable
     module ClassMethods
@@ -16,8 +11,17 @@
       def inherited(subclass)
         super
 
-        subclass.instance_variable_set("@_settings", _settings.dup)
-        subclass.instance_variable_set("@_config", config.dup) if 
respond_to?(:config)
+        subclass.instance_variable_set(:@__config_extension__, 
__config_extension__)
+
+        new_settings = _settings.dup
+        subclass.instance_variable_set(:@_settings, new_settings)
+
+        # Only classes **extending** Dry::Configurable have class-level 
config. When
+        # Dry::Configurable is **included**, the class-level config method is 
undefined because it
+        # resides at the instance-level instead (see `Configurable.included`).
+        if respond_to?(:config)
+          subclass.instance_variable_set(:@config, 
config.dup_for_settings(new_settings))
+        end
       end
 
       # Add a setting to the configuration
@@ -52,7 +56,7 @@
       #
       # @api public
       def settings
-        @settings ||= Set[*_settings.map(&:name)]
+        Set[*_settings.map(&:name)]
       end
 
       # Return declared settings
@@ -70,17 +74,25 @@
       #
       # @api public
       def config
-        # The _settings provided to the Config remain shared between the class 
and the
-        # Config. This allows settings defined _after_ accessing the config to 
become
-        # available in subsequent accesses to the config. The config is duped 
when
-        # subclassing to ensure it remains distinct between subclasses and 
parent classes
-        # (see `.inherited` above).
-        @config ||= Config.new(_settings)
+        @config ||= __config_build__
+      end
+
+      # @api private
+      def __config_build__(settings = _settings)
+        __config_extension__.config_class.new(settings)
+      end
+
+      # @api private
+      def __config_extension__
+        @__config_extension__
       end
 
       # @api private
       def __config_dsl__
-        @__config_dsl__ ||= DSL.new
+        @__config_dsl__ ||= DSL.new(
+          config_class: __config_extension__.config_class,
+          default_undefined: __config_extension__.default_undefined
+        )
       end
 
       # @api private
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dry/configurable/compiler.rb 
new/lib/dry/configurable/compiler.rb
--- old/lib/dry/configurable/compiler.rb        2022-04-21 09:30:01.000000000 
+0200
+++ new/lib/dry/configurable/compiler.rb        2022-10-08 01:24:53.000000000 
+0200
@@ -1,8 +1,5 @@
 # frozen_string_literal: true
 
-require "dry/configurable/setting"
-require "dry/configurable/settings"
-
 module Dry
   module Configurable
     # Setting compiler used internally by the DSL
@@ -32,7 +29,9 @@
       # @api private
       def visit_nested(node)
         parent, children = node
-        visit(parent).nested(call(children))
+        name, opts = parent[1]
+
+        Setting.new(name, **opts, children: Settings.new(call(children)))
       end
     end
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dry/configurable/config.rb 
new/lib/dry/configurable/config.rb
--- old/lib/dry/configurable/config.rb  2022-04-21 09:30:01.000000000 +0200
+++ new/lib/dry/configurable/config.rb  2022-10-08 01:24:53.000000000 +0200
@@ -1,12 +1,9 @@
 # frozen_string_literal: true
 
-require "concurrent/map"
+require "dry/core/constants"
 
 require "dry/core/equalizer"
 
-require "dry/configurable/constants"
-require "dry/configurable/errors"
-
 module Dry
   module Configurable
     # Config exposes setting values through a convenient API
@@ -19,12 +16,17 @@
       attr_reader :_settings
 
       # @api private
-      attr_reader :_resolved
+      attr_reader :_values
 
       # @api private
-      def initialize(settings)
+      def initialize(settings, values: {})
         @_settings = settings
-        @_resolved = Concurrent::Map.new
+        @_values = values
+      end
+
+      # @api private
+      def dup_for_settings(settings)
+        self.class.new(settings, values: dup_values)
       end
 
       # Get config value by a key
@@ -34,9 +36,18 @@
       # @return Config value
       def [](name)
         name = name.to_sym
-        raise ArgumentError, "+#{name}+ is not a setting name" unless 
_settings.key?(name)
 
-        _settings[name].value
+        unless (setting = _settings[name])
+          raise ArgumentError, "+#{name}+ is not a setting name"
+        end
+
+        _values.fetch(name) {
+          # When reading values, only capture cloneable (i.e. mutable) values 
in local state, making
+          # it easier to determine which values have actually been changed vs 
just read
+          setting.to_value.tap { |value|
+            _values[name] = value if setting.cloneable?
+          }
+        }
       end
 
       # Set config value.
@@ -45,7 +56,15 @@
       # @param [String,Symbol] name
       # @param [Object] value
       def []=(name, value)
-        public_send(:"#{name}=", value)
+        raise FrozenConfig, "Cannot modify frozen config" if frozen?
+
+        name = name.to_sym
+
+        unless (setting = _settings[name])
+          raise ArgumentError, "+#{name}+ is not a setting name"
+        end
+
+        _values[name] = setting.constructor.(value)
       end
 
       # Update config with new values
@@ -70,61 +89,96 @@
         self
       end
 
-      # Dump config into a hash
+      # Returns true if the value for the given key has been set on this 
config.
+      #
+      # For simple values, this returns true if the value has been explicitly 
assigned.
+      #
+      # For cloneable (mutable) values, since these are captured on read, 
returns true if the value
+      # does not compare equally to its corresdponing default value. This 
relies on these objects
+      # having functioning `#==` checks.
+      #
+      # @return [Bool]
+      #
+      # @api public
+      def configured?(key)
+        if _settings[key].cloneable? && _values.key?(key)
+          return _values[key] != _settings[key].to_value
+        end
+
+        _values.key?(key)
+      end
+
+      # Returns the current config values.
+      #
+      # Nested configs remain in their {Config} instances.
       #
       # @return [Hash]
       #
       # @api public
       def values
-        _settings
-          .map { |setting| [setting.name, setting.value] }
-          .map { |key, value| [key, value.is_a?(self.class) ? value.to_h : 
value] }
-          .to_h
+        _settings.to_h { |setting| [setting.name, self[setting.name]] }
+      end
+
+      # Returns config values as a hash, with nested values also converted 
from {Config} instances
+      # into hashes.
+      #
+      # @return [Hash]
+      #
+      # @api public
+      def to_h
+        values.to_h { |key, value| [key, value.is_a?(self.class) ? value.to_h 
: value] }
       end
-      alias_method :to_h, :values
 
       # @api private
       def finalize!(freeze_values: false)
-        _settings.finalize!(freeze_values: freeze_values)
+        values.each_value do |value|
+          if value.is_a?(self.class)
+            value.finalize!(freeze_values: freeze_values)
+          elsif freeze_values
+            value.freeze
+          end
+        end
+
         freeze
       end
 
       # @api private
       def pristine
-        self.class.new(_settings.pristine)
-      end
-
-      # @api private
-      def respond_to_missing?(meth, include_private = false)
-        super || _settings.key?(resolve(meth))
+        self.class.new(_settings)
       end
 
       private
 
-      # @api private
-      def method_missing(meth, *args)
-        setting = _settings[resolve(meth)]
+      def method_missing(name, *args)
+        setting_name = setting_name_from_method(name)
+        setting = _settings[setting_name]
 
         super unless setting
 
-        if setting.writer?(meth)
-          raise FrozenConfig, "Cannot modify frozen config" if frozen?
-
-          _settings << setting.with(input: args[0])
+        if name.end_with?("=")
+          self[setting_name] = args[0]
         else
-          setting.value
+          self[setting_name]
         end
       end
 
-      # @api private
-      def resolve(meth)
-        _resolved.fetch(meth) { _resolved[meth] = meth.to_s.tr("=", "").to_sym 
}
+      def respond_to_missing?(meth, include_private = false)
+        _settings.key?(setting_name_from_method(meth)) || super
+      end
+
+      def setting_name_from_method(method_name)
+        method_name.to_s.tr("=", "").to_sym
+      end
+
+      def dup_values
+        _values.each_with_object({}) { |(key, val), dup_hsh|
+          dup_hsh[key] = _settings[key].cloneable? ? val.dup : val
+        }
       end
 
-      # @api private
       def initialize_copy(source)
         super
-        @_settings = source._settings.dup
+        @_values = source.__send__(:dup_values)
       end
     end
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dry/configurable/dsl.rb 
new/lib/dry/configurable/dsl.rb
--- old/lib/dry/configurable/dsl.rb     2022-04-21 09:30:01.000000000 +0200
+++ new/lib/dry/configurable/dsl.rb     2022-10-08 01:24:53.000000000 +0200
@@ -1,10 +1,5 @@
 # frozen_string_literal: true
 
-require "dry/configurable/constants"
-require "dry/configurable/flags"
-require "dry/configurable/setting"
-require "dry/configurable/settings"
-require "dry/configurable/compiler"
 require "dry/core/deprecations"
 
 module Dry
@@ -15,16 +10,16 @@
     class DSL
       VALID_NAME = /\A[a-z_]\w*\z/i.freeze
 
-      # @api private
       attr_reader :compiler
 
-      # @api private
       attr_reader :ast
 
-      # @api private
-      def initialize(&block)
+      attr_reader :options
+
+      def initialize(**options, &block)
         @compiler = Compiler.new
         @ast = []
+        @options = options
         instance_exec(&block) if block
       end
 
@@ -33,106 +28,15 @@
       # @see ClassMethods.setting
       # @api private
       # @return Setting
-      def setting(name, default = Undefined, **options, &block) # 
rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, 
Metrics/PerceivedComplexity
+      def setting(name, **options, &block) # rubocop:disable Metrics/AbcSize, 
Metrics/PerceivedComplexity
         unless VALID_NAME.match?(name.to_s)
           raise ArgumentError, "#{name} is not a valid setting name"
         end
 
-        if default != Undefined
-          if Dry::Configurable.warn_on_setting_positional_default
-            Dry::Core::Deprecations.announce(
-              "default value as positional argument to settings",
-              "Provide a `default:` keyword argument instead",
-              tag: "dry-configurable",
-              uplevel: 2
-            )
-          end
-
-          options = options.merge(default: default)
-        end
-
-        if RUBY_VERSION < "3.0" &&
-           default == Undefined &&
-           (valid_opts, invalid_opts = valid_and_invalid_options(options)) &&
-           invalid_opts.any? &&
-           valid_opts.none?
-          # In Ruby 2.6 and 2.7, when a hash is given as the second positional 
argument
-          # (i.e. the hash is intended to be the setting's default value), and 
there are
-          # no other keyword arguments given, the hash is assigned to the 
`options`
-          # variable instead of `default`.
-          #
-          # For example, for this setting:
-          #
-          #   setting :hash_setting, {my_hash: true}
-          #
-          # We'll have a `default` of `Undefined` and an `options` of 
`{my_hash: true}`
-          #
-          # If any additional keyword arguments are provided, e.g.:
-          #
-          #   setting :hash_setting, {my_hash: true}, reader: true
-          #
-          # Then we'll have a `default` of `{my_hash: true}` and an `options` 
of `{reader:
-          # true}`, which is what we want.
-          #
-          # To work around that first case and ensure our (deprecated) 
backwards
-          # compatibility holds for Ruby 2.6 and 2.7, we extract all invalid 
options from
-          # `options`, and if there are no remaining valid options (i.e. if 
there were no
-          # keyword arguments given), then we can infer the invalid options to 
be a
-          # default hash value for the setting.
-          #
-          # This approach also preserves the behavior of raising an 
ArgumentError when a
-          # distinct hash is _not_ intentionally provided as the second 
positional
-          # argument (i.e. it's not enclosed in braces), and instead invalid 
keyword
-          # arguments are given alongside valid ones. So this setting:
-          #
-          #   setting :some_setting, invalid_option: true, reader: true
-          #
-          # Would raise an ArgumentError as expected.
-          #
-          # However, the one case we can't catch here is when invalid options 
are supplied
-          # without hash literal braces, but there are no other keyword 
arguments
-          # supplied. In this case, a setting like:
-          #
-          #   setting :hash_setting, my_hash: true
-          #
-          # Is parsed identically to the first case described above:
-          #
-          #   setting :hash_setting, {my_hash: true}
-          #
-          # So in both of these cases, the default value will become 
`{my_hash: true}`. We
-          # consider this unlikely to be a problem in practice, since users 
are not likely
-          # to be providing invalid options to `setting` and expecting them to 
be ignored.
-          # Additionally, the deprecation messages will make the new behavior 
obvious, and
-          # encourage the users to upgrade their setting definitions.
-
-          if Dry::Configurable.warn_on_setting_positional_default
-            Dry::Core::Deprecations.announce(
-              "default value as positional argument to settings",
-              "Provide a `default:` keyword argument instead",
-              tag: "dry-configurable",
-              uplevel: 2
-            )
-          end
-
-          options = {default: invalid_opts}
-        end
-
-        if block && !block.arity.zero?
-          if Dry::Configurable.warn_on_setting_constructor_block
-            Dry::Core::Deprecations.announce(
-              "passing a constructor as a block",
-              "Provide a `constructor:` keyword argument instead",
-              tag: "dry-configurable",
-              uplevel: 2
-            )
-          end
-
-          options = options.merge(constructor: block)
-          block = nil
-        end
-
         ensure_valid_options(options)
 
+        options = {default: default, config_class: config_class, **options}
+
         node = [:setting, [name.to_sym, options]]
 
         if block
@@ -144,6 +48,14 @@
         compiler.visit(ast.last)
       end
 
+      def config_class
+        options[:config_class]
+      end
+
+      def default
+        options[:default_undefined] ? Undefined : nil
+      end
+
       private
 
       def ensure_valid_options(options)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dry/configurable/extension.rb 
new/lib/dry/configurable/extension.rb
--- old/lib/dry/configurable/extension.rb       1970-01-01 01:00:00.000000000 
+0100
+++ new/lib/dry/configurable/extension.rb       2022-10-08 01:24:53.000000000 
+0200
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+module Dry
+  module Configurable
+    class Extension < Module
+      # @api private
+      attr_reader :config_class
+
+      # @api private
+      attr_reader :default_undefined
+
+      # @api private
+      def initialize(config_class: Configurable::Config, default_undefined: 
false)
+        super()
+        @config_class = config_class
+        @default_undefined = default_undefined
+        freeze
+      end
+
+      # @api private
+      def extended(klass)
+        super
+        klass.extend(ClassMethods)
+        klass.instance_variable_set(:@__config_extension__, self)
+      end
+
+      # @api private
+      def included(klass)
+        raise AlreadyIncluded if klass.include?(InstanceMethods)
+
+        super
+
+        klass.class_eval do
+          extend(ClassMethods)
+          include(InstanceMethods)
+          prepend(Initializer)
+
+          class << self
+            undef :config
+            undef :configure
+          end
+        end
+
+        klass.instance_variable_set(:@__config_extension__, self)
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dry/configurable/flags.rb 
new/lib/dry/configurable/flags.rb
--- old/lib/dry/configurable/flags.rb   2022-04-21 09:30:01.000000000 +0200
+++ new/lib/dry/configurable/flags.rb   1970-01-01 01:00:00.000000000 +0100
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-require "dry/core/class_attributes"
-
-module Dry
-  module Configurable
-    extend Core::ClassAttributes
-
-    # Set to false to suppress deprecation warning when a setting default is 
provided as a
-    # positional argument
-    defines :warn_on_setting_positional_default
-    warn_on_setting_positional_default true
-
-    # Set to false to suppress deprecation warning when a setting constructor 
is provided
-    # as a block
-    defines :warn_on_setting_constructor_block
-    warn_on_setting_constructor_block true
-  end
-end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dry/configurable/instance_methods.rb 
new/lib/dry/configurable/instance_methods.rb
--- old/lib/dry/configurable/instance_methods.rb        2022-04-21 
09:30:01.000000000 +0200
+++ new/lib/dry/configurable/instance_methods.rb        2022-10-08 
01:24:53.000000000 +0200
@@ -12,10 +12,7 @@
     module Initializer
       # @api private
       def initialize(*)
-        # Dup settings at time of initializing to ensure setting values are 
specific to
-        # this instance. This does mean that any settings defined on the class 
_after_
-        # initialization will not be available on the instance.
-        @config = Config.new(self.class._settings.dup)
+        @config = self.class.__config_build__(self.class._settings)
 
         super
       end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dry/configurable/methods.rb 
new/lib/dry/configurable/methods.rb
--- old/lib/dry/configurable/methods.rb 2022-04-21 09:30:01.000000000 +0200
+++ new/lib/dry/configurable/methods.rb 2022-10-08 01:24:53.000000000 +0200
@@ -1,7 +1,5 @@
 # frozen_string_literal: true
 
-require "dry/configurable/errors"
-
 module Dry
   module Configurable
     # Common API for both classes and instances
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dry/configurable/setting.rb 
new/lib/dry/configurable/setting.rb
--- old/lib/dry/configurable/setting.rb 2022-04-21 09:30:01.000000000 +0200
+++ new/lib/dry/configurable/setting.rb 2022-10-08 01:24:53.000000000 +0200
@@ -4,18 +4,15 @@
 
 require "dry/core/equalizer"
 
-require "dry/configurable/constants"
-require "dry/configurable/config"
-
 module Dry
   module Configurable
     # This class represents a setting and is used internally.
     #
     # @api private
     class Setting
-      include Dry::Equalizer(:name, :value, :options, inspect: false)
+      include Dry::Equalizer(:name, :default, :constructor, :children, 
:options, inspect: false)
 
-      OPTIONS = %i[input default reader constructor cloneable settings].freeze
+      OPTIONS = %i[default reader constructor cloneable settings 
config_class].freeze
 
       DEFAULT_CONSTRUCTOR = -> v { v }.freeze
 
@@ -25,105 +22,35 @@
       attr_reader :name
 
       # @api private
-      attr_reader :writer_name
+      attr_reader :default
 
       # @api private
-      attr_reader :input
+      attr_reader :constructor
 
       # @api private
-      attr_reader :default
+      attr_reader :children
 
       # @api private
       attr_reader :options
 
-      # Specialized Setting which includes nested settings
-      #
-      # @api private
-      class Nested < Setting
-        CONSTRUCTOR = Config.method(:new)
-
-        # @api private
-        def pristine
-          with(input: input.pristine)
-        end
-
-        # @api private
-        def constructor
-          CONSTRUCTOR
-        end
-      end
-
       # @api private
       def self.cloneable_value?(value)
         CLONEABLE_VALUE_TYPES.any? { |type| value.is_a?(type) }
       end
 
       # @api private
-      def initialize(name, input: Undefined, default: Undefined, **options)
+      def initialize(
+        name,
+        default:,
+        constructor: DEFAULT_CONSTRUCTOR,
+        children: EMPTY_ARRAY,
+        **options
+      )
         @name = name
-        @writer_name = :"#{name}="
-        @options = options
-
-        # Setting collections (see `Settings`) are shared between the 
configurable class
-        # and its `config` object, so for cloneable individual settings, we 
duplicate
-        # their _values_ as early as possible to ensure no impact from 
unintended mutation
-        @input = input
         @default = default
-        if cloneable?
-          @input = input.dup
-          @default = default.dup
-        end
-
-        evaluate if input_defined?
-      end
-
-      # @api private
-      def input_defined?
-        !input.equal?(Undefined)
-      end
-
-      # @api private
-      def value
-        return @value if evaluated?
-
-        @value = constructor[Undefined.coalesce(input, default, nil)]
-      end
-      alias_method :evaluate, :value
-      private :evaluate
-
-      # @api private
-      def evaluated?
-        instance_variable_defined?(:@value)
-      end
-
-      # @api private
-      def nested(settings)
-        Nested.new(name, input: settings, **options)
-      end
-
-      # @api private
-      def pristine
-        with(input: Undefined)
-      end
-
-      # @api private
-      def finalize!(freeze_values: false)
-        if value.is_a?(Config)
-          value.finalize!(freeze_values: freeze_values)
-        elsif freeze_values
-          value.freeze
-        end
-        freeze
-      end
-
-      # @api private
-      def with(new_opts)
-        self.class.new(name, input: input, default: default, **options, 
**new_opts)
-      end
-
-      # @api private
-      def constructor
-        options[:constructor] || DEFAULT_CONSTRUCTOR
+        @constructor = constructor
+        @children = children
+        @options = options
       end
 
       # @api private
@@ -132,35 +59,19 @@
       end
 
       # @api private
-      def writer?(meth)
-        writer_name.equal?(meth)
-      end
-
-      # @api private
       def cloneable?
-        if options.key?(:cloneable)
-          # Return cloneable option if explicitly set
-          options[:cloneable]
-        else
-          # Otherwise, infer cloneable from any of the input, default, or value
-          Setting.cloneable_value?(input) || Setting.cloneable_value?(default) 
|| (
-            evaluated? && Setting.cloneable_value?(value)
-          )
-        end
+        children.any? || options.fetch(:cloneable) { 
Setting.cloneable_value?(default) }
       end
 
-      private
-
       # @api private
-      def initialize_copy(source)
-        super
-
-        @options = source.options.dup
+      def to_value
+        if children.any?
+          (options[:config_class] || Config).new(children)
+        else
+          value = default
+          value = constructor.(value) unless value.eql?(Undefined)
 
-        if source.cloneable?
-          @input = source.input.dup
-          @default = source.default.dup
-          @value = source.value.dup if source.evaluated?
+          cloneable? ? value.dup : value
         end
       end
     end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dry/configurable/settings.rb 
new/lib/dry/configurable/settings.rb
--- old/lib/dry/configurable/settings.rb        2022-04-21 09:30:01.000000000 
+0200
+++ new/lib/dry/configurable/settings.rb        2022-10-08 01:24:53.000000000 
+0200
@@ -1,9 +1,6 @@
 # frozen_string_literal: true
 
-require "concurrent/map"
-
 require "dry/core/equalizer"
-require "dry/configurable/constants"
 
 module Dry
   module Configurable
@@ -11,27 +8,27 @@
     #
     # @api private
     class Settings
-      include Dry::Equalizer(:elements)
+      include Dry::Equalizer(:settings)
 
       include Enumerable
 
       # @api private
-      attr_reader :elements
+      attr_reader :settings
 
       # @api private
-      def initialize(elements = EMPTY_ARRAY)
-        initialize_elements(elements)
+      def initialize(settings = EMPTY_ARRAY)
+        @settings = settings.each_with_object({}) { |s, m| m[s.name] = s }
       end
 
       # @api private
       def <<(setting)
-        elements[setting.name] = setting
+        settings[setting.name] = setting
         self
       end
 
       # @api private
       def [](name)
-        elements[name]
+        settings[name]
       end
 
       # @api private
@@ -41,37 +38,18 @@
 
       # @api private
       def keys
-        elements.keys
+        settings.keys
       end
 
       # @api private
       def each(&block)
-        elements.values.each(&block)
-      end
-
-      # @api private
-      def pristine
-        self.class.new(map(&:pristine))
-      end
-
-      # @api private
-      def finalize!(freeze_values: false)
-        each { |element| element.finalize!(freeze_values: freeze_values) }
-        freeze
+        settings.each_value(&block)
       end
 
       private
 
-      # @api private
       def initialize_copy(source)
-        initialize_elements(source.map(&:dup))
-      end
-
-      # @api private
-      def initialize_elements(elements)
-        @elements = elements.each_with_object(Concurrent::Map.new) { |s, m|
-          m[s.name] = s
-        }
+        @settings = source.settings.dup
       end
     end
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dry/configurable/version.rb 
new/lib/dry/configurable/version.rb
--- old/lib/dry/configurable/version.rb 2022-04-21 09:30:01.000000000 +0200
+++ new/lib/dry/configurable/version.rb 2022-10-08 01:24:53.000000000 +0200
@@ -3,6 +3,6 @@
 module Dry
   module Configurable
     # @api public
-    VERSION = "0.15.0"
+    VERSION = "0.16.0"
   end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/dry/configurable.rb new/lib/dry/configurable.rb
--- old/lib/dry/configurable.rb 2022-04-21 09:30:01.000000000 +0200
+++ new/lib/dry/configurable.rb 2022-10-08 01:24:53.000000000 +0200
@@ -1,15 +1,17 @@
 # frozen_string_literal: true
 
-require "concurrent/array"
+require "zeitwerk"
 
+require "dry/core/constants"
 require "dry/configurable/constants"
-require "dry/configurable/class_methods"
-require "dry/configurable/instance_methods"
-require "dry/configurable/config"
-require "dry/configurable/setting"
 require "dry/configurable/errors"
 
 module Dry
+  # @api public
+  def self.Configurable(**options)
+    Configurable::Extension.new(**options)
+  end
+
   # A simple configuration mixin
   #
   # @example class-level configuration
@@ -44,27 +46,32 @@
   #
   # @api public
   module Configurable
+    def self.loader
+      @loader ||= Zeitwerk::Loader.new.tap do |loader|
+        root = File.expand_path("..", __dir__)
+        loader.tag = "dry-configurable"
+        loader.inflector = 
Zeitwerk::GemInflector.new("#{root}/dry-configurable.rb")
+        loader.push_dir(root)
+        loader.ignore(
+          "#{root}/dry-configurable.rb",
+          "#{root}/dry/configurable/{constants,errors,version}.rb"
+        )
+        loader.inflector.inflect("dsl" => "DSL")
+      end
+    end
+
     # @api private
     def self.extended(klass)
       super
-      klass.extend(ClassMethods)
+      klass.extend(Extension.new)
     end
 
     # @api private
     def self.included(klass)
-      raise AlreadyIncluded if klass.include?(InstanceMethods)
-
       super
-      klass.class_eval do
-        extend(ClassMethods)
-        include(InstanceMethods)
-        prepend(Initializer)
-
-        class << self
-          undef :config
-          undef :configure
-        end
-      end
+      klass.include(Extension.new)
     end
+
+    loader.setup
   end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata        2022-04-21 09:30:01.000000000 +0200
+++ new/metadata        2022-10-08 01:24:53.000000000 +0200
@@ -1,43 +1,43 @@
 --- !ruby/object:Gem::Specification
 name: dry-configurable
 version: !ruby/object:Gem::Version
-  version: 0.15.0
+  version: 0.16.0
 platform: ruby
 authors:
 - Andy Holland
-autorequire: 
+autorequire:
 bindir: bin
 cert_chain: []
-date: 2022-04-21 00:00:00.000000000 Z
+date: 2022-10-07 00:00:00.000000000 Z
 dependencies:
 - !ruby/object:Gem::Dependency
-  name: concurrent-ruby
+  name: dry-core
   requirement: !ruby/object:Gem::Requirement
     requirements:
     - - "~>"
       - !ruby/object:Gem::Version
-        version: '1.0'
+        version: '0.6'
   type: :runtime
   prerelease: false
   version_requirements: !ruby/object:Gem::Requirement
     requirements:
     - - "~>"
       - !ruby/object:Gem::Version
-        version: '1.0'
+        version: '0.6'
 - !ruby/object:Gem::Dependency
-  name: dry-core
+  name: zeitwerk
   requirement: !ruby/object:Gem::Requirement
     requirements:
     - - "~>"
       - !ruby/object:Gem::Version
-        version: '0.6'
+        version: '2.6'
   type: :runtime
   prerelease: false
   version_requirements: !ruby/object:Gem::Requirement
     requirements:
     - - "~>"
       - !ruby/object:Gem::Version
-        version: '0.6'
+        version: '2.6'
 - !ruby/object:Gem::Dependency
   name: bundler
   requirement: !ruby/object:Gem::Requirement
@@ -99,7 +99,7 @@
 - lib/dry/configurable/constants.rb
 - lib/dry/configurable/dsl.rb
 - lib/dry/configurable/errors.rb
-- lib/dry/configurable/flags.rb
+- lib/dry/configurable/extension.rb
 - lib/dry/configurable/instance_methods.rb
 - lib/dry/configurable/methods.rb
 - lib/dry/configurable/setting.rb
@@ -114,7 +114,7 @@
   changelog_uri: 
https://github.com/dry-rb/dry-configurable/blob/main/CHANGELOG.md
   source_code_uri: https://github.com/dry-rb/dry-configurable
   bug_tracker_uri: https://github.com/dry-rb/dry-configurable/issues
-post_install_message: 
+post_install_message:
 rdoc_options: []
 require_paths:
 - lib
@@ -129,8 +129,8 @@
     - !ruby/object:Gem::Version
       version: '0'
 requirements: []
-rubygems_version: 3.1.6
-signing_key: 
+rubygems_version: 3.3.7
+signing_key:
 specification_version: 4
 summary: A mixin to add configuration functionality to your classes
 test_files: []

Reply via email to