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 th
If you don't want to go full OO with this, a simple way that you can make this a lot more flexible is to allow each menu choice to control how it is executed. Let's say each menu has an array of hashes that contain the menu text and a coderef that implements what the menu does.
use strict;
use warnings;
sub menu {
my @items = @_;
my $count = 0;
foreach my $item( @items ) {
printf "%d: %s\n", ++$count, $item->{text};
}
print "\n?: ";
while( my $line = ) {
chomp $line;
if ( $line =~ m/\d+/ && $line <= @items ) {
return $items[ $line - 1 ]{code}->();
}
print "\nInvalid input\n\n?: ";
}
}
my @menu_choices;
my @other_menu_choices;
@menu_choices = (
{ text => 'do something',
code => sub { print "I did something!\n" } },
{ text => 'do something else',
code => sub { print "foobar!\n" } },
{ text => 'go to other menu',
code => sub { menu( @other_menu_choices ) } }
);
@other_menu_choices = (
{ text => 'go back',
code => sub { menu( @menu_choices ) } }
);
menu( @menu_choices );
The menu subroutine takes an array of options, and each option "knows" how to perform its own action. If you want to switch between menus, the menu option just calls menu again with a different list of options, as in the "go back" example from @other_menu_choices. This make linking between menus very easy and it's also easy to add exit options and such.
To keep this code clean and readable, for anything other than trivial menu actions, use a named reference to a subroutine instead of an anonymous subroutine reference. For example:
@another_menu_options = (
{ text => 'complicated action'
code => \&do_complicated_action
}
);
sub do_complicated_action {
...
}