class HighLine::QuestionAsker

Deals with the task of “asking” a question

def answer_matches_regex(answer)

def answer_matches_regex(answer)
  if question.gather.is_a?(::String) || question.gather.is_a?(Symbol)
    answer.to_s == question.gather.to_s
  elsif question.gather.is_a?(Regexp)
    answer.to_s =~ question.gather
  end
end

def ask_once

Returns:
  • (String) - answer
def ask_once
  # If in readline mode, let reline take care of the prompt
  question.show_question(@highline) unless question.readline
  begin
    question.get_response_or_default(@highline)
    raise NotValidQuestionError unless question.valid_answer?
    question.convert
    question.check_range
    if question.confirm
      confirmation = @highline.send(:confirm, question)
      raise NoConfirmationQuestionError unless confirmation
    end
  rescue ExplainableError => e
    explain_error(e.explanation_key)
    retry
  rescue ArgumentError => error
    case error.message
    when /ambiguous/
      # the assumption here is that OptionParser::Completion#complete
      # (used for ambiguity resolution) throws exceptions containing
      # the word 'ambiguous' whenever resolution fails
      explain_error(:ambiguous_completion)
      retry
    when /invalid value for/
      explain_error(:invalid_type)
      retry
    else
      raise
    end
  end
  question.answer
end

def explain_error(explanation_key) # eg: :not_valid, :not_in_range

eg: :not_valid, :not_in_range
# Delegate to Highline
def explain_error(explanation_key) # eg: :not_valid, :not_in_range
  @highline.say(question.final_response(explanation_key))
  @highline.say(question.ask_on_error_msg)
end

def gather_answers

Returns:
  • (Array, Hash) - answers
def gather_answers
  verify_match = question.verify_match
  answers = []
  # when verify_match is set this loop will repeat until unique_answers == 1
  loop do
    answers = gather_answers_based_on_type
    break unless verify_match &&
                 (@highline.send(:unique_answers, answers).size > 1)
    explain_error(:mismatch)
  end
  verify_match ? @highline.send(:last_answer, answers) : answers
end

def gather_answers_based_on_type

def gather_answers_based_on_type
  case question.gather
  when Integer
    gather_integer
  when ::String, Symbol, Regexp
    gather_regexp
  when Hash
    gather_hash
  end
end

def gather_hash

Returns:
  • (Hash) -
def gather_hash
  sorted_keys = question.gather.keys.sort_by(&:to_s)
  sorted_keys.each_with_object({}) do |key, answers|
    @highline.key = key
    answers[key]  = ask_once
  end
end

def gather_integer

Returns:
  • (Array) - answers
def gather_integer
  gather_with_array do |answers|
    (question.gather - 1).times { answers << ask_once }
  end
end

def gather_regexp

Returns:
  • (Array) - answers
def gather_regexp
  gather_with_array do |answers|
    answers << ask_once until answer_matches_regex(answers.last)
    answers.pop
  end
end

def gather_with_array

def gather_with_array
  [].tap do |answers|
    answers << ask_once
    question.template = ""
    yield answers
  end
end

def initialize(question, highline)

Parameters:
  • highline (HighLine) -- context
  • question (Question) -- question to be asked
def initialize(question, highline)
  @question = question
  @highline = highline
end