10.15. Power PromptingBecause programs so often need to prompt for interactive input and then read that input, it's probably not surprising that there would be a CPAN module to make that process easier. It's called IO::Prompt and it exports only a single subroutine: prompt( ). At its simplest, you can just write:
use IO::Prompt;
my $line = prompt 'Enter a line: ';The specified string will be printed (but only if the program is interactive), and then a single line will be read in. That line will also be automatically chomped[*], unless you specifically request it not be.
The prompt( ) subroutine can also control the echoing of characters. For example:
my $password = prompt 'Password: ', -echo => '*';which echoes an asterisk for each character typed in:
> Password: ***********You can even prevent echoing entirely (by echoing an empty string in place of each character):
my $password = prompt 'Password: ', -echo => $EMPTY_STR;prompt( ) can return a single key-press (without requiring the Return key to be pressed as well):
my $choice = prompt 'Enter your choice [a-e]: ', -onechar;It can ignore inputs that are not acceptable:
my $choice = prompt 'Enter your choice [a-e]: ', -onechar,
-require=>{ 'Must be a, b, c, d, or e: ' => qr/[a-e]/xms };It can be restricted to certain kinds of common inputs (e.g., only integers, only valid filenames, only 'y' or 'n'):
CODE:
while (my $ord = prompt -integer, 'Enter a code (zero to quit): ') {
if ($ord == 0) {
exit if prompt -yn, 'Really quit? ';
next CODE;
}
print qq{Character $ord is: '}, chr($ord), qq{'\n};
}It has many more features, but the real power of prompt( ) is that it abstracts the ask-answer-verify sequence of operations into a single higher-level command, which can significantly reduce the amount of code you need to write. For example, the command-processing loop shown earlier in the "Simple Prompting" guideline:
# No command entered yet...
my $cmd = $EMPTY_STR;
# Until the q[uit] command is entered...
CMD:
while ($cmd !~ $QUIT) {
# Prompt if we're running interactively...
if (is_interactive( )) {
print get_prompt_str( );
}
# Get the next command...
$cmd = <>;
last CMD if not defined $cmd;
# Clean it up and run it...
chomp $cmd;
execute($cmd)
or carp "Unknown command: $cmd";
}can be reduced to:
# Until the q[uit] command is entered...
while ( my $cmd = prompt(get_prompt_str( ), -fail_if => $QUIT) ) {
Note especially that the $cmd variable no longer has to be defined outside the loop and can be more appropriately restricted in scope to the loop block itself. |