class Dry::Types::Constructor

Constructor types apply a function to the input that is supposed to return a new value. Coercion is a common use case for constructor types.

@api public

@api public

Attributes

fn[R]

@return [#call]

type[R]

@return [Type]

Public Class Methods

[](type, fn:, **options) click to toggle source

@param [Builder, Object] input @param [Hash] options @param [#call, nil] block

@api public

# File lib/dry/types/constructor.rb, line 40
def self.[](type, fn:, **options)
  function = Function[fn]

  if function.wrapper?
    wrapper_type.new(type, fn: function, **options)
  else
    new(type, fn: function, **options)
  end
end
new(input, **options, &block) click to toggle source

@param [Builder, Object] input @param [Hash] options @param [#call, nil] block

@api public

Calls superclass method
# File lib/dry/types/constructor.rb, line 30
def self.new(input, **options, &block)
  type = input.is_a?(Builder) ? input : Nominal.new(input)
  super(type, **options, fn: Function[options.fetch(:fn, block)])
end
new(type, fn: nil, **options) click to toggle source

Instantiate a new constructor type instance

@param [Type] type @param [Function] fn @param [Hash] options

@api private

Calls superclass method
# File lib/dry/types/constructor.rb, line 68
def initialize(type, fn: nil, **options)
  @type = type
  @fn = fn

  super(type, **options, fn: fn)
end
wrapper_type() click to toggle source

@api private

# File lib/dry/types/constructor.rb, line 51
def self.wrapper_type
  @wrapper_type ||= begin
    if self < Wrapper
      self
    else
      const_set(:Wrapping, ::Class.new(self).include(Wrapper))
    end
  end
end

Public Instance Methods

<<(new_fn = nil, **options, &block)
Alias for: prepend
>>(new_fn = nil, **options, &block)
Alias for: constructor
append(new_fn = nil, **options, &block)
Alias for: constructor
call_safe(input) { |output| ... } click to toggle source

@return [Object]

@api private

# File lib/dry/types/constructor.rb, line 78
def call_safe(input)
  coerced = fn.(input) { |output = input| return yield(output) }
  type.call_safe(coerced) { |output = coerced| yield(output) }
end
call_unsafe(input) click to toggle source

@return [Object]

@api private

# File lib/dry/types/constructor.rb, line 86
def call_unsafe(input)
  type.call_unsafe(fn.(input))
end
constrained_type() click to toggle source

@return [Class]

@api private

# File lib/dry/types/constructor.rb, line 130
def constrained_type
  Constrained::Coercible
end
constructor(new_fn = nil, **options, &block) click to toggle source

Build a new constructor by appending a block to the coercion function

@param [#call, nil] new_fn @param [Hash] options @param [#call, nil] block

@return [Constructor]

@api public

# File lib/dry/types/constructor.rb, line 115
def constructor(new_fn = nil, **options, &block)
  next_fn = Function[new_fn || block]

  if next_fn.wrapper?
    self.class.wrapper_type.new(with(**options), fn: next_fn)
  else
    with(**options, fn: fn >> next_fn)
  end
end
Also aliased as: append, >>
lax() click to toggle source

Build a lax type

@return [Lax] @api public

# File lib/dry/types/constructor.rb, line 159
def lax
  Lax.new(constructor_type[type.lax, **options])
end
prepend(new_fn = nil, **options, &block) click to toggle source

Build a new constructor by prepending a block to the coercion function

@param [#call, nil] new_fn @param [Hash] options @param [#call, nil] block

@return [Constructor]

@api public

# File lib/dry/types/constructor.rb, line 150
def prepend(new_fn = nil, **options, &block)
  with(**options, fn: fn << (new_fn || block))
end
Also aliased as: <<
to_ast(meta: true) click to toggle source

@see Nominal#to_ast

@api public

# File lib/dry/types/constructor.rb, line 137
def to_ast(meta: true)
  [:constructor, [type.to_ast(meta: meta), fn.to_ast]]
end
to_proc() click to toggle source

Wrap the type with a proc

@return [Proc]

@api public

# File lib/dry/types/constructor.rb, line 168
def to_proc
  proc { |value| self.(value) }
end
try(input) { |failure| ... } click to toggle source

@param [Object] input @param [#call,nil] block

@return [Logic::Result, Types::Result] @return [Object] if block given and try fails

@api public

# File lib/dry/types/constructor.rb, line 97
def try(input, &block)
  value = fn.(input)
rescue CoercionError => e
  failure = failure(input, e)
  block_given? ? yield(failure) : failure
else
  type.try(value, &block)
end

Private Instance Methods

method_missing(method, *args, &block) click to toggle source

Delegates missing methods to {#type}

@param [Symbol] method @param [Array] args @param [#call, nil] block

@api private

Calls superclass method
# File lib/dry/types/constructor.rb, line 190
def method_missing(method, *args, &block)
  if type.respond_to?(method)
    response = type.public_send(method, *args, &block)

    if response.is_a?(Type) && type.class.equal?(response.class)
      response.constructor_type[response, **options]
    else
      response
    end
  else
    super
  end
end
respond_to_missing?(meth, include_private = false) click to toggle source

@param [Symbol] meth @param [Boolean] include_private @return [Boolean]

@api private

Calls superclass method
# File lib/dry/types/constructor.rb, line 179
def respond_to_missing?(meth, include_private = false)
  super || type.respond_to?(meth)
end