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;

With touch.dat present, this will work this way

$ perl6 Main.p6
Verbosity off

Or this way with -v or --verbose

$ perl6 Main.p6 -v
Verbosity on

The :v(:$verbose) is an alias, as explained in Signatures. In fact, since this is an alias, both verbose and v can use single or double dashes (- or --).


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, one needs to set up its own %*SUB-MAIN-OPTS hash and fill it with the appropriate settings. For instance:

  :named-anywhere,    # allow named variables at any location 
  :!foo,              # don't allow foo 
sub MAIN ($a$b:$c:$d{
    say "Accepted!"

Available options are:


By default, named arguments to the program cannot be given after any positional arguments are specified. However, if %*SUB-MAIN-OPTS<named-anywhere> is set to a truthy 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 script 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.