Reputation: 129
The following function iterates over an array MASTER_INVENTORY
, and presents choices to buy. Typing 1
buys Item #1
, Typing 2
buys Item #2
, Typing 34
buys Item #34
.
def buy_menu()
choices = ['Go [B]ack']
i = 1
MASTER_INVENTORY.each do |obj|
choices << "[#{i}] Buy #{obj.name} Price: #{obj.price}"
i += 1
end
choicemap = choices.map { |c| " #{c}\n" }.join
puts choicemap
input = gets.chomp
case input
when "b","B"
main_menu
when "1"
buy_item_index(1)
buy_menu
when "2"
buy_item_index(2)
buy_menu
when ...
...
else
puts "Not a valid input"
buy_menu
end
end
How can I dynamically increment case
when
options instead of hard-coding them like I did above?
Upvotes: 0
Views: 538
Reputation: 121010
case input.to_i
when 1..choices.count-1
buy_item_index(input.to_i)
else
puts "Not a valid input" unless input.downcase == 'b'
end
buy_menu
or:
if (1..choices.count-1).cover? input.to_i
buy_item_index(input.to_i)
elsif input.downcase != 'b'
puts "Not a valid input"
end
buy_menu
Update: one case for all:
case input
when 'b', 'B'
main_menu
when ->(i) { (1..choices.count-1).cover? i.to_i }
buy_item_index(input.to_i)
buy_menu
else
puts "Not a valid input"
buy_menu
end
Upvotes: 2
Reputation: 3734
There are many ways to do things in Ruby. This is one solution :
O = Struct.new(:name, :price)
o1 = O.new('a', 1)
o2 = O.new('b', 2)
o3 = O.new('c', 3)
o4 = O.new('d', 4)
o5 = O.new('e', 5)
MASTER_INVENTORY = [o1, o2, o3, o4, o5]
def buy_item_index(p)
puts "-----buy #{p}"
end
def main_menu
puts '-----Main Menu'
end
def prepare_buy_menu_and_case
choices = ['Go [B]ack']
i = 1
MASTER_INVENTORY.each do |obj|
choices << "[#{i}] Buy #{obj.name} Price: #{obj.price}"
i += 1
end
@choice_map = choices.join("\n")
@case_body = ''
MASTER_INVENTORY.size.times do | number0 |
number = number0 + 1
@case_body <<
"when '#{number}'
buy_item_index(#{number})
buy_menu\n"
puts "when #{number} generated"
end
puts "@case_body=#{@case_body}"
end
def buy_menu
puts @choice_map
input = gets.chomp
eval("
case input
when 'b', 'B'
main_menu
#{@case_body}
else
puts 'Not a valid input'
buy_menu
end
")
end
prepare_buy_menu_and_case
buy_menu
Execution :
$ ruby -w t.rb
t.rb:40: warning: assigned but unused variable - input
when 1 generated
when 2 generated
when 3 generated
when 4 generated
when 5 generated
@case_body=when '1'
buy_item_index(1)
buy_menu
when '2'
...
Go [B]ack
[1] Buy a Price: 1
[2] Buy b Price: 2
[3] Buy c Price: 3
[4] Buy d Price: 4
[5] Buy e Price: 5
2
-----buy 2
Go [B]ack
[1] Buy a Price: 1
[2] Buy b Price: 2
[3] Buy c Price: 3
[4] Buy d Price: 4
[5] Buy e Price: 5
5
-----buy 5
Go [B]ack
[1] Buy a Price: 1
[2] Buy b Price: 2
[3] Buy c Price: 3
[4] Buy d Price: 4
[5] Buy e Price: 5
6
Not a valid input
Go [B]ack
[1] Buy a Price: 1
[2] Buy b Price: 2
[3] Buy c Price: 3
[4] Buy d Price: 4
[5] Buy e Price: 5
b
-----Main Menu
$
This time, the warning about assigned but unused variable
can be ignored.
Preparing the menu and the case
code separately in prepare_buy_menu_and_case
avoids to recompute them each time buy_menu
is called.
The initial puts
are for my comfort and can of course be removed.
Upvotes: 1
Reputation: 5586
when 1..99
send("buy_item_index", input)
end
https://repl.it/repls/ChillyPaltryHippopotamus
Upvotes: 1