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. |