Skip to content

Instantly share code, notes, and snippets.

@treyharris
Last active March 9, 2016 23:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save treyharris/7eb7494563ee5b759b30 to your computer and use it in GitHub Desktop.
Save treyharris/7eb7494563ee5b759b30 to your computer and use it in GitHub Desktop.
Examples of argument processing with MAIN
#!/usr/bin/env perl6
=NAME 00-main-multi-example
=DESCRIPTION Original multi-less version
unit sub MAIN(
Str $action, #= One of: add|div|mult
Numeric $x,
Numeric $y,
Bool :d(:$double), #= Double the result
);
my $multiple = do if $double { 2 } else { 1 };
for $action {
when 'add' { say ($x + $y) * $multiple }
when 'div' { say ($x / $y) * $multiple }
when 'mult' { say ($x * $y) * $multiple }
}
=begin output
$ K<./00-main-multi-example --help>
Usage:
./00-main-multi-example [-d|--double] <action> <x> <y>
<action> One of: add|div|mult
-d|--double Double the result
$ K<./main-multi-example add 2 3>
5
$ K<./main-multi-example -d add 2 3>
10
$ K<./main-multi-example -double add 2 3>
10
=end output
=begin Note
For usage and behavior, this version works correctly.
=end Note
#!/usr/bin/env perl6
=NAME 01-main-multi-example
=DESCRIPTION multis version with repeated flag
multi MAIN('add',
$x, $y,
Bool :d(:$double),
) { say ($x + $y) * multiplier($double) }
multi MAIN('div',
$x, $y,
Bool :d(:$double),
) { say ($x / $y) * multiplier($double) }
multi MAIN('mult',
$x, $y,
Bool :d(:$double),
) { say ($x * $y) * multiplier($double) }
sub multiplier(Bool $double) {
$double ?? 2 !! 1
}
=begin output
$ K<./01-main-multi-example --help>
Usage:
./01-main-multi-example [-d|--double] add <x> <y>
./01-main-multi-example [-d|--double] div <x> <y>
./01-main-multi-example [-d|--double] mult <x> <y>
$ K<./01-main-multi-example add 2 3>
5
$ K<./01-main-multi-example --double add 2 3>
./01-main-multi-example --double add 2 3
10
$ K<./01-main-multi-example -d add 2 3>
./01-main-multi-example --double add 2 3
10
=end output
=begin Note
So far, so good, but we'd expect to be able to
use it like this, too...
=end Note
=begin output
$ K<./01-main-multi-example add -d 2 3>
Usage:
./01-main-multi-example [-d|--double] add <x> <y>
./01-main-multi-example [-d|--double] div <x> <y>
./01-main-multi-example [-d|--double] mult <x> <y>
=end output
=Note ...but it doesn't work.
#!/usr/bin/env perl6
=NAME 02-main-multi-example
=DESCRIPTION Now we'll try a proto:
proto MAIN(Str $action,
$x, $y,
Bool :d(:$double), #= Double the result
) {*}
multi MAIN('add',
$x, $y,
*%h,
) { say ($x + $y) * multiplier(%h<double>) }
multi MAIN('div',
$x, $y,
*%h,
) { say ($x / $y) * multiplier(%h<double>) }
multi MAIN('mult',
$x, $y,
*%h,
) { say ($x * $y) * multiplier(%h<double>) }
sub multiplier(Bool $double) {
$double ?? 2 !! 1
}
=Note A problem from the start, --help is wrong:
=begin output
$ K<./02-main-multi-example --help>
Usage:
./02-main-multi-example [--<h>=...] add <x> <y>
./02-main-multi-example [--<h>=...] div <x> <y>
./02-main-multi-example [--<h>=...] mult <x> <y>
=end output
=Note And trying to leave the option out causes problems:
=begin output
$ K<./02-main-multi-example add 2 3>
Type check failed in binding $double; expected Bool but got Any
in sub multiplier at ./02-main-multi-example line 27
in sub MAIN at ./02-main-multi-example line 14
in block <unit> at ./02-main-multi-example line 27
=end output
=Note Undeclared options are caught:
=begin output
$ K<./02-main-multi-example -c add 2 3>
Unexpected named parameter 'c' passed
in sub MAIN at ./02-main-multi-example line 9
in block <unit> at ./02-main-multi-example line 27
$ K<./02-main-multi-example --triple add 2 3>
Unexpected named parameter 'triple' passed
in sub MAIN at ./02-main-multi-example line 9
in block <unit> at ./02-main-multi-example line 27
=end output
=Note And it works correctly with --double:
=begin output
$ K<./02-main-multi-example --double add 2 3>
10
=end output
=Note But the short version isn't recognized:
=begin output
$ K<./02-main-multi-example -d add 2 3>
Type check failed in binding $double; expected Bool but got Any
in sub multiplier at ./02-main-multi-example line 27
in sub MAIN at ./02-main-multi-example line 14
in block <unit> at ./02-main-multi-example line 27
=end output
#!/usr/bin/env perl6
=NAME 03-main-multi-example
=DESCRIPTION A proto with code:
my Int $multiplier = 1;
proto MAIN(Str $action,
$x, $y,
Bool :d(:$double), #= Double the result
) {
$multiplier = 2 if $double;
{*}
}
multi MAIN('add',
$x, $y,
*%h,
) { say ($x + $y) * $multiplier }
multi MAIN('div',
$x, $y,
*%h,
) { say ($x / $y) * $multiplier }
multi MAIN('mult',
$x, $y,
*%h,
) { say ($x * $y) * $multiplier }
=Note Now, --help is still wrong:
=begin output
$ K<./03-main-multi-example --help>
Usage:
./03-main-multi-example [--<h>=...] add <x> <y>
./03-main-multi-example [--<h>=...] div <x> <y>
./03-main-multi-example [--<h>=...] mult <x> <y>
=end output
=Note But the functionality is now almost all right:
=begin output
$ K<./03-main-multi-example add 2 3>
5
$ K<./03-main-multi-example -d add 2 3>
10
$ K<./03-main-multi-example --double add 2 3>
10
$ K<./03-main-multi-example --nonesuch add 2 3>
Unexpected named parameter 'nonesuch' passed
in sub MAIN at ./03-main-multi-example line 11
in block <unit> at ./03-main-multi-example line 27
$ K<./03-main-multi-example subtract 5 2>
Usage:
./03-main-multi-example [--<h>=...] add <x> <y>
./03-main-multi-example [--<h>=...] div <x> <y>
./03-main-multi-example [--<h>=...] mult <x> <y>
$ K<./03-main-multi-example add 2>
Usage:
./03-main-multi-example [--<h>=...] add <x> <y>
./03-main-multi-example [--<h>=...] div <x> <y>
./03-main-multi-example [--<h>=...] mult <x> <y>
$ K<./03-main-multi-example --double add 2>
Usage:
./03-main-multi-example [--<h>=...] add <x> <y>
./03-main-multi-example [--<h>=...] div <x> <y>
./03-main-multi-example [--<h>=...] mult <x> <y>
$ K<./03-main-multi-example -d add 2>
Usage:
./03-main-multi-example [--<h>=...] add <x> <y>
./03-main-multi-example [--<h>=...] div <x> <y>
./03-main-multi-example [--<h>=...] mult <x> <y>
=end output
=Note It's only broken now for options like this:
=begin output
$ K<./03-main-multi-example add -d 2 3>
Usage:
./03-main-multi-example [--<h>=...] add <x> <y>
./03-main-multi-example [--<h>=...] div <x> <y>
./03-main-multi-example [--<h>=...] mult <x> <y>
$ K<./02-main-multi-example --double add 2 3>
10
=end output
=begin Note
...but maybe that's correct since -d is global?
If we can do I<local> options as well, then yes. Let's try it.
=end Note
#!/usr/bin/env perl6
=NAME 04-main-multi-example
=begin DESCRIPTION
Global & local options
We'll try adding a C<--rational> flag to C<div> to see if it works.
=end DESCRIPTION
my Int $multiplier = 1;
proto MAIN(Str $action,
$x, $y,
Bool :d(:$double), #= Double the result
) {
$multiplier = 2 if $double;
{*}
}
multi MAIN('add',
$x, $y,
*%h,
) { say ($x + $y) * $multiplier }
multi MAIN('div',
$x, $y,
Bool :r(:$rational), #= Return a Rat form
*%h,
) {
my $result = ($x / $y) * $multiplier;
if $rational { $result .= nude; }
say $result;
}
multi MAIN('mult',
$x, $y,
*%h,
) { say ($x * $y) * $multiplier }
=Note Now, C<--help> looks promising aside from the previous issues:
=begin output
$ K<./04-main-multi-example --help>
Usage:
./04-main-multi-example [--<h>=...] add <x> <y>
./04-main-multi-example [-r|--rational] [--<h>=...] div <x> <y>
./04-main-multi-example [--<h>=...] mult <x> <y>
-r|--rational Return a Rat form
=end output
=Note The functionality not including the C<-r> is all the same as before:
=begin output
$ K<./04-main-multi-example add 2 3>
5
$ K<./04-main-multi-example -d add 2 3>
10
$ K<./04-main-multi-example -double add 2 3>
./04-main-multi-example -double add 2 3
10
$ K<./04-main-multi-example subtract 2 3>
Usage:
./04-main-multi-example [--<h>=...] add <x> <y>
./04-main-multi-example [-r|--rational] [--<h>=...] div <x> <y>
./04-main-multi-example [--<h>=...] mult <x> <y>
-r|--rational Return a Rat form
$ K<./04-main-multi-example add 2>
Usage:
./04-main-multi-example [--<h>=...] add <x> <y>
./04-main-multi-example [-r|--rational] [--<h>=...] div <x> <y>
./04-main-multi-example [--<h>=...] mult <x> <y>
-r|--rational Return a Rat form
=end output
=Note But attempting to use the C<div> gives us:
=begin output
$ K<./04-main-multi-example div 2 3>
0.666667
$ K<./04-main-multi-example -d div 2 3>
1.333333
$ K<./04-main-multi-example --double div 2 3>
1.333333
$ K<./04-main-multi-example -r div 2 3>
Unexpected named parameter 'r' passed
in sub MAIN at ./04-main-multi-example line 17
in block <unit> at ./04-main-multi-example line 38
$ K<./04-main-multi-example --rational div 2 3>
Unexpected named parameter 'rational' passed
in sub MAIN at ./04-main-multi-example line 17
in block <unit> at ./04-main-multi-example line 38
$ K<./04-main-multi-example -d -r div 2 3>
Unexpected named parameter 'r' passed
in sub MAIN at ./04-main-multi-example line 17
in block <unit> at ./04-main-multi-example line 38
$ K<./04-main-multi-example -r -d div 2 3>
Unexpected named parameter 'r' passed
in sub MAIN at ./04-main-multi-example line 17
in block <unit> at ./04-main-multi-example line 38
$ K<./04-main-multi-example --doubley div 2 3>
Unexpected named parameter 'doubley' passed
in sub MAIN at ./04-main-multi-example line 17
in block <unit> at ./04-main-multi-example line 38
=end output
=begin Note
...what if we add a slurpy hash to the proto?
That's next.
=end Note
#!/usr/bin/env perl6
=NAME 05-main-multi-example
=begin DESCRIPTION
Global & local options
We've added a C<--rational> flag to C<div>. but it didn't work.
So let's add a slurpy hash to the proto.
=end DESCRIPTION
my Int $multiplier = 1;
proto MAIN(Str $action,
$x, $y,
Bool :d(:$double), #= Double the result
*%h,
) {
$multiplier = 2 if $double;
{*}
}
multi MAIN('add',
$x, $y,
*%h,
) { say ($x + $y) * $multiplier }
multi MAIN('div',
$x, $y,
Bool :r(:$rational), #= Return a Rat form
*%h,
) {
my $result = ($x / $y) * $multiplier;
if $rational { $result .= nude; }
say $result;
}
multi MAIN('mult',
$x, $y,
*%h,
) { say ($x * $y) * $multiplier }
=Note C<--help> looks the same as with 04-main-multi-example:
=begin output
$ K<./05-main-multi-example --help>
Usage:
./05-main-multi-example [--<h>=...] add <x> <y>
./05-main-multi-example [-r|--rational] [--<h>=...] div <x> <y>
./05-main-multi-example [--<h>=...] mult <x> <y>
-r|--rational Return a Rat form
=end output
=Note The functionality not including the C<-r> is all the same as before:
=begin output
$ K<./05-main-multi-example add 2 3>
5
$ K<./05-main-multi-example -d add 2 3>
10
$ K<./05-main-multi-example -double add 2 3>
10
$ K<./05-main-multi-example subtract 2 3>
Usage:
./05-main-multi-example [--<h>=...] add <x> <y>
./05-main-multi-example [-r|--rational] [--<h>=...] div <x> <y>
./05-main-multi-example [--<h>=...] mult <x> <y>
-r|--rational Return a Rat form
=end output
=Note Now attempting to use the C<div> gives us:
=begin output
$ ./05-main-multi-example div 2 3
./05-main-multi-example div 2 3
0.666667
$ ./05-main-multi-example -d div 2 3
./05-main-multi-example -d div 2 3
1.333333
$ ./05-main-multi-example -r div 2 3
./05-main-multi-example -r div 2 3
(2 3)
$ ./05-main-multi-example -d -r div 2 3
./05-main-multi-example -d -r div 2 3
(4 3)
$ ./05-main-multi-example --double -r div 2 3
./05-main-multi-example --double -r div 2 3
(4 3)
$ ./05-main-multi-example --double --rational div 2 3
./05-main-multi-example --double --rational div 2 3
(4 3)
=end output
=Note However, we no longer get errors for using spurious flags:
=begin output
$ K<./05-main-multi-example --nonesuch div 2 3>
0.666667
$ K<./05-main-multi-example --nonesuch --rational div 2 3>
(2 3)
$ K<./05-main-multi-example --nonesuch --rotional div 2 3>
0.666667
$ K<./05-main-multi-example -l add 2 3>
5
=end output
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment