class Verifly::Applicator::MethodExtractor

MethodExtractor is used when applicable is a symbol. It extracts a method from binding_ and executes it on binding_ (so it works just like send except it sends nothing when method arity is zero). @example

Applicator.call(Applicator.build(:foo), User.new, context)
# => User.new.foo(context)
# or => User.new.foo, if it does not accept context

Public Class Methods

build_class(applicable) click to toggle source

@param applicable [Symbol] @return MethodExtractor if applicable is a Symbol @return [nil] otherwise

# File lib/verifly/applicator.rb, line 59
def self.build_class(applicable)
  self if applicable.is_a?(Symbol)
end

Public Instance Methods

binding_method(binding_) click to toggle source

@param binding_ [#instance_exec] binding to find relative source @return [Method] method, extracted from binding

# File lib/verifly/applicator.rb, line 90
def binding_method(binding_)
  binding_.is_a?(Binding) ? binding_.receiver : binding_
end
call(binding_, *context) click to toggle source

@param binding_ [#instance_exec] target to apply applicable to @param context additional info to send to applicable @return application result

# File lib/verifly/applicator.rb, line 66
def call(binding_, *context)
  if binding_.is_a?(Binding)
    call_on_binding(binding_, *context)
  else
    invoke_lambda(binding_.method(applicable), binding_, *context)
  end
end
source(binding_) click to toggle source

@param binding_ [#instance_exec] binding to find relative source @return [String] relative method source defenition @raise [NameError] if method does not exist on binding_

# File lib/verifly/applicator.rb, line 84
def source(binding_)
  binding_method(binding_).method(applicable).source
end
source_location(binding_) click to toggle source

@param binding_ [#instance_exec] binding to find relative source @return [[String, Integer]] (file, line) location of calblack source (if exists) @raise [NameError] if method does not exist on binding_

# File lib/verifly/applicator.rb, line 77
def source_location(binding_)
  binding_method(binding_).method(applicable).source_location
end

Private Instance Methods

call_on_binding(binding_, *context) click to toggle source

When Binding is a target, we have to respect both methods and variables @param binding_ [Binding] target to apply applicable to @param context additional info to send to applicable @return application result

# File lib/verifly/applicator.rb, line 100
def call_on_binding(binding_, *context)
  if binding_.local_variable_defined?(applicable)
    binding_.local_variable_get(applicable)
  else
    invoke_lambda(binding_.receiver.method(applicable), binding_, *context)
  end
end