Brandon's Notepad

January 13, 2012

Single Keystroke Menu Using Term::ReadKey

Filed under: Perl — Brandon @ 11:55 am
Tags: ,

Home > My Lists > Programming Notes > PERL > Single Keystroke Menu


Using Term::ReadKey, you can implement a console menu/prompt that accepts a single keystroke. There are many similar implementations of ReadKey available on the Web. This one is in the form of a reusable subroutine. Only valid options are accepted and the choice is returned to the calling script for futher use. It does not convert the choice to upper- or lower-case, because sometimes it is nice to have both options available.



The Subroutine

This code can be placed in a script or in a separate module.

 1: use Term::ReadKey;
 2:
 3: sub getPromptOption ($$)
 4: {
 5: 	my $prompt  = shift;
 6:	my $options = shift;
 7:	my $choice;
 8:
 9:	ReadMode 'cbreak';
10:	print $prompt;
11:	$choice = ReadKey(0) until $choice =~ m/[$options]/;
12:	ReadMode 'normal';
13:	return $choice;
14: }

Obviously, the Term::ReadKey must be loaded first (line 1). The getPromptOption() subroutine accepts two mandatory parameters as indicated by the declared prototype (line 3). Additional field-validation logic may be desired, but is omitted here for brevity. The terminal’s “read” mode is changed to cbreak, which accepts a single character as input (line 9). The prompt that was passed into the subroutine is printed on the screen (line 10) and then the program enters a loop that reads characters from keyboard input until one of the valid options is entered (line 11). Once a valid key has been pressed, the read mode is returned to normal mode (input accepted until the Enter key is pressed; line 12) and the chosen option is returned to the calling logic (line 13).

Usage

This is a very contrived routine that illustrates the use of the subroutine described above. It allows the user to increment or decrement a current value.

 1. my $i = 0;
 2. my $action = '';
 3. print "Current value: $i\n\n";
 4. until ( $action =~ m/[Xx]/ ) {
 5.	$action = getPromptOption(
 6.		"Select Action: [I]ncr, [D]ecr, or E[X]it",
 7.		"IiDdXx"
 8.	);
 9.	$i++ if ( $action =~ m/[Ii]/ );
10.	$i-- if ( $action =~ m/[Dd]/ );
11.	print "\n\nCurrent value: $i\n\n";
12. }

The iterator (“$i”) is set to an initial value of zero (line 1) and the next action flag (“$action”) set to null (line 2). The current value is printed on the screen (line 3) so that the user knows what it is. Next, the user is prompted to increment or decrement the value, or to exit the program (lines 5-8). If the user chooses to change the value by pressing the “i” key (line 9) or the “d” key (line 10), then the value is printed again on the screen for the benefit of the user (line 11). If the user presses the “x” key, the loop ends (line 4) and process control flows out to the end of the script. Please notice that both the upper- and lower-cases are valid options (line 7), but that the program is indifferent to which is used (lines 4, 9, 10).


Advertisements

Blog at WordPress.com.

%d bloggers like this: