module Dry

Namespace for gems in a dry-rb community

The module is responsible for __normalizing__ arguments of `.param` and `.option`.

What the module does is convert the source list of arguments into the standard set of options:

It is this set is used to build [Dry::Initializer::Definition].

@example

# from `option :foo, [], as: :bar, optional: :true
input = { name: :foo, as: :bar, type: [], optional: true }

Dry::Initializer::Dispatcher.call(input)
# => {
#      source:   "foo",
#      target:   "bar",
#      reader:   :public,
#      ivar:     "@bar",
#      type:  ->(v) { Array(v) } }, # simplified for brevity
#      optional: true,
#      default:  -> { Dry::Initializer::UNDEFINED },
#    }

# Settings

The module uses global setting `null` to define what value should be set to variables that kept unassigned. By default it uses `Dry::Initializer::UNDEFINED`

# Syntax Extensions

The module supports syntax extensions. You can add any number of custom dispatchers __on top__ of the stack of default dispatchers. Every dispatcher should be a callable object that takes the source set of options and converts it to another set of options.

@example Add special dispatcher

# Define a dispatcher for key :integer
dispatcher = proc do |integer: false, **opts|
  opts.merge(type: proc(&:to_i)) if integer
end

# Register a dispatcher
Dry::Initializer::Dispatchers << dispatcher

# Now you can use option `integer: true` instead of `type: proc(&:to_i)`
class Foo
  extend Dry::Initializer
  param :id, integer: true
end

Prepare nested data type from a block

@example

option :foo do
  option :bar
  option :qux
end

Checks whether an unwrapped type is valid

Prepares the `:default` option

It must respond to `.call` without arguments

Prepares the variable name of a parameter or an option.

Defines whether an argument is optional

Checks the reader privacy

The dispatcher verifies a correctness of the source name of param or option, taken as a `:source` option.

We allow any stringified name for the source. For example, this syntax is correct because we accept any key in the original hash of arguments, but give them proper names:

“`ruby class Foo

extend Dry::Initializer

option "", as: :first
option 1,  as: :second

end

foo = Foo.new(“”: 42, 1: 666) foo.first # => 42 foo.second # => 666 “`

Prepares the target name of a parameter or an option.

Unlike source, the target must satisfy requirements for Ruby variable names. It also shouldn't be in conflict with names used by the gem.

Looks at the `:type` option and counts how many nested arrays it contains around either nil or a callable value.

The counted number is preserved in the `:wrap` virtual option used by the [WrapType] dispatcher.

Takes `:type` and `:wrap` to construct the final value coercer

The nested structure that takes nested hashes with indifferent access