Previous Page
Next Page

10.15. Power Prompting

Use the IO::Prompt module for 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.

[*] How many times have you read in a line, then immediately had to chomp it? That sequence seems to be the rule, rather than the exception, so prompt makes chomping the default. This particular design is discussed further in Chapter 17.

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'):

    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...
    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;
            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) ) {
# Run whatever else was...
execute($cmd) or carp "Unknown command: $cmd"; }

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.

    Previous Page
    Next Page