I'm working on a Perl script that requires some basic menu functionality. Ultimately I would like each menu to have a few options and then the option to either return to the previous menu or exit.
example:
This is a menu:
Select an option:
I currently have a menu subroutine making the menus, but there is no functionality allowing it to go back to the previous menu.
sub menu
{
for (;;) {
print "--------------------\n";
print "$_[0]\n";
print "--------------------\n";
for (my $i = 0; $i < scalar(@{ $_[1]}); $i++) {
print $i + 1, "\.\t ${ $_[1] }[$i]\n";
}
print "\n?: ";
my $i = <STDIN>; chomp $i;
if ($i && $i =~ m/[0-9]+/ && $i <= scalar(@{ $_[1]})) {
return ${ $_[1] }[$i - 1];
} else {
print "\nInvalid input.\n\n";
}
}
}
# Using the menu
my $choice1 = menu('Menu1 header', \@list_of_choices1);
# I would like this menu to give the option to go back to
# the first menu to change $choice1
my $choice2 = menu('Menu2 header', \@list_of_choices2);
I don't want to hard code all of the menus and use if/elsif statements for all of the processing so I turned the menu into a function.
My menus currently look like this...
Menu Header:
?: (Enter input here)
This solution still doesn't allow the user to go back to the previous menu or exit though. I was considering making a menu class to handle the menus, but I am still not very good with object oriented Perl. This is a small program with only a few menus so using a complex menu building module may be overkill. I would like to keep my code as light as possible.
Thanks for the quick responses! However there is still an issue. When I select an option from "Menu1" and it progresses to "Menu2" I would like the save the choice from "Menu1" for later use:
Menu1:
Menu2:
Selecting either Choice1 or Choice2 should store a value in a variable for later use and progress to the next menu. Then if you choose to go back to the first menu from Menu2, it will give you the option to reselect your choice and redefine the variable. I'm trying to avoid using global variables which makes this quite difficult.
After progressing through all of the menus and setting the values of all of these variables, I want to run a subroutine to process all of the choices and print a final output.
sub main () {
# DO MENU STUFF HERE
# PROCESS RESULTS FROM MENU CHOICES
my $output = process($menu1_choice, $menu2_choice, $menu3_choice, ... );
}
Also if anyone has an object oriented approach to this using classes or some other data structure, although it may be overkill, I would still love to see it and try to wrap my head around the idea!
You could use a module such as Term::Choose:
use Term::Choose qw( choose );
my $submenus = {
menu1 => [ qw( s_1 s_2 s_3 ) ],
menu2 => [ qw( s_4 s_5 s_6 s_7) ],
menu3 => [ qw( s_8 s_9 ) ],
};
my @menus = ( qw( menu1 menu2 menu3 ) );
my $mm = 0;
MAIN: while ( 1 ) {
my $i = choose(
[ undef, @menus ],
{ layout => 3, undef => 'quit', index => 1, default => $mm }
);
last if ! $i;
if ( $mm == $i ) {
$mm = 0;
next MAIN;
}
else {
$mm = $i;
}
$i--;
SUB: while ( 1 ) {
my $choice = choose(
[ undef, @{$submenus->{$menus[$i]}} ],
{ layout => 3, undef => 'back' }
);
last SUB if ! defined $choice;
say "choice: $choice";
}
}