class Question
def self.option(option_text, &response)
self.class_eval do
if c = instance_variable_get("@count")
instance_variable_set "@count", c + 1
else
c = 0
instance_variable_set "@count", c + 1
end
if q = instance_variable_get("@options")
q ||= []
q << option_text
instance_variable_set "@options", q
else
instance_variable_set "@options", [option_text]
end
if response
if r = instance_variable_get("@responses")
r ||= {}
r[c + 1] = response
instance_variable_set "@responses", r
else
instance_variable_set "@responses", {c + 1 => response}
end
end
end
end
def self.default_option(option_text, &response)
self.option(option_text, &response)
self.class_eval do
instance_variable_set("@default", instance_variable_get("@count"))
end
end
def self.question(question_text)
self.class_eval do
instance_variable_set "@question", question_text
end
end
def self.error_message(err_text)
self.class_eval do
instance_variable_set "@err", err_text
end
end
def self.on_select(&action)
self.class_eval do
instance_variable_set("@on_select", action)
end
end
def options
self.class.instance_variable_get("@options")
end
def question
self.class.instance_variable_get("@question")
end
def error_msg
self.class.instance_variable_get("@err")
end
def default_option
self.class.instance_variable_get("@default")
end
def initialize(limit=nil)
@limit = limit
end
def ask(indent = 0)
counter = 0
options_width = options.length.to_s.length
loop do
counter += 1
puts "#{' ' * indent}#{question}"
puts
options.each_with_index do |option, index|
puts "#{' ' * indent}#{" " * (options_width - index.to_s.length)}#{index + 1}. #{option}"
end
print "#{" " * indent}#{"[#{default_option}] " if default_option}"
answer_string = gets
answer = answer_string =~ /^\s*$/ ? default_option : answer_string.to_i
if (1..options.length).include? answer
responses = self.class.instance_variable_get("@responses")
responses[answer].call(answer, options[answer - 1]) if responses and responses.has_key? answer
on_select = self.class.instance_variable_get("@on_select")
on_select.call(answer, options[answer - 1]) if on_select
break answer
elsif error_msg and not (@limit and counter >= @limit)
puts
puts "#{' ' * indent}#{error_msg}"
puts
elsif @limit and counter >= @limit
break
end
end
end
end |