Home > Raku > Fuzzy commands

## Fuzzy commands

Reading can make one learned. Today I had a peak into lizmat´s new module shorten-sub-commands and learned about `Parameter.constraint_list`. We need this method to introspect a routines literal parameters.

``````use MONKEY-TYPING;
augment class Parameter {
method literal {
!self.name && !self.named && self.type ~~ Str|Numeric && self.constraint_list == 1
!! Nil
}
}

multi sub foo('literal', 42) { }
multi sub foo(\$not-a-literal, 42) { }
.say for &foo.candidates».signature».params».literal;

# OUTOUT: (literal 42)
#         (Nil 42)``````

We can generalise lizmat´s idea of transforming command line arguments.

``````multi sub MAIN('foo', |c) { say 'foo', @*ARGS[0] }
multi sub MAIN('Barbara', |c) { say ['bar', @*ARGS[0]] }

sub transform-first-arg(Mu:D \$test is raw, &mapper) {
&MAIN.add_dispatchee: sub (Str:D \$subcommand, |c) is hidden-from-USAGE {
my &this-candidate := &?ROUTINE;
my @real-subcommands = &MAIN.candidates.grep(* !=:= &this-candidate)».signature».params».[0]».literal;
if \$subcommand ~~ \$test {
MAIN(mapper(\$subcommand), |c)
}
}
}

transform-first-arg({ .lc.contains(<fo ba>.any) }, { .trans: ['fo', /:i ba.*/] => ['foo', 'Barbara'] });``````

This program is now very generous when it comes to it’s first argument. Even `!./% bAR` will result in the right `MAIN`-candidate to be called.

I used `augment` because this doesn’t feel like an ENODOC. One needs to know quite a lot of the internal workings of `Parameter` to make use of `method constraint_list`. We may have to support more then just string and numeral literals in the future. So maybe there is a PR in order.

Categories: Raku