A more idiomatic way of doing this?
I'm doing a program and I would like to output a menu with two submenus in a module. I only want the main menu to show when you run the program. Then from the main menu be able to navigate to the submenus and back. If anyone could find a better way doing this (which I'm positive there is) please do say so. I'm not even sure this will work. Thanks!
module Menus
def self.getValidPositiveNumber
input = gets.chomp
while (input.to_i.to_s != input && input.to_f.to_s != input) do
puts "Ogiltig data. Försök igen."
input = gets.chomp
end
# Är talet större än 0?
number = input.to_f
if (number <= 0)
puts "you cant put that."
getValidPositiveNumber
end
return number
end
def self.get_valid_input(valid_options)
input = gets.chomp
while (!valid_options.include?(input) && !valid_options.include?(input.to_i))
# både Range och Array har include?
puts "no good, please choose something inbetween " + valid_options.inspect
input = gets.chomp
end
return input
end
class Menu
attr_reader :valid_options_range, :menu_string
def initialize(valid_options_range, menu_string)
@valid_options_range = valid_options_range
@menu_string = menu_string
end
def do_menu_action(action)
raise "Has to be called to in any subclass!"
end
def to_s
return @menu_string
end
end
MAIN_MENU = <<END
"---------------------------"
Welcome to Ruby Camping!
Menu
1. Checkin
2. Checkout
3. Lists
4. Economy
5. Exit
What do you want to do?
"---------------------------"
END
def make_menu_choice(choice)
case choice
when 1:
$camping.check_in
when 2:
$camping.check_out
when 3:
$current_menu = LISTS_MENU
when 4:
$current_menu = ECONOMY_MENU
when 5:
exit
end
end
LISTS_MENU = <<END
"---------------------------"
-- 1. List current guests --
-- 2. List all guests --
-- --
-- 0. Back to Main menu --
------------------------------"
END
def make_menu_choice(choice)
case choice
when 1:
$camping
when 2:
$camping.all_guests
when 0:
$current_menu = MAIN_MENU
end
end
ECONOMY_MENU = <<END
"---------------------------"
-- 1. List current guests --
-- 2. List all guests --
-- --
-- 0. Back to Main menu --
---------------开发者_运维技巧---------------"
END
end
puts Menus::MAIN_MENU
if Menus == 3 then LISTS_MENU = Lists_Menu.new
elsif Menus == 4 then ECONOMY_MENU = Economy_Menu.new
end
__END__
I won't write the code for you (sorry), but I would do it this way:
A generic menu class which can be supplied with menu items mapped to numbers and method name symbols...
Then I'd create a class which has methods for all menu items and would instanciate the Menu Class dynamically how I need it and supply it with the required information...
From the menu then the methods would be called in the way like
ClassHoldingMethods.method( methodname[entered_number] ).call
(in this case methodname is an array mapping indices to methods to be called when chosen and entered_number the already sanity-checked number from the user)
That would be much more clean, because the menu class would be flexible and you could easily add new menu pages...
You should consider using the commander gem, which includes the highline gem, both of which were designed to facilitate user input and validation.
精彩评论