class Contract
This is the main Contract
class. When you write a new contract, you'll write it as:
Contract [contract names] => return_value
This class also provides useful callbacks and a validation method.
Attributes
args_contracts[R]
args_validators[R]
klass[R]
method[R]
ret_contract[R]
ret_validator[R]
Public Class Methods
new(klass, method, *contracts)
click to toggle source
# File lib/contracts/contract.rb, line 24 def initialize(klass, method, *contracts) contracts = correct_ret_only_contract(contracts, method) # internally we just convert that return value syntax back to an array @args_contracts = contracts[0, contracts.size - 1] + contracts[-1].keys @ret_contract = contracts[-1].values[0] determine_has_proc_contract! determine_has_options_contract! @pattern_match = false @klass = klass @method = method end
valid?(arg, contract)
click to toggle source
Used to verify if an argument satisfies a contract.
Takes: an argument and a contract.
Returns: a tuple: [Boolean, metadata]. The boolean indicates whether the contract was valid or not. If it wasn't, metadata contains some useful information about the failure.
# File lib/contracts/contract.rb, line 19 def self.valid?(arg, contract) make_validator(contract)[arg] end
Public Instance Methods
[](*args, &blk)
click to toggle source
# File lib/contracts/contract.rb, line 43 def [](*args, &blk) call(*args, &blk) end
call(*args, &blk)
click to toggle source
# File lib/contracts/contract.rb, line 47 def call(*args, &blk) call_with(nil, *args, &blk) end
failure_exception()
click to toggle source
Used to determine type of failure exception this contract should raise in case of failure
# File lib/contracts/contract.rb, line 62 def failure_exception return PatternMatchingError if pattern_match? ParamContractError end
pattern_match!()
click to toggle source
mark contract as pattern matching contract
# File lib/contracts/contract.rb, line 52 def pattern_match! @pattern_match = true end
pattern_match?()
click to toggle source
Used to determine if contract is a pattern matching contract
# File lib/contracts/contract.rb, line 57 def pattern_match? @pattern_match end
to_s()
click to toggle source
# File lib/contracts/contract.rb, line 39 def to_s "#{args_contracts_to_s} => #{ret_contract_to_s}".gsub!("Contracts::Builtin::", "") end
Private Instance Methods
args_contracts_to_s()
click to toggle source
# File lib/contracts/contract.rb, line 112 def args_contracts_to_s args_contracts.map { |c| pretty_contract(c) }.join(", ") end
correct_ret_only_contract(contracts, method)
click to toggle source
BEFORE
Contracts::Builtin::Num
-
AFTER:
- {nil=>Contracts::Builtin::Num}
# File lib/contracts/contract.rb, line 73 def correct_ret_only_contract(contracts, method) unless contracts.last.is_a?(Hash) unless contracts.one? raise %{ It looks like your contract for #{method.name} doesn't have a return value. A contract should be written as `Contract arg1, arg2 => return_value`. }.strip end contracts = [nil => contracts[-1]] end contracts end
determine_has_options_contract!()
click to toggle source
# File lib/contracts/contract.rb, line 107 def determine_has_options_contract! relevant_contract = (@has_proc_contract ? args_contracts[-2] : args_contracts[-1]) @has_options_contract = kinda_hash?(relevant_contract) end
determine_has_proc_contract!()
click to toggle source
# File lib/contracts/contract.rb, line 103 def determine_has_proc_contract! @has_proc_contract = kinda_proc?(args_contracts.last) end
kinda_hash?(v)
click to toggle source
# File lib/contracts/contract.rb, line 125 def kinda_hash?(v) v.is_a?(Hash) || v.is_a?(Contracts::Builtin::KeywordArgs) end
kinda_proc?(v)
click to toggle source
# File lib/contracts/contract.rb, line 129 def kinda_proc?(v) is_a_proc = v.is_a?(Class) && (v <= Proc || v <= Method) maybe_a_proc = v.is_a?(Contracts::Maybe) && v.include_proc? is_func_contract = v.is_a?(Contracts::Func) (is_a_proc || maybe_a_proc || is_func_contract) end
pretty_contract(c)
click to toggle source
# File lib/contracts/contract.rb, line 120 def pretty_contract(c) return c.name if c.is_a?(Class) c.class.name end
ret_contract_to_s()
click to toggle source
# File lib/contracts/contract.rb, line 116 def ret_contract_to_s pretty_contract(ret_contract) end
splat_args_contract_index()
click to toggle source
# File lib/contracts/contract.rb, line 87 def splat_args_contract_index @splat_args_contract_index ||= args_contracts.index do |contract| contract.is_a?(Contracts::SplatArgs) end end