class Typecheck::SignatureCompiler
Public Instance Methods
call(signature, method)
click to toggle source
# File lib/typecheck.rb, line 10 def call(signature, method) unchecked_method = "#{method}_unchecked" check_args, check_out = parse_sig(signature) ->(*args) do check_args.(*args) __send__(unchecked_method, *args).tap do |result| check_out.(result) end end end
check_array(type, array)
click to toggle source
# File lib/typecheck.rb, line 78 def check_array(type, array) array.all? {|element| check_class(type, element) } end
check_class(klz, value)
click to toggle source
# File lib/typecheck.rb, line 87 def check_class(klz, value) value.is_a? klz end
check_respond_to(method, value)
click to toggle source
# File lib/typecheck.rb, line 69 def check_respond_to(method, value) value.respond_to?(method) end
parse_sig(sig)
click to toggle source
# File lib/typecheck.rb, line 21 def parse_sig(sig) in_t, out_t = sig.split('->').map(&:strip) in_ts = in_t.split(',') in_checks = in_ts.map(&method(:parse_type_list)) out_check = parse_type_list(out_t) args_checker = ->(*args) { args.each.with_index do |arg, idx| in_checks[idx].(arg) end } [args_checker, out_check] end
parse_type(subtype, check_or_raise)
click to toggle source
# File lib/typecheck.rb, line 56 def parse_type(subtype, check_or_raise) pred_and subtype.split(';').map(&:strip).map { |type| case type when /#(.*)/ method("#{check_or_raise}_respond_to").to_proc.curry.(type[1..-1]) when /\[(.*)\]/ method("#{check_or_raise}_array").to_proc.curry.(eval(type[1..-2])) else method("#{check_or_raise}_class").to_proc.curry.(eval(type)) end } end
parse_type_list(choices)
click to toggle source
# File lib/typecheck.rb, line 44 def parse_type_list(choices) types = choices.split('|') pred_or [ pred_or(types.map {|choice| parse_type(choice, :check) }), pred_or(types.map {|choice| parse_type(choice, :raise) }) ] end
pred_and(preds)
click to toggle source
# File lib/typecheck.rb, line 40 def pred_and(preds) ->(value) { preds.all?{|pred| pred.(value) } } end
pred_or(preds)
click to toggle source
# File lib/typecheck.rb, line 36 def pred_or(preds) ->(value) { preds.any?{|pred| pred.(value) } } end
raise_array(type, array)
click to toggle source
# File lib/typecheck.rb, line 82 def raise_array(type, array) raise TypeError, "Bad type: expected #{array} to only contain #{type}" unless check_array(type, array) true end
raise_class(klz, value)
click to toggle source
# File lib/typecheck.rb, line 91 def raise_class(klz, value) raise TypeError, "Bad type: #{value.inspect}, expected #{klz}" unless check_class(klz, value) true end
raise_respond_to(method, value)
click to toggle source
# File lib/typecheck.rb, line 73 def raise_respond_to(method, value) raise TypeError, "Expected #{value.inspect}, to respond_to #{method}" unless check_respond_to(method, value) true end