40 lines
839 B
Ruby
40 lines
839 B
Ruby
![]() |
class Menu
|
||
|
attr_accessor :prompt
|
||
|
attr_accessor :entries
|
||
|
|
||
|
def initialize
|
||
|
@entries = []
|
||
|
end
|
||
|
|
||
|
def choice(name, &action)
|
||
|
entries << { :name => name, :action => action }
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def choose
|
||
|
menu = Menu.new
|
||
|
yield menu
|
||
|
|
||
|
choice = nil
|
||
|
while choice.nil?
|
||
|
menu.entries.each_with_index do |entry, i|
|
||
|
puts "#{i+1}. #{entry[:name]}"
|
||
|
end
|
||
|
print menu.prompt unless menu.prompt.nil?
|
||
|
reply = $stdin.gets.chomp
|
||
|
|
||
|
i = reply.to_i
|
||
|
if i > 0
|
||
|
choice = menu.entries[i-1]
|
||
|
else
|
||
|
possible = menu.entries.find_all {|e| e[:name].to_s.start_with? reply }
|
||
|
case possible.size
|
||
|
when 0 then puts "No such option"
|
||
|
when 1 then choice = possible.first
|
||
|
else puts "Multiple options match: #{possible.map{|e| e[:name]}.join(' ')}"
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
choice[:action].call
|
||
|
end
|