Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Minimum command length matcher

by jcwren (Prior)
on Aug 29, 2000 at 18:44 UTC ( #30139=sourcecode: print w/replies, xml ) Need Help??
Category: Miscellaneous
Author/Contact Info jcwren
Description: I write a fair number of programs that use interactive commands. I intensely dislike programs that require me to type more than the minimum number of characters to distinguish one command from another. I also dislike have to have special parameters that instruct the command interpeter what portion of the command is unique.

To that end, this snippet takes a hash of commands, keyed by the command name, and the user input, and finds the minimum match. Errors are no matches, or ambiguous matches, in which case an error message with the list of commands is returned. If no error, the full name of the hash is returned.
#!/usr/local/bin/perl -w

use strict;
use Carp;

my %Commands = ('who'      => \&do_who,
                'what'     => \&do_what,
                'why'      => \&do_why,
                'never'    => \&do_never,
                'again'    => \&do_again,
                'answer'   => \&do_answer);

   my $userinput = $ARGV[0];

   my ($errmsg, $command) = check_commands (\%Commands, $userinput);

   if ($errmsg)
      print "$errmsg\n";

   &{$Commands {$command}};

sub check_commands
   @_ == 2 or croak "Incorrect number of parameters";
   my ($cmdhash, $command) = @_;
   my @matches = grep /^$command/i, sort keys %$cmdhash;
   if (scalar @matches == 0)
      return ("I don't know what '$command' means", undef);
   elsif (scalar @matches > 1)
      my $lastcmd = pop @matches;

      return ("'$command' is ambigous.  It could mean " . join (', ', 
+@matches) . " or $lastcmd", undef);
   return (undef, $matches [0]);

sub do_who     {print "Who\n"};
sub do_what    {print "What\n"};
sub do_why     {print "Why\n"};
sub do_never   {print "Never\n"};
sub do_again   {print "Again\n"};
sub do_answer  {print "Answer\n"};
Replies are listed 'Best First'.
RE: Minimum command length matcher
by KM (Priest) on Aug 29, 2000 at 18:53 UTC
    You could easily take this one step further and give it the ability to then accept which command the user meant (like some shells do). By changing the 'ambiguous match' (you have it 'ambigous', BTW) part to create a hash. Actually, if you make @matched into %matched with the structure of:

    %matches = (1 => 'match1', 2 => 'match2', etc... );

    You could then make the 'ambiguous match' section as which was meant.. ie..

    'monkey' is ambiguous. It could mean monkeylover [1] or monkeyman [2]:

    The user would then enter 1 or 2, you read it on STDIN, and run the correct sub. Just an idea :)


Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://30139]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (2)
As of 2023-02-01 01:46 GMT
Find Nodes?
    Voting Booth?

    No recent polls found