class Arity::Function
Attributes
callable[R]
Public Class Methods
make(fn, silent: false)
click to toggle source
# File lib/arity/function.rb, line 8 def self.make(fn, silent: false) return new(fn) if fn.respond_to?(:call) return if silent raise NotCallableError, "function is not callable: #{fn.inspect}" end
new(fn)
click to toggle source
# File lib/arity/function.rb, line 14 def initialize(fn) @callable = unwrap_function(fn) end
Public Instance Methods
arity()
click to toggle source
# File lib/arity/function.rb, line 18 def arity callable.arity end
run(*args, **opts)
click to toggle source
# File lib/arity/function.rb, line 50 def run(*args, **opts) args.push(opts) unless opts.empty? callable.call(*args) end
runnable?(*args, **opts)
click to toggle source
# File lib/arity/function.rb, line 46 def runnable?(*args, **opts) takes?(arg_count: args.size, keywords: opts.keys) end
signature()
click to toggle source
# File lib/arity/function.rb, line 22 def signature @signature ||= compute_signature end
takes?(arg_count:, keywords:)
click to toggle source
# File lib/arity/function.rb, line 26 def takes?(arg_count:, keywords:) bad_param('arg_count', 'an int', arg_count) if !arg_count.is_a?(Integer) bad_param('keywords', 'an array', keywords) if !keywords.is_a?(Array) return false if arg_count < signature[:min_args] if signature[:max_args] > -1 return false if arg_count > signature[:max_args] end missing = signature[:required_keys] - keywords return false if !missing.empty? return true if signature[:any_key] extra_keys = keywords - signature[:required_keys] \ - signature[:optional_keys] extra_keys.empty? end
Private Instance Methods
bad_param(name, type, value)
click to toggle source
# File lib/arity/function.rb, line 68 def bad_param(name, type, value) raise ArgumentError, "#{name} must be #{type}, got: #{value.inspect}" end
compute_signature()
click to toggle source
# File lib/arity/function.rb, line 72 def compute_signature splat = false { min_args: 0, max_args: 0, required_keys: [], optional_keys: [], any_key: false }.tap do |signature| callable.parameters.each do |type,name| case type when :req signature[:min_args] += 1 signature[:max_args] += 1 when :opt signature[:max_args] += 1 when :rest splat = true when :key signature[:optional_keys] << name when :keyreq signature[:required_keys] << name when :keyrest signature[:any_key] = true else unknown_parameter_type!(type, name) end end signature[:max_args] = -1 if splat signature[:required_keys].freeze signature[:optional_keys].freeze end.freeze end
unknown_parameter_type!(type, name)
click to toggle source
# File lib/arity/function.rb, line 61 def unknown_parameter_type!(type, name) msg = "do not known how to parse the function signature" msg += " for type #{type.inspect} with parameter #{name.inspect}" msg += "; please file an issue at https://www.github.com/fledman/arity" raise UnknownParameterTypeError, msg end
unwrap_function(fn)
click to toggle source
# File lib/arity/function.rb, line 57 def unwrap_function(fn) fn.respond_to?(:arity) ? fn : fn.method(:call) end