Flexible type system for Ruby with coercions and constraints
Wrapping constructor types :tada: (@flash-gordon)
Constructor blocks can have a second argument. The second argument is the underlying type itself:
age_from_year = Dry::Types['coercible.integer'].constructor do |input, type|
Date.today.year - type.(input)
end
age_from_year.('2000') # => 21
With wrapping constructors you have control over "type application". You can even run it more than once:
inc = Dry::Types['integer'].constructor(&:succ)
inc2x = inc.constructor { _2.(_2.(_2.(_1))) }
inc2x.(10) # => 13
Fallbacks :tada: (@flash-gordon)
age = Dry::Types['coercible.ineger'].fallback(18)
age.('10') # => 10
age.('20') # => 20
age.('abc') # => 18
Fallbacks are different from default values: the later will be evaluated only when no input provided.
Under the hood, .fallback
creates a wrapping constructor.
params.string
as an alias for strict.string
. This addition should be non-breaking (@flash-gordon)
API for defining custom type builders similar to .default
, .constructor
, or .optional
(@flash-gordon)
# Making an alias for `.fallback`
Dry::Types.define_builder(:or) { |type, v| type.fallback(v) }
# Using new builder
type = Dry::Types['integer'].or(-273)
type.(:invalid) # => -273
Inferring predicates from class names is deprecated. It's very unlikely your code depends on it, however, if it does, you'll get an exception with instructions. (@flash-gordon)
If you don't rely on inferring, just disable it with:
Dry::Types::PredicateInferrer::Compiler.infer_predicate_by_class_name false
Otherwise, enable it explicitly:
Dry::Types::PredicateInferrer::Compiler.infer_predicate_by_class_name true
Schema#merge
for merging two hash schemas (@waiting-for-dev).constructor
to non-constructor types. Now you can call .prepend
/.append
without silly checks for the type being a constructor (flash-gordon)
(Dry::Types['integer'].prepend(-> { _1 + 1 })).(1) # => 2
(Dry::Types['coercible.integer'] >> -> { _1 * 2 }).('99') # => 198
Hash::Schema#clear
returns a schema with the same options but without keysSchema::Key#optional
returns an instance of Schema::Key
as it should have done