10.15. Power Prompting
Because 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. |