class Contracts::ArgsValidator
Attributes
args_contracts[RW]
args_validators[RW]
contracts[RW]
klass[RW]
method[RW]
splat_args_contract_index[RW]
Public Class Methods
new(opts)
click to toggle source
# File lib/contracts/args_validator.rb, line 4 def initialize(opts) @splat_args_contract_index = opts.fetch(:splat_args_contract_index) @klass = opts.fetch(:klass) @method = opts.fetch(:method) @contracts = opts.fetch(:contracts) @args_contracts = opts.fetch(:args_contracts) @args_validators = opts.fetch(:args_validators) end
Public Instance Methods
validate_args_before_splat!(args)
click to toggle source
Loop forward validating the arguments up to the splat (if there is one) may change the `args` param
# File lib/contracts/args_validator.rb, line 15 def validate_args_before_splat!(args) (splat_args_contract_index || args.size).times do |i| validate!(args, i) end end
validate_splat_args_and_after!(args)
click to toggle source
possibilities
-
splat is last argument, like: def hello(a, b, *args)
-
splat is not last argument, like: def hello(*args, n)
# File lib/contracts/args_validator.rb, line 24 def validate_splat_args_and_after!(args) return unless splat_args_contract_index from, count = splat_range(args) validate_splat(args, from, count) splat_upper_bound = from + count return if splat_upper_bound == args.size validate_rest(args, from, splat_upper_bound) end
Private Instance Methods
fail_if_invalid(validator, arg, arg_pos, args_size, contract)
click to toggle source
# File lib/contracts/args_validator.rb, line 82 def fail_if_invalid(validator, arg, arg_pos, args_size, contract) return if validator && validator.call(arg) throw :return, Contracts::CallWith::SILENT_FAILURE unless Contract.failure_callback( :arg => arg, :contract => contract, :class => klass, :method => method, :contracts => contracts, :arg_pos => arg_pos, :total_args => args_size, :return_value => false ) end
splat_range(args)
click to toggle source
-
2, 3, 4, 5 >>> 0, 4
-
2 >>> 0, 1
-
2, 3, 4, 5, 6, 7 >>> 0, 6
# File lib/contracts/args_validator.rb, line 65 def splat_range(args) args_after_splat = args_contracts.size - (splat_args_contract_index + 1) in_splat = args.size - args_after_splat - splat_args_contract_index [splat_args_contract_index, in_splat] end
validate!(args, index, contract = nil, validator = nil)
click to toggle source
# File lib/contracts/args_validator.rb, line 72 def validate!(args, index, contract = nil, validator = nil) arg = args[index] contract ||= args_contracts[index] validator ||= args_validators[index] fail_if_invalid(validator, arg, index + 1, args.size, contract) return unless contract.is_a?(Contracts::Func) args[index] = Contract.new(klass, arg, *contract.contracts) end
validate_rest(args, from, splat_upper_bound)
click to toggle source
# File lib/contracts/args_validator.rb, line 46 def validate_rest(args, from, splat_upper_bound) args[splat_upper_bound..-1].each_with_index do |_arg, index| arg_index = splat_upper_bound + index contract_index = from + index + 1 contract = args_contracts[contract_index] validator = args_validators[contract_index] validate!(args, arg_index, contract, validator) end end
validate_splat(args, from, count)
click to toggle source
# File lib/contracts/args_validator.rb, line 37 def validate_splat(args, from, count) args.slice(from, count).each_with_index do |_arg, index| arg_index = from + index contract = args_contracts[from] validator = args_validators[from] validate!(args, arg_index, contract, validator) end end