class HighLine::QuestionAsker
Deals with the task of “asking” a question
Attributes
@return [Question] question to be asked
Public Class Methods
To do its work QuestionAsker
needs a Question
to be asked and a HighLine
context where to direct output.
@param question [Question] question to be asked @param highline [HighLine] context
# File lib/highline/question_asker.rb, line 17 def initialize(question, highline) @question = question @highline = highline end
Public Instance Methods
Gets just one answer, as opposed to gather_answers
@return [String] answer
# File lib/highline/question_asker.rb, line 26 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
Collects an Array/Hash full of answers as described in HighLine::Question.gather()
.
@return [Array, Hash] answers
# File lib/highline/question_asker.rb, line 70 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
Gather multiple values and store them on a Hash with keys provided by the Hash on {Question#gather} @return [Hash]
# File lib/highline/question_asker.rb, line 108 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
Gather multiple integer values based on {Question#gather} count @return [Array] answers
# File lib/highline/question_asker.rb, line 89 def gather_integer gather_with_array do |answers| (question.gather - 1).times { answers << ask_once } end end
Gather multiple values until any of them matches the {Question#gather} Regexp. @return [Array] answers
# File lib/highline/question_asker.rb, line 98 def gather_regexp gather_with_array do |answers| answers << ask_once until answer_matches_regex(answers.last) answers.pop end end
Private Instance Methods
# File lib/highline/question_asker.rb, line 133 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
Delegate to Highline
# File lib/highline/question_asker.rb, line 119 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
# File lib/highline/question_asker.rb, line 141 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
# File lib/highline/question_asker.rb, line 124 def gather_with_array [].tap do |answers| answers << ask_once question.template = "" yield answers end end