class AASM::Core::Invokers::LiteralInvoker

record methods as state/event/transition callbacks.
Literal invoker which allows to use strings or symbols to call
#

def ensure_method_exists

def ensure_method_exists
  raise(*record_error) unless record.respond_to?(subject, true)
end

def exec_subject

def exec_subject
  ensure_method_exists
  return simple_invoke if subject_arity.zero?
  invoke_with_arguments
end

def instance_with_keyword_args

def instance_with_keyword_args
  positional_args, keyword_args = parse_arguments
  if keyword_args.nil?
    record.send(subject, *positional_args)
  else
    record.send(subject, *positional_args, **keyword_args)
  end
end

def invoke_subject

def invoke_subject
  @result = exec_subject
end

def invoke_with_arguments

def invoke_with_arguments
  if keyword_arguments?
    instance_with_keyword_args
  elsif subject_arity < 0
    invoke_with_variable_arity
  else
    invoke_with_fixed_arity
  end
end

def invoke_with_fixed_arity

def invoke_with_fixed_arity
  req_args = args[0..(subject_arity - 1)]
  if req_args[0].is_a?(Hash)
    record.__send__(subject, **req_args[0])
  else
    record.__send__(subject, *req_args)
  end
end

def invoke_with_variable_arity

def invoke_with_variable_arity
  record.__send__(subject, *args)
end

def keyword_arguments?

def keyword_arguments?
  params = record.method(subject).parameters
  params.any? { |type, _| [:key, :keyreq].include?(type) }
end

def log_failure

def log_failure
  failures << subject
end

def may_invoke?

def may_invoke?
  subject.is_a?(String) || subject.is_a?(Symbol)
end

def record_error

def record_error
  [
    NoMethodError,
    'NoMethodError: undefined method ' \
    "`#{subject}' for #{record.inspect}:#{record.class}"
  ]
end

def simple_invoke

def simple_invoke
  record.__send__(subject)
end

def subject_arity

def subject_arity
  @arity ||= record.__send__(:method, subject.to_sym).arity
end