class BusinessFlow::Callable
Isolate the logic around invoking a 'callable' – a symbol representing a method, a symbol representing another class which implements .call, or a proc/lambda
Public Class Methods
new(callable)
click to toggle source
# File lib/business_flow/callable.rb, line 6 def initialize(callable) @callable = callable check_callable end
Public Instance Methods
call(instance, inputs)
click to toggle source
:reek: ManualDispatch At this stage @callable is a symbol and is either a method or a constant. Checking respond_to? is easier and faster than generating a NoMethodError and catching it.
# File lib/business_flow/callable.rb, line 14 def call(instance, inputs) if instance.respond_to?(@callable, true) send_callable(instance, inputs) else @callable = lookup_callable(instance) || raise(NameError, "undefined constant #{@callable}") check_callable call(instance, inputs) end end
to_s()
click to toggle source
# File lib/business_flow/callable.rb, line 25 def to_s @callable.to_s end
Private Instance Methods
call_callable()
click to toggle source
# File lib/business_flow/callable.rb, line 62 def call_callable case @callable.method(:call).arity when 1, -1 single_inputs_callable when 0 zero_inputs_callable else two_inputs_callable end end
check_callable()
click to toggle source
# File lib/business_flow/callable.rb, line 40 def check_callable if @callable.is_a?(Proc) proc_callable else call_callable end rescue NameError unless @callable.is_a?(Symbol) raise ArgumentError, 'callable must be a symbol or respond to #call' end end
lookup_callable(first_instance)
click to toggle source
# File lib/business_flow/callable.rb, line 96 def lookup_callable(first_instance) constant_name = @callable.to_s.camelcase first_instance.class.parents.each do |parent| begin return parent.const_get(constant_name) rescue NameError next end end nil end
proc_callable()
click to toggle source
# File lib/business_flow/callable.rb, line 52 def proc_callable instance_eval %{ def call(instance, inputs) instance.instance_exec( #{@callable.arity.zero? ? '' : 'inputs, '}&@callable ) end }, __FILE__, __LINE__ - 6 end
send_callable(instance, inputs)
click to toggle source
# File lib/business_flow/callable.rb, line 31 def send_callable(instance, inputs) instance_eval %{ def call(instance, _inputs) instance.send(@callable) end }, __FILE__, __LINE__ - 4 call(instance, inputs) end
single_inputs_callable()
click to toggle source
# File lib/business_flow/callable.rb, line 72 def single_inputs_callable instance_eval %{ def call(_instance, inputs) @callable.call(inputs) end }, __FILE__, __LINE__ - 4 end
two_inputs_callable()
click to toggle source
# File lib/business_flow/callable.rb, line 88 def two_inputs_callable instance_eval %{ def call(instance, inputs) @callable.call(instance, inputs) end }, __FILE__, __LINE__ - 4 end
zero_inputs_callable()
click to toggle source
# File lib/business_flow/callable.rb, line 80 def zero_inputs_callable instance_eval %{ def call(_instance, _inputs) @callable.call end }, __FILE__, __LINE__ - 4 end