class Stannum::Contracts::ParametersContract
A Parameters
defines constraints on the parameters for a block or method.
The ParametersContract
requires that the actual object matched be a Hash with the following keys: :arguments, with an Array value; :keywords, with a Hash value; and :block, with a value of either a Proc or nil.
For the arguments constraints, the contract verifies that the correct number of arguments are given and that each argument matches the type or constraint specified. If the contract has a variadic arguments constraint, then each variadic (or “splatted”) argument is checked against the type or constraint.
For the keywords constraints, the contract verifies that the expected keywords are given and that each keyword value matches the type or constraint specified. If the contract has a variadic keywords constraint, then each variadic keyword value is checked against the type or constraint.
For the block constraint, the contract specifies that the block is present, the block is absent, or the block matches the given constraint.
@example Defining A Parameters
Contract
With Arguments
contract = Stannum::Contracts::ParametersContract.new do argument :name, String argument :size, String, default: true end contract.matches?( { arguments: [], keywords: {}, block: nil } ) #=> false contract.matches?( { arguments: [:a_symbol], keywords: {}, block: nil } ) #=> false contract.matches?( { arguments: ['Widget', 'Small', :extra], keywords: {}, block: nil } ) #=> false contract.matches?( { arguments: ['Widget', 'Small', :extra], keywords: {}, block: nil } ) #=> false contract.matches?( { arguments: ['Widget'], keywords: {}, block: nil } ) #=> true contract.matches?( { arguments: ['Widget', nil], keywords: {}, block: nil } ) #=> false contract.matches?( { arguments: ['Widget', 'Small'], keywords: {}, block: nil } ) #=> true
@example Defining A Parameters
Contract
With Keywords
contract = Stannum::Contracts::ParametersContract.new do keyword :price, String keyword :quantity, Integer, optional: true end contract.matches?( { arguments: [], keywords: {}, block: nil } ) #=> false contract.matches?( arguments: [], keywords: { price: 1_000_000, }, block: nil ) #=> false contract.matches?( arguments: [], keywords: { currency: 'USD', price: '$1_000_000', }, block: nil ) #=> false contract.matches?( arguments: [], keywords: { price: '$1_000_000', }, block: nil ) #=> true contract.matches?( arguments: [], keywords: { price: '$1_000_000', quantity: 50, }, block: nil ) #=> true
@example Defining A Parameters
Contract
With Variadic Arguments
contract = Stannum::Contracts::ParametersContract.new do arguments :words, String end contract.matches?( { arguments: [1, 2, 3], keywords: {}, block: nil } ) #=> false contract.matches?( { arguments: [], keywords: {}, block: nil } ) #=> true contract.matches?( { arguments: ['foo', 'bar', 'baz'], keywords: {}, block: nil } ) #=> true
@example Defining A Parameters
Contract
With Variadic Keywords
contract = Stannum::Contracts::ParametersContract.new do keywords :options, Symbol end contract.matches?( arguments: [], keywords: { price: 1_000_000, }, block: nil ) #=> false contract.matches?( arguments: [], keywords: {}, block: nil ) #=> true contract.matches?( arguments: [], keywords: { color: :red, shape: :triangle }, block: nil ) #=> true
@example Defining A Parameters
Contract
With A Block Constraint
contract = Stannum::Contracts::ParametersContract.new do block true end contract.matches?( { arguments: [], keywords: {}, block: nil } ) #=> false contract.matches?( { arguments: [], keywords: {}, block: Proc.new } ) #=> true
Attributes
Public Instance Methods
Adds an argument constraint to the contract.
Generates an argument constraint based on the given type. If the type is a constraint, then the given constraint will be copied with the given options and added for the argument at the index. If the type is a Class or a Module, then a Stannum::Constraints::Type
constraint will be created with the given type and options and added for the argument.
If the index is specified, then the constraint will be added for the argument at the specified index. If the index is not given, then the constraint will be applied to the next unconstrained argument. For example, the first argument constraint will be added for the argument at index 0, the second constraint for the argument at index 1, and so on.
@param index [Integer, nil] The index of the argument. If not given, then
the next argument will be constrained with the type.
@param type [Class, Module, Stannum::Constraints
:Base] The expected type
of the argument.
@param options [Hash<Symbol, Object>] Configuration options for the
constraint. Defaults to an empty Hash.
@return [Stannum::Contracts::ParametersContract] the contract.
# File lib/stannum/contracts/parameters_contract.rb, line 398 def add_argument_constraint(index, type, **options) arguments_contract.add_argument_constraint(index, type, **options) self end
Adds a keyword constraint to the contract.
Generates a keyword constraint based on the given type. If the type is a constraint, then the given constraint will be copied with the given options and added for the given keyword. If the type is a Class or a Module, then a Stannum::Constraints::Type
constraint will be created with the given type and options and added for the keyword.
@param keyword [Symbol] The keyword to constrain. @param type [Class, Module, Stannum::Constraints
:Base] The expected type
of the argument.
@param options [Hash<Symbol, Object>] Configuration options for the
constraint. Defaults to an empty Hash.
@return [Stannum::Contracts::ParametersContract] the contract.
# File lib/stannum/contracts/parameters_contract.rb, line 419 def add_keyword_constraint(keyword, type, **options) keywords_contract.add_keyword_constraint(keyword, type, **options) self end
Sets the variadic arguments constraint for the contract.
If the parameters includes variadic (or “splatted”) arguments, then each item in the variadic arguments array must match the given type or constraint. If the type is a constraint, then the given constraint will be copied with the given options. If the type is a Class or a Module, then a Stannum::Constraints::Type
constraint will be created with the given type.
@param name [String, Symbol] a human-readable name for the variadic
arguments; used in generating error messages.
@param type [Class, Module, Stannum::Constraints
:Base] The expected type
of the variadic arguments items.
@return [Stannum::Contracts::ParametersContract] the contract.
@raise [RuntimeError] if there is already a variadic arguments constraint
defined for the contract.
# File lib/stannum/contracts/parameters_contract.rb, line 442 def set_arguments_item_constraint(name, type) arguments_contract.set_variadic_item_constraint(type, as: name) self end
Sets the block parameter constraint for the contract.
If the expected presence is true, a block must be given as part of the parameters. If the expected presence is false, a block must not be given. If the presence is a constraint, then the block must match the constraint.
@param present [true, false, Stannum::Constraint
] The expected presence of
the block.
@return [Stannum::Contracts::ParametersContract] the contract.
@raise [RuntimeError] if there is already a block constraint defined for
the contract.
# File lib/stannum/contracts/parameters_contract.rb, line 461 def set_block_constraint(present) # rubocop:disable Naming/AccessorMethodName raise 'block constraint is already set' if @block_constraint @block_constraint = build_block_constraint(present) add_key_constraint(:block, @block_constraint) end
Sets the variadic keywords constraint for the contract.
If the parameters includes variadic (or “splatted”) keywords, then each value in the variadic keywords hash must match the given type or constraint. If the type is a constraint, then the given constraint will be copied with the given options. If the type is a Class or a Module, then a Stannum::Constraints::Type
constraint will be created with the given type.
@param name [String, Symbol] a human-readable name for the variadic
keywords; used in generating error messages.
@param type [Class, Module, Stannum::Constraints
:Base] The expected type
of the variadic keywords values.
@return [Stannum::Contracts::ParametersContract] the contract.
@raise [RuntimeError] if there is already a variadic keywords constraint
defined for the contract.
# File lib/stannum/contracts/parameters_contract.rb, line 486 def set_keywords_value_constraint(name, type) keywords_contract.set_variadic_value_constraint(type, as: name) self end
Private Instance Methods
# File lib/stannum/contracts/parameters_contract.rb, line 496 def add_extra_keys_constraint; end
# File lib/stannum/contracts/parameters_contract.rb, line 498 def add_type_constraint add_constraint \ Stannum::Contracts::Parameters::SignatureContract.new, sanity: true end
# File lib/stannum/contracts/parameters_contract.rb, line 504 def arguments_contract @arguments_contract ||= Stannum::Contracts::Parameters::ArgumentsContract.new end
# File lib/stannum/contracts/parameters_contract.rb, line 509 def build_block_constraint(value) Stannum::Support::Coercion.presence_constraint(value) \ do |present, **options| next Stannum::Constraints::Types::ProcType.new(**options) if present Stannum::Constraints::Types::NilType.new(**options) end end
Stannum::Contracts::MapContract#define_constraints
# File lib/stannum/contracts/parameters_contract.rb, line 518 def define_constraints(&block) super(&block) add_key_constraint :arguments, arguments_contract add_key_constraint :keywords, keywords_contract end
# File lib/stannum/contracts/parameters_contract.rb, line 525 def keywords_contract @keywords_contract ||= Stannum::Contracts::Parameters::KeywordsContract.new end