#!/usr/bin/perl -w use strict; sub foo { print "FOO!\n" } sub bar { print "BAR!\n" } sub menu { my ($menu) = @_; for (;;) { print "\n$menu->[0]\n"; print map "$_. $menu->[$_ * 2 - 1]\n", 1 .. $#$menu / 2; print '> '; chomp (my $choice = readline *STDIN); if ($choice and $choice <= $#$menu / 2) { my $action = \$menu->[$choice * 2]; return if not defined $action; $action->() if ref $action eq 'CODE'; menu $action if ref $action eq 'ARRAY' } else { print "Invalid choice: $choice\n" } } } my ($mainmenu, $submenu); $mainmenu = [ 'Main menu', 'Foo' => \&foo, 'Submenu...' => sub { menu $submenu }, 'Exit' => undef, ]; $submenu = [ 'Submenu', 'Bar', => \&bar, 'Back to previous menu' => undef, ]; menu $mainmenu;