# simple menu/input collection enter word: foo you entered enter word: q quitting... #### sub check_input { my $input = shift; return $input if length($input) != 1; if ($input eq 'q') { exit } elsif ($input eq 'b') { ... } else { print 'not recognized'; } } #### sub check_input { my ($type, $input) = @_; return $input if length($input) != 1; exit if $input eq 'q'; # etc for universal options # handle prompt types if ($type eq 'start') { if ($input eq 'n') { # do something useful with currently out-of-scope variables ... # (uh oh) } } # etc, etc } #### while(1) { my $input = <>; chomp $input; check_input('ptype', $input); } BREAK: ... # sub check_input if ($input eq 'b') { goto BREAK: } #### my @working = (1 .. 10); # globally scoped anonymous coderef my $push = sub { push @working, shift }; my $pop = sub { pop @working }; while(1) { my $input = input(); check_input('type', $input); } ... # sub check_input if ($input eq 'p') { $pop->(); } #### sub check_input { my ($input, $opts_href) = @_; return $input if length($input) != 1; exit if $input =~ m/Q|c/; $opts_href->{$input}->() if defined $opts_href->{$input} && ref $opts_href->{$input} eq 'CODE'; } ... # define non-global options hash in menu scope my %opts_hash = ( a => sub { goto SOMESPOT }, o => sub { print "continue? (y/N): "; $input = input(); pop @working if $input =~ m/^y$/i; }, 'default' => sub { say "error: please select 'a', 'o', or 'c'" }, ); ... # cannot find this label! sub elsewhere { ... SOMESPOT: ... }