In Unix environment, many scripts take arguments and options from the command line. With Perl 6 it’s very easy to accept those:
$ cat add.pl sub MAIN($x, $y) { say $x + $y } $ perl6 add.pl 3 4 7 $ perl6 add.pl too many arguments Usage: add.pl x y
By just writing a subroutine called MAIN
with a signature, you automatically get a command line parser, binding from the command line arguments into the signature variables $x
and $y
, and a usage message if the command line arguments don’t fit.
The usage message is customizable by adding another sub called USAGE
:
$ cat add2.pl sub MAIN($x, $y) { say $x + $y } sub USAGE() { say "Usage: add.pl <num1> <num2>"; } $ perl6 add2.pl too many arguments Usage: add.pl <num1> <num2>
Declaring the MAIN
sub as multi
allows declaring several alternative syntaxes, or dispatch based on some constant:
$ cat calc #!/usr/bin/env perl6 multi MAIN('add', $x, $y) { say $x + $y } multi MAIN('div', $x, $y) { say $x / $y } multi MAIN('mult', $x, $y) { say $x * $y } $ ./calc add 3 5 8 $ ./calc mult 3 5 15 $ ./calc Usage: ./calc add x y or ./calc div x y or ./calc mult x y
Named parameters correspond to options:
$ cat copy.pl sub MAIN($source, $target, Bool :$verbose) { say "Copying '$source' to '$target'" if $verbose; run "cp $source $target"; } $ perl6 copy.pl calc calc2 $ perl6 copy.pl --verbose calc calc2 Copying 'calc' to 'calc2'
Declaring the parameter as Bool
makes it accept no value; without a type constraint of Bool it will take an argument:
$ cat do-nothing.pl sub MAIN(:$how = 'fast') { say "Do nothing, but do it $how"; } $ perl6 do-nothing.pl Do nothing, but do it fast $ perl6 do-nothing.pl --how=well Do nothing, but do it well $ perl6 do-nothing.pl what? Usage: do-nothing.pl [--how=value-of-how]
In summary, Perl 6 offers you built-in command line parsing and usage messages, just by using subroutine signatures and multi subs.
Writing good, declarative code has never been so easy before.
This seems like such a little thing, but for me it’s a killer feature. I write tons of little scripts to automate away busywork. Now it’s development tools, it used to be sysadmin scripts. I either end up not checking input or I have to constantly go back to perldoc and remind myself how to set up Getopt::Long. This and the power of perl6’s prototypes are going to make it a lot easier to whip out little tools by hiding a lot of boilerplate code.
multi MAIN(‘add’, $x, $y) { say $x + $y }
should probably give usage
./calc ‘add’ x y
If it gives just
./calc add x y
as in the example, ‘add’ might be a variable name?
I have a few questions regarding this feature.
For example, does
sub MAIN(Num $x, Num $y)
provide you with a different usage message?
Is it possible to distinguish certain alternatives just by using their types? For example will
multi MAIN(Str $type, Num $x, Num $y)
multi MAIN(Num $x, Num $y, Num $z)
work as expected?
And what about arrays? Does
multi MAIN(Num @x)
{
say [+] @x;
}
work as expected?
I really like this feature of Perl6, I just also would like to know about its limitations.
Currently the type of all arguments (except those that match parameters declared as Bool) are Str, so declaring a sub MAIN with an Int parameter will never do what you mean.
We know this is not ideal, and are looking for alternative mechanisms. Maybe some smarter type detection for literals would be desirable.
This a really a remarkable feature, the first that makes me go “wow that’s good” in years of lurking.
At first sight declaring a MAIN in perl seems _so damn wrong_, but given a good look it is _so damn right_ and it introduces first timers to all subroutine argument types fast.
Very good starting point for tutorials.
I now ask a minute of silence over Getopt::Long.
It served us well, and until now it was the best command line parser I had ever had the pleasure to work with, in any language.
Hey, I think your site might be having browser compatibility issues.
When I look at your blog site in Chrome, it looks fine but when opening in Internet Explorer, it has some overlapping.
I just wanted to give you a quick heads up! Other then that,
amazing blog!