kuerbis/Term-Choose

wrap a dispatch table?

Closed this issue · 1 comments

I've found that whenever I use Term::Choose I usually want to run a subroutine based on which option I choose, so I was wondering if having this functionality built in might make for a good feature request.

In the past, in random scripts, I've implemented this one of two ways. You always want the menu options to appear in a consistent order, so a plain hash associating subs to labels won't do. Instead, one can have

(a) an array of hashes holding the menu label and the subroutine:

use Term::Choose qw(choose);

sub mkMenuArray($dispArray) {
    my @opts = map { $_->{label} } @{$dispArray};
    my $choice = choose(\@opts, { index => 1 });
    &{$dispArray->[$choice]->{fn}};
}

my $dispArray=[
    { label => 'continue', fn => sub {say "Moving on.."; return} },
    { label => 'quit', fn => sub {exit} },
    ];

while(1) {
    mkMenuArray($dispArray);
}

or

(b) an ordered hash associating menu entries to subs:

use Hash::Ordered;
use Term::Choose qw(choose);

sub mkMenuHash($dispHash) {
    my @opts = $dispHash->keys;
    my $choice = choose(\@opts);
    &{$dispHash->get($choice)};
}

my $dispHash=Hash::Ordered->new(    
    'continue' => sub {say "Moving on.."; return},
    'quit' => sub {exit},
    );

while(1) {
    mkMenuHash($dispHash);
}

So the idea would be to have a mechanism built into Term::Choose that would obviate the need to define the subs mkMenu.. above (it feels unnatural to define them every time: they are entirely generic, and non-specific to whatever I'm doing in the script).

Both approaches have some disadvantages:

  • having (a) built in would impose on the user the keys of the hash they have to pass (I used labels and fn above, but even if they're something else, they'd presumably have to be hard-coded);
  • on the other hand (b) would impose a dependence on Hash::Ordered.

In any event, I thought I'd ask what you think of having something like this available. Or perhaps it's just not worth the headache?

Thanks for the suggestion. But since I want to keep Term::Choose as simple as possible, I won't add the suggestion. If I change my mind, I will open the ticket again.