class Naseweis::Nase
A class to read a Weisfile
and gather user input
@attr_reader [String] filename The path to the file which is used by this
{Nase}
@attr_reader [Array] questions All questions handled by this {Nase}.
To update the questions, use the {#read} method.
@attr_reader [Converter] converter The converter that is used to convert
types
Attributes
Public Class Methods
Create a new {Nase} which reads questions from the given file
@param path [String] path to the file with the questions
# File lib/naseweis.rb, line 38 def initialize(path) @filename = path @questions = {} @converter = Converter.new end
Public Instance Methods
Start the question session and return the user answers
@param instream [File] input stream, i.e. stream where data is read from @param outstream [File] output stream, i.e. stream where prompts are
printed to
@return [Hash] Hash of the user answers, where the keys are defined by
the question file.
# File lib/naseweis.rb, line 80 def interrogate(instream: $stdin, outstream: $stdout) @io = HighLine.new instream, outstream ask @questions @io = nil end
Update the questions and re-read them from the file that the Nase
was initialized with
@return [void] @raise [WeisheitError] if the input file is malformed
# File lib/naseweis.rb, line 49 def read questions = YAML.load_file(@filename) verify questions @questions = questions end
Check whether the given question is wellformed
@param q [Hash,Array] the question or list of questions to check @return [void] @raise [WeisheitError] if the question is malformed
# File lib/naseweis.rb, line 60 def verify(q) # Currently only checks if the question type is valid if q.is_a? Array q.each { |x| verify x } return end type = q['type'] qs = q['q'] well = type.nil? || @converter.supported_types.include?(type.intern) raise WeisheitError, "invalid type #{type}" unless well verify qs if qs.is_a? Array end
Private Instance Methods
Ask the given list of questions and return the answers as a Hash
@param questions [Array] list of questions to ask @return [Hash] Hash of the user answers
# File lib/naseweis.rb, line 92 def ask(questions) namespace = {} questions.each do |q| answer = do_question q namespace[q['target']] = answer if q.key?('target') && !answer.nil? end namespace end
Handle a single question and return the answer
@param q [Hash] the question data @return [String] for a simple question @return [Array] for a repeating question
# File lib/naseweis.rb, line 106 def do_question(q) if q.key? 'desc' # Always output the description first @io.say q['desc'] end repeat = q['repeat'] return get_valid_input q if repeat.nil? return (1..repeat).collect { get_valid_input q } if repeat.is_a? Integer if repeat.is_a? String result = [get_valid_input(q)] result.push(get_valid_input(q)) while @io.agree repeat else result = [] loop do line = get_valid_input q break if line.empty? result << line end end result end
Get a single line of user input that is valid for the given question
@param q [Hash] the question which to get input for @return [String] if the question is a simple question @return [Hash] if the question has sub-questions @return [Object] if the question is type-converted
# File lib/naseweis.rb, line 135 def get_valid_input(q) prompt = q['q'] prompt = '' if prompt.nil? result = nil loop do if prompt.is_a? Array result = ask prompt elsif !q['choices'].nil? @io.say prompt result = @io.choose(*q['choices']) else result = @io.ask prompt end break if q['type'].nil? begin result = @converter.convert result, q['type'] rescue ConversionError @io.say "invalid value for type #{q['type']}" else break end end result end