sub MAIN

Documentation for sub MAIN assembled from the following types:

language documentation Functions

From Functions

(Functions) sub MAIN

The sub with the special name MAIN is executed after all relevant phasers. Its signature is the means by which command line arguments can be parsed. Multi methods are supported and a usage method is automatically generated and displayed if no command line arguments are provided. All command line arguments are also available in @*ARGS, which can be mutated before being processed by MAIN.

Unlike other ordinary functions, any return value provided by MAIN will be ignored by the invoker, even if explicitly set by means of a return statement (that will terminate the MAIN function). The default return code of MAIN is always zero (0, success). In order to provide any return value different from zero, a call to exit has to be performed.

#|(optional description for USAGE message) 
sub MAINInt :$length = 24,
           :file($datawhere { .IO.f // die "file not found in $*CWD" } = 'file.dat',
           Bool :v(:$verbose) #`( -verbose, --verbose, -v or --v ) )
{
    say $length if $length.defined;
    say $data   if $data.defined;
    say 'Verbosity ', ($verbose ?? 'on' !! 'off');
 
    exit 1;
}

This MAIN is defining two kind of aliases, as explained in Signatures: :file($data) aliases the content passed to the command-line parameter --file= to the variable $data; :v(:$verbose) not only aliases v to verbose, but also creates a new command line parameter verbose thanks to the specification of the :. In fact, since this is an alias, both verbose and v can use single or double dashes (- or --).

With file.dat present, this will work this way

$ perl6 Main.p6
24
file.dat
Verbosity off

Or this way with -v or --verbose

$ perl6 Main.p6 -v
24
file.dat
Verbosity on

%*SUB-MAIN-OPTS

It's possible to alter how arguments are processed before they're passed to sub MAIN {} by setting options in %*SUB-MAIN-OPTS hash. Due to the nature of dynamic variables, it is required to set up %*SUB-MAIN-OPTS hash and fill it with the appropriate settings. For instance:

my %*SUB-MAIN-OPTS =
  :named-anywhere,    # allow named variables at any location 
  :!foo,              # don't allow foo 
;
sub MAIN ($a$b:$c:$d{
    say "Accepted!"
}

Available options are:

named-anywhere

By default, named arguments passed to the program (i.e., MAIN) cannot appear after any positional argument. However, if %*SUB-MAIN-OPTS<named-anywhere> is set to a true value, named arguments can be specified anywhere, even after positional parameter. For example, the above program can be called with:

perl6 example.p6 1 --c=2 3 --d=4

Unit-scoped definition of MAIN

If the entire program body resides within MAIN, you can use the unit declarator as follows:

unit sub MAINInt :$length = 24,
                :file($datawhere { .IO.f // die "file not found in $*CWD" } = 'file.dat',
                Bool :v(:$verbose) #`( -verbose, --verbose, -v or --v ) );
 
# rest of script is part of MAIN 

Note that this is only appropriate if you do not need a proto or multi definition.