You say
"Frankly, I think I need an object, but I'm reluctant to use one or a closure.", but you're using closures in your code segment above.
You might want to consider this approach:
my $dispatch = {
1 => sub { search_menu() },
2 => sub { my $book = shift; edit_name($book) },
3 => sub { my $book = shift; add_entry($book) },
4 => sub { my $book = shift; delete_entry($book) },
5 => sub { save_default() },
6 => sub { print "Goodbye!\n"; exit },
e => sub { print "Goodbye!\n"; exit }
};
sub process {
my ( $choice, $book ) = @_;
print $dispatch->{$choice}->($book);
}
Here, we're removing the closure completely, and passing the args directly to the appropriate sub. Did I completely miss what you're trying to do?