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
?? self.constraint_list.head
!! 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
Comments (0)
Trackbacks (1)
Leave a comment
Trackback
-
February 14, 2022 at 16:542022.07 Unsigned Release – Rakudo Weekly News