The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Sublike::Extended - enable extended features when parsing sub-like syntax

SYNOPSIS

   use v5.26;
   use Sublike::Extended;
   use experimental 'signatures';

   extended sub greet (:$name = "world") {
      say "Hello, $name";
   }

   greet( name => $ENV{USER} );

DESCRIPTION

This module extends the syntax for declaring named or anonymous subroutines using Perl's builtin sub keyword, or other similar keywords provided by third-party modules, to enable parsing of extra features.

Currently, the only extended features that are provided are related to the parsing of a subroutine signature. Since signatures are only available on Perl version 5.26 or later, this module is unlikely to be useful in earlier versions of Perl.

Named parameters

Extended subroutines can declare named parameters in the signature, after any positional ones. These take the form of a name prefixed by a colon character. The caller of such a function should pass values for these parameters by the usual name-value pair syntax that would be used for passing into a regular hash. Within the body of the subroutine the values passed into these are unpacked into regular lexical variables.

   extended sub colour (:$red, :$green, :$blue) {
      ... # $red, $green and $blue are available as regular lexicals
   }

   # argument order at the caller site is not important
   colour(green => 1, blue => 2, red => 3);

Positional parameters can be placed after optional positional ones, but in order to make use of them the caller would have to pass a value for every positional parameter including the optional ones first. This is unlikely to be very useful; if you want to have optional parameters and named parameters, use named optional ones after any mandatory positional parameters.

As with positional parameters, they are normally mandatory, but can be made optional by supplying a defaulting expression. If the caller fails to pass a value corresponding to an optional parameter, the default expression is evaluated and used instead.

   extended sub f (:$x0, :$x1, :$x2 = 0) { ... }
   # The caller must provide x0 and x1, but x2 is optional

Since version 0.23 named parameters can be given defaulting expressions with the //= or ||= operators, meaning their defaults apply also if the caller passed a present-but-undef, or present-but-false value.

   extended sub f (:$x0, :$x1, :$x2 //= 0) { ... }
   # $x2 will be set to 0 even if the caller passes  x2 => undef

An optional slurpy hash or (since version 0.24) slurpy array is also permitted after all of these. It will contain the values of any other name-value pairs given by the caller, after those corresponding to named parameters have already been extracted.

   extended sub g (:$alpha, :$beta, %rest) { ... }

   extended sub g (:$alpha, :$beta, @rest) { ... }

In the case of a slurpy array, it will contain every argument value that was not consumed as a named parameter pair, in the original order passed by the caller, including any duplicates.

Parameter Attributes

Parameters to extended subroutines can use attribute syntax to apply extra attributes to individual parameters.

   extended sub info ($x :Attribute) { ... }

Any attributes that are available are ones that have been previously registered with XS::Parse::Sublike using its XS-level API. The particular behaviour of such an attribute would be defined by whatever module provided the attribute.

KEYWORDS

extended

   extended sub NAME (SIGNATURE...) { BODY... }

   extended sub (SIGNATURE...) { BODY... };

This prefix keyword enables extra parsing features when handling a sub (or other sub-like function keyword).

This keyword can be freely mixed with other sub-prefix keywords, such as async from Future::AsyncAwait

   async extended sub f (:$param) { ... }

This can also be used with other keywords that provide sub-like syntax, such as method from Object::Pad or the core use feature 'class'.

   extended method f (:$param) { ... }

TODO

  • Support defined-or and true-or positional parameters even on versions of Perl before they were officially added (v5.38).

AUTHOR

Paul Evans <leonerd@leonerd.org.uk>