Harry Putnam wrote:
Summary:
How to arrange for a default action in a dispatch table, along with
several single Letter choics and numeric choices.
Details:
This script is a mock up of something I'm trying to do, and is way
pared down from a much larger script... mostly its the dispatch table
I'm working on right now.
Dinking around with arrays and modulo at the beginning is just a
way to feed the dispatch table sort of like the real script.
sub function `dispt()'(the table) has an array coming in as @_.
I've create a %hash from that array in order to have a number
associated with the parts to be acted on. Unless someone knows a better
way that is.
The dispatch table tries to have both Letters and Numbers as selectors,
and a default action (that is where the numbers come in).
It looks pretty awkward, the way I just kind of wedged the default
action in there... is there a more canonical way of doing that?
It does seem to work though.
------- --------- ---=--- --------- --------
#!/usr/local/bin/perl
use strict;
use warnings;
my @ar1 = ("r2one","r2two","r2three","r2four","r2five","r2five","r2four",
"r2four","r2three","r2two","r2seven","r2six");
my @exp;
my $r1name = 'r1_r1r1';
my $arcnt = 1;
for (@ar1) {
push @exp,$_;
$arcnt++;
if (($arcnt % 4) == 0) {
dispt($r1name,@exp);
@exp = ();
$arcnt = 1;
}
}
Much simpler as:
for ( my $i = 0; $i <= $#ar1; $i += 3 ) {
dispt( $r1name, @ar1[ $i .. $i + 2 ] );
}
sub dispt {
my $chosen;
## Boolean that keeps the while loop up
my $cnt = 1;
## This element will never be acted on.
my $r1name = shift;
my %h = ();
my $lcnt = 1;
## Generate a hash to have numbers associated with these elements.
for (@_) {
$h{$lcnt++} = $_;
}
print "$r1name\n----- -----\n";
foreach my $key (sort {$a<=>$b} keys %h) {
printf "%2d %s\n", $key, $h{$key};
}
print "\n----- -----\n";
Just use an array instead of a hash:
sub dispt {
## This element will never be acted on.
my ( $r1name, @h ) = @_;
print "$r1name\n----- -----\n";
for my $key ( 0 .. $#h ) {
printf "%2d %s\n", $key + 1, $h[ $key ];
}
print "\n----- -----\n";
my %hash = (
A => sub { print "You chose A, very smart\n";$cnt = 0; },
N => sub { print "You chose N, very dumb\n";$cnt = 0; },
L => sub { print "$r1name\n----- -----\n";
foreach my $key (sort {$a<=>$b} keys %h) {
printf "%2d %s\n", $key, $h{$key}}; },
c => sub { print "Continue\n"; $cnt = 0; },
q => sub { print "Goodbye\n" and exit; },
error => sub { print "invalid choice\n" }
);
while ($cnt == 1) {
print "press a file number for the default action\n",
"press A to test this dispatch table\n",
"press N to test this dispatch table\n",
"press L to redisplay the list\n",
"press c to continue (no action taken)\n",
"press q to Exit (abort completely)\n";
chomp($chosen = <STDIN>);
my $done = '';
if ($chosen =~ /^\d+$/) {
foreach my $key (keys %h) {
if ("$chosen" eq "$key") {
print "Taking some action on $h{$key}\n";
$cnt = 0; $done = 'TRUE';
}
}
}
if (!$done) {
my $code = $hash{$chosen} || $hash{'error'} ;
$code->();
}
}
You don't need $cnt or $done for the while loop:
while ( 1 ) {
print <<'PROMPT';
press a file number for the default action
press A to test this dispatch table
press N to test this dispatch table
press L to redisplay the list
press c to continue (no action taken)
press q to Exit (abort completely)
PROMPT
chomp( my $chosen = <STDIN> );
exit 0 if $chosen eq 'q';
next if $chosen eq 'c';
if ( $chosen =~ /\A\d+\z/ && $chosen >= 1 && $chosen <= @h ) {
print "Taking some action on $h[$chosen - 1]\n";
last;
}
else {
my $code = $hash{ $chosen } || $hash{ error };
$code->();
}
}
}
John
--
The programmer is fighting against the two most
destructive forces in the universe: entropy and
human stupidity. -- Damian Conway
--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/