Sha256: 4e9df1027207c8108e98cebba9d33d03bbbdeae309dc7d88d0dff094c21102d1
Contents?: true
Size: 1.96 KB
Versions: 2
Compression:
Stored size: 1.96 KB
Contents
module BusinessFlow # Isolate the logic around invoking a 'callable' -- a symbol representing a # method, a symbol representing another class which implements .call, or a # proc/lambda class Callable def initialize(callable, metaclass) @metaclass = metaclass @callable = callable check_callable end def call(instance, inputs) cached_proc.call(instance, inputs) end def to_s @callable.to_s end private # :reek:ManualDispatch Look reek I don't know what you want me to do. def check_callable if @callable.is_a?(Proc) @cached_proc = proc_callable elsif @callable.respond_to?(:call) @cached_proc = call_callable elsif !@callable.is_a?(Symbol) raise ArgumentError, 'callable must be a symbol or respond to #call' end end def cached_proc @cached_proc ||= if @metaclass.method_defined?(@callable) || @metaclass.private_method_defined?(@callable) proc { |instance, _| instance.send(@callable) } else @callable = lookup_callable || raise(NameError, "undefined constant #{@callable}") check_callable end end def proc_callable proc do |instance, inputs| if @callable.arity.zero? instance.instance_exec(&@callable) else instance.instance_exec(inputs, &@callable) end end end def call_callable proc do |instance, inputs| case @callable.method(:call).arity when 1, -1 @callable.call(inputs) when 0 @callable.call else @callable.call(instance, inputs) end end end def lookup_callable constant_name = @callable.to_s.camelcase @metaclass.parents.each do |parent| begin return parent.const_get(constant_name) rescue NameError next end end nil end end end
Version data entries
2 entries across 2 versions & 1 rubygems
Version | Path |
---|---|
business_flow-0.7.0 | lib/business_flow/callable.rb |
business_flow-0.6.0 | lib/business_flow/callable.rb |