Welcome to the official documentation of the Perl 6 programming language! Besides online browsing and searching, you can also view everything in one file or contribute by reporting mistakes or sending patches.
Language Reference & Tutorials
A collection of documents describing, in detail, the various conceptual parts of the language.
Type Reference
Index of built-in classes and roles.
Routine Reference
Index of built-in subroutines and methods.
Perl 6 Programs
A collection of documents describing the variables that affect the the Perl 6 executable, how to run the p6doc documentation front-end, how to debug Perl 6 programs, and how to hack on Perl 6 source code.

The Perl 6 homepage offers a comprehensive list of Perl 6 resources, including tutorials, how-tos and FAQs (Frequently Asked Questions).

Perl 6 compiler developers may also be interested in The Perl 6 Specification. Documentation for the different but related Perl 5 language can be found on the Perl 5 documentation website.

Part of this official documentation has been translated into Chinese. Here's the index to the pages that have been translated.

1 At the beginning

~

2 Brief introduction

Using Perl 6 official documentation

Documenting a large language like Perl 6 has to balance several contradictory goals, such as being brief whilst being comprehensive, catering to professional developers with wide experience whilst also being accessible to newcomers to the language.

For a quick hands-on introduction, there is a short annotated programming example.

For programmers with experience in other languages, there are a number of Migration guides that compare and contrast the features of Perl 6 with other languages.

A number of Tutorials cover several areas in which Perl 6 is particularly innovative. The section headers should help navigate the remaining documents.

There are a number of useful resources listed elsewhere on the perl6.org site. These include articles, books, slide presentations, and videos.

It has been found that newcomers to Perl 6 often ask questions that indicate assumptions carried over from other programming paradigms. It is suggested that the following sections in the Fundamental topics section should be reviewed first.

3 Perl 6 by example P6-101

A basic introductory example of a Perl 6 program

Suppose that you host a table tennis tournament. The referees tell you the results of each game in the format Player1 Player2 | 3:2, which means that Player1 won against Player2 by 3 to 2 sets. You need a script that sums up how many matches and sets each player has won to determine the overall winner.

The input data (stored in a file called scores.txt) looks like this:

Beth Ana Charlie Dave 
 Ana Dave | 3:0 
 Charlie Beth | 3:1 
 Ana Beth | 2:3 
 Dave Charlie | 3:0 
 Ana Charlie | 3:1 
 Beth Dave | 0:3 

The first line is the list of players. Every subsequent line records a result of a match.

Here's one way to solve that problem in Perl 6:

use v6; 
 
 # Single line comments like this one start with '#'. 
 my $file  = open 'scores.txt'; # Comments can also follow code on a line. 
 my @names = $file.get.words; 
 
 my %matches; 
 my %sets; 
 
 #`(  Multiple line comments 
      are denoted by a #, then `, then one of {,[, or ( 
      and closed by the corresponding },], and ). 
      Nested pairs of square brackets, curly braces and 
      parentheses are matched, so 
      something like this () will not end the comment. 
      In this case, closed by: ) 
 for $file.lines -> $line { 
     next unless $line; # ignore any empty lines 
 
     my ($pairing, $result) = $line.split(' | '); 
     my ($p1, $p2)          = $pairing.words; 
     my ($r1, $r2)          = $result.split(':'); 
 
     %sets{$p1} += $r1; 
     %sets{$p2} += $r2; 
 
     if $r1 > $r2 { 
         %matches{$p1}++; 
     } else { 
         %matches{$p2}++; 
     } 
 } 
 
 #`[ 
   This is another multi-line comment. ] 
 #`{ So is this, though it's not actually multi-line. } 
 my @sorted = @names.sort({ %sets{$_} }).sort({ %matches{$_} }).reverse; 
 
 for @sorted -> $n { 
     my $match-noun = %matches{$n} == 1 ?? 'match' !! 'matches'; 
     my $set-noun   = %sets{$n} == 1 ?? 'set' !! 'sets'; 
     say "$n has won %matches{$n} $match-noun and %sets{$n} $set-noun"; 
 } 

This produces the output:

Ana has won 2 matches and 8 sets 
 Dave has won 2 matches and 6 sets 
 Charlie has won 1 match and 4 sets 
 Beth has won 1 match and 4 sets 

v6

Every Perl 6 program should begin with a line similar to use v6;. This line tells the compiler which version of Perl 6 the program expects. For instance, 6.c is an example of a Perl 6 version. Should you accidentally run the file with Perl 5, you'll get a helpful error message.

statement

A Perl 6 program consists of zero or more statements. A statement ends with a semicolon or a curly brace at the end of a line:

my $file = open 'scores.txt'; 

lexical and block

my declares a lexical variable, which are visible only in the current block from the point of declaration to the end of the block. If there's no enclosing block, it's visible throughout the remainder of the file (which would effectively be the enclosing block). A block is any part of the code enclosed between curly braces { }.

sigil and identifier

A variable name begins with a sigil, which is a non-alpha-numeric symbol such as $, @, %, or & — or occasionally the double colon ::. Sigils indicate the structural interface for the variable, such as whether it should be treated as a single value, a compound value, a subroutine, etc. After the sigil comes an identifier, which may consist of letters, digits and the underscore. Between letters you can also use a dash - or an apostrophe ', so isn't and double-click are valid identifiers.

scalar

Sigils indicate the default access method for a variable. Variables with the @ sigil are accessed positionally; variables with the % sigil are accessed by string key. The $ sigil, however, indicates a general scalar container that can hold any single value and be accessed in any manner. A scalar can even contain a compound object like an Array or a Hash; the $ sigil signifies that it should be treated as a single value, even in a context that expects multiple values (as with an Array or Hash).

filehandle and assignment

The built-in function open opens a file, here named scores.txt, and returns a filehandle — an object representing that file. The equality sign = assigns that filehandle to the variable on the left, which means that $file now stores the filehandle.

string literal

'scores.txt' is a string literal. A string is a piece of text, and a string literal is a string which appears directly in the program. In this line, it's the argument provided to open.

my @names = $file.get.words; 

array, method and invocant

The right-hand side calls a method — a named group of behavior — named get on the filehandle stored in $file. The get method reads and returns one line from the file, removing the line ending. If you print the contents of $file after calling get, you will see that the first line is no longer in there. words is also a method, called on the string returned from get. words decomposes its invocant — the string on which it operates — into a list of words, which here means strings separated by whitespace. It turns the single string 'Beth Ana Charlie Dave' into the list of strings 'Beth', 'Ana', 'Charlie', 'Dave'.

Finally, this list gets stored in the Array @names. The @ sigil marks the declared variable as an Array. Arrays store ordered lists.

my %matches; 
 my %sets; 

hash

These two lines of code declare two hashes. The % sigil marks each variable as a Hash. A Hash is an unordered collection of key-value pairs. Other programming languages call that a hash table, dictionary, or map. You can query a hash table for the value that corresponds to a certain $key with %hash{$key}.

In the score counting program, %matches stores the number of matches each player has won. %sets stores the number of sets each player has won. Both of these hashes are indexed by the player's name.

for $file.lines -> $line { 
     ... 
 } 

for and block

for produces a loop that runs the block delimited by curly braces once for each item of the list, setting the variable $line to the current value of each iteration. $file.lines produces a list of the lines read from the file scores.txt, starting with the second line of the file since we already called $file.get once, and going all the way to the end of the file.

During the first iteration, $line will contain the string Ana Dave | 3:0; during the second, Charlie Beth | 3:1, and so on.

my ($pairing, $result) = $line.split(' | '); 

my can declare multiple variables simultaneously. The right-hand side of the assignment is a call to a method named split, passing along the string ' | ' as an argument.

split decomposes its invocant into a list of strings, so that joining the list items with the separator ' | ' produces the original string.

$pairing gets the first item of the returned list, and $result the second.

After processing the first line, $pairing will hold the string Ana Dave and $result will hold 3:0.

The next two lines follow the same pattern:

my ($p1, $p2) = $pairing.words; 
 my ($r1, $r2) = $result.split(':'); 

The first extracts and stores the names of the two players in the variables $p1 and $p2. The second extracts the results for each player and stores them in $r1 and $r2.

After processing the first line of the file, the variables contain the values:

Variable Contents
$line 'Ana Dave | 3:0'
$pairing 'Ana Dave'
$result '3:0'
$p1 'Ana'
$p2 'Dave'
$r1 '3'
$r2 '0'

The program then counts the number of sets each player has won:

%sets{$p1} += $r1; 
 %sets{$p2} += $r2; 

The += assignment operator is a shortcut for:

%sets{$p1} = %sets{$p1} + $r1; 
 %sets{$p2} = %sets{$p2} + $r2; 

Any and +=

+= $r1 means increase the value in the variable on the left by $r1. In the first iteration %sets{$p1} is not yet set, so it defaults to a special value called Any. The addition and incrementing operators treat Any as a number with the value of zero; the strings get automatically converted to numbers, as addition is a numeric operation.

fat arrow, pair and autovivification

Before these two lines execute, %sets is empty. Adding to an entry that is not in the hash yet will cause that entry to spring into existence just-in-time, with a value starting at zero. (This is autovivification). After these two lines have run for the first time, %sets contains 'Ana' => 3, 'Dave' => 0 . (The fat arrow => separates the key and the value in a Pair.)

if $r1 > $r2 { 
     %matches{$p1}++; 
 } else { 
     %matches{$p2}++; 
 } 

If $r1 is numerically larger than $r2, %matches{$p1} increments by one. If $r1 is not larger than $r2, %matches{$p2} increments. Just as in the case of +=, if either hash value did not exist previously, it is autovivified by the increment operation.

postincrement and preincrement

$thing++ is short for $thing += 1 or $thing = $thing + 1, with the small exception that the return value of the expression is $thing before the increment, not the incremented value. As in many other programming languages, you can use ++ as a prefix. Then it returns the incremented value; my $x = 1; say ++$x prints 2.

my @sorted = @names.sort({ %sets{$_} }).sort({ %matches{$_} }).reverse; 

variables, $_

This line consists of three individually simple steps. An array's sort method returns a sorted version of the array's contents. However, the default sort on an array sorts by its contents. To print player names in winner-first order, the code must sort the array by the scores of the players, not their names. The sort method's argument is a block used to transform the array elements (the names of players) to the data by which to sort. The array items are passed in through the topic variable $_.

block

You have seen blocks before: both the for loop -> $line { ... } and the if statement worked on blocks. A block is a self-contained piece of Perl 6 code with an optional signature (the -> $line part).

The simplest way to sort the players by score would be @names.sort({ %matches{$_} }), which sorts by number of matches won. However Ana and Dave have both won two matches. That simple sort doesn't account for the number of sets won, which is the secondary criterion to decide who has won the tournament.

stable sort

When two array items have the same value, sort leaves them in the same order as it found them. Computer scientists call this a stable sort. The program takes advantage of this property of Perl 6's sort to achieve the goal by sorting twice: first by the number of sets won (the secondary criterion), then by the number of matches won.

After the first sorting step, the names are in the order Beth Charlie Dave Ana. After the second sorting step, it's still the same, because no one has won fewer matches but more sets than someone else. Such a situation is entirely possible, especially at larger tournaments.

sort sorts in ascending order, from smallest to largest. This is the opposite of the desired order. Therefore, the code calls the .reverse method on the result of the second sort, and stores the final list in @sorted.

for @sorted -> $n { 
     my $match-noun = %matches{$n} == 1 ?? 'match' !! 'matches'; 
     my $set-noun   = %sets{$n} == 1 ?? 'set' !! 'sets'; 
     say "$n has won %matches{$n} $match-noun and %sets{$n} $set-noun"; 
 } 

say, print and put

To print out the players and their scores, the code loops over @sorted, setting $n to the name of each player in turn. Read this code as "For each element of sorted, set $n to the element, then execute the contents of the following block." The variable $match-noun will store either the string match if the player has won a single match or matches if the player has won zero or more matches. In order to do this, the ternary operator (?? !!) is used. If %matches{$n} == 1 evaluates to True, then match is returned. Otherwise, matches is returned. Either way, the returned value is stored in $match-noun. The same approach applies to <$set-noun>.

The statement say prints its arguments to the standard output (the screen, normally), followed by a newline. (Use print if you don't want the newline at the end.)

Note that say will truncate certain data structures by calling the .gist method so put is safer if you want exact output.

interpolation

When you run the program, you'll see that say doesn't print the contents of that string verbatim. In place of $n it prints the contents of the variable $n — the names of players stored in $n. This automatic substitution of code with its contents is interpolation. This interpolation happens only in strings delimited by double quotes "...". Single quoted strings '...' do not interpolate:

double-quoted strings and single-quoted strings

my $names = 'things'; 
 say 'Do not call me $names'; # OUTPUT: «Do not call me $names␤» 
 say "Do not call me $names"; # OUTPUT: «Do not call me things␤» 

Double quoted strings in Perl 6 can interpolate variables with the $ sigil as well as blocks of code in curly braces. Since any arbitrary Perl code can appear within curly braces, Arrays and Hashes may be interpolated by placing them within curly braces.

Arrays within curly braces are interpolated with a single space character between each item. Hashes within curly braces are interpolated as a series of lines. Each line will contain a key, followed by a tab character, then the value associated with that key, and finally a newline.

Let's see an example of this now.

In this example, you will see some special syntax that makes it easier to make a list of strings. This is the <...> quote-words construct. When you put words in between the < and > they are all assumed to be strings, so you do not need to wrap them each in double quotes "...".

say "Math: { 1 + 2 }"; 
 # OUTPUT: «Math: 3␤» 
 
 my @people = <Luke Matthew Mark>; 
 say "The synoptics are: {@people}"; 
 # OUTPUT: «The synoptics are: Luke Matthew Mark␤» 
 
 say "{%sets}␤"; 
 # OUTPUT (From the table tennis tournament): 
 
 # Charlie 4 
 # Dave    6 
 # Ana     8 
 # Beth    4 

When array and hash variables appear directly in a double-quoted string (and not inside curly braces), they are only interpolated if their name is followed by a postcircumfix — a bracketing pair that follows a statement. It's also ok to have a method call between the variable name and the postcircumfix.

Zen slice

my @flavors = <vanilla peach>; 
 
 say "we have @flavors";           # OUTPUT: «we have @flavors␤» 
 say "we have @flavors[0]";        # OUTPUT: «we have vanilla␤» 
 # so-called "Zen slice" 
 say "we have @flavors[]";         # OUTPUT: «we have vanilla peach␤» 
 
 # method calls ending in postcircumfix 
 say "we have @flavors.sort()";    # OUTPUT: «we have peach vanilla␤» 
 
 # chained method calls: 
 say "we have @flavors.sort.join(', ')"; 
                                   # OUTPUT: «we have peach, vanilla␤» 

Exercises

1. The input format of the example program is redundant: the first line containing the name of all players is not necessary, because you can find out which players participated in the tournament by looking at their names in the subsequent rows.

How can you make the program run if you do not use the @names variable? Hint: %hash.keys returns a list of all keys stored in %hash.

Answer: Remove the line my @names = $file.get.words;, and change:

my @sorted = @names.sort({ %sets{$_} }).sort({ %matches{$_} }).reverse; 

... into:

my @sorted = %sets.keys.sort({ %sets{$_} }).sort({ %matches{$_} }).reverse; 

2. Instead of deleting the redundant @names variable, you can also use it to warn if a player appears that wasn't mentioned in the first line, for example due to a typo. How would you modify your program to achieve that?

Hint: Try using membership operators.

Answer: Change @names to @valid-players. When looping through the lines of the file, check to see that $p1 and $p2 are in @valid-players. Note that for membership operators you can also use (elem) and !(elem).

...; 
 my @valid-players = $file.get.words; 
 ...; 
 
 for $file.lines -> $line { 
     my ($pairing, $result) = $line.split(' | '); 
     my ($p1, $p2)          = $pairing.split(' '); 
     if $p1 ∉ @valid-players { 
         say "Warning: '$p1' is not on our list!"; 
     } 
     if $p2 ∉ @valid-players { 
         say "Warning: '$p2' is not on our list!"; 
     } 
     ... 
 } 

4 Migration guides

~

5 Perl 5 to Perl 6 guide - in a nutshell

How do I do what I used to do? (Perl 6 in a nutshell)

This page attempts to provide a fast-path to the changes in syntax and semantics from Perl 5 to Perl 6. Whatever worked in Perl 5 and must be written differently in Perl 6, should be listed here (whereas many new Perl 6 features and idioms need not).

Hence this should not be mistaken for a beginner tutorial or a promotional overview of Perl 6; it is intended as a technical reference for Perl 6 learners with a strong Perl 5 background and for anyone porting Perl 5 code to Perl 6 (though note that #Automated translation might be more convenient).

A note on semantics; when we say "now" in this document, we mostly just mean "now that you are trying out Perl 6." We don't mean to imply that Perl 5 is now suddenly obsolete. Quite the contrary, most of us love Perl 5, and we expect Perl 5 to continue in use for a good many years. Indeed, one of our more important goals has been to make interaction between Perl 5 and Perl 6 run smoothly. However, we do also like the design decisions in Perl 6, which are certainly newer and arguably better integrated than many of the historical design decisions in Perl 5. So many of us do hope that over the next decade or two, Perl 6 will become the more dominant language. If you want to take "now" in that future sense, that's okay too. But we're not at all interested in the either/or thinking that leads to fights.

CPAN

See https://modules.perl6.org/.

If the module that you were using has not been converted to Perl 6, and no alternative is listed in this document, then its use under Perl 6 may not have been addressed yet.

The Inline::Perl5 project makes it possible to use Perl 5 modules directly from Perl 6 code by using an embedded instance of the perl interpreter to run Perl 5 code.

This is as simple as:

# the :from<Perl5> makes Perl 6 load Inline::Perl5 first (if installed) 
 # and then load the Scalar::Util module from Perl 5 
 use Scalar::Util:from<Perl5> <looks_like_number>; 
 say looks_like_number "foo";   # 0 
 say looks_like_number "42";    # 1 

A number of Perl 5 modules have been ported to Perl 6, trying to maintain the API of these modules as much as possible, as part of the CPAN Butterfly Plan. These can be found at https://modules.perl6.org/t/CPAN5.

Many Perl 5 built-in functions (about a 100 so far) have been ported to Perl 6 with the same semantics. Think about the shift function in Perl 5 having magic shifting from @_ or @ARGV by default, depending on context. These can be found at https://modules.perl6.org/t/Perl5 as separately loadable modules, and in the P5built-ins bundle to get them all at once.

Syntax

There are a few differences in syntax between the two languages, starting with how identifiers are defined.

Identifiers

Perl 6 allows the use of dashes (-), underscores (_), apostrophes ('), and alphanumerics in identifiers, :

sub test-doesn't-hang { ... }
my $ความสงบ = 42;
my \Δ = 72; say 72 - Δ;

-> Method calls

If you've read any Perl 6 code at all, it's immediately obvious that method call syntax now uses a dot instead of an arrow:

$person->name  # Perl 5 
$person.name   # Perl 6 

The dot notation is both easier to type and more of an industry standard. But we also wanted to steal the arrow for something else. (Concatenation is now done with the ~ operator, if you were wondering.)

To call a method whose name is not known until runtime:

$object->$methodname(@args);  # Perl 5 
$object."$methodname"(@args); # Perl 6 

If you leave out the quotes, then Perl 6 expects $methodname to contain a Method object, rather than the simple string name of the method. Yes, everything in Perl 6 can be considered an object.

Whitespace

Perl 5 allows a surprising amount of flexibility in the use of whitespace, even with strict mode and warnings turned on:

# unidiomatic but valid Perl 5 
 say"Hello ".ucfirst  ($people 
     [$ i] 
     -> 
     name)."!"if$greeted[$i]<1; 

Perl 6 also endorses programmer freedom and creativity, but balanced syntactic flexibility against its design goal of having a consistent, deterministic, extensible grammar that supports single-pass parsing and helpful error messages, integrates features like custom operators cleanly, and doesn't lead programmers to accidentally misstate their intent. Also, the practice of "code golf" is slightly de-emphasized; Perl 6 is designed to be more concise in concepts than in keystrokes.

As a result, there are various places in the syntax where whitespace is optional in Perl 5, but is either mandatory or forbidden in Perl 6. Many of those restrictions are unlikely to concern much real-life Perl code (e.g., whitespace being disallowed between the sigil and name of a variable), but there are a few that will unfortunately conflict with some Perl hackers' habitual coding styles:

However, note that you can use unspace to add whitespace in Perl 6 code in places where it is otherwise not allowed.

See also other lexical conventions in the syntax page.

Sigils

In Perl 5, arrays and hashes use changing sigils depending on how they are being accessed. In Perl 6 the sigils are invariant, no matter how the variable is being used - you can think of them as part of the variable's name.

$ Scalar

The $ sigil is now always used with "scalar" variables (e.g. $name), and no longer for array indexing and Hash indexing. That is, you can still use $x[1] and $x{"foo"}, but it will act on $x, with no effect on a similarly named @x or %x. Those would now be accessed with @x[1] and %x{"foo"}.

@ Array

The @ sigil is now always used with "array" variables (e.g. @months, @months[2], @months[2, 4]), and no longer for value-slicing hashes.

% Hash

The % sigil is now always used with "hash" variables (e.g. %calories, %calories<apple>, %calories<pear plum>), and no longer for key/value-slicing arrays.

& Sub

The & sigil is now used consistently (and without the help of a backslash) to refer to the function object of a named subroutine/operator without invoking it, i.e. to use the name as a "noun" instead of a "verb":

my $sub = \&foo; # Perl 5 
my $sub = &foo;  # Perl 6 
callback => sub { say @_ }  # Perl 5 - can't pass built-in sub directly 
callback => &say            # Perl 6 - & gives "noun" form of any sub 

Since Perl 6 does not allow adding/removing symbols in a lexical scope once it has finished compiling, there is no equivalent to Perl 5's undef &foo;, and the closest equivalent to Perl 5's defined &foo would be defined ::('&foo') (which uses the "dynamic symbol lookup" syntax). However, you can declare a mutable named subroutine with my &foo; and then change its meaning at runtime by assigning to &foo.

In Perl 5, the ampersand sigil can additionally be used to call subroutines in special ways with subtly different behavior compared to normal sub calls. In Perl 6 those special forms are no longer available:

* Glob

In Perl 5, the * sigil referred to the GLOB structure that Perl uses to store non-lexical variables, filehandles, subs, and formats.

This should not be confused with the Perl 5 built-in glob() function, which reads filenames from a directory.

You are most likely to encounter a GLOB in code written on an early Perl version that does not support lexical filehandles, when a filehandle needed to be passed into a sub.

# Perl 5 - ancient method 
 sub read_2 { 
     local (*H) = @_; 
     return scalar(<H>), scalar(<H>); 
 } 
 open FILE, '<', $path or die; 
 my ($line1, $line2) = read_2(*FILE); 

You should refactor your Perl 5 code to remove the need for the GLOB, before translating into Perl 6.

# Perl 5 - modern use of lexical filehandles 
 sub read_2 { 
     my ($fh) = @_; 
     return scalar(<$fh>), scalar(<$fh>); 
 } 
 open my $in_file, '<', $path or die; 
 my ($line1, $line2) = read_2($in_file); 

And here's just one possible Perl 6 translation:

# Perl 6 
 sub read-n($fh, $n) { 
     return $fh.get xx $n; 
 } 
 my $in-file = open $path or die; 
 my ($line1, $line2) = read-n($in-file, 2); 

[] Array indexing/slicing

Index and slice operations on arrays no longer inflect the variable's sigil, and adverbs can be used to control the type of slice:

Also note that the subscripting square brackets are now a normal postcircumfix operator rather than a special syntactic form, and thus checking for existence of elements and unsetting elements is done with adverbs.

{} Hash indexing/slicing

Index and slice operations on hashes no longer inflect the variable's sigil, and adverbs can be used to control the type of slice. Also, single-word subscripts are no longer magically autoquoted inside the curly braces; instead, the new angle brackets version is available which always autoquotes its contents (using the same rules as the qw// quoting construct):

Also note that the subscripting curly braces are now a normal postcircumfix operator rather than a special syntactic form, and thus checking for existence of keys and removing keys is done with adverbs.

Creating references and using them

In Perl 5, references to anonymous arrays and hashes and subs are returned during their creation. References to existing named variables and subs were generated with the \ operator. the "referencing/dereferencing" metaphor does not map cleanly to the actual Perl 6 container system, so we will have to focus on the intent of the reference operators instead of the actual syntax.

my $aref = \@aaa  ; # Perl 5 

This might be used for passing a reference to a routine, for instance. But in Perl 6, the (single) underlying object is passed (which you could consider to be a sort of pass by reference).

my @array = 4,8,15; 
 { $_[0] = 66 }(@array);   # run the block with @array aliased to $_ 
 say @array; #  OUTPUT: «[66 8 15]␤» 

The underlying Array object of @array is passed, and its first value modified inside the declared routine.

In Perl 5, the syntax for dereferencing an entire reference is the type-sigil and curly braces, with the reference inside the curly braces. In Perl 6, this concept simply does not apply, since the reference metaphor does not really apply.

In Perl 5, the arrow operator, -> , is used for single access to a composite's reference or to call a sub through its reference. In Perl 6, the dot operator . is always used for object methods, but the rest does not really apply.

# Perl 5 
     say $arrayref->[7]; 
     say $hashref->{'fire bad'}; 
     say $subref->($foo, $bar); 

In relatively recent versions of Perl 5 (5.20 and later), a new feature allows the use of the arrow operator for dereferencing: see Postfix Dereferencing. This can be used to create an array from a scalar. This operation is usually called decont, as in decontainerization, and in Perl 6 methods such as .list and .hash are used:

# Perl 5.20 
     use experimental qw< postderef >; 
     my @a = $arrayref->@*; 
     my %h = $hashref->%*; 
     my @slice = $arrayref->@[3..7]; 
# Perl 6 
     my @a = $contains-an-array.list;        # or @($arrayref) 
     my %h = $contains-a-hash.hash;          # or %($hashref) 

The "Zen" slice does the same thing:

# Perl 6 
     my @a = $contains-an-array[]; 
     my %h = $contains-a-hash{}; 

See the "Containers" section of the documentation for more information.

Operators

See the documentation for operators for full details on all operators.

Unchanged:

, (Comma) List separator

Unchanged, but note that in order to flatten an array variable to a list (in order to append or prefix more items) one should use the | operator (see also Slip). For instance:

my @numbers = 100, 200, 300; 
 my @more_numbers = 500, 600, 700; 
 my @all_numbers = |@numbers, 400, |@more_numbers; 

That way one can concatenate arrays.

Note that one does not need to have any parentheses on the right-hand side: the List Separator takes care of creating the list, not the parentheses!

<=> cmp Three-way comparisons

In Perl 5, these operators returned -1, 0, or 1. In Perl 6, they return Order::Less, Order::Same, or Order::More.

cmp is now named leg; it forces string context for the comparison.

<=> still forces numeric context.

cmp in Perl 6 does either <=> or leg, depending on the existing type of its arguments.

~~ Smartmatch operator

While the operator has not changed, the rules for what exactly is matched depend on the types of both arguments, and those rules are far from identical in Perl 5 and Perl 6. See ~~ and the smartmatch operator

& | ^ String bitwise ops

& | ^ Numeric bitwise ops

& | ^ Boolean ops

In Perl 5, & | ^ were invoked according to the contents of their arguments. For example, 31 | 33 returns a different result than "31" | "33".

In Perl 6, those single-character ops have been removed, and replaced by two-character ops which coerce their arguments to the needed context.

# Infix ops (two arguments; one on each side of the op) 
 +&  +|  +^  And Or Xor: Numeric 
 ~&  ~|  ~^  And Or Xor: String 
 ?&  ?|  ?^  And Or Xor: Boolean 
 
 # Prefix ops (one argument, after the op) 
 +^  Not: Numeric 
 ~^  Not: String 
 ?^  Not: Boolean (same as the ! op) 

<< >> Numeric shift left|right ops

Replaced by +< and +> .

say 42 << 3; # Perl 5 
say 42 +< 3; # Perl 6 

=> Fat comma

In Perl 5, => acted just like a comma, but also quoted its left-hand side.

In Perl 6, => is the Pair operator, which is quite different in principle, but works the same in many situations.

If you were using => in hash initialization, or in passing arguments to a sub that expects a hashref, then the usage is likely identical.

sub get_the_loot { ... }; # Perl 6 stub
# Works in Perl 5 and Perl 6
my %hash = ( AAA => 1, BBB => 2 );
get_the_loot( 'diamonds', { quiet_level => 'very', quantity => 9 }); # Note the curly braces

If you were using => as a convenient shortcut to not have to quote part of a list, or in passing arguments to a sub that expects a flat list of KEY, VALUE, KEY, VALUE, then continuing to use => may break your code. The easiest workaround is to change that fat arrow to a regular comma, and manually add quotes to its left-hand side. Or, you can change the sub's API to slurp a hash. A better long-term solution is to change the sub's API to expect Pairs; however, this requires you to change all sub calls at once.

# Perl 5 
 sub get_the_loot { 
     my $loot = shift; 
     my %options = @_; 
     # ... 
 } 
 # Note: no curly braces in this sub call 
 get_the_loot( 'diamonds', quiet_level => 'very', quantity => 9 ); 
# Perl 6, original API 
 sub get_the_loot( $loot, *%options ) { # The * means to slurp everything 
     ... 
 } 
 get_the_loot( 'diamonds', quiet_level => 'very', quantity => 9 ); # Note: no curly braces in this API 
 
 # Perl 6, API changed to specify valid options 
 # The colon before the sigils means to expect a named variable, 
 # with the key having the same name as the variable. 
 sub get_the_loot( $loot, :$quiet_level?, :$quantity = 1 ) { 
     # This version will check for unexpected arguments! 
     ... 
 } 
 get_the_loot( 'diamonds', quietlevel => 'very' ); # Throws error for misspelled parameter name 

? : Ternary operator

The conditional operator ? : has been replaced by ?? !!:

my $result = $score > 60 ?  'Pass' :  'Fail'; # Perl 5 
my $result = $score > 60 ?? 'Pass' !! 'Fail'; # Perl 6 

. (Dot) String concatenation

Replaced by the tilde.

Mnemonic: think of "stitching" together the two strings with needle and thread.

$food = 'grape' . 'fruit'; # Perl 5 
$food = 'grape' ~ 'fruit'; # Perl 6 

x List repetition or string repetition operator

In Perl 5, x is the Repetition operator, which behaves differently in scalar or list contexts:

Perl 6 uses two different Repetition operators to achieve the above:

Mnemonic: x is short and xx is long, so xx is the one used for lists.

# Perl 5 
     print '-' x 80;             # Print row of dashes 
     @ones = (1) x 80;           # A list of 80 1's 
     @ones = (5) x @ones;        # Set all elements to 5 
# Perl 6 
     print '-' x 80;             # Unchanged 
     @ones = 1 xx 80;            # Parentheses no longer needed 
     @ones = 5 xx @ones;         # Parentheses no longer needed 

.. ... Two dots or three dots, range op or flipflop op

In Perl 5, .. was one of two completely different operators, depending on context.

In list context, .. is the familiar range operator. Ranges from Perl 5 code should not require translation.

In scalar context, .. and ... were the little-known Flipflop operators. They have been replaced by ff and fff.

String interpolation

In Perl 5, "${foo}s" deliminates a variable name from regular text next to it. In Perl 6, simply extend the curly braces to include the sigil too: "{$foo}s". This is in fact a very simple case of interpolating an expression.

Compound statements

These statements include conditionals and loops.

Conditionals

if elsif else unless

Mostly unchanged; parentheses around the conditions are now optional, but if used, must not immediately follow the keyword, or it will be taken as a function call instead. Binding the conditional expression to a variable is also a little different:

if (my $x = dostuff()) {...}  # Perl 5 
if dostuff() -> $x {...}      # Perl 6 

(You can still use the my form in Perl 6, but it will scope to the outer block, not the inner.)

The unless conditional only allows for a single block in Perl 6; it does not allow for an elsif or else clause.

given-when

The given-when construct is like a chain of if-elsif-else statements or like the switch-case construct in e.g. C. It has the general structure:

given EXPR { 
     when EXPR { ... } 
     when EXPR { ... } 
     default { ... } 
 } 

In its simplest form, the construct is as follows:

given $value {                   # assigns $_ 
     when "a match" {             # if $_ ~~ "a match" 
         # do-something(); 
     } 
     when "another match" {       # elsif $_ ~~ "another match" 
         # do-something-else(); 
     } 
     default {                    # else 
         # do-default-thing(); 
     } 
 } 

This is simple in the sense that a scalar value is matched in the when statements against $_, which was set by the given. More generally, the matches are actually smartmatches on $_ such that lookups using more complex entities such as regexps can be used instead of scalar values.

See also the warnings on the smartmatch op above.

Loops

while until

Mostly unchanged; parentheses around the conditions are now optional, but if used, must not immediately follow the keyword, or it will be taken as a function call instead. Binding the conditional expression to a variable is also a little different:

while (my $x = dostuff()) {...}  # Perl 5 
while dostuff() -> $x {...}      # Perl 6 

(You can still use the my form in Perl 6, but it will scope to the outer block, not the inner.)

Note that reading line-by-line from a filehandle has changed.

In Perl 5, it was done in a while loop using the diamond operator. Using for instead of while was a common bug, because the for causes the whole file to be sucked in at once, swamping the program's memory usage.

In Perl 6, for statement is lazy, so we read line-by-line in a for loop using the .lines method.

while (<IN_FH>)  { } # Perl 5 
for $IN_FH.lines { } # Perl 6 

Also note that in Perl 6, lines are chomped by default.

do while/until

# Perl 5 
 do { 
     ... 
 } while $x < 10; 
 
 do { 
     ... 
 } until $x >= 10; 

The construct is still present, but do was renamed to repeat, to better represent what the construct does:

# Perl 6 
 repeat { 
     ... 
 } while $x < 10; 
 
 repeat { 
     ... 
 } until $x >= 10; 

for foreach

Note first this common misunderstanding about the for and foreach keywords: Many programmers think that they distinguish between the C-style three-expression form and the list-iterator form; they do not! In fact, the keywords are interchangeable; the Perl 5 compiler looks for the semicolons within the parentheses to determine which type of loop to parse.

The C-style three-factor form now uses the loop keyword, and is otherwise unchanged. The parentheses are still required.

for  ( my $i = 1; $i <= 10; $i++ ) { ... } # Perl 5 
loop ( my $i = 1; $i <= 10; $i++ ) { ... } # Perl 6 

The loop-iterator form is named for in Perl 6 and foreach is no longer a keyword. The for loop has the following rules:

for my $car (@cars)  {...} # Perl 5; read-write 
for @cars  -> $car   {...} # Perl 6; read-only 
 for @cars <-> $car   {...} # Perl 6; read-write 

If the default topic $_ is being used, it is also read-write.

for (@cars)      {...} # Perl 5; $_ is read-write 
for @cars        {...} # Perl 6; $_ is read-write 
 for @cars <-> $_ {...} # Perl 6; $_ is also read-write 

It is possible to consume more than one element of the list in each iteration simply specifying more than one variable after the arrow operator:

my @array = 1..10; 
 for @array -> $first, $second { 
     say "First is $first, second is $second"; 
 } 

each

Here is the equivalent to Perl 5’s while…each(%hash) or while…each(@array) (i.e., iterating over both the keys/indices and values of a data structure) in Perl 6:

while (my ($i, $v) = each(@array)) { ... } # Perl 5 
for @array.kv -> $i, $v { ... } # Perl 6 
while (my ($k, $v) = each(%hash)) { ... } # Perl 5 
for %hash.kv -> $k, $v { ... } # Perl 6 

Flow control statements

Unchanged:

continue

There is no longer a continue block. Instead, use a NEXT block (phaser) within the body of the loop.

# Perl 5 
     my $str = ''; 
     for (1..5) { 
         next if $_ % 2 == 1; 
         $str .= $_; 
     } 
     continue { 
         $str .= ':' 
     } 
# Perl 6 
     my $str = ''; 
     for 1..5 { 
         next if $_ % 2 == 1; 
         $str ~= $_; 
         NEXT { 
             $str ~= ':' 
         } 
     } 

Please note that phasers don't really need a block. This can be very handy when you don't want another scope:

# Perl 6 
     my $str = ''; 
     for 1..5 { 
         next if $_ % 2 == 1; 
         $str ~= $_; 
         NEXT $str ~= ':'; 
     } 

Functions

NOTE FOR EDITORS: When adding functions, please place them in alphabetical order.

Built-ins with bare blocks

Builtins that previously accepted a bare block followed, without a comma, by the remainder of the arguments will now require a comma between the block and the arguments e.g. map, grep, etc.

my @results = grep { $_ eq "bars" } @foo; # Perl 5 
my @results = grep { $_ eq "bars" }, @foo; # Perl 6 

delete

Turned into an adverb of the {} hash subscripting and [] array subscripting operators.

my $deleted_value = delete $hash{$key};  # Perl 5 
my $deleted_value = %hash{$key}:delete;  # Perl 6 - use :delete adverb 
my $deleted_value = delete $array[$i];  # Perl 5 
my $deleted_value = @array[$i]:delete;  # Perl 6 - use :delete adverb 

exists

Turned into an adverb of the {} hash subscripting and [] array subscripting operators.

say "element exists" if exists $hash{$key};  # Perl 5 
say "element exists" if %hash{$key}:exists;  # Perl 6 - use :exists adverb 
say "element exists" if exists $array[$i];  # Perl 5 
say "element exists" if @array[$i]:exists;  # Perl 6 - use :exists adverb 

Regular expressions ( regex / regexp )

Change =~ and !~ to ~~ and !~~ .

In Perl 5, matches and substitutions are done against a variable using the =~ regexp-binding op.

In Perl 6, the ~~ smartmatch op is used instead.

next if $line  =~ /static/  ; # Perl 5 
next if $line  ~~ /static/  ; # Perl 6 
next if $line  !~ /dynamic/ ; # Perl 5 
next if $line !~~ /dynamic/ ; # Perl 6 
$line =~ s/abc/123/;          # Perl 5 
$line ~~ s/abc/123/;          # Perl 6 

Alternately, the new .match and .subst methods can be used. Note that .subst is non-mutating.

Captures start with 0, not 1

/(.+)/ and print $1; # Perl 5 
/(.+)/ and print $0; # Perl 6 

Move modifiers

Move any modifiers from the end of the regex to the beginning. This may require you to add the optional m on a plain match like /abc/.

next if $line =~    /static/i ; # Perl 5 
next if $line ~~ m:i/static/  ; # Perl 6 

Add :P5 or :Perl5 adverb

If the actual regex is complex, you may want to use it as-is, by adding the P5 modifier.

next if $line =~    m/[aeiou]/   ; # Perl 5 
next if $line ~~ m:P5/[aeiou]/   ; # Perl 6, using P5 modifier 
 next if $line ~~ m/  <[aeiou]> / ; # Perl 6, native new syntax 

Please note that the Perl 5 regular expression syntax dates from many years ago and may lack features that have been added since the beginning of the Perl 6 project.

Special matchers generally fall under the <> syntax

There are many cases of special matching syntax that Perl 5 regexes support. They won't all be listed here, but often instead of being surrounded by (), the assertions will be surrounded by <>.

For character classes, this means that:

For lookaround assertions:

For more info see lookahead assertions.

(Unrelated to <> syntax, the "lookaround" /foo\Kbar/ becomes /foo <( bar )> /

Longest token matching (LTM) displaces alternation

In Perl 6 regexes, | does LTM, which decides which alternation wins an ambiguous match based off of a set of rules, rather than about which was written first.

The simplest way to deal with this is just to change any | in your Perl 5 regex to a ||.

However, if a regex written with || is inherited or composed into a grammar that uses | either by design or typo, the result may not work as expected. So when the matching process becomes complex, you finally need to have some understanding of both, especially how LTM strategy works. Besides, | may be a better choice for grammar reuse.

Named captures

These work in a slightly different way; also they only work in the latest versions of Perl 5.

use v5.22; 
 "þor is mighty" =~ /is (?<iswhat>\w+)/n; 
 say $+{iswhat}; 

The iswhat within a non-capturing group is used to actually capture what is behind, and up to the end of the group (the )). The capture goes to the %+ hash under the key with the name of the capture. In Perl 6 named captures work this way

"þor is mighty" ~~ /is \s+ $<iswhat>=(\w+)/; 
 say $<iswhat>; 

An actual assignment is made within the regular expression; that's the same syntax used for the variable outside it.

TODO more rules. Use L<< C<translate_regex.pl> from Blue Tiger|https://github.com/Util/Blue_Tiger/>> in the meantime.

Comments

As with Perl 5, comments work as usual in regexes.

/ word #`(match lexical "word") /

BEGIN, UNITCHECK, CHECK, INIT and END

Except for UNITCHECK, all of these special blocks exist in Perl 6 as well. In Perl 6, these are called Phasers. But there are some differences!

UNITCHECK becomes CHECK

There is currently no direct equivalent of CHECK blocks in Perl 6. The CHECK phaser in Perl 6 has the same semantics as the UNITCHECK block in Perl 5: it gets run whenever the compilation unit in which it occurs has finished parsing. This is considered a much saner semantic than the current semantics of CHECK blocks in Perl 5. But for compatibility reasons, it was impossible to change the semantics of CHECK blocks in Perl 5, so a UNITCHECK block was introduced in 5.10. Consequently, it was decided that the Perl 6 CHECK phaser would follow the saner Perl 5 UNITCHECK semantics.

No block necessary

In Perl 5, these special blocks must have curly braces, which implies a separate scope. In Perl 6 this is not necessary, allowing these special blocks to share their scope with the surrounding lexical scope.

my $foo;             # Perl 5 
 BEGIN { $foo = 42 } 
BEGIN my $foo = 42;  # Perl 6 

Changed semantics with regards to precompilation

If you put BEGIN and CHECK phasers in a module that is being precompiled, then these phasers will only be executed during precompilation and not when a precompiled module is being loaded. So when porting module code from Perl 5, you may need to change BEGIN and CHECK blocks to INIT blocks to ensure that they're run when loading that module.

Pragmas

strict

Strict mode is now on by default.

warnings

Warnings are now on by default.

no warnings is currently NYI, but putting things in a quietly {} block will silence.

autodie

The functions which were altered by autodie to throw exceptions on error, now generally return Failures by default. You can test a Failure for definedness / truthiness without any problem. If you use the Failure in any other way, then the Exception that was encapsulated by the Failure will be thrown.

# Perl 5 
 open my $i_fh, '<', $input_path;  # Fails silently on error 
 use autodie; 
 open my $o_fh, '>', $output_path; # Throws exception on error 
# Perl 6 
 my $i_fh = open $input_path,  :r; # Returns Failure on error 
 my $o_fh = open $output_path, :w; # Returns Failure on error 

Because you can check for truthiness without any problem, you can use the result of an open in an if statement:

# Perl 6 
 if open($input_path,:r) -> $handle { 
     .say for $handle.lines; 
 } 
 else { 
     # gracefully handle the fact that the open() failed 
 } 

base, parent

Both use base and use parent have been replaced in Perl 6 by the is keyword, in the class declaration.

# Perl 5 
 package Cat; 
 use base qw(Animal); 
# Perl 6 
 class Cat is Animal {} 

Note that the Animal class must be known at compilation time prior to be able to inherit from it.

bigint bignum bigrat

No longer relevant.

Int is now arbitrary precision, as is the numerator of Rat (the denominator is limited to 2**64, after which it will automatically upgrade to Num to preserve performance). If you want a Rat with an arbitrary-precision denominator, FatRat is available.

constant

In Perl 6, constant is a declarator for variables, just like my, except the variable is permanently locked to the result of its initialization expression (evaluated at compile time).

So, change the => to =.

use constant DEBUG => 0; # Perl 5 
constant DEBUG = 0;      # Perl 6 
use constant pi => 4 * atan2(1, 1); # Perl 5 
tau, pi, e, i; # built-in constants in Perl 6 
 τ, π, 𝑒        # and their unicode equivalents 

encoding

Allows you to write your script in non-ascii or non-utf8. Perl 6 uses, for the time being, only utf8 for its scripts.

integer

Perl pragma to use integer arithmetic instead of floating point. There is no such thing in Perl 6. If you use native integers in your calculations, then this will be the closest thing.

#Perl 6 
 my int $foo = 42; 
 my int $bar = 666; 
 say $foo * $bar;    # uses native integer multiplication 

lib

Manipulate where modules are looked up at compile time. The underlying logic is very different from Perl 5, but in the case you are using an equivalent syntax, use lib in Perl 6 works the same as in Perl 5.

mro

No longer relevant.

In Perl 6, method calls now always use the C3 method resolution order. If you need to find out parent classes of a given class, you can invoke the mro meta-method thusly:

say Animal.^mro;    # .^ indicates calling a meta-method on the object 

utf8

No longer relevant: in Perl 6, source code is expected to be in utf8 encoding.

vars

Discouraged in Perl 5. See https://perldoc.perl.org/vars.html.

You should refactor your Perl 5 code to remove the need for use vars, before translating into Perl 6.

Command-line flags

See the command line flags that Rakudo uses

Unchanged:

-c -e -h -I -n -p -v -V

-a

Change your code to use .split manually.

-F

Change your code to use .split manually.

-l

This is now the default behavior.

-M -m

Only -M remains. And, as you can no longer use the "no Module" syntax, the use of - with -M to "no" a module is no longer available.

-E

Since all features are already enabled, just use lowercase -e .

-d, -dt, -d:foo, -D, etc.

Replaced with the ++BUG metasyntactic option.

-s

Switch parsing is now done by the parameter list of the MAIN subroutine.

# Perl 5 
     #!/usr/bin/perl -s 
     if ($xyz) { print "$xyz\n" } 
 ./example.pl -xyz=5 
 5 
# Perl 6 
     sub MAIN( Int :$xyz ) { 
         say $xyz if $xyz.defined; 
     } 
perl6 example.p6 --xyz=5 
 5 
 perl6 example.p6 -xyz=5 
 5 

Removed.

Removed. See Removed Syntactic Features.

This is now the default behavior.

This has been eliminated. Several ways to replicate "taint" mode are discussed in Reddit.

File-related operations

Reading the lines of a text file into an array

In Perl 5, a common idiom for reading the lines of a text file goes something like this:

open my $fh, "<", "file" or die "$!"; 
 my @lines = <$fh>;                # lines are NOT chomped 
 close $fh; 

In Perl 6, this has been simplified to

my @lines = "file".IO.lines;  # auto-chomped

Do not be tempted to try slurping in a file and splitting the resulting string on newlines as this will give an array with a trailing empty element, which is one more than you probably expect (it's also more complicated), e.g.:

# initialize the file to read
spurt "test-file", q:to/END/;
first line
second line
third line
END
# read the file
my @lines = "test-file".IO.slurp.split(/\n/);
say @lines.elems;    #-> 4

If for some reason you do want to slurp the file first, then you can call the lines method on the result of slurp instead:

my @lines = "test-file".IO.slurp.lines;  # also auto-chomps

Also, be aware that $! is not really relevant for file IO operation failures in Perl 6. An IO operation that fails will return a Failure instead of throwing an exception. If you want to return the failure message, it is in the failure itself, not in $!. To do similar IO error checking and reporting as in Perl 5:

my $fh = open('./bad/path/to/file', :w) or die $fh;

Note: $fh instead of $!. Or, you can set $_ to the failure and die with $_:

my $fh = open('./bad/path/to/file', :w) orelse .die; # Perl 6

Any operation that tries to use the failure will cause the program to fault and terminate. Even just a call to the .self method is sufficient.

my $fh = open('./bad/path/to/file', :w).self;

Capturing the standard output of executables.

Whereas in Perl 5 you would do:

my $arg = 'Hello'; 
 my $captured = `echo \Q$arg\E`; 
 my $captured = qx(echo \Q$arg\E); 

Or using String::ShellQuote (because \Q…\E is not completely right):

my $arg = shell_quote 'Hello'; 
 my $captured = `echo $arg`; 
 my $captured = qx(echo $arg); 

In Perl 6, you will probably want to run commands without using the shell:

my $arg = 'Hello';
my $captured = run('echo', $arg, :out).out.slurp;
my $captured = run(«echo "$arg"», :out).out.slurp;

You can also use the shell if you really want to:

my $arg = 'Hello';
my $captured = shell("echo $arg", :out).out.slurp;
my $captured = qqx{echo $arg};

But beware that in this case there is no protection at all! run does not use the shell, so there is no need to escape the arguments (arguments are passed directly). If you are using shell or qqx, then everything ends up being one long string which is then passed to the shell. Unless you validate your arguments very carefully, there is a high chance of introducing shell injection vulnerabilities with such code.

Environment variables

Perl module library path

In Perl 5 one of the environment variables to specify extra search paths for Perl modules is PERL5LIB.

$ PERL5LIB="/some/module/lib" perl program.pl 

In Perl 6 this is similar, one merely needs to change a number! As you probably guessed, you just need to use PERL6LIB:

$ PERL6LIB="/some/module/lib" perl6 program.p6 

In Perl 5 one uses the ':' (colon) as a directory separator for PERL5LIB, but in Perl 6 one uses the ',' (comma). For example:

$ export PERL5LIB=/module/dir1:/module/dir2; 

but

$ export PERL6LIB=/module/dir1,/module/dir2; 

(Perl 6 does not recognize either the PERL5LIB or the older Perl environment variable PERLLIB.)

As with Perl 5, if you don't specify PERL6LIB, you need to specify the library path within the program via the use lib pragma:

use lib '/some/module/lib' 

Note that PERL6LIB is more of a developer convenience in Perl 6 (as opposed to the equivalent usage of PERL5LIB in Perl5) and shouldn't be used by module consumers as it could be removed in the future. This is because Perl 6's module loading isn't directly compatible with operating system paths.

Misc.

'0' is True

Unlike Perl 5, a string containing nothing but zero ('0') is True. As Perl 6 has types in core, that makes more sense. This also means the common pattern:

... if defined $x and length $x; # or just length() in modern perls 

In Perl 6 becomes a simple

... if $x; 

dump

Gone.

The Perl 6 design allows for automatic and transparent saving-and-loading of compiled bytecode.

Rakudo supports this only for modules so far.

AUTOLOAD

The FALLBACK method provides similar functionality.

Importing specific functions from a module

In Perl 5 it is possible to selectively import functions from a given module like so:

use ModuleName qw{foo bar baz}; 

In Perl 6 one specifies the functions which are to be exported by using the is export role on the relevant subs; all subs with this role are then exported. Hence, the following module Bar exports the subs foo and bar but not baz:

unit module Bar; 
 
 sub foo($a) is export { say "foo $a" } 
 sub bar($b) is export { say "bar $b" } 
 sub baz($z) { say "baz $z" } 

To use this module, simply use Bar and the functions foo and bar will be available

use Bar; 
 foo(1);    #=> "foo 1" 
 bar(2);    #=> "bar 2" 

If one tries to use baz an "Undeclared routine" error is raised at compile time.

So, how does one recreate the Perl 5 behavior of being able to selectively import functions? By defining an EXPORT sub inside the module which specifies the functions to be exported and removing the module Bar statement.

The former module Bar now is merely a file called Bar.pm6 with the following contents:

sub EXPORT(*@import-list) { 
     my %exportable-subs = 
         '&foo' => &foo, 
         '&bar' => &bar, 
         ; 
     my %subs-to-export; 
     for @import-list -> $import { 
         if grep $sub-name, %exportable-subs.keys { 
             %subs-to-export{$sub-name} = %exportable-subs{$sub-name}; 
         } 
     } 
     return %subs-to-export; 
 } 
 
 sub foo($a, $b, $c) { say "foo, $a, $b, $c" } 
 sub bar($a) { say "bar, $a" } 
 sub baz($z) { say "baz, $z" } 

Note that the subs are no longer explicitly exported via the is export role, but by an EXPORT sub which specifies the subs in the module we want to make available for export and then we are populating a hash containing the subs which will actually be exported. The @import-list is set by the use statement in the calling code thus allowing us to selectively import the subs made available by the module.

So, to import only the foo routine, we do the following in the calling code:

use Bar <foo>; 
 foo(1);       #=> "foo 1" 

Here we see that even though bar is exportable, if we don't explicitly import it, it's not available for use. Hence this causes an "Undeclared routine" error at compile time:

use Bar <foo>; 
 foo(1); 
 bar(5);       #!> "Undeclared routine: bar used at line 3" 

However, this will work

use Bar <foo bar>; 
 foo(1);       #=> "foo 1" 
 bar(5);       #=> "bar 5" 

Note also that baz remains unimportable even if specified in the use statement:

use Bar <foo bar baz>; 
 baz(3);       #!> "Undeclared routine: baz used at line 2" 

In order to get this to work, one obviously has to jump through many hoops. In the standard use-case where one specifies the functions to be exported via the is export role, Perl 6 automatically creates the EXPORT sub in the correct manner for you, so one should consider very carefully whether or not writing one's own EXPORT routine is worthwhile.

Importing groups of specific functions from a module

If you would like to export groups of functions from a module, you just need to assign names to the groups, and the rest will work automagically. When you specify is export in a sub declaration, you are in fact adding this subroutine to the :DEFAULT export group. But you can add a subroutine to another group, or to multiple groups:

unit module Bar; 
 sub foo() is export { }                   # added by default to :DEFAULT 
 sub bar() is export(:FNORBL) { }          # added to the FNORBL export group 
 sub baz() is export(:DEFAULT:FNORBL) { }  # added to both 

So now you can use the Bar module like this:

use Bar;                     # imports foo / baz 
 use Bar :FNORBL;             # imports bar / baz 
 use Bar :ALL;                # imports foo / bar / baz 

Note that :ALL is an auto-generated group that encompasses all subroutines that have an is export trait.

Core modules

Data::Dumper

In Perl 5, the Data::Dumper module was used for serialization, and for debugging views of program data structures by the programmer.

In Perl 6, these tasks are accomplished with the .perl method, which every object has.

# Given: 
     my @array_of_hashes = ( 
         { NAME => 'apple',   type => 'fruit' }, 
         { NAME => 'cabbage', type => 'no, please no' }, 
     ); 
 # Perl 5 
     use Data::Dumper; 
     $Data::Dumper::Useqq = 1; 
     print Dumper \@array_of_hashes; # Note the backslash. 
# Perl 6 
 say @array_of_hashes.perl; # .perl on the array, not on its reference. 

In Perl 5, Data::Dumper has a more complex optional calling convention, which allows for naming the VARs.

In Perl 6, placing a colon in front of the variable's sigil turns it into a Pair, with a key of the var name, and a value of the var value.

# Given: 
     my ( $foo, $bar ) = ( 42, 44 ); 
     my @baz = ( 16, 32, 64, 'Hike!' ); 
 # Perl 5 
     use Data::Dumper; 
     print Data::Dumper->Dump( 
         [     $foo, $bar, \@baz   ], 
         [ qw(  foo   bar   *baz ) ], 
     ); 
 # Output 
 #    $foo = 42; 
 #    $bar = 44; 
 #    @baz = ( 
 #             16, 
 #             32, 
 #             64, 
 #             'Hike!' 
 #           ); 
# Perl 6 
 say [ :$foo, :$bar, :@baz ].perl; 
 # OUTPUT: «["foo" => 42, "bar" => 44, "baz" => [16, 32, 64, "Hike!"]]␤» 

There is also a Rakudo-specific debugging aid for developers called dd (Tiny Data Dumper, so tiny it lost the "t"). This will print the .perl representation plus some extra information that could be introspected, of the given variables on STDERR:

# Perl 6 
 dd $foo, $bar, @baz; 
 # OUTPUT: «Int $foo = 42␤Int $bar = 44␤Array @baz = [16, 32, 64, "Hike!"]␤» 

Getopt::Long

Switch parsing is now done by the parameter list of the MAIN subroutine.

# Perl 5 
     use 5.010; 
     use Getopt::Long; 
     GetOptions( 
         'length=i' => \( my $length = 24       ), # numeric 
         'file=s'   => \( my $data = 'file.dat' ), # string 
         'verbose'  => \( my $verbose           ), # flag 
     ) or die; 
     say $length; 
     say $data; 
     say 'Verbosity ', ($verbose ? 'on' : 'off') if defined $verbose; 
 perl example.pl 
     24 
     file.dat 
 perl example.pl --file=foo --length=42 --verbose 
     42 
     foo 
     Verbosity on 
 
 perl example.pl --length=abc 
     Value "abc" invalid for option length (number expected) 
     Died at c.pl line 3. 
# Perl 6 
     sub MAIN( Int :$length = 24, :file($data) = 'file.dat', Bool :$verbose ) { 
         say $length if $length.defined; 
         say $data   if $data.defined; 
         say 'Verbosity ', ($verbose ?? 'on' !! 'off'); 
     } 
perl6 example.p6 
     24 
     file.dat 
     Verbosity off 
 perl6 example.p6 --file=foo --length=42 --verbose 
     42 
     foo 
     Verbosity on 
 perl6 example.p6 --length=abc 
     Usage: 
       c.p6 [--length=<Int>] [--file=<Any>] [--verbose] 

Note that Perl 6 auto-generates a full usage message on error in command-line parsing.

Automated translation

A quick way to find the Perl 6 version of a Perl 5 construct, is to run it through an automated translator.

NOTE: None of these translators are yet complete.

Blue Tiger

This project is dedicated to automated modernization of Perl code. It does not (yet) have a web front-end, and so must be locally installed to be useful. It also contains a separate program to translate Perl 5 regexes into Perl 6.

https://github.com/Util/Blue_Tiger/

Perlito

Online translator!

This project is a suite of Perl cross-compilers, including Perl 5-to-6 translation. It has a web front-end, and so can be used without installation. It only supports a subset of Perl 5 syntax so far.

https://fglock.github.io/Perlito/perlito/perlito5.html

Perl-ToPerl6

Jeff Goff's Perl::ToPerl6 module for Perl 5 is designed around Perl::Critic's framework. It aims to convert Perl5 to compilable (if not necessarily running) Perl 6 code with the bare minimum of changes. Code transformers are configurable and pluggable, so you can create and contribute your own transformers, and customize existing transformers to your own needs. You can install the latest release from CPAN, or follow the project live on GitHub. An online converter may become available at some point.

Other sources of translation knowledge

6 Perl 5 to Perl 6 guide - overview

How do I do what I used to do?

These documents should not be mistaken for a beginner tutorial or a promotional overview of Perl 6; it is intended as a technical reference for Perl 6 learners with a strong Perl 5 background and for anyone porting Perl 5 code to Perl 6.

Perl 6 in a nutshell

Perl 6 in a Nutshell provides a quick overview of things changed in syntax, operators, compound statements, regular expressions, command-line flags, and various other bits and pieces.

Syntactic differences

The Syntax section provides an overview of the syntactic differences between Perl 5 and Perl 6: how it is still mostly free form, additional ways to write comments, and how switch is very much a Perl 6 thing.

Operators in Perl 6

The Operators section guides you from the operators in Perl 5's perlop to the equivalent in Perl 6.

Functions in Perl 6

The Functions section describes all of the Perl 5 functions and their Perl 6 equivalent and any differences in behavior. It also provides references to ecosystem modules that provide the Perl 5 behavior of functions, either existing in Perl 6 with slightly different semantics (such as shift), or non-existing in Perl 6 (such as tie).

Special variables in Perl 6

The Special Variables section describes if and how a lot of Perl 5's special (punctuation) variables are supported in Perl 6.

### Guidelines for contributions:

Headers should contain the text that a Perl 5 user might search for, since those headings will be in the Table of Contents generated for the top of the document.

We use POD =item instead of =head3 or =head4 for unchanged bits that need not appear in the table of contents.

This article does not describe the additions to syntax, nor details of possible improvements. For example, 0 + $string still works, even though we would write it as +$string now. (Blue Tiger will offer a Perl Modernization guide, with step-by-step procedures for translation, along with details of new idioms and "better ways to do it")

Example code and links to other documents should be favored over long explanations of details better found elsewhere.

Finally, if a real user asks a P5->P6 question not answered here, please add it to the document, even if we don't have a good answer yet. That will be better than losing the information about a real need.

7 Perl 5 to Perl 6 guide - functions

Builtin functions in Perl 5 to Perl 6

DESCRIPTION

A (hopefully) comprehensive list of Perl 5 builtin functions with their Perl 6 equivalents with notes on variations between them where necessary.

NOTE

This document is an attempt to guide you from the functions in Perl 5's perlfunc document to their equivalents in Perl 6. For full documentation on the Perl 6 functions, follow the links in this document to their respective documentation.

One general comment: Perl 6 takes its objects a lot more seriously than Perl 5. In Perl 6, everything is an object, although the language is flexible enough to not force you to work in an object oriented manner if you do not wish to do so. What this does mean, however, is that a lot of things that are function calls of the form function(@args) are now also method calls of the form @args.function (In rare cases, there is only a method call). This should be obvious in the following text, but it probably behooves you to get into that frame of mind now.

Also, unless otherwise stated, the use of the term "function" here will mean a function in the style of func(@args), while "method" will refer to a function in the style of @args.func.

Alphabetical listing of Perl functions

Filetests

Perl 6 gives you a couple of options when it comes to file tests. You can do a smartmatch (~~) or you can call a method.

In Perl 6, you don't need to actually open a filehandle in the traditional way (although you can) to do a filetest. You can simply append .IO to the filename. For instance, here is how to check if a file is readable using smartmatch:

'/path/to/file'.IO ~~ :r

You can, of course, use an already opened filehandle. Here, using the filehandle $fh, is an example, using the method syntax for the file test:

$fh.r 

Most of the former filetests have colon equivalents for use with smartmatch:

:e Exists
:d Directory
:f File
:l Symbolic link
:r Readable
:w Writable
:x Executable
:s Size
:z Zero size

All of these tests can be used as methods (without the colon).

Three tests, however, only have method equivalents:

$fh.modified; # -M $fh 
 $fh.accessed; # -A $fh 
 $fh.changed;  # -C $fh 

The remaining filetests in Perl 5 do not appear to be implemented in Perl 6.

The documentation for this can be found at File test operators.

There is more information on reading and writing files at io. Also, the section on open() below may be helpful.

The Perl 6 ecosystem has a module P5-X which exports the behavior as much as possible in Perl 6.

abs

Works as a function (abs($x)), but also as a method. One gotcha, however - method calls bind more tightly than -, so, for example, -15.abs evaluates as -(15.abs) giving you -15. In this example, you would have to do something like (-15).abs.

abs also operates on $_ in the absence of a value, but not as a function, and as a method you need to call it as .abs rather than simply abs.

The Perl 6 ecosystem has a module P5math which exports an abs function that mimics the original Perl 5 behavior as much as possible.

accept

accept is a method you can call on a server, e. g. $server.accept(). Instead of returning a packed address, it returns a socket, most likely an IO::Socket object of some sort.

alarm

alarm() is no more. But it is possible to have code execute after a certain time has elapsed, or at a given time:

Promise.in(5).then: { say "five seconds have passed" }

Promise.at(now + 5).then: { say "five seconds have passed" }

In Perl 6, this does *not* involve any (dummy) signals.

atan2

Available as a function as well as being able to be used as a method. For instance, these are equivalent:

atan2(100);
100.atan2;

bind

[NEEDS FURTHER RESEARCH] No sign of a socket-related bind() in Perl 6. At a guess, whatever socket binding is needed happens when you create a new socket object.

binmode

Instead of this, you would use :bin as the file mode when opening the socket. E. g. my $fh = open("path/to/file", :bin);

bless

With the changes in class creation in Perl 6, this may find less use than in Perl 5, and is a method as well as a function. The Perl 6 docs say "Creates a new object of the same type as the invocant, uses the named arguments to initialize attributes, and returns the created object." If you're porting a module from Perl 5 to Perl 6, it's quite possible you'll want to use new for creating objects rather than bless, although there may be some situations in which the latter may still be useful.

break

Not in Perl 6. For breaking out of given blocks, you should probably take a look at proceed and succeed here.

caller

There are a couple different ways to get at caller information in Perl 6. The basic functionality is provided through callframe now. However, Perl 6 constructs call frames for regular blocks, not just for subroutines, so there are more frames to look through. The following will retrieve the basic information that caller can return:

my $frame   = callframe(0); # OR just callframe()
my ($subroutine, $package);
if $frame.code ~~ Routine {
    $subroutine = $frame.code.name;
    $package    = $frame.code.package;
}
my $file    = $frame.file;
my $line    = $frame.line;

Many of the other details returned by caller are specific to Perl 5 and have no meaning in Perl 6.

You can also get some of the information for the current frame or routine frame by using the dynamic variables &?ROUTINE, &?BLOCK, $?PACKAGE, $?FILE, and $?LINE. For many purposes, Backtrace may provide an easier way to browse through the call stack.

The Perl 6 ecosystem has a module P5caller which exports a caller function that mimics the original Perl 5 behavior as much as possible.

chdir

Works as it does in Perl 5 but must take an argument. The behavior of chdir() (with regards to looking at HOME and LOGDIR) is not supported.

In Perl 6, chdir only changes the $*CWD dynamic variable. It does not actually change the default directory from the OS's point of view; the special dynamic-variable routine &*chdir can be used for that, if needed.

This is done this way, because there is no concept of a "default directory per OS thread". And since Perl 6 does not fork, but only does threading, it was felt that the "current directory" concept should be in the $*CWD dynamic variable, which can be lexically scoped, and thus can be thread-safe.

The Perl 6 ecosystem has a module P5chdir which exports a chdir function that mimics the original Perl 5 behavior as much as possible, including looking at HOME and LOGDIR.

chmod

Functions as under Perl 5, with the difference that octal numbers are represented differently (0o755 rather than 0755). You may also use it as a method, e. g. $fh.chmod(0o755).

chomp

The behavior of chomp is different than in Perl 5. It leaves the target unaffected and returns a copy of the target with a final logical newline removed, e.g. $x = "howdy\n";$y = chomp($x); results in $x containing "howdy\n" and $y containing "howdy". Also works as a method, e.g. $y = $x.chomp. As with many other methods, also works with assignment to modify the target in place, e.g. $x.=chomp results in $x containing "howdy".

Note that chomp() (without arguments) is not supported in Perl 6.

The Perl 6 ecosystem has a module P5chomp which exports a chomp function that mimics the original Perl 5 behavior as much as possible.

chop

As with chomp, in Perl 6, this returns the chopped string, rather than chopping in place. I. e. $x = "howdy";$y = chop($x); results in $x being "howdy" and $y being "howd". Also works as a method: $y = $x.chop.

Note that chop() (without arguments) is not supported in Perl 6.

The Perl 6 ecosystem has a module P5chomp which exports a chop function that mimics the original Perl 5 behavior as much as possible.

.head2 chown

chown is not in Perl 6.

chr

Similar to the Perl 5 version, coerces the target to an integer, and uses that as a Unicode code point to return the relevant character. Can be used as a function and a method:

chr(65); # "A"
65.chr;  # "A"

Note that chr() (without arguments) is not supported in Perl 6.

The Perl 6 ecosystem has a module P5chr which exports a chr function that mimics the original Perl 5 behavior as much as possible.

chroot

chroot is not in Perl 6.

close

As in Perl 5, closes a filehandle. Returns a boolean value. Both close $fh and $fh.close will work.

Note that close() (without arguments) is not supported in Perl 6.

closedir

Not supported in Perl 6.

The Perl 6 ecosystem has a module P5opendir which exports a closedir function that mimics the original Perl 5 behavior as much as possible.

connect

Use connect from IO::Socket::Async for an asynchronous socket or create a IO::Socket::INET socket for a synchronous one.

continue

Instead of a continue block, you should use a NEXT block. The closest analog to a bare continue; in Perl 5 appears to be proceed/succeed.

cos

Works as in Perl 5.

cos also operates on $_ in the absence of a value, but not as a function, and as a method you need to call it as .cos rather than simply cos.

The Perl 6 ecosystem has a module P5math which exports a cos function that mimics the original Perl 5 behavior as much as possible.

crypt

Not available in Perl 6.

The Perl 6 ecosystem has a module P5math which exports a crypt function that mimics the original Perl 5 behavior as much as possible.

dbm functions

These functions have largely been superseded in Perl 5, and are unlikely to ever turn up in Perl 6 (although any assumptions about the Perl 6 database implementation may be premature).

defined

Probably does what you expect, but technically it returns False on the type object, and True otherwise. This may make more sense when you realize that $num.perl is the type Any if you haven't assigned anything to it, and the assigned value if you have. Can, of course be used as a method: $num.defined. And any newly created class can have its own .defined method, thereby deciding how and when it should be considered undefined.

Note that defined() (without arguments) is not supported in Perl 6.

The Perl 6 ecosystem has a module P5defined which exports a defined function that mimics the original Perl 5 behavior as much as possible.

delete

Perl 6 replaces this with the new adverb syntax, specifically the :delete adverb. E. g. my $deleted_value = %hash{$key}:delete; and my $deleted_value = @array[$i]:delete;.

die

Works similarly to the Perl 5 version, but Perl 6's Exception mechanism may give you more power and flexibility than is available in Perl 5. See exceptions. To omit the stacktrace and location, like Perl 5's die "...\n", use:

note "...";
exit 1;

do

Similar to the Perl 5 version. Note that there must be a space between the do and the block.

Has been replaced in Perl 6 by EVALFILE.

dump

According to S29, dump has been... dumped.

each

There is no exact equivalent, but you can use %hash.kv which returns a list of keys and values. For example: for %hash.kv -> $k, $v { say "$k: $v" }

Incidentally, what we have there with the -> is called a pointy block and, though there are a number of examples in the documentation, there doesn't seem to be a really clear explanation of how they work. https://design.perl6.org/S04.html#The_for_statement may be of some help here, as well as the design document at https://design.perl6.org/S06.html#%22Pointy_blocks%22. There is also some information at https://en.wikibooks.org/wiki/Perl_6_Programming/Blocks_and_Closures#Pointy_Blocks

The Perl 6 ecosystem has a module P5each which exports an each function that mimics the original Perl 5 behavior as much as possible.

eof

In Perl 6, this is not usable as a function, but only as a method. I. e. $filehandle.eof. Returns True if at end of file.

eval

The closest replacement is the EVAL function. However, this function has to be allowed explicitly using a pragma to work in the same way. Note that EVAL does not do any exception handling!

evalbytes

No equivalent.

exec

Nothing in Perl 6 exactly replicates the Perl 5 exec. shell and run are similar to Perl 5's system, but exec's behavior of not returning after executing a system command would have to be emulated by something like shell($command);exit(); or possibly exit shell($command);.

Neither of these workarounds have the behavior (on Unix-like systems) of replacing your Perl program's process with the new program; notably, they will not work for the practice in some long-running daemons of periodically redoing exec on themselves to reset their state or force operating-system cleanup. Nor will they serve exec's function of returning stale resources to the operating system.

If you want exec for these behaviors, you can use an exec* function via the NativeCall interface. Consult your operating system manual pages for exec (or other similarly-named calls such as execl, execv, execvp, or execvpe). (Beware: these calls are not generally portable between Unix-like operating system families.) Given those caveats, the Perl 6 ecosystem Native::Exec module exports an exec function for Unix-like systems.

exists

In Perl 6, this is not a function, but an adverb:

%hash{$key}:exists; 
 @array[$i]:exists; 

exit

Appears to do the same thing as in Perl 5.

exp

Same as in Perl 5.

exp also operates on $_ in the absence of a value, but not as a function, and as a method you need to call it as .exp rather than simply exp.

The Perl 6 ecosystem has a module P5math which exports an exp function that mimics the original Perl 5 behavior as much as possible.

fc

Looks like it does the same thing as in Perl 5 except that calling it without arguments is not supported in Perl 6.

The Perl 6 ecosystem has a module P5fc which exports a fc function that mimics the original Perl 5 behavior as much as possible.

fcntl

Appears not to be in Perl 6.

__FILE__

Replaced by $?FILE which is slightly different from __FILE__ in that it is always an absolute path, rather than a relative one in the Perl 5 case.

The Perl 6 ecosystem has a module P5__FILE__ which exports a __FILE__ term that mimics the original Perl 5 behavior as much as possible.

fileno

The native-descriptor method on IO::Handle returns the equivalent of fileno.

The Perl 6 ecosystem has a module P5fileno which exports a fileno function that mimics the original Perl 5 behavior as much as possible.

flock

Currently unimplemented.

fork

There is no built-in fork function. While it's possible to call it using NativeCall, it's highly unlikely that the resulting process will be usable.

Perl 6 provides extensive support for, and internally uses, threads. However, fork only clones the thread that called fork, resulting in a process that will be missing its other threads, which will have been in unknown states and probably holding locks. Even if a Perl 6 program doesn't knowingly start any threads, the compiler may create some of its own in the process of precompilation, and the VMs that Perl 6 runs on also create their own internal worker threads for doing things like optimization and GC in the background. Thus, the presence of threads is pretty much assured, and there's no reasonable way to make fork reliably work in this case.

formats

Perl 6 does not have built-in formats.

getc

Reads a single character from the input stream as in Perl 5. May now also be used as a method: $filehandle.getc

getpeername

S29 lists it, but the implementation does not seem clear or, for that matter, implemented.

getpgrp

Will not be implemented.

The Perl 6 ecosystem has a module P5getpriority which exports a getpgrp function that mimics the original Perl 5 behavior as much as possible.

getppid

Will not be implemented.

The Perl 6 ecosystem has a module P5getpriority which exports a getppid function that mimics the original Perl 5 behavior as much as possible.

getpriority

Will not be implemented.

The Perl 6 ecosystem has a module P5getpriority which exports a getpriority function that mimics the original Perl 5 behavior as much as possible.

get and set functions

The Perl 6 ecosystem has a module P5getpwnam which exports the endpwent, getlogin, getpwent, getpwnam, getpwuid and setpwent functions that mimic the original Perl 5 behavior as much as possible.

The Perl 6 ecosystem has a module P5getgrnam which exports the endgrent, getgrent, getgrgid, getgrnam and setgrent functions that mimic the original Perl 5 behavior as much as possible.

The Perl 6 ecosystem has a module P5getnetbyname which exports the endnetent, getnetent, getnetbyaddr, getnetbyname and setnetent functions that mimic the original Perl 5 behavior as much as possible.

The Perl 6 ecosystem has a module P5getservbyname which exports the endservent, getservent, getservbyname, getservbyport and setservent functions that mimic the original Perl 5 behavior as much as possible.

The Perl 6 ecosystem has a module P5getprotobyname which exports the endprotoent, getprotoent, getprotobyname, getprotobynumber and setprotoent functions that mimic the original Perl 5 behavior as much as possible.

[NEEDS FURTHER RESEARCH] Apparently this range of functions are to be handled by roles like User, Group, etc.

getsock*

[NEEDS FURTHER RESEARCH] These are likely implemented by some kind of IO::Socket object, but details are unclear.

glob

Not available in core, although some of the functionality is offered by dir routine and its test argument.

See IO::Glob module in ecosystem

gmtime

Like the various parts of localtime, gmtime's functionality appears to in the DateTime object. To get a UTC version of a DateTime object for the current time, for instance, use my $gmtime = DateTime.now.utc.

The Perl 6 ecosystem has a module P5localtime which exports a gmtime function that mimics the original Perl 5 behavior as much as possible.

goto

The syntax for goto LABEL is already accepted, but the runtime part of goto is not yet implemented. So this will result in a runtime error:

FOO: goto FOO; # Label.goto() not yet implemented. Sorry.

grep

Still in Perl 6, with the caveat that the block form now requires a comma after the block. I.e. @foo = grep { $_ = "bars" }, @baz. Can also be used as a method: @foo = @bar.grep(/^f/)

hex

In Perl 6 an expression must be specified.

Replaced by the adverbial form :16. E. g. :16("aF") returns 175. This is Str->Int.

The opposite result can be achieved (Int->Str) by using the .base method: 0xaF.base(10)

It just so happens that .Str defaults to base 10, so if you just say 0xaF, that will also print 175, but that may not be immediately obvious, so may not be the best way to go for this.

The Perl 6 ecosystem has a module P5hex which exports a hex function that mimics the original Perl 5 behavior as much as possible.

import

Was never a builtin function in Perl 5 in the first place. In Perl 6, typically, one declares functions as exportable or not, and all the exportable ones are exported. Nevertheless, selective importing is possible, but beyond the scope of this document. For details, see this section.

index

Works as in Perl 5. Can also now be used as a method: "howdy!".index("how"); # 0. Main difference with Perl 5 is that Nil is returned instead of -1 when the substring is not found. This is very useful in combination with the with command:

with index("foo","o") -> $index {
    say "Found it at $index";
}
else {
    say "Not found"
}

The Perl 6 ecosystem has a module P5index which exports an index function that mimics the original Perl 5 behavior as much as possible.

int

There is a truncate function in Perl 6 (also usable as a method) that does what Perl 5's int does. You may want to use that as a direct translation of Perl 5 code, but in Perl 6, you can just as easily call the .Int method on the number. 3.9.Int; # 3 and 3.9.truncate are equivalent.

Please note that int does have a meaning in Perl 6. It is type that can be used to indicate a native integer:

my int $a = 42;   # a native integer, similar to Perl 5's integer values

int also operates on $_ in the absence of a value, but not as a function, and as a method you need to call it as .int rather than simply int.

The Perl 6 ecosystem has a module P5math which exports an int function that mimics the original Perl 5 behavior as much as possible.

ioctl

Currently unimplemented in Perl 6.

join

Works as in Perl 5, and also works as a method: @x.join(",")

keys

Works as in Perl 5, and can also be used as a method: %hash.keys

kill

No pre-defined core alternative exists. A non-portable method can be to use NativeCall:

use NativeCall;
sub kill(int32, int32) is native {*};
kill $*PID, 9; # OUTPUT: «Killed␤»

To kill processes that were started by creating a Proc::Async, use Proc::Async.kill method.

last

Same as in Perl 5.

lc

Works as in Perl 5, and also as a method: "UGH".lc. In Perl 6 an expression must be specified.

The Perl 6 ecosystem has a module P5lc which exports an lc function that mimics the original Perl 5 behavior as much as possible.

lcfirst

Does not exist in Perl 6.

The Perl 6 ecosystem has a module P5lcfirst which exports an lcfirst function that mimics the original Perl 5 behavior as much as possible.

length

Replaced by chars, typically used as a method ($string.chars), but also works as a function.

The Perl 6 ecosystem has a module P5length which exports an length function that mimics the original Perl 5 behavior as much as possible.

__LINE__

Replaced by $?LINE.

The Perl 6 ecosystem has a module P5__FILE__ which exports a __LINE__ term that mimics the original Perl 5 behavior as much as possible.

See link

listen

Not clearly documented, but it appears that listen will be a method you would call on some variety of IO::Socket object.

local

The Perl 6 equivalent is temp. Unlike local, however, the value of the given variable is not immediately unset: it retains its original value until assigned to.

localtime

Most of the functionality of localtime is found in DateTime. The specific parts of localtime can be found as follows:

my $d = DateTime.now; 
 my $sec  = $d.second; # Potentially includes fractional seconds 
 my $min  = $d.minute; 
 my $hour = $d.hour; 
 my $mday = $d.day-of-month; # or $d.day; 1..31 
 my $mon  = $d.month; # 1..12 
 my $year = $d.year; 
 my $wday = $d.day-of-week; # 1 => Monday, 2 => Tuesday, etc. 
 my $yday = $d.day-of-year; # 1..366 

Please note that ranges are not 0-based in Perl 6, as shown in the comments in the example.

There does not currently appear to be a way to get Perl 5's $isdst. Also, the result of scalar(localtime) that Perl 5 provides is not available. $d.Str will give something along the lines of "2015-06-29T12:49:31-04:00".

The Perl 6 ecosystem has a module P5localtime which exports a localtime function that mimics the original Perl 5 behavior as much as possible.

lock

There currently is no equivalent for this In Perl 6. There is a Lock class for creating a Lock object, that can be locked/unlocked as needed. But such a lock does not refer to any external objects.

log

Same as in Perl 5.

log also operates on $_ in the absence of a value, but not as a function, and as a method you need to call it as .log rather than simply log.

The Perl 6 ecosystem has a module P5math which exports a log function that mimics the original Perl 5 behavior as much as possible.

lstat

Likely implemented somewhere in one of the IO classes in Perl 6, but it is not clear where at this time.

m//

Regular expression syntax is somewhat different in Perl 6, but the match operator still exists. If you're trying to rewrite some Perl 5 code, the most important difference is that =~ is replaced by the smartmatch operator, ~~. Similarly, !~ is replaced by !~~. Options for regex operators are adverbs and are complicated. For details, see Adverbs

map

As a function, the only difference between Perl 5 and Perl 6 is that, if you're using a block, the block must be followed by a comma. Can also be used as a method: @new = @old.map: { $_ * 2 }

mkdir

Works as in Perl 5. When giving a multi-level directory specification, it will automatically create non-existing intermediate directories with the same MASK (similar to what "make_path" does of the File::Path module in Perl 5).

The zero argument (implicit $_) version is not permitted in Perl 6.

msg*

Not builtins in Perl 6. May appear in an external module at some point. Maybe.

my

Works as in Perl 5.

next

The same in Perl 6.

no

In Perl 6, this is usable for pragmas such as strict, but not for modules or versions.

oct

Replaced by the adverbial form :8. E. g. :8("100") returns 64.

If you want to deal with strings that start in 0x, 0o, or 0b, you can just use the prefix:<+> operator.

The Perl 6 ecosystem has a module P5hex which exports an oct function that mimics the original Perl 5 behavior as much as possible.

open

The most obvious change from Perl 5 is the file mode syntax. To open a file for reading only, you would say open("file", :r). For write- only, read-write, and append, you would use :w, :rw, and :a respectively. There are also options for encoding and how the filehandle deals with newlines. Details here.

Another important change is that filehandles don't get automatically closed on scope exit. It's necessary to call close explicitly.

opendir

No replacement. See &dir / IO::Path.dir for alternatives.

The Perl 6 ecosystem has a module P5opendir which exports an opendir function that mimics the original Perl 5 behavior as much as possible.

ord

Same as in Perl 5. May be used as a method: "howdy!".ord; # 104

Note that ord() (without arguments) is not supported in Perl 6.

The Perl 6 ecosystem has a module P5chr which exports a ord function that mimics the original Perl 5 behavior as much as possible.

our

The same in Perl 6.

pack

Available in Perl 6 when use experimental :pack has been specified in the scope where pack needs to be called. The template options are currently more restricted than they are in Perl 5. The current documented list can be found at unpack.

The Perl 6 ecosystem has a module P5pack which exports a pack function that mimics the original Perl 5 behavior as much as possible and which has a bigger set of supported features than the experimental Perl 6 version.

package

S10 indicates that package can be used in Perl 6, but only with a block. I. e. package Foo { ... } means that the code within the block would be in package Foo. There is a special case where a declaration of the form package Foo; as the first statement in a file indicates that the rest of the file is Perl 5 code, but the usefulness of this is unclear. In fact, as modules and classes are declared with distinct keywords (such as class), it's unlikely you will use package directly in Perl 6.

__PACKAGE__

Replaced by $?PACKAGE which is slightly different from __PACKAGE__ in that it is the actual package object. You should call the .^name method on it to get a string.

The Perl 6 ecosystem has a module P5__FILE__ which exports a __PACKAGE__ term that mimics the original Perl 5 behavior as much as possible.

pipe

Depending on your needs, see Channel to shuttle data between threads (and Concurrency tutorial for other options), or see Proc type for piping to and from processes.

pop

Works in Perl 6, and can also be used as a method. I. e. my $x = pop @a; and my $x = @a.pop; are equivalent.

The non-parameter version of pop does not exist. Also, if the array is empty, a Failure will be returned in Perl 6, which will throw if the value is actually used in a significant way.

If you are using only defined values in your array, you can use the with function to handle this case:

with pop @array -> $popped { 
     say "popped '$popped' of the array"; 
 } 
 else { 
     say "there was nothing to pop"; 
 } 

The Perl 6 ecosystem has a module P5push which exports a pop function that mimics the original Perl 5 behavior as much as possible.

pos

Not available in Perl 6. The closest equivalent is the :c adverb, which defaults to $/.to if $/ is true, and 0 if it isn't. For information on :c, see Continue.

print

print can be used as a function in Perl 6, writing to standard out. To use print as a function with a filehandle instead of standard out, you can use a method call: $fh.print("howdy!")

The Perl 6 ecosystem has a module P5print which exports a print function that mimics the original Perl 5 behavior as much as possible.

printf

Perl 6 version is similar; see sprintf for details on acceptable format directives. To print to a filehandle other than STDOUT, use the .printf method on that filehandle.

The Perl 6 ecosystem has a module P5print which exports a printf function that mimics the original Perl 5 behavior as much as possible.

prototype

Not available in Perl 6. The closest equivalent is .signature. E. g. say &sprintf.signature results in "(Cool $format, *@args)".

push

Works as in Perl 5, as well as being available as a method: @a.push("foo");. Note: the flattening behavior is different in Perl 6: @b.push: @a will push @a into @b as a single element. See also the append method.

Also note that push in Perl 6 returns the array to which was pushed, contrary to Perl 5 where it returns the new number of elements.

The Perl 6 ecosystem has a module P5push which exports a push function that mimics the original Perl 5 behavior as much as possible.

quoting

These survive the transition to Perl 6. Some notes:

q/.../;  # is still equivalent to using single quotes. 
 qq/.../; # is still equivalent to using double quotes. 
 qw/.../; # is more commonly rendered as C<< <...> >> in Perl 6. 

There are some added quoting constructs and equivalents, as explained at quoting.

Has been replaced by rx/.../.

No direct equivalent, i.e. nothing that just returns the string with all the ASCII non-word characters backslashed. In regexes, however, using $foo will treat $foo as a literal string, and using <$foo> will interpret the contents of $foo as regex code. Note that the angle brackets are doing something different here than they do outside a regex. For more information on this, see https://design.perl6.org/S05.html#Extensible_metasyntax_(%3C...%3E)

The Perl 6 ecosystem has a module P5quotemeta which exports a quotemeta function that mimics the original Perl 5 behavior as much as possible.

rand

rand by itself works as it does in Perl 5, but you can no longer give it an argument. You can, however, use it as a method on a number to get that behavior. I. e. the Perl 5 rand(100) is equivalent to 100.rand in Perl 6. Additionally, you can get a random integer by using something like (^100).pick. For why you are able to do that, see ^ operator and pick.

The Perl 6 ecosystem has a module P5math which exports a rand function that mimics the original Perl 5 behavior as much as possible.

read

read is found in IO::Handle and IO::Socket in Perl 6. It reads the specified number of bytes (rather than characters) from the relevant handle or socket. The use of an offset available in Perl 5 is not documented to exist at this time.

readdir

Not a builtin function. To iterate through the contents of a directory, take a look at dir routine.

The Perl 6 ecosystem has a module P5opendir which exports a readdir function that mimics the original Perl 5 behavior as much as possible.

readline

Not available in Perl 6. You most likely want to use the .lines method in some way. For more detailed information on reading from files, see io.

Appears to be gone from Perl 6. There is a method resolve in IO::Path that will follow symlinks if the OS / Filesystem supports them.

The Perl 6 ecosystem has a module P5readlink which exports a readlink function that mimics the original Perl 5 behavior as much as possible.

readpipe

Doesn't appear to be working in Perl 6, but qx// is functional, so it might be lurking around in some class that isn't obvious.

recv

Appears to be in IO::Socket. Not extensively documented at this time.

redo

Unchanged in Perl 6.

ref

Gone. To quote S29, "If you really want the type name, you can use $var.WHAT.^name.

The Perl 6 ecosystem has a module P5ref which exports a ref function that mimics the original Perl 5 behavior as much as possible.

rename

Still available in Perl 6.

requires

No equivalent.

reset

No equivalent.

The Perl 6 ecosystem has a module P5reset which exports a reset function that mimics the original Perl 5 behavior as much as possible.

return

Appears to be available in Perl 6, although not clearly documented.

reverse

In Perl 6, this only reverses the elements of a list. reverse(@a) or @a.reverse. To reverse the characters in a string, use the .flip method.

reverse without parameters is not supported in Perl 6.

The Perl 6 ecosystem has a module P5reverse which exports a reverse function that mimics the original Perl 5 behavior as much as possible.

rewinddir

Not supported in Perl 6.

The Perl 6 ecosystem has a module P5rewinddir which exports a rewinddir function that mimics the original Perl 5 behavior as much as possible.

rindex

Works as in Perl 5, and may also be used as a method. E. g. $x = "babaganush";say $x.rindex("a"); say $x.rindex("a", 3); # 5, 3. Main difference with Perl 5 is that Nil is returned instead of -1 when the substring is not found. This is very useful in combination with the with command:

with index("foo","o") -> $index {
    say "Found it at $index";
}
else {
    say "Not found"
}

The Perl 6 ecosystem has a module P5index which exports a rindex function that mimics the original Perl 5 behavior as much as possible.

rmdir

Works in Perl 6 and can also be used as a method. rmdir "Foo"; and "Foo".IO.rmdir; are equivalent.

s///

Regular expression syntax is somewhat different in Perl 6, but the substitution operator exists. If you're trying to rewrite some Perl 5 code, the most important difference is that =~ is replaced by the smartmatch operator, ~~. Similarly, !~ is !~~. Options for regex operators are adverbs and are complicated. For details, see Adverbs page

say

say can be used as a function, defaulting to standard out. To use say as a function with a filehandle instead of standard out, you need to put a colon after the filehandle. I. e. say $fh: "Howdy!". The use of the colon as an "invocant marker" here is discussed at https://design.perl6.org/S03.html#line_4019. Alternately, you can use a method call: $fh.say("howdy!")

The Perl 6 ecosystem has a module P5print which exports a say function that mimics the original Perl 5 behavior as much as possible.

scalar

Gone. Apparently "very" gone.

Some functions of the modules created for the CPAN Butterfly Plan accept a :scalar named parameter to indicate that the scalar behavior of the function is required.

seek

Not documented in any real way yet, but listed as a method of the IO::Handle class.

The Perl 6 ecosystem has a module P5seek which exports a seek function that mimics the original Perl 5 behavior as much as possible.

seekdir

Not supported in Perl 6.

The Perl 6 ecosystem has a module P5opendir which exports a seekdir function that mimics the original Perl 5 behavior as much as possible.

select

"[S]elect as a global concept is dead." When I asked around about select, I was told that $*OUT and such are overridable in dynamic scope, and that IO::Capture::Simple (at https://github.com/sergot/IO-Capture-Simple) may be of use for something you might be doing with the value of select.

semctl

No longer in core.

semget

No longer in core.

semop

No longer in core.

send

Can be found in the IO::Socket class.

setpgrp

Will not be implemented.

The Perl 6 ecosystem has a module P5getpriority which exports a setpgrp function that mimics the original Perl 5 behavior as much as possible.

setpriority

Will not be implemented.

The Perl 6 ecosystem has a module P5getpriority which exports a setpriority function that mimics the original Perl 5 behavior as much as possible.

setsockopt

Not documented, but probably hiding in an IO class somewhere.

shift

Works in Perl 6, and can also be used as a method. I. e. my $x = shift @a; and my $x = @a.shift; are equivalent.

The non-parameter version of shift does not exist. Also, if the array is empty, a Failure will be returned in Perl 6, which will throw if the value is actually used in a significant way.

If you are using only defined values in your array, you can use the with function to handle this case:

with shift @array -> $shifted { 
     say "shifted '$shifted' of the array"; 
 } 
 else { 
     say "there was nothing to shift"; 
 } 

The Perl 6 ecosystem has a module P5shift which exports a shift function that mimics the original Perl 5 behavior as much as possible.

shm*

Gone from the core. May turn up in a module somewhere.

shutdown

Not documented, but likely moved into IO::Socket.

sin

Same as in Perl 5.

sin also operates on $_ in the absence of a value, but not as a function, and as a method you need to call it as .sin rather than simply sin.

The Perl 6 ecosystem has a module P5math which exports a sin function that mimics the original Perl 5 behavior as much as possible.

sleep

Still works as in Perl 5, but is not limited to integer values for seconds. And it always returns Nil.

If you're interested in the return values of sleep to ensure sleeping until a specified time, then you should use sleep-until in Perl 6 (which takes an Instant).

If you're interested in running some code every N seconds, and you don't care on which thread it runs, you should probably use react and whenever with a Supply.interval.

The Perl 6 ecosystem has a module P5sleep which exports a sleep function that mimics the original Perl 5 behavior as much as possible.

sockets

Not currently documented, but will likely wind up in IO::Socket.

sort

sort exists in Perl 6, but is somewhat different. $a and $b are no longer special (see Special Variables) and sort routines no longer return positive integers, negative integers, or 0, but rather Order::Less, Order::Same, or Order::More objects. See sort for details. May also be used as a method I. e. sort(@a) is equivalent to @a.sort.

splice

Available in Perl 6. Can also be used as a method. splice(@foo, 2, 3, <M N O P>); is equivalent to @foo.splice(2, 3, <M N O P>); .

split

Works mostly as in Perl 5. There are some exceptions, though. To get the special behavior of using the empty string, you must actually use the empty string - the special case of the empty pattern // being treated as the empty string does not apply. If you use a regex for the split, it will use the regex, while a literal string will be treated literally. If you wish to have the delimiters included in the resulting list, you need to use the named parameter :all, like this: split(';', "a;b;c", :all) # a ; b ; c Empty chunks are not removed from the result list as they are in Perl 5. For that behavior, see comb. Details on split are here. Unsurprisingly, split also now works as a method: "a;b;c".split(';')

The zero argument version must now be called with an explicit empty string, as described above.

sprintf

Works as in Perl 5. The formats currently available are:

% a literal percent sign
c a character with the given codepoint
s a string
d a signed integer, in decimal
u an unsigned integer, in decimal
o an unsigned integer, in octal
x an unsigned integer, in hexadecimal
e a floating-point number, in scientific notation
f a floating-point number, in fixed decimal notation
g a floating-point number, in %e or %f notation
X like x, but using uppercase letters
E like e, but using an uppercase "E"
G like g, but with an uppercase "E" (if applicable)

Compatibility:

i a synonym for %d
D a synonym for %ld
U a synonym for %lu
O a synonym for %lo
F a synonym for %f

Perl 5 (non-)compatibility:

n produces a runtime exception
p produces a runtime exception

There are modifiers for integers, but they're mainly no-ops, as the semantics aren't settled:

h interpret integer as native "short" (typically int16)
l interpret integer as native "long" (typically int32 or int64)
ll interpret integer as native "long long" (typically int64)
L interpret integer as native "long long" (typically uint64)
q interpret integer as native "quads" (typically int64 or larger)

sqrt

Same as in Perl 5.

sqrt also operates on $_ in the absence of a value, but not as a function, and as a method you need to call it as .sqrt rather than simply sqrt.

The Perl 6 ecosystem has a module P5math which exports a sqrt function that mimics the original Perl 5 behavior as much as possible.

srand

Available in Perl 6.

stat

Unlikely to be implemented as a built in function since it's POSIX specific, but available through the NativeCall interface.

state

Available in Perl 6, see state.

study

study is no more.

The Perl 6 ecosystem has a module P5study which exports a study function that mimics the original Perl 5 behavior as much as possible.

sub

Unsurprisingly, we still have subroutines! You can have a signature in your subroutine which allows you to specify arguments. Nevertheless, in the absence of a signature (and only in the absence of a signature), @_ still contains what is passed to the function. So, in theory, you don't need to change that aspect of a function if porting from Perl 5 to Perl 6 (although you should probably consider the option of using a signature). For all the gory details, see functions.

__SUB__

Replaced by &?ROUTINE which is slightly different from __SUB__ in that it is the actual Sub (or Method) object. You should call the .name method on it to get a string.

The Perl 6 ecosystem has a module P5__FILE__ which exports a __SUB__ term that mimics the original Perl 5 behavior as much as possible.

substr

Can be used as a function or a method. substr("hola!", 1, 3) and "hola!".substr(1, 3) both return "ola".

See symlink.

syscall

Not a builtin in Perl 6. Most likely out in a module somewhere, but it's currently unclear where.

sys*

As with the non-sys versions of these functions, are probably lurking in the IO classes somewhere.

system

For this, you probably want (run) or (shell routine).

syswrite

As with sysopen and friends, this has moved into the IO classes.

tell

As a method on IO::Handle.

telldir

Not supported in Perl 6.

The Perl 6 ecosystem has a module P5opendir which exports a telldir function that mimics the original Perl 5 behavior as much as possible.

tie

The Perl 6 alternative to tying a scalar, is the Proxy container. For example:

sub lval() {
  Proxy.new(
    FETCH => method () { ...},
    STORE => method ($new) { ... }
  )
}

This makes lval a left-value sub. Whenever the value is requested, the FETCH method is called. And whenever it is used in an assignment, the STORE method is called.

For arrays and hashes (objects that do the Positional and/or Associative role), one only needs to provide the methods that these roles require to get the functionality that tie provides in Perl 5. These are documented in the Subscripts section.

The Perl 6 ecosystem has a module P5tie which exports tie / tied functions that mimics the original Perl 5 behavior as much as possible.

time

Number of seconds since epoch (as an Int), same as in Perl 5.

times

Not available in Perl 6.

The Perl 6 ecosystem has a module P5times which exports a times function that mimics the original Perl 5 behavior as much as possible.

tr///

Works similarly to how it does in Perl 5. The one caveat is that ranges are specified differently. Instead of using a range "a-z", you would use "a..z", i.e. with Perl's range operator. In Perl 6, tr/// has a method version, called trans, which offers a few additional features.

Perl 5's /r flag is instead implemented as TR/// operator. The y/// equivalent does not exist.

truncate

Not currently implemented (2018.04).

uc

Works as a function and a method. uc("ha") and "ha".uc both return "HA". There is no support for the parameterless version.

The Perl 6 ecosystem has a module P5lc which exports a uc function that mimics the original Perl 5 behavior as much as possible.

ucfirst

Perl 6 has done away with ucfirst. The title case function tc probably does what you need.

The Perl 6 ecosystem has a module P5lcfirst which exports a ucfirst function that mimics the original Perl 5 behavior as much as possible.

undef

There is no undef in Perl 6. You can't undefine a function, and the closest equivalent value is probably Nil, but you'll likely have no use for that.

If you were using something like (undef, $file, $line) = caller;, you would just get the filename and line number directly in Perl 6 instead of discarding the first result of caller. caller has been replaced by callframe in Perl 6, so the equivalent statement would be ($file, $line) = callframe.annotations<file line>;

The Perl 6 ecosystem has a module P5defined which exports an undef function that mimics the original Perl 5 behavior as much as possible.

Add a note here about Type-based undefined values.

Still available. Usable as a method: "filename".IO.unlink

The zero argument (implicit $_) version of unlink is not available in Perl 6.

unpack

Available in Perl 6 when use experimental :pack has been specified in the scope where unpack needs to be called. The template options are currently more restricted than they are in Perl 5. The current documented list can be found at unpack.

The Perl 6 ecosystem has a module P5pack which exports an unpack function that mimics the original Perl 5 behavior as much as possible and which has a bigger set of supported features than the experimental Perl 6 version.

unshift

Works as in Perl 5, as well as being available as a method: @a.unshift("foo");. Note: the flattening behavior is different in Perl 6: @b.unshift: @a will unshift @a into @b as a single element. See also the prepend method.

Also note that unshift in Perl 6 returns the array to which was pushed, contrary to Perl 5 where it returns the new number of elements.

The Perl 6 ecosystem has a module P5shift which exports an unshift function that mimics the original Perl 5 behavior as much as possible.

untie

Not supported in Perl 6, but see tie for the whole story.

The Perl 6 ecosystem has a module P5tie which exports an untie function that mimics the original Perl 5 behavior as much as possible.

use

In Perl 5, this requires a minimum version of the perl executable in order to run. In Perl 6, this requires a version of the specification, (e.g. 6.c), which can be implemented by various perl6 executables.

utime

No equivalent.

values

Available in Perl 6. Can also be used as a method. values %hash is equivalent to %hash.values.

vec

There is no support for vec() in Perl 6.

S29 says "Should replace vec with declared buffer/array of bit, uint2, uint4, etc." Support for bit, uint2, uint4 has not landed yet. But support for uint8, int8, uint16, int16, uint32, int32, uint64, int64 as well as the system sized uint and int have landed. In scalar forms, as well as in array and shaped array (aka matrix) forms.

wait

[NEEDS FURTHER RESEARCH] Unclear where this has gone. There's a wait method in Supply, and an await method in both Channel and Promise. Which, if any or all, of these is a direct equivalent of Perl 5's wait is unclear.

waitpid

As with wait, the disposition of this is unclear.

wantarray

There is no wantarray in Perl 6; however, there are very easy ways to cover many of the use cases which wantarray filled.

First, since Perl 6 does not need special reference syntax to contain a List or Array in a Scalar, simply returning a list may be all that is needed:

sub listofstuff {
    return 1, 2, 3;
}
my $a = listofstuff();
print $a;                      # prints "123"
print join("<", listofstuff()) # prints "1<2<3"

One of the most common use cases is to provide either an array of lines or elements, or a prettier string than would be produced by simply printing the array. One can mix in a custom .Str method for this purpose:

sub prettylist(*@origlist) {
    @origlist but role {
        method Str { self.join("<") }
    }
}
print prettylist(1, 2, 3);  # prints "1<2<3"
print join(">", prettylist(3, 2, 1)); # prints "3>2>1"

In the above example, the returned list may be lazy, and the .Str method is not called until stringification happens, so no extra work is done to generate something which is not asked for.

Another use case is to create methods which are mutators when called in void context but produce copies during assignment. It is generally considered better form in Perl 6 not to do so, even more so because void context does not exist in Perl 6, with the closest equivalent being sink context, since users can quite easily turn any copy-producing method into a mutator using the .= operator:

my $a = "foo\n";
$a.ords.say; # says "(102 111 111 10)"
$a .= chomp;
$a.ords.say; # says "(102 111 111)"

However if you have your heart set on using the same function name for both operations, you can get most of the way there by mixing in a .sink method, which will be called when the result finds itself in sink context. There are some caveats however, so again, this is not advised:

multi sub increment($b is rw) {
    ($b + 1) does role { method sink { $b++ } }
}
multi sub increment($b) {
    $b + 1
}
my $a = 1;
increment($a);
say $a;                 # says "2"
my $b = increment($a);
say $a, $b;             # says "2 3"
# ...users will just have to be aware that they should not accidentally
# sink a stored value later, though this requires some effort to
# actually do:
sub identity($c is rw) { $c };
$a = 1;
$b = increment($a);
identity($b);
$a.say;                  # says "2"

warn

warn throws a resumable exception. To simply print a message to $*ERR, you would use the note function. For more on exceptions, see Exceptions.

write

Formats are gone from Perl 6, so this no longer works.

y///

This synonym for tr/// is gone. For functionality, see the entry for tr///.

8 Perl 5 to Perl 6 guide - operators

Operators in Perl 5 to Perl 6: equivalencies and variations

DESCRIPTION

A (hopefully) comprehensive list of Perl 5 operators with their Perl 6 equivalents with notes on variations between them where necessary.

NOTE

This document does not explain the operators in detail. This document is an attempt to guide you from the operators in Perl 5's perlop document to their equivalents in Perl 6. For full documentation on the Perl 6 equivalents, please see the Perl 6 documentation.

Operator precedence and associativity

The operator precedence table is somewhat different in Perl 6 than it is in Perl 5, so it will not be detailed here. If you need to know the precedence and associativity of a given operator in Perl 6, refer to Operator Precedence.

Terms and list operators

The things listed in Perl 5's perlop document as unary and list operators in this section tend to be things that can also be thought of as functions, such as print and chdir. As such, you can find information about them in the functions guide. Parentheses are still used for grouping. There is one caveat: in Perl 6, it's the , (comma) that creates lists, not parentheses. So:

my @foo = 1,2,3,4,5;   # no parentheses needed 
 .say for 1,2,3,4,5;    # also no parentheses 
 
 my $scalar = (1);      # *not* a list, as there is no comma 
 my $list   = (1,);     # a List in a scalar container 

The arrow operator

As you typically will not be using references in Perl 6, the arrow is probably less useful as a dereferencing operator. If you do need to dereference something, however, the arrow is the dot. It is also the dot for method calls. So, Perl 5's $arrayref->[7] becomes $arrayref.[7] in Perl 6 and, similarly, $user->name becomes $user.name. The => arrow is used for constructing Pairs, see Pair term documentation.

Auto-increment and auto-decrement

Work as in Perl 5. The one possible caveat is that they function by calling the succ method for ++ and the pred method for --. For builtin numeric types, this is unlikely to do something unusual, but custom types can define their own succ and pred methods, so in those cases, you should probably take note of what ++ and -- will actually do.

Exponentiation

Works as you would expect. The caveat in Perl 5's perlop about ** binding more tightly than unary minus (i. e. "-2**4" evaluates as "-(2**4)" rather than "(-2)**4)") is also true for Perl 6.

Symbolic unary operators

As in Perl 5, unary ! and - do logical and arithmetic negation, respectively. ?^ is used for bitwise logical negation, which the documentation indicates is equivalent to !. It may be relevant to note that these coerce their arguments to Bool and Numeric, respectively.

Unary ~ is the string context operator in Perl 6, so use prefix +^ for bitwise integer negation. Assumes two's complement.

+ does have an effect in Perl 6, coercing its argument to the Numeric type.

Unary \ is no more. If you really want to take a "reference" to an existing named variable, you can use item context, like so: $aref = item(@array), or maybe more familiarly by prefixing with a $: $aref = $@array. Please note that you're not really getting a reference, but a scalar container with the referenced object in it.

You can get a "reference" to a named subroutine by using the & sigil: $sref = &foo. Anonymous arrays, hashes, and subs return the underlying object during creation right away: $sref = sub { }.

Binding operators

=~ and !~ have been replaced by ~~ and !~~, respectively. Those of you who consider smartmatching broken in Perl 5 will be happy to hear that it works much better in Perl 6, as the stronger typing means less guesswork. See the smartmatch documentation for a more extensive explanation of how smartmatch works in Perl 6.

Multiplicative operators

Binary *, /, and % do multiplication, division, and modulo, respectively, as in Perl 5.

Binary x is slightly different in Perl 6, and has a companion. print '-' x 80; gives you a string of 80 dashes, but for the Perl 5 behavior of @ones = (1) x 80; giving you a list of 80 "1"s, you would use @ones = 1 xx 80;.

Additive operators

Binary + and - do addition and subtraction, respectively, as you would expect.

As . is the method call operator, so binary ~ acts as the concatenation operator in Perl 6.

Shift operators

<< and >> have been replaced by +< and +> .

Named unary operators

As noted above, you'll find these in the functions guide.

Relational operators

These all work as in Perl 5.

Equality operators

== and != both work as in Perl 5.

<=> and cmp have different behavior in Perl 6. <=> does a numeric comparison, but returns Order::Less, Order::Same, or Order::More instead of Perl 5's -1, 0, or 1. To get the Perl 5 behavior (with the change that it returns the Order objects, rather than integers) of cmp, you would use the leg operator.

cmp does either <=> or leg, depending on the existing type of its arguments.

~~ is the smartmatch operator as in Perl 5, but it's also just the match operator in Perl 6, as noted above. For how smartmatching works in Perl 6, see the smartmatch documentation.

Smartmatch operator

See the smartmatch documentation for a more extensive explanation of how smartmatch works in Perl 6.

Bitwise And

Binary & is +& in Perl 6.

Bitwise Or and Exclusive Or

Bitwise OR has changed from | in Perl 5 to +| in Perl 6. Similarly, bitwise XOR ^ is +^, except this operates on integers.

C-style Logical And

Unchanged.

C-style Logical Or

Unchanged.

Logical Defined-Or

Remains in Perl 6 as //. Returns the first defined operand, or else the last operand. Also, there is a low precedence version, called orelse.

Range operators

In list context, .. operates as the range operator and should not need to be changed. That said, there are exclusionary range operators that may be useful. These are:

The following example shows the effects of all the above range operators (please note parentheses are used only to allow the method call):

(1..^5).list;  # (1 2 3 4) 
 (1^..5).list;  # (2 3 4 5) 
 (1^..^5).list; # (2 3 4) 
 (^5).list;     # (0 1 2 3 4) 

In Perl 5, in scalar context, the operators .. and ... work as flip-flop operators, even if they are little-known and probably less used. Those operators have been replaced in Perl 6 by ff and fff respectively.

Conditional operator

The conditional operator ? : has been replaced by ?? !!:

$x = $ok  ? $yes  : $no;  # Perl 5 
$x = $ok ?? $yes !! $no;  # Perl 6 

Assignment operators

Although not fully documented, S03 indicates that the mathematical and logical assignment operators should work as you would expect. The one noticeable change is that .= calls a mutating method on the object on the left (which can also be a type-object). This allows for the following useful idiom:

class LongClassName { 
     has $.frobnicate; 
 } 
 my LongClassName $bar .= new( frobnicate => 42 ); # no need to repeat class name 

This ensures that $bar will only be able to contain a LongClassName object, as well not having to repeat (and possibly misspell) the class name.

~= is the string concatenation assignment, as you might expect with the changes in . and ~. Also, the bitwise assignment operators are likely not separated into numeric and string versions (&=, etc., vs. &.=, etc.), as that feature is currently experimental in Perl 5 itself - although, again, this is not specifically documented.

Comma operator

The comma operator works mostly as expected, but technically it creates Lists) or separates arguments in function calls. Also, there is a : variant that turns function calls into method calls - see this page.

The => operator, or fat arrow, works similarly to the Perl 5 "fat comma" in that it allows an unquoted (ordinary) identifier on its left side, but in Perl 6 constructs Pair objects, rather than just functioning as a separator. If you are trying to just literally translate a line of Perl 5 code to Perl 6, it should behave as expected.

List operators (rightward)

Like the Named Unary Operators, you'll find these discussed under Functions.

Logical Not

The lower precedence version of !. As with !, coerces its argument to Bool.

Logical And

Lower precedence version of && as in Perl 5.

Logical or and Exclusive Or

or is the low precedence version of ||, and xor is the low precedence version of ^^.

Additionally, there is a low precedence version of //, called orelse.

Quote and quote-like operators

For all the gory details on quoting constructs, see quoting.

There is a quoting operator that allows absolute literal strings: Q or 「…」, although the latter might be difficult to find on your keyboard, depending on your keyboard... Backslash escapes do not apply in Q quoted strings. E. g. Q{This is still a closing curly brace → \} renders "This is still a closing curly brace → \".

q does what you expect, allowing backslash escapes. E. g. q{This is not a closing curly brace → \}, but this is → } returning "This is not a closing curly brace → }, but this is →". As in Perl 5, you can get this behavior with single quotes.

qq allows interpolation of variables. However, by default, only scalar variables are interpolated. To get other variables to interpolate, you need to put square brackets after them (the so-called zen-slice) to get them to interpolate. E.g. @a = <1 2 3>; say qq/@a[] example@example.com/; results in "1 2 3 example@example.com". Hashes interpolate in the same manner: %a = 1 => 2, 3 => 4;say "%a{}"; results in a space separating the pairs and tabs separating the key from the value in each pair (because that's the standard stringification of Pairs, and a hash acts as list of Pairs when stringified). You can also interpolate Perl 6 code in strings using curly braces. For all the details, see Interpolation.

qw works as in Perl 5, and can also be rendered as <...> . E. g. qw/a b c/ is equivalent to <a b c> .

There is also a version of qw that interpolates, which is qqw. So my $a = 42;say qqw/$a b c/; gives you "42 b c".

Shell quoting is available through qx, but you should note that backticks do not do shell quoting as in Perl 5, and Perl variables are not interpolated in qx strings. If you need to interpolate Perl variables in a shell command string, you can use qqx instead.

The qr operator is gone from Perl 6.

tr/// works similarly to how it does in Perl 5. The one caveat is that ranges are specified differently. Instead of using a range "a-z", you would use "a..z", i. e. with Perl's range operator. tr/// has a method version, which is better documented, called .trans. .trans uses a list of pairs, as follows: $x.trans(['a'..'c'] => ['A'..'C'], ['d'..'q'] => ['D'..'Q'], ['r'..'z'] => ['R'..'Z']); A much more extensive description of the uses of .trans can be found at https://design.perl6.org/S05.html#Transliteration. The y/// equivalent has been done away with.

Heredocs are specified differently in Perl 6. You use :to with your quoting operator, e. g. q:to/END/; would start a heredoc ending with "END". Similarly, you get escaping and interpolation based on your quoting operator, i. e. literals with Q, backslash escapes with q, and interpolation with qq.

I/O operators

The full details on Input/Output in Perl 6 can be found at io.

As <...> is the quote-words construct in Perl 6, <> is not used for reading lines from a file. You can do that by either making an IO object from a file name or using an open filehandle and then, in either case, calling .lines on it. I. e. either my @a = "filename".IO.lines; or my $fh = open "filename", :r;my @a = $fh.lines; (In the latter case, we are using :r to specifically open the file for reading). To do this in an iterative manner, you can use a for loop this way:

for 'huge-csv'.IO.lines -> $line { 
     # Do something with $line 
 } 

Note the use of -> there. That's part of the Block syntax, and in Perl 6 is needed for if, for, while, etc.

If you want to slurp the entire file into a scalar, you would - surprise! - use the .slurp method. For instance

my $x = "filename".IO.slurp; 
 # ... or ... 
 my $fh = open "filename", :r; 
 my $x = $fh.slurp; 

As noted in the Special Variables guide, the ARGV magic input filehandle has been replaced by $*ARGFILES, and the @ARGV array of command line arguments has been replaced by @*ARGS.

No-ops

1 while foo(); works in the same way as it does in Perl 5, however it generates a warning. In Perl 6 the idiom is now written as Nil while foo(); instead.

Bitwise string operators

Documented individually above, but to summarize...

Bitwise integer negation is prefix +^. Bitwise boolean negation is ?^.

Bitwise and is +&.

Bitwise integer or is +|. Bitwise integer xor is infix +^. Bitwise boolean or is ?|.

Left shift and right shift are +< and +> .

9 Perl 5 to Perl 6 guide - syntax

Syntactic differences between Perl 5 and Perl 6

perlsyn - Perl syntax

DESCRIPTION

A (hopefully) comprehensive description of the differences between Perl 5 and Perl 6 with regards to the syntax elements described in the perlsyn document.

NOTE

I will not be explaining Perl 6 syntax in detail. This document is an attempt to guide you from how things work in Perl 5 to the equivalents in Perl 6. For full documentation on the Perl 6 syntax, please see the Perl 6 documentation.

Free form

Perl 6 is still largely free form. However, there are a few instances where the presence or lack of whitespace is now significant. For instance, in Perl 5, you can omit a space following a keyword (e. g. while($x < 5) or my($x, $y)). In Perl 6, that space is required, thus while ($x < 5) or my ($x, $y). In Perl 6, however, you can omit the parentheses altogether: while $x < 5 . This holds for if, for, etc.

Oddly, in Perl 5, you can leave spaces between an array or hash and its subscript, and before a postfix operator. So $seen {$_} ++ is valid. No more. That would now have to be %seen{$_}++.

If it makes you feel better, you can use backslashes to "unspace" whitespace, so you can use whitespace where it would otherwise be forbidden.

See Whitespace for details.

Declarations

As noted in the Functions guide, there is no undef in Perl 6. A declared, but uninitialized scalar variable will evaluate to its type. In other words, my $x;say $x; will give you "(Any)". my Int $y;say $y; will give you "(Int)".

Comments

# starts a comment that runs to the end of the line as in Perl 5.

Embedded comments start with a hash character and a backtick (#`), followed by an opening bracketing character, and continue to the matching closing bracketing character. Like so:

if #`( why would I ever write an inline comment here? ) True { 
     say "something stupid"; 
 } 

As in Perl 5, you can use pod directives to create multiline comments, with =begin comment before and =end comment after the comment.

Truth and falsehood

The one difference between Perl 5 truth and Perl 6 truth is that, unlike Perl 5, Perl 6 treats the string "0" as true. Numeric 0 is still false, and you can use prefix + to coerce string "0" to numeric to get it to be false. Perl 6, additionally has an actual Boolean type, so, in many cases, True and False may be available to you without having to worry about what values count as true and false.

Statement modifiers

Mostly, statement modifiers still work, with a few exceptions.

First, for loops are exclusively what were known in Perl 5 as foreach loops and for is not used for C-style for loops in Perl 6. To get that behavior, you want loop. loop cannot be used as a statement modifier.

In Perl 6, you cannot use the form do {...} while $x. You will want to replace do in that form with repeat. Similarly for do {...} until $x.

Compound statements

The big change from Perl 5 is that given is not experimental or disabled by default in Perl 6. For the details on given see this page.

Loop control

next, last, and redo have not changed from Perl 5 to Perl 6.

continue, however, does not exist in Perl 6. You would use a NEXT block in the body of the loop.

# Perl 5 
 my $str = ''; 
 for (1..5) { 
     next if $_ % 2 == 1; 
     $str .= $_; 
 } 
 continue { 
     $str .= ':' 
 } 
 
# Perl 6 
 my $str = ''; 
 for 1..5 { 
     next if $_ % 2 == 1; 
     $str ~= $_; 
     NEXT { 
         $str ~= ':' 
     } 
 } 

For loops

As noted above, C-style for loops are not called for loops in Perl 6. They are just loop loops. To write an infinite loop, you do not need to use the C idiom of loop (;;) {...}, but may just omit the spec completely: loop {...}

Foreach loops

In Perl 5, for, in addition to being used for C-style for loops, is a synonym for foreach. In Perl 6, for is just used for foreach style loops.

Switch statements

Perl 6 has actual switch statements, provided by given with the individual cases handled by when and default. The basic syntax is:

given EXPR { 
     when EXPR { ... } 
     when EXPR { ... } 
     default { ... } 
 } 

The full details can be found here.

Goto

goto is currently not implemented (yet). Labels are implemented, and can be used as a target for next, last and redo:

FOO:                         # Labels end with colons, like in Perl 5 
 for ^10 { 
     say "outer for before"; 
     for ^10 { 
         say "inner for"; 
         last FOO; 
     } 
     say "outer for after";   # Will not show because of the "last" 
 } 
 # outer for before 
 # inner for 

For what is planned for goto, see https://design.perl6.org/S04.html#The_goto_statement.

Ellipsis statement

... (along with !!! and ???) are used to create stub declarations. This is a bit more complicated than the use of ... in Perl 5, so you'll probably want to look at https://design.perl6.org/S06.html#Stub_declarations for the gory details. That said, there doesn't seem to be an obvious reason why it shouldn't still fulfill the role it did in Perl 5, despite its role being expanded in Perl 6.

PODs: embedded documentation

Pod has changed between Perl 5 and Perl 6. Probably the biggest difference is that you need to enclose your pod between =begin pod and =end pod directives. There are a few tweaks here and there as well. For instance, as I have discovered while writing these documents, the vertical bar ("|") is significant in X<> codes, and it's not clear how to get a literal "|" into them. Your best bet may be to use the Perl 6 interpreter to check your pod. You can do this by using the --doc switch. E. g. perl6 --doc Whatever.pod. This will output any problems to standard error. (Depending on how/where you've installed perl6, you may need to specify the location of Pod::To::Text.) Details on Perl 6 style pod is at https://design.perl6.org/S26.html.

10 Perl 5 to Perl 6 guide - special variables

A comparison of special variables in Perl 5 and Perl 6

DESCRIPTION

A (hopefully) comprehensive list of Perl 5 Special Variables with their Perl 6 equivalents with notes on variations between them where necessary.

NOTE

This document is an attempt to guide the reader from the Special Variables in Perl 5 to their equivalents in Perl 6. For full documentation on the Perl 6 Special Variables, please see the Perl 6 documentation for each of them.

SPECIAL VARIABLES

General variables

$ARG, $_

Thankfully, $_ is the general default variable as in Perl 5. The main difference in Perl 6 is that you can now call methods on it. For instance, Perl 5's say $_ can be rendered in Perl 6 as $_.say. Furthermore, as it is the default variable, you don't even need to use the variable name. The previous example can also be achieved by using .say.

@ARG, @_

As Perl 6 now has function signatures, your arguments can go there, rather than depending on @_ for them. In fact, if you use a function signature, use of @_ will spit at you telling it cannot override an existing signature.

If, however, you do not use a function signature, @_ will contain the arguments you pass to the function as it did in Perl 5. Again, as with $_, you can call methods on it. Unlike $_ you cannot assume @_ as the default variable for those methods to operate on (i. e. @_.shift works, .shift does not).

$LIST_SEPARATOR, $"

Currently, there is no equivalent of the List Separator variable in Perl 6. Design document S28 says there isn't one, so you probably don't want to hold your breath.

$PROCESS_ID, $PID, $$

$$ is replaced in Perl 6 by $*PID

$PROGRAM_NAME, $0

You can access the program name in Perl 6 via $*PROGRAM-NAME.

Note: $0 in Perl 6 is the variable holding the first captured value from a regexp match (i. e. capture variables now start from $0 rather than $1).

$REAL_GROUP_ID, $GID, $(

In Perl 6 the group information is handled by $*GROUP, which holds an object of type IntStr and therefore can be used either within a string or a numeric context. The group id is therefore obtained via +$*GROUP, while the group name via ~$*GROUP.

$EFFECTIVE_GROUP_ID, $EGID, $)

The effective group id does not appear to be currently provided by Perl 6.

$REAL_USER_ID, $UID, $<

In Perl 6 the user information is handled by $*USER, which holds an object of type IntStr and therefore can be used either within a string or a numeric context (this is similar to how the group information is handled by the $*GROUP object). The user id is therefore obtained via +$*USER, while the username via ~$*USER.

$EFFECTIVE_USER_ID, $EUID, $>

The effective user id does not appear to be currently provided by Perl 6.

$SUBSCRIPT_SEPARATOR, $SUBSEP, $;

The subscript separator variable is not included in Perl 6. Frankly, if your Perl 5 code is using this, it's almost certainly really, really old.

$a, $b

$a and $b have no special meaning in Perl 6. sort() does not use them for anything special. They're just regular old variables.

This feature has been extended by having blocks with placeholder parameters which are more versatile. Placeholder variables are created with the ^ twigil (e. g. $^z. They can be used in a bare block or in a subroutine without an explicit parameter list. The arguments to the block are assigned to the placeholder variables in their Unicode order. I. e. even if the variables appear in the block in the order ($^q, $^z, $^a), they will be assigned in the order ($^a, $^q, $^z). Ergo:

sort { $^a cmp $^z }, 1, 5, 6, 4, 2, 3; 
 # OUTPUT: «(1 2 3 4 5 6)␤» 
 sort { $^g cmp $^a }, 1, 5, 6, 4, 2, 3; 
 # OUTPUT: «(6 5 4 3 2 1)␤» 
 for 1..9 { say $^c, $^a, $^b; last } 
 # OUTPUT: «312␤» 

For more on placeholder variables, see this page

%ENV

%ENV has been replaced by %*ENV in Perl 6. Note that the keys of this hash may not be exactly the same between Perl 5 and Perl 6. For example, OLDPWD is missing from Perl 6's %ENV.

$OLD_PERL_VERSION, $]

The running version of Perl 6 is kept by $*PERL special variable, that is an object. The running version is retrieved via $*PERL.version, which returns something like v6.c; the full stringified version of the Perl interpreter is obtained via ~$*PERL, which returns something like Perl 6 (6.c).

$SYSTEM_FD_MAX, $^F

Although the design documents (S28) indicate that this will likely become $*SYS_FD_MAX, this has not yet been implemented.

@F

[NEEDS FURTHER RESEARCH] A bit confusing at this point. Design doc S28 indicates that @F in Perl 5 is replaced by @_ in Perl 6, but it's unclear just how that works. On the other hand, it's currently something of a moot point, as the Perl 5 to Perl 6 Translation doc indicates that the -a and -F command-line switches are not yet implemented in rakudo.

@INC

No longer exists in Perl 6. Please use "use lib" to manipulate the module repositories to be searched. The closest thing to @INC is really $*REPO. But that works completely differently from @INC mostly because of the precompilation capabilities of Perl 6.

# Print out a list of compunit repositories
.say for $*REPO.repo-chain;

%INC

No longer exists in Perl 6. Because each Repository is responsible for remembering which modules have been loaded already. You can get a list of all loaded modules (compilation units) like so:

use Test; 
 use MyModule; 
 say flat $*REPO.repo-chain.map(*.loaded); #-> (MyModule Test) 

$INPLACE_EDIT, $^I

S28 suggests $*INPLACE_EDIT, but it does not yet exist.

$^M

S28 suggests $*EMERGENCY_MEMORY, but it does not yet exist.

$OSNAME, $^O

This is somewhat unclear. It probably depends on what you mean by "the name of the operating system" as design document S28 has three different suggestions, all of which give different answers.

There are currently three main objects containing information about the "running environment":

All the above objects have methods in common:

As a short example, the following piece of code prints information about all the above components:

for $*KERNEL, $*DISTRO, $*VM -> $what { 
     say $what.^name; 
     say 'version '  ~ $what.version 
         ~ ' named ' ~ $what.name 
         ~ ' by '    ~ $what.auth; 
 } 
 
 # Kernel 
 # version 4.10.0.42.generic named linux by unknown 
 # Distro 
 # version 17.04.Zesty.Zapus named ubuntu by https://www.ubuntu.com/ 
 # VM 
 # version 2017.11 named moar by The MoarVM Team 

The Str method on all of the above produces the short version of the information, at the current time the name.

All the objects have other methods that can be useful when trying to identify the exact running instance, for more information use <.^methods> to introspect all the above.

%SIG

No equivalent variable. To have your code executed on the reception of a signal, you can call the signal subroutine, which returns a Supply that can be tapped.

$SIG{"INT"} = sub { say "bye"; exit } 
signal(SIGINT).tap: { say "bye"; exit }; loop {} 

Or, if you have a generic code that want to know which signal it got:

signal(SIGINT).tap: -> $signal { say "bye with $signal"; exit }; loop {} 

A more idiomatic way of using signals in an event driven situation:

react { 
     whenever signal(SIGINT) { 
         say "goodbye"; 
         done 
     } 
 } 

$BASETIME, $^T

Replaced in Perl 6 by $*INIT-INSTANT. Unlike in Perl 5, this is not in seconds since epoch, but an Instant object, which is measured in atomic seconds, with fractions.

$PERL_VERSION, $^V

As with $] this has been replaced with $*PERL.version.

${^WIN32_SLOPPY_STAT}

There is no analog to this in Perl 6.

$EXECUTABLE_NAME, $^X

This has been replaced by $*EXECUTABLE-NAME. Note that there is also $*EXECUTABLE, which is an IO object in Perl 6.

Performance issues

As shown below, $`, $&, and $' are gone from Perl 6, primarily replaced by variations on $/ and, with their elimination, the associated performance issues in Perl 5 do not apply.

$<digits> ($1, $2, ...)

These existing variables do the same thing in Perl 6 as they do in Perl 5, except that they now start at $0 rather than $1. Furthermore, they are synonyms for indexed items in the match variable $/. I. e. $0 is equivalent to $/[0], $1 is equivalent to $/[1], etc.

$MATCH, $&

$/ now contains the match object, so the Perl 5 behavior of $& can be obtained by stringifying it, i. e. ~$/.

Please note that while $/.Str should also work, ~$/ is currently the more common idiom.

${^MATCH}

Since the former performance issues are done away with, this variable is not of use in Perl 6.

$PREMATCH, $`

Replaced by $/.prematch.

${^PREMATCH}

Since the former performance issues are done away with, this variable is not of use in Perl 6.

$POSTMATCH, $'

Replaced by $/.postmatch.

${^POSTMATCH}

Since the former performance issues are done away with, this variable is not of use in Perl 6.

$LAST_PAREN_MATCH, $+

Does not exist in Perl 6, but you can get the same information using $/[*- 1].Str ($/[*-1] would be the match object, not the actual string).

If you want to understand why that works, you can look at these documents:

...and possibly

...though the design documents are not always up to date.

$LAST_SUBMATCH_RESULT, $^N

S28 suggests $*MOST_RECENT_CAPTURED_MATCH, but there does not seem to be any implemented variable that matches $^N.

@LAST_MATCH_END, @+

As with most regular expression related variables, this functionality is, at least in part, moved to the $/ variable in Perl 6. Or, in this case, the numbered variables that alias to the indexes of it. The offset is found by using the .to method. I. e. the first offset is $/[0].to, which is synonymous with $0.to. The value Perl 5 provides as $+[0] is provided by $/.to.

%LAST_PAREN_MATCH, %+

Once again, we move over to $/. The former $+{$match} is $/{$match}.

@LAST_MATCH_START, @-

Similarly to @+ being replaced by using the .to method, @- is replaced by using the .from method on $/ and its variations. The first offset is $/[0].from or the equivalent $0.from. Perl 5's $- [0] is $/.from.

%LAST_MATCH_START, %-

Much like %+, a use of %-{$match} would be replaced with $/{$match}.

$LAST_REGEXP_CODE_RESULT, $^R

No equivalent.

${^RE_DEBUG_FLAGS}

No equivalent.

${^RE_TRIE_MAXBUF}

No equivalent.

$ARGV

The name of the current file when reading lines can be obtained through $*ARGFILES.path.

@ARGV

@*ARGS contains the command line arguments.

ARGV

This has been replaced by $*ARGFILES.

ARGVOUT

As the -i command line switch has not yet been implemented, there is not yet an equivalent of ARGVOUT.

$OUTPUT_FIELD_SEPARATOR, $OFS, $,

Currently no obvious equivalent.

$INPUT_LINE_NUMBER

$NR, $.

No direct replacement exists.

When iterating using lines method from IO::Path or IO::Handle types, you can call the .kv method on it to get an interleaved list of indexes and values (then iterate by 2 each loop):

for "foo".IO.lines.kv -> $n, $line { 
     say "{$n + 1}: $line" 
 } 
 # OUTPUT: 
 # 1: a 
 # 2: b 
 # 3: c 
 # 4: d 

For IO::CatHandle types (of which $*ARGFILES is one), you can use on-switch hook to reset line number on handle switch, and increment it manually. See also IO::CatHandle::AutoLines and LN modules that simplify this operation.

$INPUT_RECORD_SEPARATOR, $RS, $/

This is accessed through the .nl-in method on the filehandle. E. g. $*IN.nl-in.

$OUTPUT_RECORD_SEPARATOR, $ORS, $\

This is accessed through the .nl-out method on the filehandle. E. g. $*OUT.nl-out.

$OUTPUT_AUTOFLUSH, $|

No global alternative available. TTY handles are unbuffered by default, for others, set out-buffer to zero or use :!out-buffer with open on a specific IO::Handle.

${^LAST_FH}

Not implemented in Perl 6.

There are no built-in formats in Perl 6.

Error variables

Because of how error variables have changed in Perl 6, they will not be detailed here individually.

To quote the Perl 6 docs, "$! is the error variable." That's it. All the error variables appear to have been eaten by $!. As with the rest of Perl 6, it's an object that will return various things depending on the type of error or exception.

In particular, when dealing with exceptions the $! provides information about the thrown exception, assuming the program has not halted:

try { 
     fail "Boooh"; 
     CATCH { 
         # within the catch block 
         # the exception is placed into $_ 
         say 'within the catch:'; 
         say $_.^name ~ ' : ' ~ $_.message; 
         $_.resume; # do not abort 
     } 
 } 
 
 # outside the catch block the exception is placed 
 # into $! 
 say 'outside the catch:'; 
 say $!.^name ~ ' : ' ~ $!.message; 

and the above code produces the following output

within the catch: 
 X::AdHoc : Boooh 
 outside the catch: 
 X::AdHoc : Boooh 

therefore, as stated before, the $! variable holds the exception object.

$COMPILING, $^C, $^D, ${^ENCODING}, ${^GLOBAL_PHASE}

Currently no equivalents for either of these variables.

$^H, %^H, ${^OPEN}

There may or may not be equivalents of these in Perl 6, but they're internal and you shouldn't be messing with them in the first place - certainly not if your understanding of Perl 6 requires you to read this document...

$PERLDB, $^P

The chance of the Perl 6 debugger resembling the Perl 5 debugger is slim at best, and at this point there does not seem to be an equivalent of this variable.

${^TAINT}

S28 claims this variable is "pending". Not currently in Perl 6.

${^UNICODE}, ${^UTF8CACHE}, ${^UTF8LOCALE}

These Unicode-related variables do not appear to exist in Perl 6, but - maybe? - could have analogs in $?ENC somewhere. This, however, is totally unconfirmed.

11 Haskell to Perl 6 - nutshell

Learning Perl 6 from Haskell, in a nutshell: what do I already know?

Haskell and Perl 6 are very different languages. This is obvious. However, that does not mean there are not similarities or shared ideas! This page attempts to get a Haskell user up and running with Perl 6. The Haskell user may find that they need not abandon all of their Haskelly thoughts while scripting in Perl 6.

Note that this should not be mistaken for a beginner tutorial or overview of Perl 6; it is intended as a technical reference for Perl 6 learners with a strong Haskell background.

Types

Types vs values

In Haskell, you have type level programming and then value level programming.

plusTwo :: Integer -> Integer   -- Types 
 plusTwo x = x + 2               -- Values 

You do not mix types and values in Haskell like the below

plusTwo 2          -- This is valid 
 plusTwo Integer    -- This is not valid 

In Perl 6, types (AKA type objects) live on the same level as values

sub plus-two(Int $x --> Int) { $x + 2 } 
 
 plus-two(2);    # This is valid 
 plus-two(Int);  # This is valid 

I will illustrate this unique aspect of Perl 6 with one more example:

multi sub is-string(Str $ --> True) {} 
 multi sub is-string(Any $ --> False) {} 
 
 is-string('hello');    #True 
 is-string(4);          #False 

Maybe

In Haskell, you have a Maybe type that allows you to forgo the worry of null types. Let's say you have a hypothetical function that parses a String to an Integer:

parseInt :: String -> Maybe Integer 
 
 case parseInt myString of 
   Just x  -> x 
   Nothing -> 0 

In Perl 6, since type objects coexist with regular objects, we have the concept of Defined and Undefined objects. Plain type objects are undefined while instantiated objects are defined.

sub parse-int(Str $s --> Int) { ... } 
 
 my $string = {...}; 
 given parse-int($string) { 
   when Int:D { $_ } 
   when Int:U { 0 } 
 } 

So in Perl 6 we have type constraints that indicate the definedness of a type. These are

Int:D; # This is a defined Int. 
 Int:U; # This is an undefined Int, AKA a type object 
 Int:_; # This is either defined or undefined. 

If we wanted to be explicit in the above example (probably a good idea), we could add the :_ constraint on the return type. This would let the user know that they should account for both defined and undefined return values. We could also use other methods and constructs that specifically test for definedness.

sub parse-int(Str $s --> Int:_) { ... } 
 
 # One way to do it 
 my $string = {...}; 
 given parse-int($string) { 
   when Int:D { $_ } 
   when Int:U { 0 } 
 } 
 
 # Another way to do it 
 my Int $number = parse-int($string); 
 if $number.defined { $number } else { 0 } 
 
 
 # A better way 
 with parse-int($string) { $_ } else { 0 } 
 
 # With the defined-or operator 
 parse-int($string) // 0 

The with operator that you see above is like if, except it explicitly tests for definedness and then passes the result to the following block. Similarly, without tests that the object is undefined and also passes the result to the following block.

For more natural control flow with undefined and defined types, Perl 6 introduces andthen and orelse.

sub parse-int(Str $s --> Int:_) { ... } 
 
 my $string = {...}; 
 my $result = parse-int($string) orelse 0; 
 
 sub hello() { say 'hi' } 
 hello() andthen say 'bye'; 
TODO: include a better example for andthen that makes sense. Maybe using promise objects?

So in practice, Perl 6 does not have the concept of a null type, but rather of defined or undefined types.

Data definitions

Perl 6 is fundamentally an object oriented language. However, it also gives you the freedom to write in virtually any paradigm you wish. If you only want to pure functions that take an object and return a new object, you can certainly do so.

Here is a Haskell code example:

data Point = Point x y 
 
 moveUp :: Point -> Point 
 moveUp (Point x y) = Point x (y + 1) 

And an equivalent Perl 6 example:

class Point { has $.x; has $.y; } 
 
 sub move-up(Point $p --> Point) { 
   Point.new(x => $p.x, y => $p.y + 1) 
 } 

The code I illustrated above is an example of a Product Type. If instead you'd like to write a Sum Type, there is not an exact equivalent in Perl 6. The closest thing would be an Enum.

data Animal = Dog | Cat | Bird | Horse 
 
 testAnimal :: Animal -> String 
 testAnimal Dog   = "Woof" 
 testAnimal Horse = "Neigh" 

Although it does not fit the same exact use cases, it can be used in putting constraints on types.

enum Animal < Dog Cat Bird Horse >; 
 
 proto sub test-animal( Animal        ) {*} 
 multi sub test-animal( Dog           ) { 'Woof' } 
 multi sub test-animal( Animal::Horse ) { 'Neigh'  }   # more explicit 
 
 say test-animal Animal::Dog;                          # more explicit 
 say test-animal Horse; 

Type aliases and subsets

In Haskell, you can alias an existing type to simply increase clarity of intent and re-use existing types.

type Name = String 
 
 fullName :: Name -> Name -> Name 
 fullName first last = first ++ last 

The equivalent in Perl 6 is the following.

my constant Name = Str; 
 
 sub full-name ( Name \first, Name \last --> Name ) { first ~ last } 

It should be noted that in Perl 6, one can also create a subset of an existing type.

subset Name of Str where *.chars < 20; 
 
 sub full-name(Name $first, Name $last) { 
   $first ~ $last 
 } 
 
 full-name("12345678901234567890111", "Smith") # This does not compile, as the first parameter 
                                               # doesn't fit the Name type 

Typeclasses

TODO

explain how Perl 6 roles compare to Haskell typeclasses

Functions

Definitions and signatures

Matching

Haskell makes heavy use of pattern matching in function definitions.

greeting :: String -> String 
 greeting  ""   = "Hello, World!" 
 greeting "bub" = "Hey bub." 
 greeting  name = "Hello, " ++ name ++ "!" 

Perl 6 does this as well! You just use the multi keyword to signify that it is a multiple dispatch function.

proto greeting ( Str   --> Str ) {*} 
 multi greeting ( ""    --> "Hello, World!" ) {} 
 multi greeting ( "bub" --> "Hey bub." ) {} 
 multi greeting ( \name ) { "Hello, " ~ name ~ "!" } 

The proto declarator is not necessary, but can sometimes aid in making sure that all multis follow your business rules. Using a variable name in the signature of the proto would provide more information in error messages, and for introspection.

proto greeting ( Str \name --> Str ) {*} 
 
 say &greeting.signature;                  # (Str \name --> Str) 

An interesting thing to note in the Perl 6 code above is that passing values like 'bub' as a function parameter is just syntax sugar for a where guard.

Using the example from the "Pattern Matching" section of this page, you can see the guards that are used behind the scenes to constrain our function arguments.

multi greeting ( ""    --> "Hello, World!" ) {} 
 multi greeting ( "bub" --> "Hey bub." ) {} 
 
 # The above is the same as the below 
 
 multi greeting(Str \name where ''    ) {'Hello, World!'} 
 multi greeting(Str \name where 'bub' ) {'Hey bub.'} 
 
 # The above is the same as the below, again. 
 
 multi greeting(Str \name where $_ ~~ ''   ) {'Hello, World!'} 
 multi greeting(Str \name where $_ ~~ 'bub') {'Hey bub.'} 

$_ is known as the topic variable. It assumes the form of whatever is appropriate. The smartmatch operator ~~ figures out the best way to determine if the left matches the right, be it number ranges, strings, etc. Our three examples above go from most sugared (top), to least sugared (bottom).

The bottom examples above could be wrapped in curly braces, making it more obvious that it is a code block. Note that a where clause may also take an explicit Callable.

multi greeting(Str \name where { $_ ~~ '' } ) {'Hello, World!'} 
 
 multi greeting(Str \name where -> $thing { $thing ~~ '' } ) {'Hello, World!'} 
 
 multi greeting ( Str \name where { Bool.pick } --> 'True' ){} 
 
 multi greeting ( Str \name where &some-subroutine ){…} 

If you read the section in this page on subsets, you'll notice that "where" is used in the making of subsets as well as here. The usage of "where" in both areas is exactly the same.

When using where, note that the order of definition is important, just like in Haskell.

multi greeting ( Str \name where '' --> 'Hello, World!' ){} 
 multi greeting ( Str \name where { Bool.pick } --> 'True' ){} 
 multi greeting ( Str \name where 'bub' --> 'Hey, bub.' ){} 
 
 say greeting ''   ; # will never say True 
 say greeting 'bub'; # about 50% of the time it will say True 

Deconstruction

TODO

Currying

TODO

.assuming vs currying

method chaining vs currying

Composing

TODO

show function composition operator. Maybe explain a more perl6ish way to do this though.

Case / matching

Haskell makes heavy use of case matching like the below:

case number of 
   2 -> "two" 
   4 -> "four" 
   8 -> "eight" 
   _ -> "don't care" 

In Perl 6 you can achieve this same thing with the given/when structure:

my $number = {...}; 
 given $number { 
   when 2  { "two" } 
   when 4  { "four" } 
   when 8  { "eight" } 
   default { "don't care" } 
 } 

Note that the order of the when's is also significant, just like with the where's in the guard section of this page.

Lists

TODO

explain difference between perl6 Array, Sequence, List. Explain data shapes in regards to the @ sigil. Explain how you can convert an Array to a flattened list of objects with |@

data shapes become quite intuitive, but it takes a bit of practice.

List comprehensions

There are no explicit list comprehensions in Perl6. But rather, you can achieve list comprehensions a couple of different ways.

Here is a trivial example in Haskell:

evens = [ x | x <- [0..100], even x ] 

And now in Perl6 :

# using `if` and `for` 
 my @evens = ($_ if $_ %% 2 for 0..100); 
 
 # using gather/take to build a Seq 
 my $evens = gather for 0..100 { take $_ if $_ %% 2 }; 
 
 # using gather/take to build an Array 
 my @evens = gather for 0..100 { take $_ if $_ %% 2 }; 

Since for is always eager it is generally better to use map or grep which will inherit the laziness or eagerness of its list argument.

my @evens = map { $_ if $_ %% 2 }, 0..100; 
 
 my @evens = grep { $_ %% 2 }, 0..100; 
 
 # using a Whatever lambda 
 my @evens = grep  * %% 2,  0..100; 

Here is the creation of tuples in Haskell:

tuples = [(i,j) | i <- [1,2], 
                   j <- [1..4] ] 
 -- [(1,1),(1,2),(1,3),(1,4),(2,1),(2,2),(2,3),(2,4)] 

And in Perl6:

my @tuples = 1,2  X  1..4; 
 # [(1,1), (1,2), (1,3), (1,4), (2,1), (2,2), (2,3), (2,4)] 

See this design document for more information on what kinds of list comprehensions are possible in Perl6: https://design.perl6.org/S04.html#The_do-once_loop.

As you can see, when you get into some more advanced Haskell list comprehensions, Perl6 does not translate exactly the same, but it's possible to do the same things, nonetheless.

Fold

Fold in Haskell is called Reduce in Perl 6.

mySum = foldl `+` 0 numList 
my @numbers = {...}; 
 reduce { $^a + $^b }, 0, |@numbers; 
 @numbers.reduce({$^a + $^b}, with => 0) 

However, in Perl 6, if you want to use an infix operator (+ - / % etc) there is a nice little helper called the Reduction metaoperator.

my @numbers = {...}; 
 [+] @numbers    # This is the same 
 [+] 0, @numbers # as this 

It inserts the operator in between all values in the list and produces a result, just like Fold.

In Haskell you, you have foldl and foldr. In Perl 6, this difference is determined by the associativity attached to the operator/subroutine.

sub two-elem-list ( \a, \b ) { ( a, b ) } 
 
 # you can use a subroutine as an infix operator 
 say 'a' [&two-elem-list] 'b'; # (a b) 
 
 # as the reduction prefix metaoperator takes an infix operator, it will work there too; 
 [[&two-elem-list]] 1..5;           # ((((1 2) 3) 4) 5) 
 say (1..5).reduce: &two-elem-list; # ((((1 2) 3) 4) 5) 
 
 # right associative 
 sub right-two-elem-list( \a, \b ) is assoc<right> { ( a, b ) } 
 say (1..5).reduce: &right-two-elem-list; # (1 (2 (3 (4 5)))) 
 
 # XXX there is possibly a bug here as this currently doesn't look at 
 # XXX the associativity of &right-two-elem-list and just always does left assoc 
 say [[&right-two-elem-list]] 1..5; 
 
 # chaining 
 say [<] 1..5;            # True 
 say (1..5).reduce: &[<]; # True 

Map

TODO

Ranges

Haskell and Perl 6 both allow you to specify ranges of values.

myRange1 = 10..100 
 myRange2 = 1..        -- Infinite 
 myRange3 = 'a'..'h'   -- Letters work too 
my $range1 = 10..100; 
 my $range2 = 1..*;      # Infinite 
 my $range3 = 'a'..'h';  # Letters work too 

Laziness vs eagerness

In the examples above, you have the concept of laziness displayed very plainly. Perl 6 has laziness only where it makes the most sense. For example, in the range 10..100, this is eager because it has a definite end. If a list does not have a definite end, then the list should clearly be lazy.

(1 .. 100).is-lazy; # False 
 (1 .. Inf).is-lazy; # True 

These are the "sane defaults" that Perl 6 takes pride in. But they are still defaults and can be changed into one or the other.

(1 .. 100).lazy.is-lazy;       # True 
 (1 .. 100).lazy.eager.is-lazy; # False 

Contexts (let-in / where)

TODO

explain how given/when and with/without and for loops open lexical scopes with the argument as the context.

compare it to let/in and where constructs maybe?

Parsers

Parser combinators vs grammars

TODO

### Guidelines for contributions:

Headers should contain the text that a Haskell user might search for, since those headings will be in the Table of Contents generated for the top of the document.

We use POD =item instead of =head3 or =head4 for identical bits that need not appear in the table of contents.

This article does not describe in detail language features that Haskell doesn't have at all, instead referring to other documents.

Example code and links to other documents should be favored over long explanations of details better found elsewhere.

Finally, if a real user asks a Haskell to Perl 6 question that is not being answered here, please add it to the document. Even if we do not have a good answer yet, that will be better than losing the information about a real need.

12 JavaScript (Node.js) to Perl 6 - nutshell

Learning Perl 6 from Node.js, in a nutshell

This page attempts to provide a way for users experienced in Node.js to learn Perl 6. Features shared between the two languages will be explained here, as well as major differences in syntax and features.

This is not a tutorial for learning Perl 6; this is a reference for users who are already at an intermediate to advanced skill level with Node.js.

Basic syntax

"Hello, world!"

Let's start with the typical first program when learning new languages. In Node.js, a hello world program would be written like this:

console.log('Hello, world!'); 

Here are a couple ways to write this in the same way in Perl 6:

say('Hello, world!'); 
 say 'Hello, world!'; 

Parentheses are optional for function calls in Perl 6. While semicolons are, for the most part, optional in Node.js, they are mandatory for expressions in Perl 6.

Now that we've greeted the world, let's greet our good friend, Joe. We'll start with Node.js again:

let name = 'Joe'; 
 console.log('What\'s up,' + name + '?'); 
 console.log(`What's up, ${name}?`); 
 console.log("What's up, ", name, "?"); 

Since he didn't hear us, let's greet him again, this time in Perl 6:

my $name = 'Joe'; 
 say 'What\'s up, ' ~ $name ~ '?'; 
 say "What's up, $name?"; 
 say "What's up, ", $name, "?"; 

Here, there are only a couple differences: most variables in Perl 6 have what are called sigils, which are what the $ in front of its name is, and string concatenation uses the ~ operator instead of +. What the two languages share in common here is support for string interpolation.

Now that the basic examples are out of the way, let's explain the similarities between the two languages in greater detail.

Variables

Variables in Node.js can be defined like this;

var   foo = 1;  // Lexically scoped with functions and modules 
 let   foo = 1;  // Lexically scoped with blocks 
 const foo = 1;  // Lexically scoped with blocks; constant 
 
 // No equivalent to Perl 6 dynamic variables exists. 
 
 global.foo = 1; // Globally scoped 
 foo = 1;        // Ditto, but implicit; forbidden in strict mode 

In Perl 6 there is no equivalent to var. An important note to make is that there is no variable hoisting in Perl 6; variables are defined and assigned at the line they're on, not defined at the top of its scope and later assigned at that line.

In addition to regular variables, in Perl 6 there are what is known as dynamic variables. Dynamic variables are looked up using the caller's scope, rather than the outer scope. This is what the equivalent variable declarations look like in Perl 6:

my           $foo = 1; # Lexically scoped 
 our          $foo = 1; # Package scoped 
my  constant  foo = 1; # Lexically scoped; constant 
    constant  foo = 1; # Package scoped; constant 
my  $*foo = 1; # Dynamic variable; lexically scoped 
 our $*foo = 1; # Dynamic variable; package scoped 

GLOBAL::<$foo> := 1; # Globally scoped

Use my where you'd use let, our for variables you'd define in the outermost scope needed, and constant where you'd uses const.

You may have noticed the $ and $* symbols placed before variable names. These are known as sigils and twigils respectively, and define what container the variable has. Refer to the documentation on variables for more information on sigils, twigils, and containers.

Variables in Node.js can override others from outer scopes with the same name (though linters will usually complain about it depending on how they're configured):

let foo = 1; 
 function logDupe() { 
     let foo = 2; 
     console.log(foo); 
 } 
 
 logDupe(2);       // OUTPUT: 2 
 console.log(foo); // OUTPUT: 1 

Perl 6 also allows this:

my $foo = 1; 
 sub log-dupe { 
     my $foo = 2; 
     say $foo; 
 } 
 
 log-dupe; # OUTPUT: 2 
 say $foo; # OUTPUT: 1 

Operators

Assignment

The = operator works the same across both languages.

The := operator in Perl 6 binds a value to a variable. Binding a variable to another variable gives them the same value and container, meaning mutating attributes of one will mutate the other's as well. Bound variables cannot be reassigned with = or mutated with ++, --, etc. but they can be bound to another value again:

my %map;            # This is a hash, roughly equivalent to a JS object or map 
 my %unbound = %map; 
 my %bound := %map; 
 %map<foo> = 'bar'; 
 say %unbound;       # OUTPUT: {} 
 say %bound;         # OUTPUT: {foo => bar} 
 
 %bound := %unbound; 
 say %bound;         # OUTPUT: {} 

Equality

Node.js has two equality operators: == and ===.

== is the loose equality operator. When comparing operands with the same type, it will return true if both operands are equal. However, if the operands are different types, they are both cast to their primitives before being compared, meaning these will return true:

console.log(1 == 1);   // OUTPUT: true 
 console.log('1' == 1); // OUTPUT: true 
 console.log([] == 0);  // OUTPUT: true 

Similarly, in Perl 6, both operands are cast to Numeric before comparison if they don't share the same type:

say 1 == 1;       # OUTPUT: True 
 say '1' == 1;     # OUTPUT: True 
 say [1,2,3] == 3; # OUTPUT: True, since the array has three elements 

The inverse of == is !=.

Perl 6 has another operator similar to ==: eq. Instead of casting operands to Numeric if they're different types, eq will cast them to strings:

say '1' eq '1'; # OUTPUT: True 
 say 1 eq '1';   # OUTPUT: True 

The inverse of eq is ne or !eq.

=== is the strict equality operator. This returns true if both operands are the same value. When comparing objects, this will only return true if they are the exact same object:

console.log(1 === 1);   // OUTPUT: true 
 console.log('1' === 1); // OUTPUT: false 
 console.log({} === {}); // OUTPUT: false 
 
 let obj = {}; 
 let obj2 = obj; 
 console.log(obj === obj2); // OUTPUT: true; 

In Perl 6, the operator behaves the same, with one exception: two objects that have the same value, but different containers, will return false:

say 1 === 1;                    # OUTPUT: «True␤» 
 say '1' === 1;                  # OUTPUT: «False␤» 
 say 'ayy lmao' === 'ayy lmao';  # OUTPUT: «True␤» 
 say {} === {};                  # OUTPUT: «False␤» 
 
 my \hash = {}; 
 my %hash = hash; 
 say hash === %hash; # OUTPUT: False 

In the last case it's the same object, but containers are different, which is why it returns False.

The inverse of === is !==.

This is where Perl 6's other equality operators are useful. If the values have different containers, the eqv operator can be used. This operator can be also be used to check for deep equality, which you would normally need to use a library for in Node.js:

say {a => 1} eqv {a => 1}; # OUTPUT: True 
 
 my \hash = {}; 
 my %hash := hash; 
 say hash eqv %hash; # OUTPUT: True 

In the case you need to check if two variables have the same container and value, use the =:= operator.

my @arr = [1,2,3]; 
 my @arr2 := @arr;   # Bound variables keep the container of the other variable 
 say @arr =:= @arr2; # OUTPUT: True 

Smartmatching

Perl 6 has one last operator for comparing values, but it is not exactly an equality operator. This is ~~, the smartmatch operator. This has several uses: it can be used like instanceof in Node.js, to match a regex, and to check if a value is a key in a hash, bag, set, or map:

say 'ayy lmao' ~~ Str; # OUTPUT: True 
 
 my %hash = a => 1; 
 say 'a' ~~ %hash; # OUTPUT: True 
 
 my $str = 'abc'; 
 $str ~~ s/abc/def/; # Mutates $str, like foo.replace('abc', 'def') 
 say $str;           # OUTPUT: def 

While we are talking about instanceof, the equivalent to the constructor property on Node.js objects in Perl 6 is the WHAT attribute:

console.log('foo'.constructor); // OUTPUT: String 
say 'foo'.WHAT; # OUTPUT: Str 

Numeric

Node.js has +, -, /, *, %, and (in ES6) ** as numeric operators. When the operands are different types, similarly to the equality operators, are cast to their primitives before following through with the operation, making this possible:

console.log(1 + 2);   // OUTPUT: 3 
 console.log([] + {}); // OUTPUT: [object Object] 
 console.log({} + []); // OUTPUT: 0 

In Perl 6, again, they are converted to a Numeric type, as before:

say 1 + 2;        # OUTPUT: 3 
 say [] + {};      # OUTPUT: 0 
 say {} + [1,2,3]; # OUTPUT: 3 

In addition, Perl 6 has div and %%. div behaves like int division in C, while %% checks if one number is cleanly divisible by another or not:

say 4 div 3; # OUTPUT: 1 
 say 4 %% 3;  # OUTPUT: False 
 say 6 %% 3;  # OUTPUT: True 

Bitwise

Node.js has &, |, ^, ~, <<, >>, >>>, and ~ for bitwise operators:

console.log(1 << 1);  // OUTPUT: 2 
 console.log(1 >> 1);  // OUTPUT: 0 
 console.log(1 >>> 1); // OUTPUT: 0 
 console.log(1 & 1);   // OUTPUT: 1 
 console.log(0 | 1);   // OUTPUT: 1 
 console.log(1 ^ 1);   // OUTPUT: 0 
 console.log(~1);      // OUTPUT: -2 

In Perl 6, there is no equivalent to >>>. All bitwise operators are prefixed with +, however bitwise negation uses +^ instead of ~:

say 1 +< 1; # OUTPUT: 2 
 say 1 +> 1; # OUTPUT: 0 
             # No equivalent for >>> 
 say 1 +& 1; # OUTPUT: 1 
 say 0 +| 1; # OUTPUT: 1 
 say 1 +^ 1; # OUTPUT: 0 
 say +^1;    # OUTPUT: -2 

Custom operators and operator overloading

Node.js does not allow operator overloading without having to use a Makefile or build Node.js with a custom version of V8. Perl 6 allows custom operators and operator overloading natively! Since all operators are subroutines, you can define your own like so:

multi sub infix:<||=>($a, $b) is equiv(&infix:<+=>) { $a || $b } 
 
 my $foo = 0; 
 $foo ||= 1; 
 say $foo; # OUTPUT: 1 

Operators can be defined as prefix, infix, or postfix. The is tighter, is equiv, and is looser traits optionally define the operator's precedence. In this case, ||= has the same precedence as +=.

Note how multi is used when declaring the operator subroutines. This allows multiple subroutines with the same name to be declared while also having different signatures. This will be explained in greater detail in the Functions section. For now, all we need to know is that it allows us to override any native operator we want:

# Using the `is default` trait here forces this subroutine to be chosen first, 
 # so long as the signature of the subroutine matches. 
 multi sub prefix:<++>($a) is default { $a - 1 } 
 
 my $foo = 1; 
 say ++$foo; # OUTPUT: 0 

Control flow

if/else

You should be familiar with how if/else looks in JavaScript:

let diceRoll = Math.ceil(Math.random() * 6) + Math.ceil(Math.random() * 6); 
 if (diceRoll === 2) { 
     console.log('Snake eyes!'); 
 } else if (diceRoll === 16) { 
     console.log('Boxcars!'); 
 } else { 
     console.log(`Rolled ${diceRoll}.`); 
 } 

In Perl 6, if/else works largely the same, with a few key differences. One, parentheses are not required. Two, else if is written as elsif. Three, the if clause may be written after a statement:

my Int $dice-roll = ceiling rand * 12 + ceiling rand * 12; 
 if $dice-roll == 2 { 
     say 'Snake eyes!'; 
 } elsif $dice-roll == 16 { 
     say 'Boxcars!'; 
 } else { 
     say "Rolled $dice-roll."; 
 } 

Alternatively, though less efficient, this could be written to use if after statements:

my Int $dice-roll = ceiling rand * 12 + ceiling rand * 12; 
 say 'Snake eyes!'        if $dice-roll == 2; 
 say 'Boxcars!'           if $dice-roll == 16; 
 say "Rolled $dice-roll." if $dice-roll != 2 && $dice-roll != 16; 

Perl 6 also has when, which is like if, but if the condition given is true, no code past the when block within the block it's in is executed:

{ 
     when True { 
         say 'In when block!'; # OUTPUT: In when block! 
     } 
     say 'This will never be output!'; 
 } 

Additionally, Perl 6 has with, orwith, and without, which are like if, else if, and else respectively, but instead of checking whether their condition is true, they check if it's defined.

switch

Switch statements are a way of checking for equality between a given value and a list of values and run some code if one matches. case statements define each value to compare to. default, if included, acts as a fallback for when the given value matches no cases. After matching a case, break is typically used to prevent the code from the cases that follow the one matched from being executed, though rarely this is intentionally omitted.

const ranklist = [2, 3, 4, 5, 6, 7, 8, 9, 'Jack', 'Queen', 'King', 'Ace']; 
 const ranks    = Array.from(Array(3), () => ranklist[Math.floor(Math.random() * ranks.length)]); 
 let   score    = 0; 
 
 for (let rank of ranks) { 
     switch (rank) { 
         case 'Jack': 
         case 'Queen': 
         case 'King': 
             score += 10; 
             break; 
         case 'Ace'; 
             score += (score <= 11) ? 10 : 1; 
             break; 
         default: 
             score += rank; 
             break; 
     } 
 } 

In Perl 6, given can be used like switch statements. There is no equivalent to break since when blocks are most commonly used like case statements. One major difference between switch and given is that a value passed to a switch statement will only match cases that are exactly equal to the value; given values are smartmatched (~~) against the when values.

my     @ranklist = [2, 3, 4, 5, 6, 7, 8, 9, 'Jack', 'Queen', 'King', 'Ace']; 
 my     @ranks    = @ranklist.pick: 3; 
 my Int $score    = 0; 
 
 for @ranks -> $rank { 
     # The when blocks implicitly return the last statement they contain. 
     $score += do given $rank { 
         when 'Jack' | 'Queen' | 'King' { 10                      } 
         when 'Ace'                     { $score <= 11 ?? 10 !! 1 } 
         default                        { $_                      } 
     }; 
 } 

If there are multiple when blocks that match the value passed to given and you wish to run more than one of them, use proceed. succeed may be used to exit both the when block it's in and the given block, preventing any following statements from being executed:

given Int { 
     when Int     { say 'Int is Int';     proceed } 
     when Numeric { say 'Int is Numeric'; proceed } 
     when Any     { say 'Int is Any';     succeed } 
     when Mu      { say 'Int is Mu'               } # Won't output 
 } 
 
 # OUTPUT: 
 # Int is Int 
 # Int is Numeric 
 # Int is Any 

for, while, and do/while

There are three different types of for loops in JavaScript:

// C-style for loops 
 const letters = {}; 
 for (let ord = 0x61; ord <= 0x7A; ord++) { 
     let letter = String.fromCharCode(ord); 
     letters[letter] = letter.toUpperCase(); 
 } 
 
 // for..in loops (typically used on objects) 
 for (let letter in letters) { 
     console.log(letters[letter]); 
 } 
 # OUTPUT: 
 # A 
 # B 
 # C 
 # etc. 
 
 // for..of loops (typically used on arrays, maps, and sets) 
 for (let letter of Object.values(letters)) { 
     console.log(letter); 
 } 
 # OUTPUT: 
 # A 
 # B 
 # C 
 # etc. 

Perl 6 for loops most closely resemble for..of loops, since they work on anything as long as it's iterable. C-style loops are possible to write using loop, but this is discouraged since they're better written as for loops using ranges. Like if statements, for may follow a statement, with the current iteration being accessible using the $_ variable (known as "it"). Methods on $_ may be called without specifying the variable:

my Str %letters{Str}; 
 %letters{$_} = .uc for 'a'..'z'; 
 .say for %letters.values; 
 # OUTPUT: 
 # A 
 # B 
 # C 
 # etc. 

while loops work identically between JavaScript and Perl 6. Perl 6 also has until loops, where instead of iterating until the given condition is false, they iterate until the condition is true.

do/while loops are known as repeat/while loops in Perl 6. Likewise with while, repeat/until loops also exist and loop until the given condition is false.

To write infinite loops in Perl 6, use loop rather than for or while.

In JavaScript, continue is used to skip to the next iteration in a loop, and break is used to exit a loop early:

let primes = new Set(); 
 let i      = 2; 
 
 do { 
     let isPrime = true; 
     for (let prime of primes) { 
         if (i % prime == 0) { 
             isPrime = false; 
             break; 
         } 
     } 
     if (!isPrime) continue; 
     primes.add(i); 
 } while (++i < 20); 
 
 console.log(primes); # OUTPUT: Set { 2, 3, 5, 7, 11, 13, 17, 19 } 

In Perl 6, these are known as next and last respectively. There is also redo, which repeats the current iteration without evaluating the loop's condition again.

next/redo/last statements may be followed by a label defined before an outer loop to make the statement work on the loop the label refers to, rather than the loop the statement is in:

my %primes is SetHash; 
 my Int $i = 2; 
 
 OUTSIDE: 
 repeat { 
     next OUTSIDE if $i %% $_ for %primes.keys; 
     %primes{$i}++; 
 } while ++$i < 20; 
 
 say %primes; # OUTPUT: SetHash(11 13 17 19 2 3 5 7) 

do

do is not currently a feature in JavaScript, however a proposal has been made to add it to ECMAScript. do expressions evaluate a block and return the result:

constant VERSION        = v2.0.0; 
 constant VERSION_NUMBER = do { 
     my @digits = VERSION.Str.comb(/\d+/); 
     :16(sprintf "%02x%02x%04x", |@digits) 
 }; 
 say VERSION_NUMBER; # OUTPUT: 33554432 

Types

Creating types

In JavaScript, types are created by making a class (or a constructor in ES5 and earlier). If you've used TypeScript, you can define a type as a subset of other types like so:

type ID = string | number; 

In Perl 6, classes, roles, subsets, and enums are considered types. Creating classes and roles will be discussed in the OOP section of this article. Creating an ID subset can be done like so:

subset ID where Str | Int; 

See the documentation on subset and Junction for more information.

TypeScript enums may have numbers or strings as their values. Defining the values is optional; by default, the value of the first key is 0, the next key, 1, the next, 2, etc. For example, here is an enum that defines directions for extended ASCII arrow symbols (perhaps for a TUI game):

enum Direction ( 
     UP    = '↑', 
     DOWN  = '↓', 
     LEFT  = '←', 
     RIGHT = '→' 
 ); 

Enums in Perl 6 may have any type as their keys' values. Enum keys (and optionally, values) can be defined by writing enum, followed by the name of the enum, then the list of keys (and optionally, values), which can be done using < >, « », or ( ). ( ) must be used if you want to define values for the enum's keys. Here is the Direction enum as written in Perl 6:

enum Direction ( 
     UP    => '↑', 
     DOWN  => '↓', 
     LEFT  => '←', 
     RIGHT => '→' 
 ); 

See the documentation on enum for more information.

Using types

In TypeScript, you can define the type of variables. Attempting to assign a value that doesn't match the type of the variable will make the transpiler error out. This is done like so:

enum Name (Phoebe, Daniel, Joe); 
 let name: string = 'Phoebe'; 
 name = Phoebe; # Causes tsc to error out 
 
 let hobbies: [string] = ['origami', 'playing instruments', 'programming']; 
 
 let todo: Map<string, boolean> = new Map([ 
     ['clean the bathroom', false], 
     ['walk the dog', true], 
     ['wash the dishes', true] 
 ]); 
 
 let doJob: (job: string) => boolean = function (job: string): boolean { 
     todo.set(job, true); 
     return true; 
 }; 

In Perl 6, variables can be typed by placing the type between the declarator (my, our, etc.) and the variable name. Assigning a value that doesn't match the variable's type will throw either a compile-time or runtime error, depending on how the value is evaluated:

enum Name <Phoebe Daniel Joe>; 
 my Str $name = 'Phoebe'; 
 $name = Phoebe; # Throws a compile-time error 
 
 # The type here defines the type of the elements of the array. 
 my Str @hobbies = ['origami', 'playing instruments', 'programming']; 
 
 # The type between the declarator and variable defines the type of the values 
 # of the hash. 
 # The type in the curly braces defines the type of the keys of the hash. 
 my Bool %todo{Str} = ( 
     'clean the bathroom' => False, 
     'walk the dog'       => True, 
     'wash the dishes'    => True 
 ); 
 
 # The type here defines the return value of the routine. 
 my Bool &do-job = sub (Str $job --> Bool) { 
     %todo{$job} = True; 
 }; 

Comparing JavaScript and Perl 6 types

Here is a table of some JavaScript types and their equivalents in Perl 6:

JavaScript Perl 6
Object Mu, Any, Hash
Array List, Array, Seq
String Str
Number Int, Num, Rat
Boolean Bool
Map Map, Hash
Set Set, SetHash

Object is both a superclass of all types in JavaScript and a way to create a hash. In Perl 6, Mu is a superclass of all types, though usually you want to use Any instead, which is a subclass of Mu but also a superclass of nearly every type, with Junction being an exception. When using Object as a hash, Hash is what you want to use. One key difference between Object and Hash is that Object preserves the order of its keys; Hash does not by default.

There are three types equivalent to Array. Array is most similar to Array, since it acts as a mutable array. List is similar to Array, but is immutable. Seq is used to create lazy arrays.

String and Str are for the most part used identically.

There are several different types in Perl 6 equivalent to Number, but the three you'll most commonly see are Int, Num, and Rat. Int represents an integer. Num represents a floating-point number, making it the most similar to Number. Rat represents a fraction of two numbers, and is used when Num cannot provide precise enough values.

Boolean and Bool are for the most part used identically.

Map has both a mutable and an immutable equivalent in Perl 6. Map is the immutable one, and Hash is the mutable one. Don't get them mixed up! Like Map in JavaScript, Map and Hash can have any type of key or value, not just strings for keys.

Like Map, Set also has both a mutable and an immutable equivalent in Perl 6. Set is the immutable one, and SetHash is the mutable one.

Functions

TODO

# TBD

Object-oriented programming

TODO

# TBD

Asynchronous programming

TODO

# TBD

The networking API

Net

In Perl 6, there are two APIs for dealing with networking: IO::Socket::INET (for synchronous networking), and IO::Socket::Async (for asynchronous networking).

IO::Socket::INET currently only supports TCP connections. Its API resembles that of C's socket API. If you're familiar with that, then it won't take long to understand how to use it. For example, here's an echo server that closes the connection after receiving its first message:

my IO::Socket::INET $server .= new: 
     :localhost<localhost>, 
     :localport<8000>, 
     :listen; 
 
 my IO::Socket::INET $client .= new: :host<localhost>, :port<8000>; 
 $client.print: 'Hello, world!'; 
 
 my IO::Socket::INET $conn = $server.accept; 
 my Str $msg               = $conn.recv; 
 say $msg; # OUTPUT: Hello, world! 
 $conn.print($msg); 
 
 say $client.recv; # OUTPUT: Hello, world! 
 $conn.close; 
 $client.close; 
 $server.close; 

By default, IO::Socket::INET connections are IPv4 only. To use IPv6 instead, pass :family(PF_INET6) when constructing a server or a client.

In contrast, IO::Socket::Async supports both IPv4 and IPv6 without the need to specify which family you wish to use. It also supports UDP sockets. Here's how you would write the same echo server as above asynchronously (note that Supply.tap is multithreaded; if this is undesirable, use Supply.act instead:

my $supply = IO::Socket::Async.listen('localhost', 8000); 
 my $server = $supply.tap(-> $conn { 
     $conn.Supply.tap(-> $data { 
         say $data; # OUTPUT: Hello, world! 
         await $conn.print: $data; 
         $conn.close; 
     }) 
 }); 
 
 my $client = await IO::Socket::Async.connect('localhost', 8000); 
 $client.Supply.tap(-> $data { 
     say $data; # OUTPUT: Hello, world! 
     $client.close; 
     $server.close; 
 }); 
 
 await $client.print: 'Hello, world!'; 

The equivalent code in Node.js looks like this:

const net = require('net'); 
 
 const server = net.createServer(conn => { 
     conn.setEncoding('utf8'); 
     conn.on('data', data => { 
         console.log(data); # OUTPUT: Hello, world! 
         conn.write(data); 
         conn.end(); 
     }); 
 }).listen(8000, 'localhost'); 
 
 const client = net.createConnection(8000, 'localhost', () => { 
     client.setEncoding('utf8'); 
     client.on('data', data => { 
         console.log(data); # OUTPUT: Hello, world! 
         client.end(); 
         server.close(); 
     }); 
     client.write("Hello, world!"); 
 }); 

HTTP/HTTPS

Perl 6 doesn't natively support HTTP/HTTPS. However, CPAN packages such as Cro help fill the gap.

DNS

Perl 6 does not currently support the majority of the features that Node.js's DNS module implements. IO::Socket::INET and IO::Socket::Async can resolve hostnames, but features like resolving DNS records and reverse IP lookups are not implemented yet. There are some modules that are a work in progress, such as Net::DNS::BIND::Manage, that aim to improve DNS support.

Punycode

Punycode support is available through the Net::LibIDN, Net::LibIDN2, and IDNA::Punycode modules on CPAN.

The filesystem API

TODO

# TBD

Modules and packages

TODO

# TBD

13 Python to Perl 6 - nutshell

Learning Perl 6 from Python, in a nutshell

This page is an attempt to provide a way to learn Perl 6 for folks coming from a Python background. We discuss the equivalent syntax in Perl 6 for a number of Python constructs and idioms.

Basic syntax

Hello, world

Let's start with printing "Hello, world!". The put keyword in Perl 6 is the equivalent of print in Python. Like Python 2, parentheses are optional. A newline is added to the end of the line.

Python 2

print "Hello, world!" 

Python 3

print("Hello, world!") 

Perl 6

put "Hello, world!"

There is also the say keyword, which behaves similarly, but will call the gist method of its argument.

Perl 6

my $hello = "Hello, world!";
say $hello;  # also prints "Hello, world!"
             # same as: put $hello.gist

In Python, ' and " are interchangeable. In Perl 6, both may be used for quoting, but double quotes (") signify that interpolation should be performed. For instance, variables that start with a $, and expressions contained in curly braces are interpolated.

Perl 6

my $planet = 'earth';
say "Hello, $planet";   # Hello, earth
say 'Hello, $planet';   # Hello, $planet
say "Hello, planet number { 1 + 2 }"; # Hello, planet number 3

Statement separators

In Python, a newline signifies the end of a statement. There are a few exceptions: A backslash before a newline continues a statement across lines. Also if there is an unmatched opening parentheses, square bracket, or curly brace, the statement continues across lines, until the matching curly braces are closed.

In Perl 6, a semicolon signifies the end of a statement. The semicolon may be omitted if it is the last statement of a block. The semicolon may also be omitted if there is a closing curly brace followed by a newline.

Python

print 1 + 2 + \ 
     3 + 4 
 print ( 1 + 
     2 ) 

Perl 6

say 1 + 2 +
    3 + 4;
say 1 +
    2;

Blocks

In Python, indentation is used to indicate a block. Perl 6 uses curly braces.

Python

if 1 == 2: 
     print "Wait, what?" 
 else: 
     print "1 is not 2." 

Perl 6

if 1 == 2 {
    say "Wait, what?"
} else {
    say "1 is not 2."
}

Parentheses are optional in both languages for expressions in conditionals, as shown above.

Variables

In Python, variables are declared and initialized at the same time:

foo = 12 
 bar = 19 

In Perl 6, the my declarator declares a lexical variable. A variable can be initialized with =. This variable can either be declared first and later initialized or declared and initialized at once.

my $foo;       # declare
$foo = 12;     # initialize
my $bar = 19;  # both at once

Also, as you may have noticed, variables in Perl 6 usually start with sigils -- symbols indicating the type of their container. Variables starting with a $ hold scalars. Variables starting with an @ hold arrays, and variables starting with a % hold a hash (dict). Sigilless variables, declared with a \ but used without them, are bound to the value they are assigned to and are thus immutable.

Please note that, from now on, we are going to use sigilless variables in most examples just to illustrate the similarity with Python. That is technically correct, but in general we are going to use sigilless variables in places where their immutability (or independence of type, when they are used in signatures) is needed or needs to be highlighted.

Python

s = 10 
 l = [1, 2, 3] 
 d = { a : 12, b : 99 } 
 
 print s 
 print l[2] 
 print d['a'] 
 # 10, 2, 12 

Perl 6

my $s = 10;
my @l = 1, 2, 3;
my %d = a => 12, b => 99;
my \x = 99;

say $s;
say @l[1];
say %d<a>;  # or %d{'a'}
say x;
# 10, 2, 12, 99

Scope

In Python, functions and classes create a new scope, but no other block constructor (e.g. loops, conditionals) creates a scope. In Python 2, list comprehensions do not create a new scope, but in Python 3, they do.

In Perl 6, every block creates a lexical scope.

Python

if True: 
     x = 10 
 print x 
 # x is now 10 

Perl 6

if True { 
     my $x = 10 
 } 
 say $x 
 # error, $x is not declared in this scope 
my $x; 
 if True { 
     $x = 10 
 } 
 say $x 
 # ok, $x is 10 

Python

x = 10 
 for x in 1, 2, 3: 
    pass 
 print x 
 # x is 3 

Perl 6

my \x = 10;
for 1, 2, 3 -> \x {
    # do nothing
}
say x;
# x is 10

Lambdas in Python can be written as blocks or pointy blocks in Perl 6.

Python

l = lambda i: i + 12 

Perl 6

my $l = -> $i { $i + 12 } 

Another Perl 6 idiom for constructing lambdas is the Whatever star, *.

Perl 6

my $l = * + 12    # same as above

A * in an expression will become a placeholder for the argument, and transform the expression into a lambda at compile time. Each * in an expression is a separate positional parameter.

See the section below for more constructs regarding subroutines and blocks.

Another example (from the Python FAQ):

Python

squares = [] 
 for x in range(5): 
     squares.append(lambda: x ** 2) 
 print squares[2]() 
 print squares[4]() 
 # both 16 since there is only one x 

Perl 6

my \squares = [];
for ^5 -> \x {
    squares.append({ x² });
}
say squares[2]();
say squares[4]();
# 4, 16 since each loop iteration has a lexically scoped x,

Note that ^N is like range(N). Similarly, N..^M works like range(N, M) (a list from N to M - 1). The range N..M is a list from N to M. The ^ before or after the .. indicates that the beginning or ending endpoint of the list (or both) should be excluded.

Also, is a cute way of writing x ** 2 (which also works fine); the unicode superscript 2 squares a number. Many of the other unicode operators work as you would expect (exponents, fractions, π), but every unicode operator or symbol that can be used in Perl 6 has an ASCII equivalent.

Control flow

Python has for loops and while loops:

for i in 1, 2: 
     print i 
 j = 1 
 while j < 3: 
     print j 
     j += 1 

# 1, 2, 1, 2

Perl 6 also has for loops and while loops:

for 1, 2 -> $i {
    say $i
}
my $j = 1;
while $j < 3 {
    say $j;
    $j += 1
}

(Perl 6 also has a few more looping constructs: repeat...until, repeat...while, until, and loop.)

last leaves a loop in Perl 6, and is analogous to break in Python. continue in Python is next in Perl 6.

Python

for i in range(10): 
     if i == 3: 
         continue 
     if i == 5: 
         break 
     print i 

Perl 6

for ^10 -> $i {
    next if $i == 3;
    last if $i == 5;
    say $i;
}

Using if as a statement modifier (as above) is acceptable in Perl 6, even outside of a list comprehension.

The yield statement within a for loop in Python, which produces a generator, is like a gather/take construct in Perl 6. These both print 1, 2, 3.

Python

def count(): 
     for i in 1, 2, 3: 
         yield i 
 
 for c in count(): 
     print c 

Perl 6

sub count {
    gather {
        for 1, 2, 3 -> $i {
            take $i
        }
    }
}

for count() -> $c {
    say $c;
}

Lambdas, functions and subroutines

Declaring a function (subroutine) with def in Python is accomplished with sub in Perl 6.

def add(a, b): 
     return a + b 
 
 sub add(\a, \b) { 
     return a + b 
 } 

The return is optional; the value of the last expression is used as the return value:

sub add(\a, \b) { 
     a + b 
 } 
# using variables with sigils 
 sub add($a, $b) { 
     $a + $b 
 } 

Python 2 functions can be called with positional arguments or keyword arguments. These are determined by the caller. In Python 3, some arguments may be "keyword only". In Perl 6, positional and named arguments are determined by the signature of the routine.

Python

def speak(word, times): 
     for i in range(times): 
         print word 
 speak('hi', 2) 
 speak(word='hi', times=2) 

Perl 6

Positional parameters:

sub speak($word, $times) {
  say $word for ^$times
}
speak('hi', 2);

Named parameters start with a colon:

sub speak(:$word, :$times) {
  say $word for ^$times
}
speak(word => 'hi', times => 2);
speak(:word<hi>, :times<2>);      # Alternative, more idiomatic

Perl 6 supports multiple dispatch, so several signatures could be made available by declaring a routine as a multi.

multi sub speak($word, $times) {
  say $word for ^$times
}
multi sub speak(:$word, :$times) {
    speak($word, $times);
}
speak('hi', 2);
speak(:word<hi>, :times<2>);

Named parameters can be sent using a variety of formats:

sub hello {...};
# all the same
hello(name => 'world'); # fat arrow syntax
hello(:name('world'));  # pair constructor
hello :name<world>;     # <> quotes words and makes a list
my $name = 'world';
hello(:$name);          # lexical var with the same name

Creating an anonymous function can be done with sub, with a block or with a pointy block.

Python

square = lambda x: x ** 2 

Perl 6

my $square = sub ($x) { $x ** 2 };  # anonymous sub
my $square = -> $x { $x ** 2 };     # pointy block
my $square = { $^x ** 2 };          # placeholder variable
my $square = { $_ ** 2 };           # topic variable

Placeholder variables are lexicographically ordered to form positional parameters. Thus these are the same:

my $power = { $^x ** $^y };
my $power = -> $x, $y { $x ** $y };

List comprehensions

Postfix statement modifiers and blocks can be combined to easily create list comprehensions in Perl 6.

Python

print [ i * 2 for i in 3, 9 ]                      # OUTPUT: «[6, 18]␤» 

Perl 6

say ( $_ * 2 for 3, 9 );                           # OUTPUT: «(6 18)␤»
say ( { $^i * 2 } for 3, 9 );                      # OUTPUT: «(6 18)␤»
say ( -> \i { i * 2 } for 3, 9 );                  # OUTPUT: «(6 18)␤»

Conditionals can be applied, but the if keyword comes first, unlike in Python where the if comes second.

print [ x * 2 for x in 1, 2, 3 if x > 1 ]          # OUTPUT: «[4, 6]␤» 

vs

say ( $_ * 2 if $_ > 1 for 1, 2, 3 );              # OUTPUT: «(4 6)␤»

For nested loops, the cross product operator X will help:

print [ i + j for i in 3,9 for j in 2,10 ]         # OUTPUT: «[5, 13, 11, 19]␤» 

becomes either of these:

say ( { $_[0] + $_[1] } for (3,9) X (2,10) );      # OUTPUT: «(5 13 11 19)␤»
say ( -> (\i, \j) { i + j } for (3,9) X (2,10) );  # OUTPUT: «(5 13 11 19)␤»
say ( -> ($i, $j) { $i + $j } for (3,9) X (2,10) );# OUTPUT: «(5 13 11 19)␤»
say ( { $^a[0] + $^a[1] } for (3,9) X (2,10) );    # OUTPUT: «(5 13 11 19)␤»

Using map (which is just like Python's map) and grep (which is like Python's filter) is an alternative.

Classes and objects

Here's an example from the Python docs. First let's go over "instance variables" which are known as attributes in Perl 6:

Python:

class Dog: 
     def __init__(self, name): 
         self.name = name 

Perl 6:

class Dog {
    has $.name;
}

For each created class, Perl 6 provides the constructor method new by default which takes named arguments.

Python:

d = Dog('Fido') 
 e = Dog('Buddy') 
 print d.name 
 print e.name 

Perl 6

my $d = Dog.new(:name<Fido>); # or: Dog.new(name => 'Fido') 
 my $e = Dog.new(:name<Buddy>); 
 say $d.name; 
 say $e.name; 

Class attributes in Perl 6 can be declared in a few ways. One way is to just declare a lexical variable and a method for accessing it.

Python:

class Dog: 
     kind = 'canine'                # class attribute 
     def __init__(self, name): 
         self.name = name           # instance attribute 
 d = Dog('Fido') 
 e = Dog('Buddy') 
 print d.kind 
 print e.kind 
 print d.name 
 print e.name 

Perl 6:

class Dog {
    my $kind = 'canine';           # class attribute
    method kind { $kind }
    has $.name;                    # instance attribute
}

my $d = Dog.new(:name<Fido>);
my $e = Dog.new(:name<Buddy>);
say $d.kind;
say $e.kind;
say $d.name;
say $e.name;

In order to mutate attributes in Perl 6, you must use the is rw trait on the attributes:

Python:

class Dog: 
     def __init__(self, name): 
         self.name = name 
 d = Dog() 
 d.name = 'rover' 

Perl 6:

class Dog {
    has $.name is rw;
}
my $d = Dog.new;
$d.name = 'rover';

Inheritance is done using is:

Python

class Animal: 
     def jump(self): 
         print ("I am jumping") 
 
 class Dog(Animal): 
     pass 
 
 d = Dog() 
 d.jump() 

Perl 6

class Animal {
    method jump {
        say "I am jumping"
    }
}

class Dog is Animal {
}

my $d = Dog.new;
$d.jump;

Multiple inheritance is possible by using the is trait as many times as required. Alternatively, it can be used in conjunction with the also keyword.

Python

class Dog(Animal, Friend, Pet): 
     pass 

Perl 6

class Animal {}; class Friend {}; class Pet {};
...;
class Dog is Animal is Friend is Pet {};

or

class Animal {}; class Friend {}; class Pet {};
...;
class Dog is Animal {
    also is Friend;
    also is Pet;
    ...
}

Decorators

Decorators in Python are a way of wrapping a function in another one. In Perl 6, this is done with wrap.

Python

def greeter(f): 
     def new(): 
         print 'hello' 
         f() 
     return new 
 
 @greeter 
 def world(): 
     print 'world' 
 
 world(); 

Perl 6

sub world {
    say 'world'
}

&world.wrap(sub () {
    say 'hello';
    callsame;
});

world;

An alternative would be to use a trait:

# declare the trait 'greeter'
multi sub trait_mod:<is>(Routine $r, :$greeter) {
    $r.wrap(sub {
        say 'hello';
        callsame;
    })
}

sub world is greeter {
    say 'world';
}

world;

Context managers

Context managers in Python declare actions that happen when entering or exiting a scope.

Here's a Python context manager that prints the strings 'hello', 'world', and 'bye'.

class hello: 
     def __exit__(self, type, value, traceback): 
         print 'bye' 
     def __enter__(self): 
         print 'hello' 
 
 with hello(): 
     print 'world' 

For "enter" and "exit" events, passing a block as an argument would be one option:

sub hello(Block $b) {
    say 'hello';
    $b();
    say 'bye';
}

hello {
    say 'world';
}

A related idea is 'Phasers' which may be set up to run on entering or leaving a block.

{
    LEAVE say 'bye';
    ENTER say 'hello';
    say 'world';
}

input

In Python 3, the input keyword is used to prompt the user. This keyword can be provided with an optional argument which is written to standard output without a trailing newline:

user_input = input("Say hi → ") 
 print(user_input) 

When prompted, you can enter Hi or any other string, which will be stored in the user_input variable. This is similar to prompt in Perl 6:

my $user_input = prompt("Say hi → ");
say $user_input; # OUTPUT: whatever you entered.

14 Ruby to Perl 6 - nutshell

Learning Perl 6 from Ruby, in a nutshell: what do I already know?

This page attempts to index the high-level differences in syntax and semantics between Ruby and Perl 6. Whatever works in Ruby and must be written differently in Perl 6 should be listed here (whereas many Perl 6 features and idioms won't be).

Hence this should not be mistaken for a beginner tutorial or overview of Perl 6; it is intended as a technical reference for Perl 6 learners with a strong Ruby background.

Basic syntax

Statement ending semicolons

Ruby detects the end of most statements with a newline (and a few exceptions), as long as the expression is complete. It is common break up a long expression by leaving an operator dangling at the end of a line to ensure that the parsing will continue:

foo +     # In Ruby a trailing operator means parsing should continue 
   bar + 
   baz 

In Perl 6 you must explicitly terminate statements with a ;, which allows for better feedback and more flexibility in breaking up long lines. Two exceptions not needing an explicit ; are the last statement in a block, and after the closing curly brace of the block itself (if there is nothing else on that line):

my $x;
...;
if 5 < $x < 10 {
  say "Yep!";
  $x = 17         # No ; required before closing }
}                 # No ; required after closing } because of the newline
say "Done!";      # The ; is not required here if nothing follows

Whitespace

Ruby allows a surprising amount of flexibility in the use of whitespace, even with strict mode and warnings turned on:

# unidiomatic but valid Ruby 
 puts"Hello "+ 
 (people [ i] 
     . name 
     ) . upcase+"!"if$greeted[i]<1 

Perl 6 also endorses programmer freedom and creativity, but balanced syntactic flexibility against its design goal of having a consistent, deterministic, extensible grammar that supports single-pass parsing and helpful error messages, integrates features like custom operators cleanly, and doesn't lead programmers to accidentally misstate their intent. Also, the practice of "code golf" is slightly de-emphasized; Perl 6 is designed to be more concise in concepts than in keystrokes.

As a result, there are various places in the syntax where whitespace is optional in Ruby, but is either mandatory or forbidden in Perl 6. Many of those restrictions are unlikely to concern much real-life Perl code (e.g. whitespace being disallowed between an array variable and its square brackets), but there are a few that will unfortunately conflict with some Ruby hackers' habitual coding styles:

if(a < 0); ...; end         # OK in Ruby 
my $a; ...; 
 if ($a < 0) { ... }         # Perl 6 
 if $a < 0 { ... }           # Perl 6, more idiomatic 
while(x > 5); ...; end      # OK in Ruby 
my $x; ...; 
 while ($x > 5) { ... }      # Perl 6 
 while $x > 5 { ... }        # Perl 6, more idiomatic 

. Method calls, .send

Method call syntax uses a dot just like Ruby:

person.name    # Ruby 
my $person; ...; 
 $person.name   # Perl 6 

To call a method whose name is not known until runtime:

object.send(methodname, args);  # Ruby 
my $object; my Str $methodname; my @args; ...; 
 $object."$methodname"(@args);   # Perl 6 

If you leave out the quotes, then Perl 6 expects $methodname to contain a Method object, rather than the simple string name of the method.

Variables, sigils, scope, and common types

In Ruby, variables use sigils primarily to indicate scope. $ for global scope, @@ for class scope, @ for instance scope, and no sigil for local variables (including parameters). The & sigil is also used to indicate method references. Symbols are prefixed with :, but they are not variable and so not really sigils.

In Perl 6 sigils are primarily used to indicate a role that the contained value implements, indicating the type (or at least the interface) of the value. The sigils are invariant, no matter how the variable is being used - you can think of them as part of the variable's name.

The scope of a variable is instead indicated by the declaration itself (my, has, our, etc).

Variable scope

For local variables, Ruby uses implicit variable declaration upon assignment and limited to the current block. In Ruby the content of an if or while built-in construct is not a block or scope.

Perl 6 uses explicit scope indicators, and never creates variables implicitly. Every place you see { ... } is a scope, including the body of a conditional or loop. The commonly used scope declarations:

foo = 7        # Ruby, variable scope is defined by first assignment and 
                # extends to the end of the current block 
my  $foo = 7;   # Perl 6, lexical scoped to the current block 
 our $foo = 7;   # Perl 6, package scoped 
 has $!foo = 7;  # Perl 6, instance scoped (attribute) 

$ Scalar

The $ sigil is always used with "scalar" variables (e.g. $name). These are single-value containers.

This is the most general-purpose variable type, with no restrictions on its contents. Note that you can still address/use its contents, like $x[1], $x{"foo"}, and $f("foo").

@ Array

The @ sigil is always used with "array" variables (e.g. @months, @months[2], @months[2, 4] for an array slice). Variables using the @ sigil can only contain things that do the Positional role, indicating positional indexing and slicing capabilities.

% Hash

The % sigil is always used with "hash" variables (e.g. %calories, %calories<apple>, %calories<pear plum>). Variables using the % sigil can only contain things that do the Associative role.

Ruby uses square brackets to access values for both Arrays and Hashes. Perl 6 uses curly braces for hashes instead. The angle brackets version is available which always autoquotes its contents (strings without quotes):

Adverbs can be used to control the type of slice.

& Sub

The & sigil is used very similarly to Ruby's & to refer to the function object of a named subroutine/operator without invoking it, i.e. to use the name as a "noun" instead of a "verb". Variables using the & sigil can only contain things that do the Callable role.

add = -> n, m { n + m } # Ruby lambda for an addition function 
 add.(2, 3)              # => 5, Ruby invocation of a lambda 
 add.call(2, 3)          # => 5, Ruby invocation of a lambda 
my &add = -> $n, $m { $n + $m }; # Perl 6 addition function 
 &add(2, 3);                      # => 5, you can keep the sigil 
 add(2, 3);                       # => 5, and it works without it 
foo_method = &foo;     # Ruby 
sub foo { ... }; 
 my &foo_method = &foo; # Perl 6 
some_func(&say) # Ruby pass a function reference 
sub some_func { ... }; 
 some_func(&say) # Perl 6 passes function references the same way 

Often in Ruby we pass a block as the last parameter, which is especially used for DSLs. This can be an implicit parameter called by yield, or an explicit block prefixed with &. In Perl 6 a Callable parameter is always listed and called by the variable name (instead of yield), and there are a variety of ways of invoking the function.

# Ruby, declare a method and call the implicit block argument 
 def f 
   yield 2 
 end 
 
 # Ruby, invoke f, pass it a block with 1 argument 
 f do |n| 
   puts "Hi #{n}" 
 end 
# Perl 6, declare a method with an explicit block argument 
 sub f(&g:($)) { 
   g(2) 
 } 
 
 # Perl 6, invoke f, pass it a block with 1 argument 
 # There are several other ways to do this 
 f(-> $n { say "Hi {$n}" }); # Explicit argument 
 f -> $n { say "Hi {$n}" };  # Explicit argument, no parenthesis 
 
 # Additionally, if 'f' is a method on instance 'obj' you can use ':' 
 # instead of parenthesis 
 my $obj; ...; 
 $obj.f(-> $n { say "Hi {$n}" });  # Explicit argument 
 $obj.f: -> $n { say "Hi {$n}" };  # Explicit argument, no parenthesis 

* Slurpy params / argument expansion

In Ruby you can declare an argument to slurp the remainder of the passed parameters into an array using a * prefix. It works similarly in Perl 6:

def foo(*args); puts "I got #{args.length} args!"; end # Ruby 
sub foo(*@args) { say "I got #{@args.elems} args!" }   # Perl 6 

The Perl 6 version above is slightly different in that when it slurps in the arguments into @args, one level of nesting, if any, is automatically removed:

sub foo(*@args) { say @args.perl } 
 foo([1, [2, 3], 4], 5, [6, 7]);   # [1, [2, 3], 4, 5, 6, 7] 

To preserve the structure of the arguments, you can use **:

sub foo(**@args) { say @args.perl } 
 foo([1, [2, 3], 4], 5, [6, 7]);  # [[1, [2, 3], 4], 5, [6, 7]] 

You might want to expand an array into a set of arguments. In Perl 6 this is done using a Slip |:

args = %w(a b c)         # Ruby 
 foo(*args) 
sub foo($q, $r, $s) { ... }; 
 my @args = <a b c>;       # Perl 6 
 foo(|@args); 

Perl 6 has many more advanced ways of passing parameters and receiving arguments, see Signatures and Captures.

Twigils

Perl 6 additionally uses "twigils", which are further indicators about the variable and go between the sigil and the rest of the variable name. Examples:

Variable Description
$foo Scalar with no twigil
$!foo Private instance variable
$.foo Instance variable accessor
$*foo Dynamically scoped variable
$^foo A positional (placeholder) parameter to a block
$:foo A named (placeholder) parameter to a block
$=foo POD (documentation) variables
$?FILE Current source filename. The ? twigil indicates a compile-time value
$~foo Sublanguage seen by parser, uncommon

Though each of these examples use the $ sigil, most could use @ (Positional) or % (Associative).

: Symbols

Perl 6 generally uses strings in the places where Ruby uses symbols. A primary example of this is in hash keys.

address[:joe][:street] # Typical Ruby nested hash with symbol keys 
my %address; ...; 
 %address<joe><street>  # Typical Perl 6 nested hash with string keys 

Perl 6 has colon-pair syntax, which can sometimes look like Ruby symbols.

:age            # Ruby symbol 
# All of these are equivalent for Perl 6 
 :age            ;# Perl 6 pair with implicit True value 
 :age(True)      ;# Perl 6 pair with explicit True value 
 age => True     ;# Perl 6 pair using arrow notation 
 "age" => True   ;# Perl 6 pair using arrow notation and explicit quotes 

You could probably get away with using a colon-pair without an explicit value and pretend that it is a Ruby symbol a lot of the time, but it isn't idiomatic Perl 6.

Operators

Many operators have a similar usage in both Ruby and Perl 6:

You may use $x++ instead of x += 1 as a shortcut for incrementing a variable. This can be used as a pre-increment ++$x (increment, return new value) or post-increment $x++ (increment, return old value).

You may use $x-- instead of x -= 1 as a shortcut for decrementing a variable. This can be used as a pre-decrement --$x (decrement, return new value) or post-decrement $x-- (decrement, return old value).

== != < > <= >= Comparisons

Comparisons in Perl 6 are separated between numeric and string to avoid common errors.

For example, using == tries to convert the values to numbers, and eq tries to convert the values to strings.

<=> Three-way comparisons

In Ruby, the <=> operator returns -1, 0, or 1. In Perl 6, they return Order::Less, Order::Same, or Order::More.

<=> forces numeric context for the comparison.

leg ("Less, Equal, or Greater?") forces string context for the comparison.

cmp does either <=> or leg, depending on the existing type of its arguments.

~~ Smartmatch operator

This is a very common matching operator which is similar to === in Ruby. Here are some examples:

my $foo; ...;
say "match!" if $foo ~~ /bar/;       # Regex match
say "match!" if $foo ~~ "bar";       # String match
say "match!" if $foo ~~ :(Int, Str); # Signature match (destructure)

An equivalent in Ruby would be

$foo = 'bar'; 
 puts "match 1!" if /bar/ === $foo;       # Regex match 
 puts "match 2!" if $foo === "bar";       # String match 
 puts "match 3!" if String === $foo;      # Class match 

Please note that, in this case, === is not symmetric; in the first and last case, the variable has to be in the right-hand side. There is no equivalent to the signature class in Ruby, either.

See S03/Smartmatching for more information on this feature.

& | ^ Numeric bitwise ops

& | ^ Boolean ops

In Perl 6, these single-character ops have been removed, and replaced by two-character ops which coerce their arguments to the needed context.

# Infix ops (two arguments; one on each side of the op) 
 +&  +|  +^  And Or Xor: Numeric 
 ~&  ~|  ~^  And Or Xor: String 
 ?&  ?|  ?^  And Or Xor: Boolean 
 
 # Prefix ops (one argument, after the op) 
 +^  Not: Numeric 
 ~^  Not: String 
 ?^  Not: Boolean (same as the ! op) 

&. Conditional chaining operator

Ruby uses the &. operator to chain methods without raising an error if one invocation returns nil. In Perl 6 use .? for the same purpose.

<< >> Numeric shift left, right ops, shovel operator

Replaced by +< and +> .

puts 42 << 3  # Ruby 
say  42 +< 3; # Perl 6 

Note that Ruby often uses the << operator as the "shovel operator", which is similar to .push. This usage isn't common in Perl 6.

=> and : Key-value separators

In Ruby, => is used in the context of key/value pairs for Hash literal declaration and parameter passing. : is used as a shorthand when the left side is a symbol.

In Perl 6, => is the Pair operator, which is quite different in principle, but works the same in many situations.

If you are using => in a hash literal, then the usage is very similar:

hash = { "AAA" => 1, "BBB" => 2 }  # Ruby, though symbol keys are more common 
my %hash = ( AAA => 1, BBB => 2 ); # Perl 6, uses ()'s though {} usually work 

? : Ternary operator

In Perl 6, this is spelled with two question marks instead of one question mark, and two exclamation points instead of one colon. This deviation from the common ternary operators disambiguates several situations and makes the false-case stand out more.

result     = (  score > 60 )  ? 'Pass'  : 'Fail'; # Ruby 
my $score; ...; 
 my $result = ( $score > 60 ) ?? 'Pass' !! 'Fail'; # Perl 6 

+ String concatenation

Replaced by the tilde. Mnemonic: think of "stitching" together the two strings with needle and thread.

$food = 'grape' + 'fruit'  # Ruby 
my $food = 'grape' ~ 'fruit'; # Perl 6 

String interpolation

In Ruby, "#{foo}s" deliminates a block embedded in a double-quoted string. In Perl 6 drop the # prefix: "{$foo}s". As in Ruby, you can place arbitrary code into the embedded block and it will be rendered in string context.

Simple variables can be interpolated into a double-quoted string without using the block syntax:

# Ruby 
 name = "Bob" 
 puts "Hello! My name is #{name}!" 
# Perl 6 
 my $name = "Bob"; 
 say "Hello! My name is $name!" 

The result of an embedded block in Ruby uses .to_s to get string context. Perl 6 uses .Str, or .gist for the same affect.

Compound statements

Conditionals

if elsif else unless

This work very similarly between Ruby and Perl 6, but Perl 6 uses { } to clearly delineate the blocks.

# Ruby 
 if x > 5 
     puts "Bigger!" 
 elsif x == 5 
     puts "The same!" 
 else 
     puts "Smaller!" 
 end 
# Perl 6 
 my $x; ...; 
 if $x > 5 { 
     say "Bigger!" 
 } elsif $x == 5 { 
     say "The same!" 
 } else { 
     say "Smaller!" 
 } 

Binding the conditional expression to a variable is a little different:

if x = dostuff(); ...; end   # Ruby 
sub dostuff() {...}; 
 if dostuff() -> $x {...}     # Perl 6, block-assignment uses arrow 

The unless conditional only allows for a single block in Perl 6; it does not allow for an elsif or else clause.

case-when

The Perl 6 given-when construct is like a chain of if-elsif-else statements or like the case-when construct in Ruby. A big difference is that Ruby uses the == comparison for each condition, but Perl 6 uses the more general smartmatch ~~ operator.

It has the general structure:

given EXPR { 
     when EXPR { ... } 
     when EXPR { ... } 
     default { ... } 
 } 

In its simplest form, the construct is as follows:

my $value; ...;
given $value {
    when "a match" {
        # do-something();
    }
    when "another match" {
        # do-something-else();
    }
    default {
        # do-default-thing();
    }
}

This is simple in the sense that a scalar value is matched in the when statements. More generally, the matches are actually smartmatches on the input value such that lookups using more complex entities such as regexps can be used instead of scalar values.

Loops

while until

Mostly unchanged; parentheses around the conditions are optional, but if used, must not immediately follow the keyword, or it will be taken as a function call instead. Binding the conditional expression to a variable is also a little different:

while x = dostuff(); ...; end    # Ruby 
sub dostuff {...}; ...; 
 while dostuff() -> $x {...}      # Perl 6 

for .each

for loops are rare in Ruby, instead we typically use .each on an enumerable. The most direct translation to Perl 6 would be to use .map for both .each and .map, but we typically use a for loop directly.

# Ruby for loop 
 for n in 0..5 
     puts "n: #{n}" 
 end 
 
 # Ruby, more common usage of .each 
 (0..5).each do |n| 
     puts "n: #{n}" 
 end 
# Perl 6 
 for 0..5 -> $n { 
     say "n: $n"; 
 } 
 
 # Perl 6, misusing .map 
 (0..5).map: -> $n { 
     say "n: $n"; 
 } 

In Ruby, the iteration variable for .each is a copy of the list element, and modifying it does nothing to the original list. Note that it is a copy of the REFERENCE, so you can still change the values to which it refers.

In Perl 6, that alias is read-only (for safety) and thus behaves exactly like Ruby, unless you change -> to <->.

cars.each { |car| ... }    # Ruby; read-only reference 
my @cars; ...; 
 for @cars  -> $car   {...} # Perl 6; read-only 
 for @cars <-> $car   {...} # Perl 6; read-write 

Flow interruption statements

Same as Ruby:

This is last in Perl 6.

Regular expressions ( regex / regexp )

Regular expressions in Perl 6 are significantly different, and more powerful, than in Ruby. By default whitespace is ignored and all characters must be escaped, for example. Regexes can be easily combined and declared in ways to build efficient grammars.

There are many powerful features of Perl 6 regexes, especially defining entire grammars using the same syntax. See Regexes and Grammars.

.match method and =~ operator

In Ruby, regex matches can be done against a variable using the =~ regexp match operator or the .match method. In Perl 6, the ~~ smartmatch op is used instead, or the .match method.

next if line   =~ /static/   # Ruby 
 next if line  !~  /dynamic/; # Ruby 
 next if line.match(/static/) # Ruby 
my $line; ...; 
 next if $line  ~~ /static/;    # Perl 6 
 next if $line !~~ /dynamic/ ;  # Perl 6 
 next if $line.match(/static/); # Perl 6 

Alternately, the .match and .subst methods can be used. Note that .subst is non-mutating. See S05/Substitution.

.sub and .sub!

In Perl 6 you typically use the s/// operator to do regex substitution.

fixed = line.sub(/foo/, 'bar')        # Ruby, non-mutating 
my $line; ...; 
 my $fixed = $line.subst(/foo/, 'bar') # Perl 6, non-mutating 
line.sub!(/foo/, 'bar')   # Ruby, mutating 
my $line; ...; 
 $line ~~ s/foo/bar/;      # Perl 6, mutating 

Regex options

Move any options from the end of the regex to the beginning. This may require you to add the optional m on a plain match like /abc/.

next if $line =~    /static/i # Ruby 
my $line; ...; 
 next if $line ~~ m:i/static/; # Perl 6 

Whitespace is ignored, most things must be quoted

In order to aid in readability and reusability, whitespace is not significant in Perl 6 regexes.

/this is a test/ # Ruby, boring string 
 /this.*/         # Ruby, possibly interesting string 
/ this " " is " " a " " test /; # Perl 6, each space is quoted 
 / "this is a test" /;           # Perl 6, quoting the whole string 
 / this .* /;                    # Perl 6, possibly interesting string 

Special matchers generally fall under the <> syntax

There are many cases of special matching syntax that Perl 6 regexes support. They won't all be listed here, but often instead of being surrounded by (), the assertions will be surrounded by <>.

For character classes, this means that:

For look-around assertions:

(Unrelated to <> syntax, the "lookaround" /foo\Kbar/ becomes /foo <( bar )> /

Longest token matching (LTM) displaces alternation

In Perl 6 regexes, | does Longest Token Match (LTM), which decides which alternation wins an ambiguous match based off of a set of rules, rather than about which was written first in the regex.

To avoid the new logic, change any | in your Ruby regex to a ||.

File-related operations

Reading the lines of a text file into an array

Both Ruby and Perl 6 make it easy to read all of the lines in a file into a single variable, and in both cases each line has the newline removed.

lines = File.readlines("file")   # Ruby 
my @lines = "file".IO.lines;     # Perl 6, create an IO object from a string 

Iterating over the lines of a text file

Reading the entire file into memory isn't recommended. The .lines method in Perl 6 returns a lazy sequence, but assigning to an array forces the file to be read. It is better to iterate over the results:

# Ruby 
 File.foreach("file") do |line| 
     puts line 
 end 
# Perl 6 
 for "file".IO.lines -> $line { 
     say $line 
 } 

Object orientation

Basic classes, methods, attributes

Classes are defined similarly between Ruby and Perl 6, using the class keyword. Ruby uses def for methods, whereas Perl 6 uses method.

# Ruby 
 class Foo 
     def greet(name) 
         puts "Hi #{name}!" 
     end 
 end 
# Perl 6 
 class Foo { 
     method greet($name) { 
         say "Hi $name!" 
     } 
 } 

In Ruby you can use an attribute without declaring it beforehand, and you can tell it is an attribute because of the @ sigil. You can also easily create accessors using attr_accessor and its variants. In Perl 6 you use a has declaration and a variety of sigils. You can use the ! twigil for private attributes or . to create an accessor.

# Ruby 
 class Person 
     attr_accessor :age    # Declare .age as an accessor method for @age 
     def initialize 
         @name = 'default' # Assign default value to private instance var 
     end 
 end 
# Perl 6 
 class Person { 
     has $.age;              # Declare $!age and accessor methods 
     has $!name = 'default'; # Assign default value to private instance var 
 } 

Creating a new instance of the class uses the .new method. In Ruby you must manually assign instance variables as needed inside initialize. In Perl 6 you get a default constructor that accepts key/value pairs of accessor attributes, and can do further setup in the BUILD method. Like with Ruby, you can override new itself for more advanced functionality, but this is rare.

# Ruby 
 class Person 
     attr_accessor :name, :age 
     def initialize(attrs) 
         @name = attrs[:name] || 'Jill' 
         @age  = attrs[:age] || 42 
         @birth_year = Time.now.year - @age 
     end 
 end 
 p = Person.new( name: 'Jack', age: 23 ) 
# Perl 6 
 class Person { 
     has $.name = 'Jill'; 
     has $.age  = 42; 
     has $!birth_year; 
     method BUILD { 
         $!birth_year = now.Date.year - $.age; 
     } 
 } 
 my $p = Person.new( name => 'Jack', age => 23 ) 

Private methods

Private methods in Perl 6 are declared with a ! prefixed in their name, and are invoked with a ! instead of a ..

# Ruby 
 class Foo 
     def visible 
         puts "I can be seen!" 
         hidden 
     end 
 
     private 
     def hidden 
         puts "I cannot easily be called!" 
     end 
 end 
# Perl 6 
 class Foo { 
     method visible { 
         say "I can be seen!"; 
         self!hidden; 
     } 
 
     method !hidden { 
         say "I cannot easily be called!"; 
     } 
 } 

An important note is that in Ruby child objects can see parent private methods (so they are more like "protected" methods in other languages). In Perl 6 child objects cannot call parent private methods.

Going meta

Here are a few examples of meta-programming. Note that Perl 6 separates the meta-methods from the regular methods with a caret.

# Ruby 
 person = Person.new 
 person.class 
 person.methods 
 person.instance_variables 
# Perl 6 
 class Person {}; 
 ... 
 my $person = Person.new; 
 $person.^name;             # Perl 6, returns Person (class) 
 $person.^methods;          # Perl 6, using .^ syntax to access meta-methods 
 $person.^attributes; 

Like Ruby, in Perl 6, everything is an object, but not all operations are equivalent to .send. Many operators are global functions that use typed multi-dispatch (function signatures with types) to decide which implementation to use.

5.send(:+, 3)    # => 8, Ruby 
&[+](5, 3)       # => 8, Perl 6, reference to infix addition operator 
 &[+].^candidates # Perl 6, lists all signatures for the + operator 

See Meta-Object Protocol for lots of further details.

Environment variables

Perl module library path

In Ruby, one of the environment variables to specify extra search paths for modules is RUBYLIB.

$ RUBYLIB="/some/module/lib" ruby program.rb 

In Perl 6 this is similar, you merely needs to change the name. As you probably guessed, you just need to use PERL6LIB:

$ PERL6LIB="/some/module/lib" perl6 program.p6 

As with Ruby, if you don't specify PERL6LIB, you need to specify the library path within the program via the use lib pragma:

# Ruby and Perl 6 
 use lib '/some/module/lib'; 

Misc.

Importing specific functions from a module

In Ruby there is no built-in way to selectively import/export methods from a module.

In Perl 6 you specify the functions which are to be exported by using the is export role on the relevant subs and all subs with this role are then exported. Hence, the following module Bar exports the subs foo and bar but not baz:

unit module Bar; # remainder of the file is in module Bar { ... } 
 sub foo($a) is export { say "foo $a" } 
 sub bar($b) is export { say "bar $b" } 
 sub baz($z) { say "baz $z" } 

To use this module, simply use Bar and the functions foo and bar will be available:

use Bar; 
 foo(1);    #=> "foo 1" 
 bar(2);    #=> "bar 2" 

If you try to use baz an "Undeclared routine" error is raised at compile time.

Some modules allow for selectively importing functions, which would look like:

use Bar <foo>; # Import only foo 
 foo(1);        #=> "foo 1" 
 bar(2);        # Error! 

OptionParser, parsing command-line flags

Command line argument switch parsing in Perl 6 is done by the parameter list of the MAIN subroutine.

# Ruby 
 require 'optparse' 
 options = {} 
 OptionParser.new do |opts| 
     opts.banner = 'Usage: example.rb --length=abc' 
     opts.on("--length", "Set the file") do |length| 
         raise "Length must be > 0" unless length.to_i > 0 
         options[:length] = length 
     end 
     opts.on("--filename", "Set the file") do |filename| 
         options[:file] = filename 
     end 
     opts.on("--verbose", "Increase verbosity") do |verbose| 
         options[:verbose] = true 
     end 
 end.parse! 
 
 puts options[:length] 
 puts options[:filename] 
 puts 'Verbosity ', (options[:verbose] ? 'on' : 'off') 
ruby example.rb --filename=foo --length=42 --verbose 
     42 
     foo 
     Verbosity on 
 
 ruby example.rb --length=abc 
     Length must be > 0 
# Perl 6 
 sub MAIN ( Int :$length where * > 0, :$filename = 'file.dat', Bool :$verbose ) { 
     say $length; 
     say $filename; 
     say 'Verbosity ', ($verbose ?? 'on' !! 'off'); 
 } 
perl6 example.p6 --file=foo --length=42 --verbose 
     42 
     foo 
     Verbosity on 
 perl6 example.p6 --length=abc 
     Usage: 
       example.p6 [--length=<Int>] [--file=<Any>] [--verbose] 

Note that Perl 6 auto-generates a full usage message on error in command-line parsing.

RubyGems, external libraries

See https://modules.perl6.org/, where a growing number of Perl 6 libraries are available along with the tools to manage them.

If the module that you were using has not been converted to Perl 6, and no alternative is listed in this document, then its use under Perl 6 may not have been addressed yet.

You can experiment with Inline::Ruby to call existing Ruby code from your Perl 6 programs. This uses an embedded instance of the ruby interpreter to run Ruby code called from your Perl 6 script. Note that this is an EXPERIMENTAL library. You can similarly call other language's libraries with Inline::Perl5, Inline::Python, and others.

### Guidelines for contributions:

Headers should contain the text that a Ruby user might search for, since those headings will be in the Table of Contents generated for the top of the document.

We use POD =item instead of =head3 or =head4 for identical bits that need not appear in the table of contents.

This article does not describe in detail language features that Ruby doesn't have at all, instead referring to other documents.

Example code and links to other documents should be favored over long explanations of details better found elsewhere.

Finally, if a real user asks a Ruby to Perl 6 question that is not being answered here, please add it to the document. Even if we do not have a good answer yet, that will be better than losing the information about a real need.

15 Tutorials

~

16 Classes and objects

A tutorial about creating and using classes in Perl 6

Perl 6 has a rich built-in syntax for defining and using classes.

A default constructor allows the setting of attributes for the created object:

class Point { 
     has Int $.x; 
     has Int $.y; 
 } 
 
 class Rectangle { 
     has Point $.lower; 
     has Point $.upper; 
 
     method area() returns Int { 
         ($!upper.x - $!lower.x) * ( $!upper.y - $!lower.y); 
     } 
 } 
 
 # Create a new Rectangle from two Points 
 my $r = Rectangle.new(lower => Point.new(x => 0, y => 0), 
                       upper => Point.new(x => 10, y => 10)); 
 
 say $r.area(); # OUTPUT: «100␤» 

In the two classes, the default constructor is being used. This constructor will use named parameters in its invocation: Point.new(x => 0, y => 0).

You can also provide your own constructor and BUILD implementation. You need to do it for cases in which there are private attributes that might need to be populated during object construction, as in the example below:

# Example taken from 
 # https://medium.freecodecamp.org/a-short-overview-of-object-oriented-software-design-c7aa0a622c83 
 class Hero { 
     has @!inventory; 
     has Str $.name; 
     submethod BUILD( :$name, :@inventory ) { 
         $!name = $name; 
         @!inventory = @inventory 
     } 
 
     method act { 
         return @!inventory.pick; 
     } 
 } 
 my $hero = Hero.new(:name('Þor'), 
                     :inventory(['Mjölnir','Chariot','Bilskirnir'])); 
 say $hero.act; 

In this case, we encapsulate the private attribute @!inventory; but private instance variables cannot be set by the default constructor, which is why we add a BUILD submethod that takes care of that.

The following, more elaborate example, shows how a dependency handler might look in Perl 6. It showcases custom constructors, private and public attributes, Submethods, methods, and various aspects of signatures. It's not a lot of code, and yet the result is interesting and useful.

class Task { 
     has      &!callback; 
     has Task @!dependencies; 
     has Bool $.done; 
 
     # Normally doesn't need to be written 
     method new(&callback, *@dependencies) { 
         return self.bless(:&callback, :@dependencies); 
     } 
 
     # BUILD is the equivalent of a constructor in other languages 
     submethod BUILD(:&!callback, :@!dependencies) { } 
 
     method add-dependency(Task $dependency) { 
         push @!dependencies, $dependency; 
     } 
 
     method perform() { 
         unless $!done { 
             .perform() for @!dependencies; 
             &!callback(); 
             $!done = True; 
         } 
     } 
 } 
 
 my $eat = 
     Task.new({ say 'eating dinner. NOM!' }, 
         Task.new({ say 'making dinner' }, 
             Task.new({ say 'buying food' }, 
                 Task.new({ say 'making some money' }), 
                 Task.new({ say 'going to the store' }) 
             ), 
             Task.new({ say 'cleaning kitchen' }) 
         ) 
     ); 
 
 $eat.perform(); 

In this case, BUILD is needed since we have overridden the default new constructor. bless is eventually invoking it with the two named arguments that correspond to the two properties without a default value. With its signature, BUILD converts the two positionals to the two attributes, &!callback and @!dependencies, and returns the object (or turns it in to the next phase, TWEAK, if available).

Declaring new as a method and not as a multi method prevents us from using the default constructor; this implicit constructor uses the attributes as named parameters. This is one of the reasons why using new as a method's name is discouraged. If you need to declare it anyway, use multi method new if you do not want to disable the default constructor.

TWEAK is the last submethod to be called, and it has the advantage of having the object properties available without needing to use the meta object protocol. It can be used, for instance, to assign values to instance variables based on the values of other attributes or instance variables:

class Str-with-ID is Str { 
     my $.counter = 0; 
     has Str $.string; 
     has Int $.ID; 
 
     method TWEAK() { 
         $!ID = $.counter++; 
     } 
 } 
 
 say Str-with-ID.new(string => 'First').ID;  # OUTPUT: «0» 
 say Str-with-ID.new(string => 'Second').ID; # OUTPUT: «1» 

In this case, we need to compute $.ID from the value of a counter that is a class variable, $.counter, thus we simply assign a value to it and increment the counter at the same time. Please check also this section on TWEAK in the Object Orientation (OO) document for the mechanics of object construction.

DESTROY is the submethod that gets called when an object is garbage collected. That is going to happen only if the runtime needs the memory, so we can't rely on when it's going to happen. In particular, it could happen in the middle of some running code in a thread, so we must take special care to not assume any context during that event. We can use it to close any kind of handles or supplies or delete temporary files that are no longer going to be used.

my $in_destructor = 0; 
 
 class Foo { 
     submethod DESTROY { $in_destructor++ } 
 } 
 
 my $foo; 
 for 1 .. 6000 { 
     $foo = Foo.new(); 
 } 
 
 say "DESTROY called $in_destructor times"; 

This might print something like DESTROY called 5701 times, but it only kicks in after we have stomped over former instances of Foo 6000 times. We can't rely, however, on the order of destruction, for instance.

Starting with class

Perl 6, like many other languages, uses the class keyword to define a class. The block that follows may contain arbitrary code, just as with any other block, but classes commonly contain state and behavior declarations. The example code includes attributes (state), introduced through the has keyword, and behaviors, introduced through the method keyword.

Declaring a class creates a new type object which, by default, is installed into the current package (just like a variable declared with our scope). This type object is an "empty instance" of the class. For example, types such as Int and Str refer to the type object of one of the Perl 6 built-in classes. The example above uses the class name Task so that other code can refer to it later, such as to create class instances by calling the new method.

You can use the .DEFINITE method to find out if what you have is an instance or a type object:

say Int.DEFINITE; # OUTPUT: «False␤» (type object) 
 say 426.DEFINITE; # OUTPUT: «True␤»  (instance) 
 
 class Foo {}; 
 say Foo.DEFINITE;     # OUTPUT: «False␤» (type object) 
 say Foo.new.DEFINITE; # OUTPUT: «True␤»  (instance) 

You can also use type "smileys" to only accept instances or type objects:

multi foo (Int:U) { "It's a type object!" } 
 multi foo (Int:D) { "It's an instance!"   } 
 say foo Int; # OUTPUT: «It's a type object!␤» 
 say foo 42;  # OUTPUT: «It's an instance!␤» 

State

In the Task class, the first three lines inside the block all declare attributes (called fields or instance storage in other languages). Just as a my variable cannot be accessed from outside its declared scope, attributes are not accessible outside of the class. This encapsulation is one of the key principles of object oriented design.

The first declaration specifies instance storage for a callback (i.e., a bit of code to invoke in order to perform the task that an object represents):

has &!callback; 

The & sigil indicates that this attribute represents something invocable. The ! character is a twigil, or secondary sigil. A twigil forms part of the name of the variable. In this case, the ! twigil emphasizes that this attribute is private to the class.

The second declaration also uses the private twigil:

has Task @!dependencies; 

However, this attribute represents an array of items, so it requires the @ sigil. These items each specify a task that must be completed before the present one is completed. Furthermore, the type declaration on this attribute indicates that the array may only hold instances of the Task class (or some subclass of it).

The third attribute represents the state of completion of a task:

has Bool $.done; 

This scalar attribute (with the $ sigil) has a type of Bool. Instead of the ! twigil, the . twigil is used. While Perl 6 does enforce encapsulation on attributes, it also saves you from writing accessor methods. Replacing the ! with a . both declares a private attribute and an accessor method named after the attribute. In this case, both the attribute $!done and the accessor method done are declared. It's as if you had written:

has Bool $!done; 
 method done() { return $!done } 

Note that this is not like declaring a public attribute, as some languages allow; you really get both a private attribute and a method, without having to write the method by hand. You are free instead to write your own accessor method, if at some future point you need to do something more complex than returning the value.

Note that using the . twigil has created a method that will provide read-only access to the attribute. If instead the users of this object should be able to reset a task's completion state (perhaps to perform it again), you can change the attribute declaration:

has Bool $.done is rw; 

The is rw trait causes the generated accessor method to return a container so external code can modify the value of the attribute.

You can also supply default values to attributes (which works equally for those with and without accessors):

has Bool $.done = False; 

The assignment is carried out at object build time. The right-hand side is evaluated at that time, and can even reference earlier attributes:

has Task @!dependencies; 
 has $.ready = not @!dependencies; 

Writable attributes are accessible through writable containers:

class a-class { 
     has $.an-attribute is rw; 
 } 
 say (a-class.new.an-attribute = "hey"); # OUTPUT: «hey␤» 

This attribute can also be accessed using the .an-attribute or .an-attribute() syntax. See also the is rw trait on classes for examples on how this works on the whole class.

A class declaration can also include class variables, which are variables whose value is shared by all instances, and can be used for things like counting the number of instantiations or any other shared state. Class variables use the same syntax as the rest of the attributes, but are declared as my or our, depending on the scope; our variables will be shared by subclasses, since they have package scope.

class Str-with-ID is Str { 
     my $counter = 0; 
     our $hierarchy-counter = 0; 
     has Str $.string; 
     has Int $.ID; 
 
     method TWEAK() { 
         $!ID = $counter++; 
         $hierarchy-counter++; 
     } 
 
 } 
 
 class Str-with-ID-and-tag is Str-with-ID { 
     has Str $.tag; 
 } 
 
 say Str-with-ID.new(string => 'First').ID;  # OUTPUT: «0␤» 
 say Str-with-ID.new(string => 'Second').ID; # OUTPUT: «1␤» 
 say Str-with-ID-and-tag.new( string => 'Third', tag => 'Ordinal' ).ID; 
 # OUTPUT: «2␤» 
 say $Str-with-ID::hierarchy-counter;       # OUTPUT: «4␤» 

In this case, using new might be the easiest way to initialize the $.ID field and increment the value of the counter at the same time. new, through bless, will invoke the default BUILD, assigning the values to their properties correctly. You can obtain the same effect using TWEAK, which is considered a more p6y way of achieving such effect. Please check the section on submethods for an alternative example on how to do this. Since TWEAK is called in every object instantiation, it's incremented twice when creating objects of class Str-with-ID-and-tag; this is a class hierarchy variable that is shared by all subclasses of Str-with-ID. Additionally, class variables declared with package scope are visible via their fully qualified name (FQN), while lexically scoped class variables are "private".

Static fields?

Perl 6 has no static keyword. Nevertheless, any class may declare anything that a module can, so making a scoped variable sounds like a good idea.

class Singleton { 
     my Singleton $instance; 
     method new {!!!} 
     submethod instance { 
         $instance = Singleton.bless unless $instance; 
         $instance; 
     } 
 } 

Class attributes defined by my or our may also be initialized when being declared, however we are implementing the Singleton pattern here and the object must be created during its first use. It is not 100% possible to predict the moment when attribute initialization will be executed, because it can take place during compilation, runtime or both, especially when importing the class using the use keyword.

class HaveStaticAttr { 
     my Foo $.foo = some_complicated_subroutine; 
 } 

Class attributes may also be declared with a secondary sigil – in a similar manner to instance attributes – that will generate read-only accessors if the attribute is to be public.

Methods

While attributes give objects state, methods give objects behaviors. Let's ignore the new method temporarily; it's a special type of method. Consider the second method, add-dependency, which adds a new task to a task's dependency list:

method add-dependency(Task $dependency) { 
     push @!dependencies, $dependency; 
 } 

In many ways, this looks a lot like a sub declaration. However, there are two important differences. First, declaring this routine as a method adds it to the list of methods for the current class, thus any instance of the Task class can call it with the . method call operator. Second, a method places its invocant into the special variable self.

The method itself takes the passed parameter – which must be an instance of the Task class – and pushes it onto the invocant's @!dependencies attribute.

The perform method contains the main logic of the dependency handler:

method perform() { 
     unless $!done { 
         .perform() for @!dependencies; 
         &!callback(); 
         $!done = True; 
     } 
 } 

It takes no parameters, working instead with the object's attributes. First, it checks if the task has already completed by checking the $!done attribute. If so, there's nothing to do.

Otherwise, the method performs all of the task's dependencies, using the for construct to iterate over all of the items in the @!dependencies attribute. This iteration places each item – each a Task object – into the topic variable, $_. Using the . method call operator without specifying an explicit invocant uses the current topic as the invocant. Thus the iteration construct calls the .perform() method on every Task object in the @!dependencies attribute of the current invocant.

After all of the dependencies have completed, it's time to perform the current Task's task by invoking the &!callback attribute directly; this is the purpose of the parentheses. Finally, the method sets the $!done attribute to True, so that subsequent invocations of perform on this object (if this Task is a dependency of another Task, for example) will not repeat the task.

Private methods

Just like attributes, methods can also be private. Private methods are declared with a prefixed exclamation mark. They are called with self! followed by the method's name. To call a private method of another class the calling class has to be trusted by the called class. A trust relationship is declared with trusts and the class to be trusted must already be declared. Calling a private method of another class requires an instance of that class and the fully qualified name (FQN) of the method. Trust also allows access to private attributes.

class B {...} 
 
 class C { 
     trusts B; 
     has $!hidden = 'invisible'; 
     method !not-yours () { say 'hidden' } 
     method yours-to-use () { 
         say $!hidden; 
         self!not-yours(); 
     } 
 } 
 
 class B { 
     method i-am-trusted () { 
         my C $c.=new; 
         $c!C::not-yours(); 
     } 
 } 
 
 C.new.yours-to-use(); # the context of this call is GLOBAL, and not trusted by C 
 B.new.i-am-trusted(); 

Trust relationships are not subject to inheritance. To trust the global namespace, the pseudo package GLOBAL can be used.

Constructors

Perl 6 is rather more liberal than many languages in the area of constructors. A constructor is anything that returns an instance of the class. Furthermore, constructors are ordinary methods. You inherit a default constructor named new from the base class Mu, but you are free to override new, as this example does:

method new(&callback, *@dependencies) { 
     return self.bless(:&callback, :@dependencies); 
 } 

The biggest difference between constructors in Perl 6 and constructors in languages such as C# and Java is that rather than setting up state on a somehow already magically created object, Perl 6 constructors create the object themselves. The easiest way to do this is by calling the bless method, also inherited from Mu. The bless method expects a set of named parameters to provide the initial values for each attribute.

The example's constructor turns positional arguments into named arguments, so that the class can provide a nice constructor for its users. The first parameter is the callback (the thing which will execute the task). The rest of the parameters are dependent Task instances. The constructor captures these into the @dependencies slurpy array and passes them as named parameters to bless (note that :&callback uses the name of the variable – minus the sigil – as the name of the parameter).

Private attributes really are private. This means that bless is not allowed to bind things to &!callback and @!dependencies directly. To do this, we override the BUILD submethod, which is called on the brand new object by bless:

submethod BUILD(:&!callback, :@!dependencies) { } 

Since BUILD runs in the context of the newly created Task object, it is allowed to manipulate those private attributes. The trick here is that the private attributes (&!callback and @!dependencies) are being used as the bind targets for BUILD's parameters. Zero-boilerplate initialization! See objects for more information.

The BUILD method is responsible for initializing all attributes and must also handle default values:

has &!callback; 
 has @!dependencies; 
 has Bool ($.done, $.ready); 
 submethod BUILD( 
         :&!callback, 
         :@!dependencies, 
         :$!done = False, 
         :$!ready = not @!dependencies, 
     ) { } 

See Object Construction for more options to influence object construction and attribute initialization.

Consuming our class

After creating a class, you can create instances of the class. Declaring a custom constructor provides a simple way of declaring tasks along with their dependencies. To create a single task with no dependencies, write:

my $eat = Task.new({ say 'eating dinner. NOM!' }); 

An earlier section explained that declaring the class Task installed a type object in the namespace. This type object is a kind of "empty instance" of the class, specifically an instance without any state. You can call methods on that instance, as long as they do not try to access any state; new is an example, as it creates a new object rather than modifying or accessing an existing object.

Unfortunately, dinner never magically happens. It has dependent tasks:

my $eat = 
     Task.new({ say 'eating dinner. NOM!' }, 
         Task.new({ say 'making dinner' }, 
             Task.new({ say 'buying food' }, 
                 Task.new({ say 'making some money' }), 
                 Task.new({ say 'going to the store' }) 
             ), 
             Task.new({ say 'cleaning kitchen' }) 
         ) 
     ); 

Notice how the custom constructor and the sensible use of whitespace makes task dependencies clear.

Finally, the perform method call recursively calls the perform method on the various other dependencies in order, giving the output:

making some money 
 going to the store 
 buying food 
 cleaning kitchen 
 making dinner 
 eating dinner. NOM! 

Inheritance

Object Oriented Programming provides the concept of inheritance as one of the mechanisms for code reuse. Perl 6 supports the ability for one class to inherit from one or more classes. When a class inherits from another class it informs the method dispatcher to follow the inheritance chain to look for a method to dispatch. This happens both for standard methods defined via the method keyword and for methods generated through other means, such as attribute accessors.

class Employee { 
     has $.salary; 
 } 
 
 class Programmer is Employee { 
     has @.known_languages is rw; 
     has $.favorite_editor; 
 
     method code_to_solve( $problem ) { 
         return "Solving $problem using $.favorite_editor in " 
         ~ $.known_languages[0]; 
     } 
 } 

Now, any object of type Programmer can make use of the methods and accessors defined in the Employee class as though they were from the Programmer class.

my $programmer = Programmer.new( 
     salary => 100_000, 
     known_languages => <Perl5 Perl6 Erlang C++>, 
     favorite_editor => 'vim' 
 ); 
 
 say $programmer.code_to_solve('halting problem'), 
     " will get \$ {$programmer.salary()}"; 
 # OUTPUT: «Solving halting problem using vim in Perl5 will get $100000␤» 

Overriding inherited methods

Of course, classes can override methods and attributes defined by parent classes by defining their own. The example below demonstrates the Baker class overriding the Cook's cook method.

class Cook is Employee { 
     has @.utensils  is rw; 
     has @.cookbooks is rw; 
 
     method cook( $food ) { 
         say "Cooking $food"; 
     } 
 
     method clean_utensils { 
         say "Cleaning $_" for @.utensils; 
     } 
 } 
 
 class Baker is Cook { 
     method cook( $confection ) { 
         say "Baking a tasty $confection"; 
     } 
 } 
 
 my $cook = Cook.new( 
     utensils  => <spoon ladle knife pan>, 
     cookbooks => 'The Joy of Cooking', 
     salary    => 40000 
 ); 
 
 $cook.cook( 'pizza' );       # OUTPUT: «Cooking pizza␤» 
 say $cook.utensils.perl;     # OUTPUT: «["spoon", "ladle", "knife", "pan"]␤» 
 say $cook.cookbooks.perl;    # OUTPUT: «["The Joy of Cooking"]␤» 
 say $cook.salary;            # OUTPUT: «40000␤» 
 
 my $baker = Baker.new( 
     utensils  => 'self cleaning oven', 
     cookbooks => "The Baker's Apprentice", 
     salary    => 50000 
 ); 
 
 $baker.cook('brioche');      # OUTPUT: «Baking a tasty brioche␤» 
 say $baker.utensils.perl;    # OUTPUT: «["self cleaning oven"]␤» 
 say $baker.cookbooks.perl;   # OUTPUT: «["The Baker's Apprentice"]␤» 
 say $baker.salary;           # OUTPUT: «50000␤» 

Because the dispatcher will see the cook method on Baker before it moves up to the parent class the Baker's cook method will be called.

To access methods in the inheritance chain, use re-dispatch or the MOP.

Multiple inheritance

As mentioned before, a class can inherit from multiple classes. When a class inherits from multiple classes the dispatcher knows to look at both classes when looking up a method to search for. Perl 6 uses the C3 algorithm to linearize multiple inheritance hierarchies, which is better than depth-first search for handling multiple inheritance.

class GeekCook is Programmer is Cook { 
     method new( *%params ) { 
         push( %params<cookbooks>, "Cooking for Geeks" ); 
         return self.bless(|%params); 
     } 
 } 
 
 my $geek = GeekCook.new( 
     books           => 'Learning Perl 6', 
     utensils        => ('stainless steel pot', 'knife', 'calibrated oven'), 
     favorite_editor => 'MacVim', 
     known_languages => <Perl6> 
 ); 
 
 $geek.cook('pizza'); 
 $geek.code_to_solve('P =? NP'); 

Now all the methods made available to the Programmer and the Cook classes are available from the GeekCook class.

While multiple inheritance is a useful concept to know and occasionally use, it is important to understand that there are more useful OOP concepts. When reaching for multiple inheritance it is good practice to consider whether the design wouldn't be better realized by using roles, which are generally safer because they force the class author to explicitly resolve conflicting method names. For more information on roles, see Roles.

The also declarator

Classes to be inherited from can be listed in the class declaration body by prefixing the is trait with also. This also works for the role composition trait does.

class GeekCook { 
     also is Programmer; 
     also is Cook; 
     # ... 
 } 
 
 role A {}; 
 role B {}; 
 class C { 
     also does A; 
     also does B; 
     # ... 
 } 

Introspection

Introspection is the process of gathering information about some objects in your program, not by reading the source code, but by querying the object (or a controlling object) for some properties, such as its type.

Given an object $o and the class definitions from the previous sections, we can ask it a few questions:

my Programmer $o .= new; 
 if $o ~~ Employee { say "It's an employee" }; 
 say $o ~~ GeekCook ?? "It's a geeky cook" !! "Not a geeky cook"; 
 say $o.^name; 
 say $o.perl; 
 say $o.^methods(:local)».name.join(', '); 

The output might look like this:

It's an employee 
 Not a geeky cook 
 (Programmer) 
 Programmer.new(known_languages => ["Perl", "Python", "Pascal"], 
         favorite_editor => "gvim", salary => "too small") 
 code_to_solve, known_languages, favorite_editor 
 Programmer 

The first two tests each smartmatch against a class name. If the object is of that class, or of an inheriting class, it returns true. So the object in question is of class Employee or one that inherits from it, but not GeekCook.

The .WHAT method returns the type object associated with the object $o, which tells us the exact type of $o: in this case Programmer.

$o.perl returns a string that can be executed as Perl code, and reproduces the original object $o. While this does not work perfectly in all cases, it is very useful for debugging simple objects.

For example, closures cannot easily be reproduced this way; if you don't know what a closure is don't worry. Also current implementations have problems with dumping cyclic data structures this way, but they are expected to be handled correctly by .perl at some point.
$o.^methods(:local) produces a list of Methods that can be called on $o. The :local named argument limits the returned methods to those defined in the Programmer class and excludes the inherited methods.

The syntax of calling a method with .^ instead of a single dot means that it is actually a method call on its meta class, which is a class managing the properties of the Programmer class – or any other class you are interested in. This meta class enables other ways of introspection too:

say $o.^attributes.join(', '); 
 say $o.^parents.map({ $_.^name }).join(', '); 

Finally $o.^name calls the name method on the meta object, which unsurprisingly returns the class name.

Introspection is very useful for debugging and for learning the language and new libraries. When a function or method returns an object you don't know about, by finding its type with .WHAT, seeing a construction recipe for it with .perl, and so on, you'll get a good idea of what its return value is. With .^methods, you can learn what you can do with the class.

But there are other applications too. For instance, a routine that serializes objects to a bunch of bytes needs to know the attributes of that object, which it can find out via introspection.

Overriding default gist method

Some classes might need its own version of gist, which overrides the terse way it is printed when called to provide a default representation of the class. For instance, exceptions might want to write just the payload and not the full object so that it is clearer what to see what's happened. However, this isn't limited to exceptions; you can do that with every class:

class Cook { 
     has @.utensils  is rw; 
     has @.cookbooks is rw; 
 
     method cook( $food ) { 
         return "Cooking $food"; 
     } 
 
     method clean_utensils { 
         return "Cleaning $_" for @.utensils; 
     } 
 
     multi method gist(Cook:U:) { '⚗' ~ self.^name ~ '⚗' } 
     multi method gist(Cook:D:) { 
         '⚗ Cooks with ' ~ @.utensils.join( " ‣ ") ~ ' using ' 
           ~ @.cookbooks.map( "«" ~ * ~ "»").join( " and ") } 
 } 
 
 my $cook = Cook.new( 
     utensils => <spoon ladle knife pan>, 
     cookbooks => ['Cooking for geeks','The French Chef Cookbook']); 
 
 say Cook.gist; # OUTPUT: «⚗Cook⚗» 
 say $cook.gist; # OUTPUT: «⚗ Cooks with spoon ‣ ladle ‣ knife ‣ pan using «Cooking for geeks» and «The French Chef Cookbook»␤» 

Usually you will want to define two methods, one for the class and another for class instances; in this case, the class method uses the alembic symbol, and the instance method, defined below it, aggregates the data we have on the cook to show it in a narrative way.

17 Command line interface

Creating your own CLI in Perl 6

Command line interface - an overview

The default command line interface of Perl 6 scripts consists of three parts:

Parsing the command line parameters into a capture

This looks at the values in @*ARGS, interprets these according to some policy, and creates a Capture/type/Capture object out of that. An alternative way of parsing may be provided by the developer or installed using a module.

Calling a provided MAIN subroutine using that capture

Standard multi dispatch is used to call the MAIN subroutine with the generated Capture object. This means that your MAIN subroutine may be a multi sub, each candidate of which is responsible for some part of processing the given command line arguments.

Creating / showing usage information if calling MAIN failed

If multi dispatch failed, then the user of the script should be informed as well as possible as to why it failed. By default, this is done by inspecting the signature of each MAIN candidate sub, and any associated Pod information. The result is then shown to the user on STDERR (or on STDOUT if --help was specified). An alternative way of generating the usage information may be provided by the developer or installed using a module.

sub MAIN

The sub with the special name MAIN will be executed after all relevant entry phasers (BEGIN, CHECK, INIT, PRE, ENTER) have been run and the mainline of the script has been executed. No error will occur if there is no MAIN sub: your script will then just have to do the work, such as argument parsing, in the mainline of the script.

Any normal exit from the MAIN sub will result in an exit code of 0, indicating success. Any return value of the MAIN sub will be ignored. If an exception is thrown that is not handled inside the MAIN sub, then the exit code will be 1. If the dispatch to MAIN failed, a usage message will be displayed on STDERR and the exit code will be 2.

The command line parameters are present in the @*ARGS dynamic variable and may be altered in the mainline of the script before the MAIN unit is called.

The signature of (the candidates of the multi) sub MAIN determines which candidate will actually be called using the standard multi dispatch semantics.

A simple example:

# inside file 'hello.p6'
sub MAIN($name) {
    say "Hello $name, how are you?"
}

If you call that script without any parameters, you get the following usage message:

$ perl6 hello.p6 
 Usage: 
   hello.p6 <name> 

However, if you give a default value for the parameter, running the script either with or without specifying a name will always work:

# inside file 'hello.p6'
sub MAIN($name = 'bashful') {
    say "Hello $name, how are you?"
}
$ perl6 hello.p6 
 Hello bashful, how are you? 
$ perl6 hello.p6 Liz 
 Hello Liz, how are you? 

Another way to do this is to make sub MAIN a multi sub:

# inside file 'hello.p6'
multi sub MAIN()      { say "Hello bashful, how are you?" }
multi sub MAIN($name) { say "Hello $name, how are you?"   }

Which would give the same output as the examples above. Whether you should use either method to achieve the desired goal is entirely up to you.

A more complicated example using a single positional and multiple named parameters:

# inside "frobnicate.p6" 
 sub MAIN( 
   Str   $file where *.IO.f = 'file.dat', 
   Int  :$length = 24, 
   Bool :$verbose 
 ) { 
     say $length if $length.defined; 
     say $file   if $file.defined; 
     say 'Verbosity ', ($verbose ?? 'on' !! 'off'); 
 } 

With file.dat present, this will work this way:

$ perl6 frobnicate.p6 
 24 
 file.dat 
 Verbosity off 

Or this way with --verbose:

$ perl6 frobnicate.p6 --verbose 
 24 
 file.dat 
 Verbosity on 

If the file file.dat is not present, or you've specified another filename that doesn't exist, you would get the standard usage message created from introspection of the MAIN sub:

$ perl6 frobnicate.p6 doesntexist.dat 
 Usage: 
   frobnicate.p6 [--length=<Int>] [--verbose] [<file>] 

Although you don't have to do anything in your code to do this, it may still be regarded as a bit terse. But there's an easy way to make that usage message better by providing hints using pod features:

# inside "frobnicate.p6" 
 sub MAIN( 
   Str   $file where *.IO.f = 'file.dat',  #= an existing file to frobnicate 
   Int  :$length = 24,                     #= length needed for frobnication 
   Bool :$verbose,                         #= required verbosity 
 ) { 
     say $length if $length.defined; 
     say $file   if $file.defined; 
     say 'Verbosity ', ($verbose ?? 'on' !! 'off'); 
 } 

Which would improve the usage message like this:

$ perl6 frobnicate.p6 doesntexist.dat 
 Usage: 
   frobnicate.p6 [--length=<Int>] [--verbose] [<file>] 
 
     [<file>]          an existing file to frobnicate 
     --length=<Int>    length needed for frobnication 
     --verbose         required verbosity 

As any other subroutine, MAIN can define aliases for its named parameters.

sub MAIN( 
   Str   $file where *.IO.f = 'file.dat',  #= an existing file to frobnicate 
   Int  :size(:$length) = 24,              #= length/size needed for frobnication 
   Bool :$verbose,                         #= required verbosity 
 ) { 
     say $length if $length.defined; 
     say $file   if $file.defined; 
     say 'Verbosity ', ($verbose ?? 'on' !! 'off'); 
 } 

In which case, these aliases will also be listed as alternatives with --help:

Usage: 
   frobnicate.p6 [--size|--length=<Int>] [--verbose] [<file>] 
 
     [<file>]                 an existing file to frobnicate 
     --size|--length=<Int>    length needed for frobnication 
     --verbose                required verbosity 

%*SUB-MAIN-OPTS

It's possible to alter how arguments are processed before they're passed to sub MAIN {} by setting options in the %*SUB-MAIN-OPTS hash. Due to the nature of dynamic variables, it is required to set up the %*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
  # other possible future options / custom options
;
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 

is hidden-from-USAGE

Sometimes you want to exclude a MAIN candidate from being shown in any automatically generated usage message. This can be achieved by adding a hidden-from-USAGE trait to the specification of the MAIN candidate you do not want to show. Expanding on an earlier example:

# inside file 'hello.p6'
multi sub MAIN() is hidden-from-USAGE {
    say "Hello bashful, how are you?"
}
multi sub MAIN($name) {  #= the name by which you would like to be called
    say "Hello $name, how are you?"
}

So, if you would call this script with just a named variable, you would get the following usage:

$ perl6 hello.p6 --verbose 
 Usage: 
   hello.p6 <name> -- the name by which you would like to be called 

Without the hidden-from-USAGE trait on the first candidate, it would have looked like this:

$ perl6 hello.p6 --verbose 
 Usage: 
   hello.p6 
   hello.p6 <name> -- the name by which you would like to be called 

Which, although technically correct, doesn't read as well.

Unit-scoped definition of MAIN

If the entire program body resides within MAIN, you can use the unit declarator as follows (adapting an earlier example):

unit sub MAIN( 
   Str   $file where *.IO.f = 'file.dat', 
   Int  :$length = 24, 
   Bool :$verbose, 
 );  # <- note semicolon here 
 
 say $length if $length.defined; 
 say $file   if $file.defined; 
 say 'Verbosity ', ($verbose ?? 'on' !! 'off'); 
 # rest of script is part of MAIN 

Note that this is only appropriate if you can get by with just a single (only) sub MAIN.

sub USAGE

If no multi candidate of MAIN is found for the given command line parameters, the sub USAGE is called. If no such method is found, the compiler will output a default usage message.

#|(is it the answer)
multi MAIN(Int $i) { say $i == 42 ?? 'answer' !! 'dunno' }
#|(divide two numbers)
multi MAIN($a, $b){ say $a/$b }

sub USAGE() {
    print Q:c:to/EOH/;
    Usage: {$*PROGRAM-NAME} [number]

    Prints the answer or 'dunno'.
EOH
}

The default usage message is available inside sub USAGE via the read-only $*USAGE variable. It will be generated based on available sub MAIN candidates and their parameters. As shown before, you can specify an additional extended description for each candidate using a #|(...) Pod block to set WHY.

Intercepting CLI argument parsing (2018.10, v6.d and later)

You can replace or augment the default way of argument parsing by supplying a ARGS-TO-CAPTURE subroutine yourself, or by importing one from any of the Getopt modules available in the ecosystem.

sub ARGS-TO-CAPTURE

The ARGS-TO-CAPTURE subroutine should accept two parameters: a Callable representing the MAIN unit to be executed (so it can be introspected if necessary) and an array with the arguments from the command line. It should return a Capture object that will be used to dispatch the MAIN unit. The following is a very contrived example that will create a Capture depending on some keyword that was entered (which can be handy during testing of a command line interface of a script):

sub ARGS-TO-CAPTURE(&main, @args --> Capture) {
    # if we only specified "frobnicate" as an argument
    @args == 1 && @args[0] eq 'frobnicate'
      # then dispatch as MAIN("foo","bar",verbose => 2)
      ?? Capture.new( list => <foo bar>, hash => { verbose => 2 } )
      # otherwise, use default processing of args
      !! &*ARGS-TO-CAPTURE(&main, @args)
}

Note that the dynamic variable &*ARGS-TO-CAPTURE is available to perform the default command line arguments to Capture processing so you don't have to reinvent the whole wheel if you don't want to.

Intercepting usage message generation (2018.10, v6.d and later)

You can replace or augment the default way of usage message generation (after a failed dispatch to MAIN) by supplying a GENERATE-USAGE subroutine yourself, or by importing one from any of the Getopt modules available in the ecosystem.

sub RUN-MAIN

Defined as:

sub RUN-MAIN(&main, $mainline, :$in-as-argsfiles)

This routine allows complete control over the handling of MAIN. It gets a Callable that is the MAIN that should be executed, the return value of the mainline execution and additional named variables: :in-as-argsfiles which will be True if STDIN should be treated as $*ARGFILES.

If RUN-MAIN is not provided, a default one will be run that looks for subroutines of the old interface, such as MAIN_HELPER and USAGE. If found, it will execute following the "old" semantics.

class Hero { 
     has @!inventory; 
     has Str $.name; 
     submethod BUILD( :$name, :@inventory ) { 
         $!name = $name; 
         @!inventory = @inventory 
     } 
 } 
 
 sub new-main($name, *@stuff ) { 
     Hero.new(:name($name), :inventory(@stuff) ).perl.say 
 } 
 
 RUN-MAIN( &new-main, Nil ); 

This will print the name (first argument) of the generated object.

sub GENERATE-USAGE

The GENERATE-USAGE subroutine should accept a Callable representing the MAIN subroutine that didn't get executed because the dispatch failed. This can be used for introspection. All the other parameters are the parameters that were set up to be sent to MAIN. It should return the string of the usage information you want to be shown to the user. An example that will just recreate the Capture that was created from processing the arguments:

sub GENERATE-USAGE(&main, |capture) {
    capture<foo>:exists
      ?? "You're not allowed to specify a --foo"
      !! &*GENERATE-USAGE(&main, |capture)
}

You can also use multi subroutines to create the same effect:

multi sub GENERATE-USAGE(&main, :$foo!) {
    "You're not allowed to specify a --foo"
}
multi sub GENERATE-USAGE(&main, |capture) {
    &*GENERATE-USAGE(&main, |capture)
}

Note that the dynamic variable &*GENERATE-USAGE is available to perform the default usage message generation so you don't have to reinvent the whole wheel if you don't want to.

Intercepting MAIN calling (before 2018.10, v6.e)

An older interface enabled one to intercept the calling to MAIN completely. This depended on the existence of a MAIN_HELPER subroutine that would be called if a MAIN subroutine was found in the mainline of a program.

This interface was never documented. However, any programs using this undocumented interface will continue to function until v6.e. From v6.d onward, the use of the undocumented API will cause a DEPRECATED message.

Ecosystem modules can provide both the new and the old interface for compatibility with older versions of Perl 6: if a newer Perl 6 recognizes the new (documented) interface, it will use that. If there is no new interface subroutine available, but the old MAIN_HELPER interface is, then it will use the old interface.

If a module developer decides to only offer a module for v6.d or higher, then the support for the old interface can be removed from the module.

18 Concurrency

Concurrency and asynchronous programming

In common with most modern programming languages, Perl 6 is designed to support parallelism, asynchronicity and concurrency. Parallelism is about doing multiple things at once. Asynchronous programming, which is sometimes called event driven or reactive programming, is about supporting changes in the program flow caused by events triggered elsewhere in the program. Finally, concurrency is about the coordination of access and modification of some shared resources.

The aim of the Perl 6 concurrency design is to provide a high-level, composable and consistent interface, regardless of how a virtual machine may implement it for a particular operating system, through layers of facilities as described below.

I'm not quite clear which specific features should be included below hyper-operators, autothreading junctions?

Additionally, certain Perl features may implicitly operate in an asynchronous fashion, so in order to ensure predictable interoperation with these features, user code should, where possible, avoid the lower level concurrency APIs (e.g., Thread and Scheduler) and use the higher-level interfaces.

High-level APIs

Promises

A Promise (also called future in other programming environments) encapsulates the result of a computation that may not have completed or even started at the time the promise is obtained. A Promise starts from a Planned status and can result in either a Kept status, meaning the promise has been successfully completed, or a Broken status meaning that the promise has failed. Usually this is much of the functionality that user code needs to operate in a concurrent or asynchronous manner.

my $p1 = Promise.new; 
 say $p1.status;         # OUTPUT: «Planned␤» 
 $p1.keep('Result'); 
 say $p1.status;         # OUTPUT: «Kept␤» 
 say $p1.result;         # OUTPUT: «Result␤» 
                         # (since it has been kept, a result is available!) 
 
 my $p2 = Promise.new; 
 $p2.break('oh no'); 
 say $p2.status;         # OUTPUT: «Broken␤» 
 say $p2.result;         # dies, because the promise has been broken 
 CATCH { default { say .^name, ': ', .Str } }; 
 # OUTPUT: «X::AdHoc+{X::Promise::Broken}: oh no␤» 

Promises gain much of their power by being composable, for example by chaining, usually by the then method:

my $promise1 = Promise.new();
my $promise2 = $promise1.then(
    -> $v { say $v.result; "Second Result" }
);
$promise1.keep("First Result");
say $promise2.result;   # OUTPUT: «First Result␤Second Result␤»

Here the then method schedules code to be executed when the first Promise is kept or broken, itself returning a new Promise which will be kept with the result of the code when it is executed (or broken if the code fails). keep changes the status of the promise to Kept setting the result to the positional argument. result blocks the current thread of execution until the promise is kept or broken, if it was kept then it will return the result (that is the value passed to keep), otherwise it will throw an exception based on the value passed to break. The latter behavior is illustrated with:

my $promise1 = Promise.new();
my $promise2 = $promise1.then(-> $v { say "Handled but : "; say $v.result});
$promise1.break("First Result");
try $promise2.result;
say $promise2.cause;        # OUTPUT: «Handled but : ␤First Result␤»

Here the break will cause the code block of the then to throw an exception when it calls the result method on the original promise that was passed as an argument, which will subsequently cause the second promise to be broken, raising an exception in turn when its result is taken. The actual Exception object will then be available from cause. If the promise had not been broken cause would raise a X::Promise::CauseOnlyValidOnBroken exception.

A Promise can also be scheduled to be automatically kept at a future time:

my $promise1 = Promise.in(5);
my $promise2 = $promise1.then(-> $v { say $v.status; 'Second Result' });
say $promise2.result;

The method in creates a new promise and schedules a new task to call keep on it no earlier than the supplied number of seconds, returning the new Promise object.

A very frequent use of promises is to run a piece of code, and keep the promise once it returns successfully, or break it when the code dies. The start method provides a shortcut for that:

my $promise = Promise.start(
    { my $i = 0; for 1 .. 10 { $i += $_ }; $i}
);
say $promise.result;    # OUTPUT: «55␤»

Here the result of the promise returned is the value returned from the code. Similarly if the code fails (and the promise is thus broken), then cause will be the Exception object that was thrown:

my $promise = Promise.start({ die "Broken Promise" });
try $promise.result;
say $promise.cause;

This is considered to be such a commonly required pattern that it is also provided as a keyword:

my $promise = start {
    my $i = 0;
    for 1 .. 10 {
        $i += $_
    }
    $i
}
my $result = await $promise;
say $result;

The subroutine await is almost equivalent to calling result on the promise object returned by start but it will also take a list of promises and return the result of each:

my $p1 = start {
    my $i = 0;
    for 1 .. 10 {
        $i += $_
    }
    $i
};
my $p2 = start {
    my $i = 0;
    for 1 .. 10 {
        $i -= $_
    }
    $i
};
my @result = await $p1, $p2;
say @result;            # OUTPUT: «[55 -55]␤»

In addition to await, two class methods combine several Promise objects into a new promise: allof returns a promise that is kept when all the original promises are kept or broken:

my $promise = Promise.allof(
    Promise.in(2),
    Promise.in(3)
);

await $promise;
say "All done"; # Should be not much more than three seconds later

And anyof returns a new promise that will be kept when any of the original promises is kept or broken:

my $promise = Promise.anyof(
    Promise.in(3),
    Promise.in(8600)
);

await $promise;
say "All done"; # Should be about 3 seconds later

Unlike await however the results of the original kept promises are not available without referring to the original, so these are more useful when the completion or otherwise of the tasks is more important to the consumer than the actual results, or when the results have been collected by other means. You may, for example, want to create a dependent Promise that will examine each of the original promises:

my @promises;
for 1..5 -> $t {
    push @promises, start {
        sleep $t;
        Bool.pick;
    };
}
say await Promise.allof(@promises).then({ so all(@promises>>.result) });

Which will give True if all of the promises were kept with True, False otherwise.

If you are creating a promise that you intend to keep or break yourself then you probably don't want any code that might receive the promise to inadvertently (or otherwise) keep or break the promise before you do. For this purpose there is the method vow, which returns a Vow object which becomes the only mechanism by which the promise can be kept or broken. If an attempt to keep or break the Promise is made directly then the exception X::Promise::Vowed will be thrown, as long as the vow object is kept private, the status of the promise is safe:

sub get_promise {
    my $promise = Promise.new;
    my $vow = $promise.vow;
    Promise.in(10).then({$vow.keep});
    $promise;
}

my $promise = get_promise();

# Will throw an exception
# "Access denied to keep/break this Promise; already vowed"
$promise.keep;
CATCH { default { say .^name, ': ', .Str } };
# OUTPUT: «X::Promise::Vowed: Access denied to keep/break this Promise; already vowed␤»

The methods that return a promise that will be kept or broken automatically such as in or start will do this, so it is not necessary to do it for these.

Supplies

A Supply is an asynchronous data streaming mechanism that can be consumed by one or more consumers simultaneously in a manner similar to "events" in other programming languages and can be seen as enabling event driven or reactive designs.

At its simplest, a Supply is a message stream that can have multiple subscribers created with the method tap on to which data items can be placed with emit.

The Supply can either be live or on-demand. A live supply is like a TV broadcast: those who tune in don't get previously emitted values. An on-demand broadcast is like Netflix: everyone who starts streaming a movie (taps a supply), always starts it from the beginning (gets all the values), regardless of how many people are watching it right now. Note that no history is kept for on-demand supplies, instead, the supply block is run for each tap of the supply.

A live Supply is created by the Supplier factory, each emitted value is passed to all the active tappers as they are added:

my $supplier = Supplier.new;
my $supply   = $supplier.Supply;

$supply.tap( -> $v { say $v });

for 1 .. 10 {
    $supplier.emit($_);
}

Note that the tap is called on a Supply object created by the Supplier and new values are emitted on the Supplier.

An on-demand Supply is created by the supply keyword:

my $supply = supply {
    for 1 .. 10 {
        emit($_);
    }
}
$supply.tap( -> $v { say $v });

In this case the code in the supply block is executed every time the Supply returned by supply is tapped, as demonstrated by:

my $supply = supply {
    for 1 .. 10 {
        emit($_);
    }
}
$supply.tap( -> $v { say "First : $v" });
$supply.tap( -> $v { say "Second : $v" });

The tap method returns a Tap object which can be used to obtain information about the tap and also to turn it off when we are no longer interested in the events:

my $supplier = Supplier.new;
my $supply   = $supplier.Supply;

my $tap = $supply.tap( -> $v { say $v });

$supplier.emit("OK");
$tap.close;
$supplier.emit("Won't trigger the tap");

Calling done on the supply object calls the done callback that may be specified for any taps, but does not prevent any further events being emitted to the stream, or taps receiving them.

The method interval returns a new on-demand supply which periodically emits a new event at the specified interval. The data that is emitted is an integer starting at 0 that is incremented for each event. The following code outputs 0 .. 5 :

my $supply = Supply.interval(2);
$supply.tap(-> $v { say $v });
sleep 10;

A second argument can be supplied to interval which specifies a delay in seconds before the first event is fired. Each tap of a supply created by interval has its own sequence starting from 0, as illustrated by the following:

my $supply = Supply.interval(2);
$supply.tap(-> $v { say "First $v" });
sleep 6;
$supply.tap(-> $v { say "Second $v"});
sleep 10;

A live Supply that keeps values until first tapped can be created with Supplier::Preserving.

whenever

The whenever keyword can be used in supply blocks or in react blocks. From the 6.d version, it needs to be used within the lexical scope of them. It introduces a block of code that will be run when prompted by an asynchronous event that it specifies - that could be a Supply, a Channel, a Promise or an Iterable.

In this example we are watching two supplies.

my $bread-supplier = Supplier.new; 
 my $vegetable-supplier = Supplier.new; 
 
 my $supply = supply { 
     whenever $bread-supplier.Supply { 
         emit("We've got bread: " ~ $_); 
     }; 
     whenever $vegetable-supplier.Supply { 
         emit("We've got a vegetable: " ~ $_); 
     }; 
 } 
 $supply.tap( -> $v { say "$v" }); 
 
 $vegetable-supplier.emit("Radish");   # OUTPUT: «We've got a vegetable: Radish␤» 
 $bread-supplier.emit("Thick sliced"); # OUTPUT: «We've got bread: Thick sliced␤» 
 $vegetable-supplier.emit("Lettuce");  # OUTPUT: «We've got a vegetable: Lettuce␤» 

Please note that one should keep the code inside the whenever as small as possible, as only one whenever block will be executed at any time. One can use a start block inside the whenever block to run longer running code.

react

The react keyword introduces a block of code containing one or more whenever keywords to watch asynchronous events. The main difference between a supply block and a react block is that the code in a react block runs where it appears in the code flow, whereas a supply block has to be tapped before it does anything.

Another difference is that a supply block can be used without the whenever keyword, but a react block requires at least one whenever to be of any real use.

react {
    whenever Supply.interval(2) -> $v {
        say $v;
        done() if $v == 4;
    }
}

Here the whenever keyword uses .act to create a tap on the Supply from the provided block. The react block is exited when done() is called in one of the taps. Using last to exit the block would produce an error indicating that it's not really a loop construct.

An on-demand Supply can also be created from a list of values that will be emitted in turn, thus the first on-demand example could be written as:

react {
    whenever Supply.from-list(1..10) -> $v {
        say $v;
    }
}

Transforming supplies

An existing supply object can be filtered or transformed, using the methods grep and map respectively, to create a new supply in a manner like the similarly named list methods: grep returns a supply such that only those events emitted on the source stream for which the grep condition is true is emitted on the second supply:

my $supplier = Supplier.new;
my $supply = $supplier.Supply;
$supply.tap(-> $v { say "Original : $v" });
my $odd_supply = $supply.grep({ $_ % 2 });
$odd_supply.tap(-> $v { say "Odd : $v" });
my $even_supply = $supply.grep({ not $_ % 2 });
$even_supply.tap(-> $v { say "Even : $v" });
for 0 .. 10 {
    $supplier.emit($_);
}

map returns a new supply such that for each item emitted to the original supply a new item which is the result of the expression passed to the map is emitted:

my $supplier = Supplier.new;
my $supply = $supplier.Supply;
$supply.tap(-> $v { say "Original : $v" });
my $half_supply = $supply.map({ $_ / 2 });
$half_supply.tap(-> $v { say "Half : $v" });
for 0 .. 10 {
    $supplier.emit($_);
}

Ending a supply

If you need to have an action that runs when the supply finishes, you can do so by setting the done and quit options in the call to tap:

$supply.tap: { ... }, 
     done => { say 'Job is done.' }, 
     quit => { 
         when X::MyApp::Error { say "App Error: ", $_.message } 
     }; 

The quit block works very similar to a CATCH. If the exception is marked as seen by a when or default block, the exception is caught and handled. Otherwise, the exception continues to up the call tree (i.e., the same behavior as when quit is not set).

Phasers in a supply or react block

If you are using the react or supply block syntax with whenever, you can add phasers within your whenever blocks to handle the done and quit messages from the tapped supply:

react { 
     whenever $supply { 
         ...; # your usual supply tap code here 
         LAST { say 'Job is done.' } 
         QUIT { when X::MyApp::Error { say "App Error: ", $_.message } } 
     } 
 } 

The behavior here is the same as setting done and quit on tap.

Channels

A Channel is a thread-safe queue that can have multiple readers and writers that could be considered to be similar in operation to a "fifo" or named pipe except it does not enable inter-process communication. It should be noted that, being a true queue, each value sent to the Channel will only be available to a single reader on a first read, first served basis: if you want multiple readers to be able to receive every item sent you probably want to consider a Supply.

An item is queued onto the Channel with the method send, and the method receive removes an item from the queue and returns it, blocking until a new item is sent if the queue is empty:

my $channel = Channel.new;
$channel.send('Channel One');
say $channel.receive;  # OUTPUT: «Channel One␤»

If the channel has been closed with the method close then any send will cause the exception X::Channel::SendOnClosed to be thrown, and a receive will throw a X::Channel::ReceiveOnClosed if there are no more items on the queue.

The method list returns all the items on the Channel and will block until further items are queued unless the channel is closed:

my $channel = Channel.new;
await (^10).map: -> $r {
    start {
        sleep $r;
        $channel.send($r);
    }
}
$channel.close;
for $channel.list -> $r {
    say $r;
}

There is also the non-blocking method poll that returns an available item from the channel or Nil if there is no item or the channel is closed, this does of course mean that the channel must be checked to determine whether it is closed:

my $c = Channel.new;

# Start three Promises that sleep for 1..3 seconds, and then
# send a value to our Channel
^3 .map: -> $v {
    start {
        sleep 3 - $v;
        $c.send: "$v from thread {$*THREAD.id}";
    }
}

# Wait 3 seconds before closing the channel
Promise.in(3).then: { $c.close }

# Continuously loop and poll the channel, until it's closed
my $is-closed = $c.closed;
loop {
    if $c.poll -> $item {
        say "$item received after {now - INIT now} seconds";
    }
    elsif $is-closed {
        last;
    }

    say 'Doing some unrelated things...';
    sleep .6;
}

# Doing some unrelated things...
# Doing some unrelated things...
# 2 from thread 5 received after 1.2063182 seconds
# Doing some unrelated things...
# Doing some unrelated things...
# 1 from thread 4 received after 2.41117376 seconds
# Doing some unrelated things...
# 0 from thread 3 received after 3.01364461 seconds
# Doing some unrelated things...

The method closed returns a Promise that will be kept (and consequently will evaluate to True in a boolean context) when the channel is closed.

The .poll method can be used in combination with .receive method, as a caching mechanism where lack of value returned by .poll is a signal that more values need to be fetched and loaded into the channel:

sub get-value { 
     return $c.poll // do { start replenish-cache; $c.receive }; 
 } 
 
 sub replenish-cache { 
     for ^20 { 
         $c.send: $_ for slowly-fetch-a-thing(); 
     } 
 } 

Channels can be used in place of the Supply in the whenever of a react block described earlier:

my $channel = Channel.new; 
 my $p = start { 
     react { 
         whenever $channel { 
             say $_; 
         } 
     } 
 } 
 
 await (^10).map: -> $r { 
     start { 
         sleep $r; 
         $channel.send($r); 
     } 
 } 
 
 $channel.close; 
 await $p; 

It is also possible to obtain a Channel from a Supply using the Channel method which returns a Channel which is fed by a tap on the Supply:

my $supplier = Supplier.new;
my $supply   = $supplier.Supply;
my $channel = $supply.Channel;

my $p = start {
    react  {
        whenever $channel -> $item {
            say "via Channel: $item";
        }
    }
}

await (^10).map: -> $r {
    start {
        sleep $r;
        $supplier.emit($r);
    }
}

$supplier.done;
await $p;

Channel will return a different Channel fed with the same data each time it is called. This could be used, for instance, to fan-out a Supply to one or more Channels to provide for different interfaces in a program.

Proc::Async

Proc::Async builds on the facilities described to run and interact with an external program asynchronously:

my $proc = Proc::Async.new('echo', 'foo', 'bar');

$proc.stdout.tap(-> $v { print "Output: $v" });
$proc.stderr.tap(-> $v { print "Error:  $v" });

say "Starting...";
my $promise = $proc.start;

await $promise;
say "Done.";

# Output:
# Starting...
# Output: foo bar
# Done.

The path to the command as well as any arguments to the command are supplied to the constructor. The command will not be executed until start is called, which will return a Promise that will be kept when the program exits. The standard output and standard error of the program are available as Supply objects from the methods stdout and stderr respectively which can be tapped as required.

If you want to write to the standard input of the program you can supply the :w adverb to the constructor and use the methods write, print or say to write to the opened pipe once the program has been started:

my $proc = Proc::Async.new(:w, 'grep', 'foo');

$proc.stdout.tap(-> $v { print "Output: $v" });

say "Starting...";
my $promise = $proc.start;

$proc.say("this line has foo");
$proc.say("this one doesn't");

$proc.close-stdin;
await $promise;
say "Done.";

# Output:
# Starting...
# Output: this line has foo
# Done.

Some programs (such as grep without a file argument in this example, ) won't exit until their standard input is closed so close-stdin can be called when you are finished writing to allow the Promise returned by start to be kept.

Low-level APIs

Threads

The lowest level interface for concurrency is provided by Thread. A thread can be thought of as a piece of code that may eventually be run on a processor, the arrangement for which is made almost entirely by the virtual machine and/or operating system. Threads should be considered, for all intents, largely un-managed and their direct use should be avoided in user code.

A thread can either be created and then actually run later:

my $thread = Thread.new(code => { for  1 .. 10  -> $v { say $v }});
# ...
$thread.run;

Or can be created and run at a single invocation:

my $thread = Thread.start({ for  1 .. 10  -> $v { say $v }});

In both cases the completion of the code encapsulated by the Thread object can be waited on with the finish method which will block until the thread completes:

$thread.finish; 

Beyond that there are no further facilities for synchronization or resource sharing which is largely why it should be emphasized that threads are unlikely to be useful directly in user code.

Schedulers

The next level of the concurrency API is supplied by classes that implement the interface defined by the role Scheduler. The intent of the scheduler interface is to provide a mechanism to determine which resources to use to run a particular task and when to run it. The majority of the higher level concurrency APIs are built upon a scheduler and it may not be necessary for user code to use them at all, although some methods such as those found in Proc::Async, Promise and Supply allow you to explicitly supply a scheduler.

The current default global scheduler is available in the variable $*SCHEDULER.

The primary interface of a scheduler (indeed the only method required by the Scheduler interface) is the cue method:

method cue(:&code, Instant :$at, :$in, :$every, :$times = 1; :&catch)

This will schedule the Callable in &code to be executed in the manner determined by the adverbs (as documented in Scheduler) using the execution scheme as implemented by the scheduler. For example:

my $i = 0;
my $cancellation = $*SCHEDULER.cue({ say $i++}, every => 2 );
sleep 20;

Assuming that the $*SCHEDULER hasn't been changed from the default, will print the numbers 0 to 10 approximately (i.e with operating system scheduling tolerances) every two seconds. In this case the code will be scheduled to run until the program ends normally, however the method returns a Cancellation object which can be used to cancel the scheduled execution before normal completion:

my $i = 0;
my $cancellation = $*SCHEDULER.cue({ say $i++}, every => 2 );
sleep 10;
$cancellation.cancel;
sleep 10;

should only output 0 to 5.

Despite the apparent advantage the Scheduler interface provides over that of Thread all of functionality is available through higher level interfaces and it shouldn't be necessary to use a scheduler directly, except perhaps in the cases mentioned above where a scheduler can be supplied explicitly to certain methods.

A library may wish to provide an alternative scheduler implementation if it has special requirements, for instance a UI library may want all code to be run within a single UI thread, or some custom priority mechanism may be required, however the implementations provided as standard and described below should suffice for most user code.

ThreadPoolScheduler

The ThreadPoolScheduler is the default scheduler, it maintains a pool of threads that are allocated on demand, creating new ones as necessary up to maximum number given as a parameter when the scheduler object was created (the default is 16.) If the maximum is exceeded then cue may queue the code until such time as a thread becomes available.

Rakudo allows the maximum number of threads allowed in the default scheduler to be set by the environment variable RAKUDO_MAX_THREADS at the time the program is started.

CurrentThreadScheduler

The CurrentThreadScheduler is a very simple scheduler that will always schedule code to be run straight away on the current thread. The implication is that cue on this scheduler will block until the code finishes execution, limiting its utility to certain special cases such as testing.

Locks

The class Lock provides the low level mechanism that protects shared data in a concurrent environment and is thus key to supporting thread-safety in the high level API, this is sometimes known as a "Mutex" in other programming languages. Because the higher level classes (Promise, Supply and Channel) use a Lock where required it is unlikely that user code will need to use a Lock directly.

The primary interface to Lock is the method protect which ensures that a block of code (commonly called a "critical section") is only executed in one thread at a time:

my $lock = Lock.new;

my $a = 0;

await (^10).map: {
    start {
        $lock.protect({
            my $r = rand;
            sleep $r;
            $a++;
        });
    }
}

say $a; # OUTPUT: «10␤»

protect returns whatever the code block returns.

Because protect will block any threads that are waiting to execute the critical section the code should be as quick as possible.

Safety concerns

Some shared data concurrency issues are less obvious than others. For a good general write-up on this subject see this blog post.

One particular issue of note is when container autovivification or extension takes place. When an Array or a Hash entry is initially assigned the underlying structure is altered and that operation is not async safe. For example, in this code:

my @array;
my $slot := @array[20];
$slot = 'foo';

The third line is the critical section as that is when the array is extended. The simplest fix is to use a Lock to protect the critical section. A possibly better fix would be to refactor the code so that sharing a container is not necessary.

19 Core modules

Core modules that may be useful to module authors

The Rakudo implementation has a few modules included you may want to use. The following is a list of them, along with links to their source code.

CompUnit::* modules and roles

These modules are mostly used by distribution build tools, and are not intended to be used (at least until version 6.c) by the final user.

NativeCall modules

Other modules

20 Doing math with Perl 6

Different mathematical paradigms and how they are implemented in this language

Sets

Perl 6 includes the Set data type, as well as support for most set operations. Union and intersection are not only native operations, they use their natural symbols, ∩ and ∪. For instance, this code would check the fundamental laws of the arithmetic of sets for a limited number of sets:

my @arbitrary-numbers = ^100; 
 my \U = @arbitrary-numbers.Set; 
 
 my @sets; 
 
 @sets.push: Set.new( @arbitrary-numbers.pick( @arbitrary-numbers.elems.rand)) for @arbitrary-numbers; 
 
 my (@union, @intersection); 
 
 for @sets -> $set { 
     @union.push: $set ∩ $set === $set; 
     @intersection.push: $set ∪ $set === $set; 
 } 
 
 say "Idempotent union is ", so @union.all; 
 # OUTPUT: «Idempotent union is True» 
 say "Idempotent intersection is ", so @intersection.all; 
 # OUTPUT: «Idempotent intersection is True» 
 my (@universe, @empty-set, @id-universe, @id-empty); 
 
 for @sets -> \A { 
     @universe.push: A ∪ U === U; 
     @id-universe.push: A ∩ U === A; 
     @empty-set.push: A ∩ ∅ === ∅; 
     @id-empty.push: A ∪ ∅ === A; 
 } 
 
 say "Universe dominates ", so @universe.all;    # OUTPUT: «Universe dominates True» 
 say "Empty set dominates ", so @empty-set.all;  # OUTPUT: «Empty set dominates True» 
 
 say "Identity with U ", so @id-universe.all;    # OUTPUT: «Identity with U True» 
 say "Identity with ∅ ", so @id-empty.all;       # OUTPUT: «Identity with ∅ True» 

In this code, which uses the empty set which is already defined by Perl 6, not only do we check if the equalities in the algebra of sets hold, we also use, via sigilless variables and the Unicode form of the set operators, expressions that are as close as possible to the original form; A ∪ U === U, for example, except for the use of the value identity operator === is very close to the actual mathematical expression in the Wikipedia entry.

We can even test De Morgan's law, as in the code below:

my @alphabet = 'a'..'z'; 
 my \U = @alphabet.Set; 
 sub postfix:<⁻>(Set $a) { U ⊖ $a } 
 my @sets; 
 @sets.push: Set.new( @alphabet.pick( @alphabet.elems.rand)) for @alphabet; 
 my ($de-Morgan1,$de-Morgan2) = (True,True); 
 for @sets X @sets -> (\A, \B){ 
     $de-Morgan1 &&= (A ∪ B)⁻  === A⁻ ∩ B⁻; 
     $de-Morgan2 &&= (A ∩ B)⁻  === A⁻ ∪ B⁻; 
 } 
 say "1st De Morgan is ", $de-Morgan1; 
 say "2nd De Morgan is ", $de-Morgan2; 

We declare as the complement operation, which computes the symmetrical difference ⊖ between the Universal set U and our set. Once that is declared, it is relatively easy to express operations such as the complementary of the union of A and B, (A ∪ B)⁻, with a notation that is very close to the original mathematical notation.

Arithmetic

Perl 6 can do arithmetic using different data types. Num, Rat and Complex can all operate as a field under the operations of addition, subtraction, multiplication and division (technically, it should be noted that data types dealing with floating point number representations are not a field in the mathematical sense due to the inherent imprecisions of their arithmetic. However, they constitute an approximate enough, computer friendly version of such mathematical objects for most of the cases). The equivalent mathematical fields are:

Perl 6 class Field
Rat
Num
Complex

The Ints or ℤ, as they're usually called in mathematics, are not a mathematical field but rather a ring, since they are not closed under multiplicative inverses. However, if the integer division div is used, their operations will always yield other integers; if / is used, on the other hand, in general the result will be a Rat.

Besides, Int can do infinite-precision arithmetic (or at least infinite as memory allows; Numeric overflow can still occur), without falling back to Num if the number is too big:

my @powers = 2, 2 ** * ... Inf; say @powers[4].chars; # OUTPUT: «19729␤»

Also strictly speaking, the Rational class that behaves like a mathematical field is FatRat. For efficiency reasons, operating with Rats will fall back to Num when the numbers are big enough or when there is a big difference between numerator and denominator. FatRat can work with arbitrary precision, the same as the default Int class.

Some modules in the ecosystem can work with additional data types mathematically:

Numbers are duck-typed automatically to the numeric class they actually represent:

.^name.say for (4, ⅗, 1e-9, 3+.1i); # OUTPUT: «Int␤Rat␤Num␤Complex␤»

Arithmetic operations are performed by taking into account the type of operands:

say .33-.22-.11 == 0; # OUTPUT: «True␤»

In this case, all numbers are interpreted as Rats, which makes the operation exact. In general, most other languages would interpret them as floating point numbers, which can also be achieved in Perl 6 if needed:

say .33.Num -.22.Num - .11.Num; # OUTPUT: «1.3877787807814457e-17␤»

For cases such as this, Perl 6 also includes an approximately equal operator,

say .33.Num -.22.Num - .11.Num ≅ 0; # OUTPUT: «True␤»

Sequences

A sequence is an enumerated collection of objects in which repetitions are allowed, and also a first-class data type in Perl 6 called Seq. Seq is able to represent infinite sequences, like the natural numbers:

my \𝕟 = 1,2 … ∞;
say 𝕟[3];         # OUTPUT: «4␤»

Infinite sequences use ∞, Inf or * (Whatever) as terminator. is the list generator, which in fact can understand arithmetic and geometric progression sequences as long as you insert the first numbers:

say 1,5,9 … * > 100;
# OUTPUT: «(1 5 9 13 17 21 25 29 33 37 41 45 49 53 57 61 65 69 73 77 81 85 89 93 97 101)␤»
say 1,3,9 … * > 337; # OUTPUT: «(1 3 9 27 81 243 729)␤»

The first sequence will be terminated when the generated number is bigger than 100; the second sequence, which is a geometric progression, when it is bigger than 337.

The fact that an arbitrary generator can be used makes easy to generate sequences such as Fibonacci numbers:

say 1,1, * + * … * > 50;#  OUTPUT: «(1 1 2 3 5 8 13 21 34 55)␤»

We can, in fact, compute the approximation to the golden ratio this way:

my @phis = (2.FatRat, 1 + 1 / * ... *);
my @otherphi = (1 - @phis[200], 1 + 1 / * ... *);
say @otherphi[^10, |(20, 30 ... 100)];  # OUTPUT:
# «((-0.61803398874989484820458683436563811772030918
# -0.61803398874989484820458683436563811772030918
# -0.61803398874989484820458683436563811772030918
# -0.61803398874989484820458683436563811772030918
# -0.61803398874989484820458683436563811772030918
# -0.618033…»

The Math::Sequences module includes many mathematical sequences, already defined for you. It has many sequences from the encyclopedia, some of them with their original name, such as ℤ.

Some set operators also operate on sequences, and they can be used to find out if an object is part of it:

say 876 ∈ (7,14 … * > 1000) ; # OUTPUT: «False␤»

In this particular case, we can find out if 876 is a multiple of 7 straight away, but the same principle holds for other sequences using complicated generators. And we can use set inclusion operators too:

say (55,89).Set ⊂ (1,1, * + * … * > 200); # OUTPUT: «True␤»

That said, it does not take into account if it is effectively a subsequence, just the presence of the two elements here. Sets have no order, and even if you don't explicitly cast the subsequence into a Set or explicitly cast it into a Seq it will be coerced into such for the application of the inclusion operator.

Mathematical constants

Perl 6 includes a set of mathematical constants:

say π; # OUTPUT: «3.141592653589793»
say τ; # Equivalent to 2π; OUTPUT: «6.283185307179586»
say 𝑒; # OUTPUT: «2.718281828459045␤»

These constants are also available through ASCII equivalents: e, pi and tau.

The Math::Constants module includes an additional series of physical and mathematical constants such as the previously mentioned golden ratio φ or the Planck's constant ℎ.

Since Perl 6 allows for definition of variables that use Unicode graphemes, and also variable and constant names without any kind of sigil, it is considered a good practice to use the actual mathematical name of concepts to denominate them wherever possible.

Numerical integration of ordinary differential equations

Perl 6 is an amazing programming language, and of course, you can do a lot of cool math with it. A great amount of work during an applied mathematician's work is to simulate the models they create. For this reason, in every coding language, a numerical integrator is a must-have. Learning how to do this in Perl 6 can be very useful.

Requirements

In Perl 6 there are some modules in the ecosystem that can make it easier:

For this example we are going to use Math::Model for its useful syntax, but remember that this module requires Math::RungeKutta as well. Simply install them with zef before using these examples.

Malthus model

Let's start with the 'Hello World' of mathematical Ecology: Malthusian growth model. A Malthusian growth model, sometimes called a simple exponential growth model, is essentially exponential growth based on the idea of the function being proportional to the speed to which the function grows. The equation, then, looks like this:

dx/dt = g*x

x(0) = x_0

Where g is the population growth rate, sometimes called Malthusian parameter.

How can we translate that into Perl 6? Well Math::Model brings some help with a very understandable way to do that:

use Math::Model; 
 
 my $m = Math::Model.new( 
     derivatives => { 
         velocity => 'x', 
     }, 
     variables   => { 
         velocity           => { $:growth_constant * $:x }, 
         growth_constant    => { 1 }, # basal growth rate 
     }, 
     initials    => { 
         x       => 3, 
     }, 
     captures    => ('x'), 
 ); 
 
 $m.integrate(:from(0), :to(8), :min-resolution(0.5)); 
 $m.render-svg('population growth malthus.svg', :title('population growth')); 

To fully understand what is going on, let's go through it step by step.

Step by step explanation

At this point our model is set. We need to run the simulation and render a cool plot about our results:

$m.integrate(:from(0), :to(8), :min-resolution(0.5)); 
 $m.render-svg('population growth malthus.svg', :title('population growth')); 

There, we select our time limits and the resolution. Next, we generate a plot. All understood? Well, let's see our result!

link to the image

Looks great! But to be honest, it is quite unrepresentative. Let's explore other examples from more complex situations!

Logistic model

Resources aren't infinite and our population is not going to grow forever. P-F Verhulst thought the same thing, so he presented the logistic model. This model is a common model of population growth, where the rate of reproduction is proportional to both the existing population and the amount of available resources, all else being equal. It looks like this:

dx/dt = g*x*(1-x/k)

x(0)=x_0

where the constant g defines the growth rate and k is the carrying capacity. Modifying the above code we can simulate its behavior in time:

use Math::Model; 
 
 my $m = Math::Model.new( 
     derivatives => { 
         velocity => 'x', 
     }, 
     variables   => { 
         velocity           => { $:growth_constant * $:x - $:growth_constant * $:x * $:x / $:k }, 
         growth_constant    => { 1 },   # basal growth rate 
         k                  => { 100 }, # carrying capacity 
     }, 
     initials    => { 
         x       => 3, 
     }, 
     captures    => ('x'), 
 ); 
 
 $m.integrate(:from(0), :to(8), :min-resolution(0.5)); 
 $m.render-svg('population growth logistic.svg', :title('population growth')); 

Let's look at our cool plot: link to the image

As you can see population growths till a maximum.

Strong Allee Effect

Interesting, isn't it? Even if these equations seem basic they are linked to a lot of behaviors in our world, like tumor growth. But, before end, let me show you a curious case. Logistic model could be accurate but... What happens when, from a certain threshold, the population size is so small that the survival rate and / or the reproductive rate drops due to the individual's inability to find other ones?

Well, this is an interesting phenomenon described by W.C.Allee, usually known as Allee effect. A simple way to obtain different behaviors associated with this effect is to use the logistic model as a departure, add some terms, and get a cubic growth model like this one:

dx/dt=r*x*(x/a-1)*(1-x/k)

where all the constants are the same as before and A is called critical point.

Our code would be:

use Math::Model; 
 
 my $m = Math::Model.new( 
     derivatives => { 
         velocity_x    => 'x', 
     }, 
     variables   => { 
         velocity_x           => { $:growth_constant * $:x *($:x/$:a -1)*(1- $:x/$:k) }, 
         growth_constant    => { 0.7 },   # basal growth rate 
         k                  => { 100 }, # carrying capacity 
         a                  => { 15 },  # critical point 
     }, 
     initials    => { 
         x       => 15, 
     }, 
     captures    => ('x'), 
 ); 
 
 $m.integrate(:from(0), :to(100), :min-resolution(0.5)); 
 $m.render-svg('population growth allee.svg', :title('population growth')); 

Try to execute this one yourself to see the different behaviors that arise when you change the initial condition around the critical point!

Weak Allee Effect

Whilst the strong Allee effect is a demographic Allee effect with a critical population size or density, the weak Allee effect is a demographic Allee effect without a critical population size or density, i.e., a population exhibiting a weak Allee effect will possess a reduced per capita growth rate at lower population density or size. However, even at this low population size or density, the population will always exhibit a positive per capita growth rate. This model differs lightly from the strong one, getting a new formula:

dx/dt=r*x*(1-x/k)*(x/a)**n, with n>0

Our code would be:

use Math::Model; 
 
 my $m = Math::Model.new( 
     derivatives => { 
         velocity_x => 'x', 
     }, 
     variables   => { 
         velocity_x           => { $:growth_constant * $:x *(1- $:x/$:k)*($:x/$:a)**$:n }, 
         growth_constant    => { 0.7 },   # basal growth rate 
         k                  => { 100 }, # carrying capacity 
         a                  => { 15 },  # critical point 
         n                  => { 4  } 
     }, 
     initials    => { 
         x       => 15, 
     }, 
     captures    => ('x'), 
 ); 
 
 $m.integrate(:from(0), :to(100), :min-resolution(0.5)); 
 $m.render-svg('population growth allee.svg', :title('population growth')); 

Extra info

Do you like physics? Check the original post by the creator of the modules that have been used, Moritz Lenz: https://perlgeek.de/blog-en/perl-6/physical-modelling.html.

21 Entering unicode characters

Input methods for unicode characters in terminals, the shell, and editors

Perl 6 allows the use of unicode characters as variable names. Many operators are defined with unicode symbols (in particular the set/bag operators) as well as some quoting constructs. Hence it is good to know how to enter these symbols into editors, the Perl 6 shell and the command line, especially if the symbols aren't available as actual characters on a keyboard.

General information about entering unicode under various operating systems and environments can be found on the Wikipedia unicode input page.

XCompose (Linux)

Xorg includes digraph support using a Compose key . The default of AltGr + Shift can be remapped to something easier such as Capslock. In GNOME 2 and MATE this can be setup under Preferences → Keyboard → Layouts → Options → Position of Compose Key. So, for example, to input »+« you could type CAPSLOCK > > + CAPSLOCK < <

XCompose allows customizing the digraph sequences using a .XCompose file and https://github.com/kragen/xcompose/blob/master/dotXCompose is an extremely complete one. In GNOME, XCompose was overridden and replaced with a hardcoded list, but it is possible to restore XCompose by setting GTK_IM_MODULE=xim in your environment. It might be necessary to install a xim bridge as well, such as uim-xim.

Getting compose working in all programs

You may have issues using the compose key in all programs. In that case you can try ibus.

input_module=xim 
 export GTK_IM_MODULE=$input_module 
 export XMODIFIERS=@im=$input_module 
 export QT_IM_MODULE=$input_module 

If you want this to be for all users you can put this in a file /etc/profile.d/compose.sh, which is the easiest way, since you won't have to deal with how different GUI environments set up their environment variables.

If you use KDE you can put this file in ~/.config/plasma-workspace/env/compose.sh and that should work. Other desktop environments will be different. Look up how to set environment variables in yours or use the system-wide option above.

ibus

If you have problems entering high codepoint symbols such as 🐧 using the xim input module, you can instead use ibus. You will have to install the ibus package for your distribution. Then you will have to set it to start on load of your Desktop environment. The command that needs to be run is:

ibus-daemon --xim --verbose --daemonize --replace 

Setting --xim should also allow programs not using ibus to still use the xim input method and be backward compatible.

KDE

If you are using KDE, open the start menu and type in “Autostart” and click Autostart which should be the first result. In the settings window that opens, click Add program, type in ibus-daemon and click OK. Then go into the Application tab of the window that pops up. In the Command field, enter in the full ibus-daemon command as shown above, with the --desktop option set to --desktop=plasma. Click OK. It should now launch automatically when you log in again.

WinCompose (Windows)

WinCompose adds compose key functionality to Windows. It can be installed either via the WinCompose releases page on GitHub, or with the Chocolatey package manager.

Once the program is installed and running, right click the tray icon and select Options → Composing → Behavior → Compose Key to set your desired key.

WinCompose has multiple sources to choose from in Options → Composing → Sequences. It is recommended to enable XCompose and disable Xorg, as there are a handful of operators which Xorg does not provide sequences for, and Xorg also has sequences which conflict with operator sequences present in XCompose. Sequences can be viewed by right clicking the tray icon and selecting Show Sequences. If you wish to add your own sequences, you can do so by either adding/modifying .XCompose in %USERPROFILE%, or editing user-defined sequences in the options menu.

Terminals, shells, and editors:

XTerm

Unicode support is enabled in XTerm primarily by setting its utf8 and utf8Fonts options to 1, along with its locale option to UTF-8, in ~/.Xdefaults. Here is a sample configuration that supports displaying enough of unicode to program in Perl 6:

XTerm*faceName:           xft:Noto Mono:style=Regular 
 XTerm*faceNameDoublesize: xft:Noto Emoji:style=Regular 
 XTerm*faceSize:           10 
 XTerm*locale:             UTF-8 
 XTerm*titleModes:         16 
 XTerm*utf8:               1 
 XTerm*utf8Fonts:          1 
 XTerm*utf8Title:          true 

URxvt

Similarly to XTerm, unicode support is enabled in URxvt primarily by setting its locale option to en_US.UTF-8 in ~/.Xdefaults. Here is a sample configuration that supports displaying enough of unicode to program in Perl 6:

URxvt*font:              xft:Noto Mono:pixelsize=14:style=Regular,\ 
                          xft:Noto Emoji:pixelsize=14:style=Regular 
 URxvt*letterSpace:       -1 
 URxvt*locale:            en_US.UTF-8 
 URxvt*skipBuiltInGlyphs: true 

Unix shell

At the bash shell, one enters unicode characters by using entering Ctrl-Shift-u, then the unicode code point value followed by enter. For instance, to enter the character for the element-of operator (∈) use the following key combination (whitespace has been added for clarity):

Ctrl-Shift-u 2208 Enter 

This also the method one would use to enter unicode characters into the perl6 REPL, if one has started the REPL inside a Unix shell.

Screen

GNU Screen does sport a digraph command but with a rather limited digraph table. Thanks to bindkey and exec an external program can be used to insert characters to the current screen window.

bindkey ^K exec .! digraphs 

This will bind control-k to the shell command digraphs. You can use digraphs if you prefer a Perl 6 friendly digraph table over RFC 1345 or change it to your needs.

Vim

In Vim, unicode characters are entered (in insert-mode) by pressing first Ctrl-V (also denoted ^V), then u and then the hexadecimal value of the unicode character to be entered. For example, the Greek letter λ (lambda) is entered via the key combination:

^Vu03BB 

You can also use Ctrl-K/^K along with a digraph to type in some characters. So an alternative to the above using digraphs looks like this:

^Kl* 

The list of digraphs Vim provides is documented here; you can add your own with the :digraph command.

Further information about entering special characters in Vim can be found on the Vim Wikia page about entering special characters.

vim-perl6

The vim-perl6 plugin for Vim can be configured to optionally replace ASCII based ops with their Unicode based equivalents. This will convert the ASCII based ops on the fly while typing them.

Emacs

In Emacs, unicode characters are entered by first entering the chord C-x 8 RET at which point the text Unicode (name or hex): appears in the minibuffer. One then enters the unicode code point hexadecimal number followed by the enter key. The unicode character will now appear in the document. Thus, to enter the Greek letter λ (lambda), one uses the following key combination:

C-x 8 RET 3bb RET 

Further information about unicode and its entry into Emacs can be found on the Unicode Encoding Emacs wiki page.

You can also use RFC 1345 character mnemonics by typing:

C-x RET C-\ rfc1345 RET 

Or C-u C-\ rfc1345 RET.

To type special characters, type & followed by a mnemonic. Emacs will show the possible characters in the echo area. For example, Greek letter λ (lambda) can be entered by typing:

&l* 

You can use C-\ to toggle input method.

Another input method you can use to insert special characters is TeX. Select it by typing C-u C-\ TeX RET. You can enter a special character by using a prefix such as \. For example, to enter λ, type:

\lambda 

To view characters and sequences provided by an input method, run the describe-input-method command:

C-h I TeX 

Some characters useful in Perl 6

Smart quotes

These characters are used in different languages as quotation marks. In Perl 6 they are used as quoting characters

Constructs such as these are now possible:

say 「What?!」;
say ”Whoa!“;
say „This works too!”;
say „There are just too many ways“;
say “here: “no problem” at all!”; # You can nest them!

This is very useful in shell:

perl6 -e 'say ‘hello world’' 

since you can just copy and paste some piece of code and not worry about quotes.

Guillemets

These characters are used in French and German as quotation marks. In Perl 6 they are used as interpolation word quotes, hyper operators and as an angle bracket alternative in POD6.

symbol unicode code point ascii equivalent
« U+00AB <<
» U+00BB >>

Thus constructs such as these are now possible:

say (1, 2) »+« (3, 4);     # OUTPUT: «(4 6)␤» - element-wise add
[1, 2, 3] »+=» 42;         # add 42 to each element of @array
say «moo»;                 # OUTPUT: «moo␤»

my $baa = "foo bar";
say «$baa $baa ber».perl;  # OUTPUT: «("foo", "bar", "foo", "bar", "ber")␤»

Set/bag operators

The set/bag operators all have set-theory-related symbols, the unicode code points and their ascii equivalents are listed below. To compose such a character, it is merely necessary to enter the character composition chord (e.g. Ctrl-V u in Vim; Ctrl-Shift-u in Bash) then the unicode code point hexadecimal number.

operator unicode code point ascii equivalent
U+2208 (elem)
U+2209 !(elem)
U+220B (cont)
U+220C !(cont)
U+2286 (<=)
U+2288 !(<=)
U+2282 (<)
U+2284 !(<)
U+2287 (>=)
U+2289 !(>=)
U+2283 (>)
U+2285 !(>)
U+222A (|)
U+2229 (&)
U+2216 (-)
U+2296 (^)
U+228D (.)
U+228E (+)

Mathematical symbols

Wikipedia contains a full list of mathematical operators and symbols in unicode as well as links to their mathematical meaning.

Greek characters

Greek characters may be used as variable names. For a list of Greek and Coptic characters and their unicode code points see the Greek in Unicode Wikipedia article.

For example, to assign the value 3 to π, enter the following in Vim (whitespace added to the compose sequences for clarity):

my $ Ctrl-V u 03C0  = 3;  # same as: my $π = 3; 
 say $ Ctrl-V u 03C0 ;     # 3    same as: say $π; 

Superscripts and subscripts

A limited set of superscripts and subscripts can be created directly in unicode by using the U+207x, U+208x and (less often) the U+209x ranges. However, to produce a value squared (to the power of 2) or cubed (to the power of 3), one needs to use U+00B2 and U+00B3 since these are defined in the Latin1 supplement Unicode block.

Thus, to write the Taylor series expansion around zero of the function exp(x) one would input into e.g. vim the following:

exp(x) = 1 + x + x Ctrl-V u 00B2 /2! + x Ctrl-V u 00B3 /3! 
 + ... + x Ctrl-V u 207F /n! 
 # which would appear as 
 exp(x) = 1 + x + x²/2! + x³/3! + ... + xⁿ/n! 

Or to specify the elements in a list from 1 up to k:

A Ctrl-V u 2081 , A Ctrl-V u 2082 , ..., A Ctrl-V u 2096 
 # which would appear as 
 A₁, A₂, ..., Aₖ 

22 Grammar tutorial

An introduction to grammars

Before we start

Why grammars?

Grammars parse strings and return data structures from those strings. Grammars can be used to prepare a program for execution, to determine if a program can run at all (if it's a valid program), to break down a web page into constituent parts, or to identify the different parts of a sentence, among other things.

When would I use grammars?

If you have strings to tame or interpret, grammars provide the tools to do the job.

The string could be a file that you're looking to break into sections; perhaps a protocol, like SMTP, where you need to specify which "commands" come after what user-supplied data; maybe you're designing your own domain specific language. Grammars can help.

The broad concept of grammars

Regular expressions (Regexes) work well for finding patterns in strings. However, for some tasks, like finding multiple patterns at once, or combining patterns, or testing for patterns that may surround strings regular expressions, alone, are not enough.

When working with HTML, you could define a grammar to recognize HTML tags, both the opening and closing elements, and the text in between. You could then organize these elements into data structures, such as arrays or hashes.

Getting more technical

The conceptual overview

Grammars are a special kind of class. You declare and define a grammar exactly as you would any other class, except that you use the grammar keyword instead of class.

grammar G { ... } 

As such classes, grammars are made up of methods that define a regex, a token, or a rule. These are all varieties of different types of match methods. Once you have a grammar defined, you call it and pass in a string for parsing.

my $matchObject = G.parse($string); 

Now, you may be wondering, if I have all these regexes defined that just return their results, how does that help with parsing strings that may be ahead or backwards in another string, or things that need to be combined from many of those regexes... And that's where grammar actions come in.

For every "method" you match in your grammar, you get an action you can use to act on that match. You also get an overarching action that you can use to tie together all your matches and to build a data structure. This overarching method is called TOP by default.

The technical overview

As already mentioned, grammars are declared using the grammar keyword and its "methods" are declared with regex, or token, or rule.

When a method (regex, token or rule) matches in the grammar, the string matched is put into a match object and keyed with the same name as the method.

grammar G { 
     token TOP { <thingy> .* } 
     token thingy { 'clever_text_keyword' } 
 } 

If you were to use my $match = G.parse($string) and your string started with 'clever_text_keyword', you would get a match object back that contained 'clever_text_keyword' keyed by the name of <thingy> in your match object. For instance:

grammar G { 
     token TOP { <thingy> .* } 
     token thingy { 'Þor' } 
 } 
 
 my $match = G.parse("Þor is mighty"); 
 say $match.perl;     # OUTPUT: «Match.new(made => Any, pos => 13, orig => "Þor is mighty",...» 
 say $/.perl;         # OUTPUT: «Match.new(made => Any, pos => 13, orig => "Þor is mighty",...» 
 say $/<thingy>.perl; 
 # OUTPUT: «Match.new(made => Any, pos => 3, orig => "Þor is mighty", hash => Map.new(()), list => (), from => 0)␤» 

The two first output lines show that $match contains a Match objects with the results of the parsing; but those results are also assigned to the match variable $/. Either match object can be keyed, as indicated above, by thingy to return the match for that particular token.

The TOP method (whether regex, token, or rule) is the overarching pattern that must match everything (by default). If the parsed string doesn't match the TOP regex, your returned match object will be empty (Nil).

As you can see above, in TOP, the <thingy> token is mentioned. The <thingy> is defined on the next line. That means that 'clever_text_keyword' must be the first thing in the string, or the grammar parse will fail and we'll get an empty match. This is great for recognizing a malformed string that should be discarded.

Learning by example - a REST contrivance

Let's suppose we'd like to parse a URI into the component parts that make up a RESTful request. We want the URIs to work like this:

So, if we have "/product/update/7/notify", we would want our grammar to give us a match object that has a subject of "product", a command of "update", and data of "7/notify".

We'll start by defining a grammar class and some match methods for the subject, command, and data. We'll use the token declarator since we don't care about whitespace.

grammar REST { 
     token subject { \w+ } 
     token command { \w+ } 
     token data    { .* } 
 } 

So far, this REST grammar says we want a subject that will be just word characters, a command that will be just word characters, and data that will be everything else left in the string.

Next, we'll want to arrange these matching tokens within the larger context of the URI. That's what the TOP method allows us to do. We'll add the TOP method and place the names of our tokens within it, together with the rest of the patterns that makes up the overall pattern. Note how we're building a larger regex from our named regexes.

grammar REST { 
     token TOP     { '/' <subject> '/' <command> '/' <data> } 
     token subject { \w+ } 
     token command { \w+ } 
     token data    { .* } 
 } 

With this code, we can already get the three parts of our RESTful request:

my $match = REST.parse('/product/update/7/notify'); 
 say $match; 
 
 # OUTPUT: «「/product/update/7/notify」␤ 
 #          subject => 「product」 
 #          command => 「update」 
 #          data => 「7/notify」» 

The data can be accessed directly by using $match<subject> or $match<command> or $match<data> to return the values parsed. They each contain match objects that you can work further with, such as coercing into a string ( $match<command>.Str ).

Adding some flexibility

So far, the grammar will handle retrieves, deletes and updates. However, a create command doesn't have the third part (the data portion). This means the grammar will fail to match if we try to parse a create URI. To avoid this, we need to make that last data position match optional, along with the '/' preceding it. This is accomplished by adding a question mark to the grouped '/' and data components of the TOP token, to indicate their optional nature, just like a normal regex.

So, now we have:

grammar REST { 
     token TOP     { '/' <subject> '/' <command> [ '/' <data> ]? } 
     token subject { \w+ } 
     token command { \w+ } 
     token data    { .* } 
 } 
 
 my $m = REST.parse('/product/create'); 
 say $m<subject>, $m<command>; 
 
 # OUTPUT: «「product」「create」␤» 

Next, assume that the URIs will be entered manually by a user and that the user might accidentally put spaces between the '/'s. If we wanted to accommodate for this, we could replace the '/'s in TOP with a token that allowed for spaces.

grammar REST { 
     token TOP     { <slash><subject><slash><command>[<slash><data>]? } 
     token subject { \w+ } 
     token command { \w+ } 
     token data    { .* } 
 
     token slash   { \s* '/' \s* } 
 } 
 
 my $m = REST.parse('/ product / update /7 /notify'); 
 say $m; 
 
 # OUTPUT: «「/ product / update /7 /notify」␤ 
 #          slash => 「/ 」 
 #          subject => 「product」 
 #          slash => 「 / 」 
 #          command => 「update」 
 #          slash => 「 /」 
 #          data => 「7 /notify」» 

We're getting some extra junk in the match object now, with those slashes. There's techniques to clean that up that we'll get to later.

Inheriting from a grammar

Since grammars are classes, they behave, OOP-wise, in the same way as any other class; specifically, they can inherit from base classes that include some tokens or rules, this way:

grammar Letters { 
     token letters { \w+ } 
 } 
 
 grammar Quote-Quotes { 
     token quote { "\""|"`"|"'" } 
 } 
 
 grammar Quote-Other { 
     token quote { "|"|"/"|"¡" } 
 } 
 
 grammar Quoted-Quotes is Letters is Quote-Quotes { 
     token TOP { ^  <quoted> $} 
     token quoted { <quote>? <letters> <quote>?  } 
 } 
 
 grammar Quoted-Other is Letters is Quote-Other { 
     token TOP { ^  <quoted> $} 
     token quoted { <quote>? <letters> <quote>?  } 
 } 
 
 my $quoted = q{"enhanced"}; 
 my $parsed = Quoted-Quotes.parse($quoted); 
 say $parsed; 
 #OUTPUT: 
 #「"enhanced"」 
 # quote => 「"」 
 # letters => 「enhanced」 
 #quote => 「"」 
 
 $quoted = "|barred|"; 
 $parsed = Quoted-Other.parse($quoted); 
 say $parsed; 
 #OUTPUT: 
 #|barred|」 
 #quote => 「|」 
 #letters => 「barred」 
 #quote => 「|」 

This example uses multiple inheritance to compose two different grammars by varying the rules that correspond to quotes. In this case, besides, we are rather using composition than inheritance, so we could use Roles instead of inheritance.

role Letters { 
     token letters { \w+ } 
 } 
 
 role Quote-Quotes { 
     token quote { "\""|"`"|"'" } 
 } 
 
 role Quote-Other { 
     token quote { "|"|"/"|"¡" } 
 } 
 
 grammar Quoted-Quotes does Letters does Quote-Quotes { 
     token TOP { ^  <quoted> $} 
     token quoted { <quote>? <letters> <quote>?  } 
 } 
 
 grammar Quoted-Other does Letters does Quote-Other { 
     token TOP { ^  <quoted> $} 
     token quoted { <quote>? <letters> <quote>?  } 
 
 } 

Will output exactly the same as the code above. Symptomatic of the difference between Classes and Roles, a conflict like defining token quote twice using Role composition will result in an error:

grammar Quoted-Quotes does Letters does Quote-Quotes does Quote-Other { ... } 
 # OUTPUT: ... Error while compiling ... Method 'quote' must be resolved ... 

Adding some constraints

We want our RESTful grammar to allow for CRUD operations only. Anything else we want to fail to parse. That means our "command" above should have one of four values: create, retrieve, update or delete.

There are several ways to accomplish this. For example, you could change the command method:

token command { \w+ } 
 
 # …becomes… 
 
 token command { 'create'|'retrieve'|'update'|'delete' } 

For a URI to parse successfully, the second part of the string between '/'s must be one of those CRUD values, otherwise the parsing fails. Exactly what we want.

There's another technique that provides greater flexibility and improved readability when options grow large: proto-regexes.

To utilize these proto-regexes (multimethods, in fact) to limit ourselves to the valid CRUD options, we'll replace token command with the following:

proto token command {*} 
 token command:sym<create>   { <sym> } 
 token command:sym<retrieve> { <sym> } 
 token command:sym<update>   { <sym> } 
 token command:sym<delete>   { <sym> } 

The sym keyword is used to create the various proto-regex options. Each option is named (e.g., sym<update>), and for that option's use, a special <sym> token is auto-generated with the same name.

The <sym> token, as well as other user-defined tokens, may be used in the proto-regex option block to define the specific match condition. Regex tokens are compiled forms and, once defined, cannot subsequently be modified by adverb actions (e.g., :i). Therefore, as it's auto-generated, the special <sym> token is useful only where an exact match of the option name is required.

If, for one of the proto-regex options, a match condition occurs, then the whole proto's search terminates. The matching data, in the form of a match object, is assigned to the parent proto token. If the special <sym> token was employed and formed all or part of the actual match, then it's preserved as a sub-level in the match object, otherwise it's absent.

Using proto-regex like this gives us a lot of flexibility. For example, instead of returning <sym>, which in this case is the entire string that was matched, we could instead enter our own string, or do other funny stuff. We could do the same with the token subject method and limit it also to only parsing correctly on valid subjects (like 'part' or 'people', etc.).

Putting our RESTful grammar together

This is what we have for processing our RESTful URIs, so far:

grammar REST 
 { 
     token TOP { <slash><subject><slash><command>[<slash><data>]? } 
 
     proto token command {*} 
     token command:sym<create>   { <sym> } 
     token command:sym<retrieve> { <sym> } 
     token command:sym<update>   { <sym> } 
     token command:sym<delete>   { <sym> } 
 
     token subject { \w+ } 
     token data    { .* } 
     token slash   { \s* '/' \s* } 
 } 

Let's look at various URIs and see how they work with our grammar.

my @uris = ['/product/update/7/notify', 
             '/product/create', 
             '/item/delete/4']; 
 
 for @uris -> $uri { 
     my $m = REST.parse($uri); 
     say "Sub: $m<subject> Cmd: $m<command> Dat: $m<data>"; 
 } 
 
 # OUTPUT: «Sub: product Cmd: update Dat: 7/notify␤ 
 #          Sub: product Cmd: create Dat: ␤ 
 #          Sub: item Cmd: delete Dat: 4␤» 

Note that since <data> matches nothing on the second string, $m<data> will be Nil, then using it in string context in the say function warns.

With just this part of a grammar, we're getting almost everything we're looking for. The URIs get parsed and we get a data structure with the data.

The data token returns the entire end of the URI as one string. The 4 is fine. However from the '7/notify', we only want the 7. To get just the 7, we'll use another feature of grammar classes: actions.

Grammar actions

Grammar actions are used within grammar classes to do things with matches. Actions are defined in their own classes, distinct from grammar classes.

You can think of grammar actions as a kind of plug-in expansion module for grammars. A lot of the time you'll be happy using grammars all by their own. But when you need to further process some of those strings, you can plug in the Actions expansion module.

To work with actions, you use a named parameter called actions which should contain an instance of your actions class. With the code above, if our actions class called REST-actions, we would parse the URI string like this:

my $matchObject = REST.parse($uri, actions => REST-actions.new); 
 
 #   …or if you prefer… 
 
 my $matchObject = REST.parse($uri, :actions(REST-actions.new)); 

If you name your action methods with the same name as your grammar methods (tokens, regexes, rules), then when your grammar methods match, your action method with the same name will get called automatically. The method will also be passed the corresponding match object (represented by the $/ variable).

Let's turn to an example.

Grammars by example with actions

Here we are back to our grammar.

grammar REST 
 { 
     token TOP { <slash><subject><slash><command>[<slash><data>]? } 
 
     proto token command {*} 
     token command:sym<create>   { <sym> } 
     token command:sym<retrieve> { <sym> } 
     token command:sym<update>   { <sym> } 
     token command:sym<delete>   { <sym> } 
 
     token subject { \w+ } 
     token data    { .* } 
     token slash   { \s* '/' \s* } 
 } 

Recall that we want to further process the data token "7/notify", to get the 7. To do this, we'll create an action class that has a method with the same name as the named token. In this case, our token is named data so our method is also named data.

class REST-actions 
 { 
     method data($/) { $/.split('/') } 
 } 

Now when we pass the URI string through the grammar, the data token match will be passed to the REST-actions' data method. The action method will split the string by the '/' character and the first element of the returned list will be the ID number (7 in the case of "7/notify").

But not really; there's a little more.

Keeping grammars with actions tidy with make and made

If the grammar calls the action above on data, the data method will be called, but nothing will show up in the big TOP grammar match result returned to our program. In order to make the action results show up, we need to call make on that result. The result can be many things, including strings, array or hash structures.

You can imagine that the make places the result in a special contained area for a grammar. Everything that we make can be accessed later by made.

So instead of the REST-actions class above, we should write:

class REST-actions 
 { 
     method data($/) { make $/.split('/') } 
 } 

When we add make to the match split (which returns a list), the action will return a data structure to the grammar that will be stored separately from the data token of the original grammar. This way, we can work with both if we need to.

If we want to access just the ID of 7 from that long URI, we access the first element of the list returned from the data action that we made:

my $uri = '/product/update/7/notify'; 
 
 my $match = REST.parse($uri, actions => REST-actions.new); 
 
 say $match<data>.made[0];  # OUTPUT: «7␤» 
 say $match<command>.Str;   # OUTPUT: «update␤» 

Here we call made on data, because we want the result of the action that we made (with make) to get the split array. That's lovely! But, wouldn't it be lovelier if we could make a friendlier data structure that contained all of the stuff we want, rather than having to coerce types and remember arrays?

Just like Grammar's TOP, which matches the entire string, actions have a TOP method as well. We can make all of the individual match components, like data or subject or command, and then we can place them in a data structure that we will make in TOP. When we return the final match object, we can then access this data structure.

To do this, we add the method TOP to the action class and make whatever data structure we like from the component pieces.

So, our action class becomes:

class REST-actions 
 { 
     method TOP ($/) { 
         make { subject => $<subject>.Str, 
                command => $<command>.Str, 
                data    => $<data>.made } 
     } 
 
     method data($/) { make $/.split('/') } 
 } 

Here in the TOP method, the subject remains the same as the subject we matched in the grammar. Also, command returns the valid <sym> that was matched (create, update, retrieve, or delete). We coerce each into .Str, as well, since we don't need the full match object.

We want to make sure to use the made method on the $<data> object, since we want to access the split one that we made with make in our action, rather than the proper $<data> object.

After we make something in the TOP method of a grammar action, we can then access all the custom values by calling the made method on the grammar result object. The code now becomes

my $uri = '/product/update/7/notify'; 
 
 my $match = REST.parse($uri, actions => REST-actions.new); 
 
 my $rest = $match.made; 
 say $rest<data>[0];   # OUTPUT: «7␤» 
 say $rest<command>;   # OUTPUT: «update␤» 
 say $rest<subject>;   # OUTPUT: «product␤» 

If the complete return match object is not needed, you could return only the made data from your action's TOP.

my $uri = '/product/update/7/notify'; 
 
 my $rest = REST.parse($uri, actions => REST-actions.new).made; 
 
 say $rest<data>[0];   # OUTPUT: «7␤» 
 say $rest<command>;   # OUTPUT: «update␤» 
 say $rest<subject>;   # OUTPUT: «product␤» 

Oh, did we forget to get rid of that ugly array element number? Hmm. Let's make something new in the grammar's custom return in TOP... how about we call it subject-id and have it set to element 0 of <data>.

class REST-actions 
 { 
     method TOP ($/) { 
         make { subject    => $<subject>.Str, 
                command    => $<command>.Str, 
                data       => $<data>.made, 
                subject-id => $<data>.made[0] } 
     } 
 
     method data($/) { make $/.split('/') } 
 } 

Now we can do this instead:

my $uri = '/product/update/7/notify'; 
 
 my $rest = REST.parse($uri, actions => REST-actions.new).made; 
 
 say $rest<command>;    # OUTPUT: «update␤» 
 say $rest<subject>;    # OUTPUT: «product␤» 
 say $rest<subject-id>; # OUTPUT: «7␤» 

Here's the final code:

grammar REST 
 { 
     token TOP { <slash><subject><slash><command>[<slash><data>]? } 
 
     proto token command {*} 
     token command:sym<create>   { <sym> } 
     token command:sym<retrieve> { <sym> } 
     token command:sym<update>   { <sym> } 
     token command:sym<delete>   { <sym> } 
 
     token subject { \w+ } 
     token data    { .* } 
     token slash   { \s* '/' \s* } 
 } 
 
 
 class REST-actions 
 { 
     method TOP ($/) { 
         make { subject    => $<subject>.Str, 
                command    => $<command>.Str, 
                data       => $<data>.made, 
                subject-id => $<data>.made[0] } 
     } 
 
     method data($/) { make $/.split('/') } 
 } 

Add actions directly

Above we see how to associate grammars with action objects and perform actions on the match object. However, when we want to deal with the match object, that isn't the only way. See the example below:

grammar G { 
   rule TOP { <function-define> } 
   rule function-define { 
     'sub' <identifier> 
     { 
       say "func " ~ $<identifier>.made; 
       make $<identifier>.made; 
     } 
     '(' <parameter> ')' '{' '}' 
     { say "end " ~ $/.made; } 
   } 
   token identifier { \w+ { make ~$/; } } 
   token parameter { \w+ { say "param " ~ $/; } } 
 } 
 
 G.parse('sub f ( a ) { }'); 
 # OUTPUT: «func f␤param a␤end f␤» 

This example is a reduced portion of a parser. Let's focus more on the feature it shows.

First, we can add actions inside the grammar itself, and such actions are performed once the control flow of the regex arrives at them. Note that action object's method will always be performed after the whole regex item matched. Second, it shows what make really does, which is no more than a sugar of $/.made = .... And this trick introduces a way to pass messages from within a regex item.

Hopefully this has helped introduce you to the grammars in Perl 6 and shown you how grammars and grammar action classes work together. For more information, check out the more advanced Perl Grammar Guide.

For more grammar debugging, see Grammar::Debugger. This provides breakpoints and color-coded MATCH and FAIL output for each of your grammar tokens.

23 Input/Output

File-related operations

Here we present a quick overview of the file-related input/output operations. Details can be found in the documentation for the IO role, as well as the IO::Handle and IO::Path types.

Reading from files

One way to read the contents of a file is to open the file via the open function with the :r (read) file mode option and slurp in the contents:

my $fh = open "testfile", :r; 
 my $contents = $fh.slurp; 
 $fh.close; 

Here we explicitly close the filehandle using the close method on the IO::Handle object. This is a very traditional way of reading the contents of a file. However, the same can be done more easily and clearly like so:

my $contents = "testfile".IO.slurp; 
 # or in procedural form: 
 $contents = slurp "testfile" 

By adding the IO role to the file name string, we are effectively able to refer to the string as the file object itself and thus slurp in its contents directly. Note that the slurp takes care of opening and closing the file for you.

Line by line

Of course, we also have the option to read a file line-by-line. The new line separator (i.e., $*IN.nl-in) will be excluded.

for 'huge-csv'.IO.lines -> $line { 
     # Do something with $line 
 } 
 
 # or if you'll be processing later 
 my @lines = 'huge-csv'.IO.lines; 

Writing to files

To write data to a file, again we have the choice of the traditional method of calling the open function – this time with the :w (write) option – and printing the data to the file:

my $fh = open "testfile", :w; 
 $fh.print("data and stuff\n"); 
 $fh.close; 

Or equivalently with say, thus the explicit newline is no longer necessary:

my $fh = open "testfile", :w; 
 $fh.say("data and stuff"); 
 $fh.close; 

We can simplify this by using spurt to open the file in write mode, writing the data to the file and closing it again for us:

spurt "testfile", "data and stuff\n"; 

By default all (text) files are written as UTF-8, however if necessary, an explicit encoding can be specified via the :enc option:

spurt "testfile", "latin1 text: äöüß", enc => "latin1"; 

To write formatted strings to a file, use the printf function of IO::Handle.

my $fh = open "testfile", :w; 
 $fh.printf("formatted data %04d\n", 42); 
 $fh.close; 

To append to a file, specify the :a option when opening the filehandle explicitly,

my $fh = open "testfile", :a; 
 $fh.print("more data\n"); 
 $fh.close; 

or equivalently with say, thus the explicit newline is no longer necessary,

my $fh = open "testfile", :a; 
 $fh.say("more data"); 
 $fh.close; 

or even simpler with the :append option in the call to spurt:

spurt "testfile", "more data\n", :append; 

To explicitly write binary data to a file, open it with the :bin option. The input/output operations then will take place using the Buf type instead of the Str type.

Copying and renaming files

Routines copy, rename, and move are available to avoid low-level system commands. See details at copy, rename, and move. Some examples:

my $filea = 'foo'; 
 my $fileb = 'foo.bak'; 
 my $filec = '/disk1/foo'; 
 # note 'diskN' is assumed to be a physical storage device 
 
 copy $filea, $fileb;              # overwrites $fileb if it exists 
 copy $filea, $fileb, :createonly; # fails if $fileb exists 
 
 rename $filea, 'new-foo';              # overwrites 'new-foo' if it exists 
 rename $filea, 'new-foo', :createonly; # fails if 'new-foo' exists 
 
 # use move when a system-level rename may not work 
 move $fileb, '/disk2/foo';              # overwrites '/disk2/foo' if it exists 
 move $fileb, '/disk2/foo', :createonly; # fails if '/disk2/foo' exists 

Checking files and directories

Use the e method on an IO::Handle object to test whether the file or directory exists.

if "nonexistent_file".IO.e { 
     say "file exists"; 
 } 
 else { 
     say "file doesn't exist"; 
 } 

It is also possible to use the colon pair syntax to achieve the same thing:

if "path/to/file".IO ~~ :e { 
     say 'file exists'; 
 } 
my $file = "path/to/file"; 
 if $file.IO ~~ :e { 
     say 'file exists'; 
 } 

Similarly to the file existence check, one can also check to see if a path is a directory. For instance, assuming that the file testfile and the directory lib exist, we would obtain from the existence test method e the same result, namely that both exist:

say "testfile".IO.e;  # OUTPUT: «True␤» 
 say "lib".IO.e;       # OUTPUT: «True␤» 

However, since only one of them is a directory, the directory test method d will give a different result:

say "testfile".IO.d;  # OUTPUT: «False␤» 
 say "lib".IO.d;       # OUTPUT: «True␤» 

Naturally the tables are turned if we check to see if the path is a file via the file test method f:

say "testfile".IO.f;  # OUTPUT: «True␤» 
 say "lib".IO.f;       # OUTPUT: «False␤» 

There are other methods that can be used to query a file or directory, some useful ones are:

my $f = "file"; 
 
 say $f.IO.modified; # return time of last file (or directory) change 
 say $f.IO.accessed; # return last time file (or directory) was read 
 say $f.IO.s;        # return size of file (or directory inode) in bytes 

See more methods and details at IO::Path.

Getting a directory listing

To list the contents of the current directory, use the dir function. It returns a list of IO::Path objects.

say dir;          # OUTPUT: «"/path/to/testfile".IO "/path/to/lib".IO␤»

To list the files and directories in a given directory, simply pass a path as an argument to dir:

say dir "/etc/";  # OUTPUT: «"/etc/ld.so.conf".IO "/etc/shadow".IO ....␤»

Creating and removing directories

To create a new directory, simply call the mkdir function with the directory name as its argument:

mkdir "newdir"; 

The function returns the name of the created directory on success and Nil on failure. Thus the standard Perl idiom works as expected:

mkdir "newdir" or die "$!"; 

Use rmdir to remove empty directories:

rmdir "newdir" or die "$!"; 

24 Inter-process communication

Programs running other programs and communicating with them

Running programs

Many programs need to be able to run other programs, and we need to pass information to them and receive their output and exit status. Running a program in Perl 6 is as easy as:

run 'git', 'status';

This line runs the program named "git" and passes "git" and "status" to its command-line. It will find the program using the %*ENV<PATH> setting.

If you would like to run a program by sending a command-line to the shell, there's a tool for that as well. All shell meta characters are interpreted by the shell, including pipes, redirects, environment variable substitutions and so on.

shell 'ls -lR | gzip -9 > ls-lR.gz';

Caution should be taken when using shell with user input.

The Proc object

Both run and shell return a Proc object, which can be used to communicate with the process in more detail. Please note that unless you close all output pipes, the program will usually not terminate.

my $git = run 'git', 'log', '--oneline', :out;
for $git.out.lines -> $line {
    my ($sha, $subject) = $line.split: ' ', 2;
    say "$subject [$sha]";
}
$git.out.close();

If the program fails (exits with a non-zero exit code), it will throw an exception when the returned Proc object is sunk. You can save it into a variable, even anonymous one, to prevent the sinking:

$ = run '/bin/false'; # does not sink the Proc and so does not throw

You can tell the Proc object to capture output as a filehandle by passing the :out and :err flags. You may also pass input via the :in flag.

my $echo = run 'echo', 'Hello, world', :out;
my $cat  = run 'cat', '-n', :in($echo.out), :out;
say $cat.out.get;
$cat.out.close();

You may also use Proc to capture the PID, send signals to the application, and check the exitcode.

my $crontab = run 'crontab', '-l';
if $crontab.exitcode == 0 {
    say 'crontab -l ran ok';
}
else {
    say 'something went wrong';
}

The Proc::Async object

When you need more control over the communication with and from another process, you will want to make use of Proc::Async. This class provides support for asynchronous communication with a program, as well as the ability to send signals to that program.

# Get ready to run the program 
 my $log = Proc::Async.new('tail', '-f',  '/var/log/system.log'); 
 $log.stdout.tap(-> $buf { print $buf }); 
 $log.stderr.tap(-> $buf { $*ERR.print($buf) }); 
 
 # Start the program 
 my $done = $log.start; 
 sleep 10; 
 
 # Tell the program to stop 
 $log.kill('QUIT'); 
 
 # Wait for the program to finish 
 await $done; 

The small program above uses the "tail" program to print out the contents of the log named system.log for 10 seconds and then tells the program to stop with a QUIT signal.

Whereas Proc provides access to output using IO::Handles, Proc::Async provides access using asynchronous supplies (see Supply).

If you want to run a program and do some work while you wait for the original program to finish, the start routine returns a Promise, which is kept when the program quits.

Use the write method to pass data into the program.

25 Iterating

Functionalities available for visiting all items in a complex data structure

The Iterator and Iterable roles

Perl 6 is a functional language, but functions need something to hold on to when working on complex data structures. In particular, they need a uniform interface that can be applied to all data structures in the same way. One of these kind of interfaces is provided by the Iterator and Iterable roles.

The Iterable role is relatively simple. It provides a stub for the iterator method, which is the one actually used by statements such as for. for will call .iterator on the variable it precedes, and then run a block once for every item. Other methods, such as array assignment, will make the Iterable class behave in the same way.

class DNA does Iterable { 
     has $.chain; 
     method new ($chain where { 
                        $chain ~~ /^^ <[ACGT]>+ $$ / and 
                        $chain.chars %% 3 } ) { 
         self.bless( :$chain ); 
     } 
 
     method iterator(DNA:D:){ $.chain.comb.rotor(3).iterator } 
 }; 
 
 my @longer-chain =  DNA.new('ACGTACGTT'); 
 say @longer-chain.perl; 
 # OUTPUT: «[("A", "C", "G"), ("T", "A", "C"), ("G", "T", "T")]␤» 
 
 say  @longer-chain».join("").join("|"); #OUTPUT: «ACG|TAC|GTT␤» 

In this example, which is an extension of the example in Iterable that shows how for calls .iterator, the iterator method will be called in the appropriate context only when the created object is assigned to a Positional variable, @longer-chain; this variable is an Array and we operate on it as such in the last example.

The (maybe a bit confusingly named) Iterator role is a bit more complex than Iterable. First, it provides a constant, IterationEnd. Then, it also provides a series of methods such as .pull-one, which allows for a finer operation of iteration in several contexts: adding or eliminating items, or skipping over them to access other items. In fact, the role provides a default implementation for all the other methods, so the only one that has to be defined is precisely pull-one, of which only a stub is provided by the role. While Iterable provides the high-level interface loops will be working with, Iterator provides the lower-level functions that will be called in every iteration of the loop. Let's extend the previous example with this role.

class DNA does Iterable does Iterator { 
     has $.chain; 
     has Int $!index = 0; 
 
     method new ($chain where { 
                        $chain ~~ /^^ <[ACGT]>+ $$ / and 
                        $chain.chars %% 3 } ) { 
         self.bless( :$chain ); 
     } 
 
     method iterator( ){ self } 
     method pull-one( --> Mu){ 
         if $!index < $.chain.chars { 
             my $codon = $.chain.comb.rotor(3)[$!index div 3]; 
             $!index += 3; 
             return $codon; 
         } else { 
             return IterationEnd; 
         } 
     } 
 }; 
 
 my $a := DNA.new('GAATCC'); 
 .say for $a; # OUTPUT: «(G A A)␤(T C C)␤» 

We declare a DNA class which does the two roles, Iterator and Iterable; the class will include a string that will be constrained to have a length that is a multiple of 3 and composed only of ACGT.

Let us look at the pull-one method. This one is going to be called every time a new iteration occurs, so it must keep the state of the last one. An $.index attribute will hold that state across invocations; pull-one will check if the end of the chain has been reached and will return the IterationEnd constant provided by the role. Implementing this low-level interface, in fact, simplifies the implementation of the Iterable interface. Now the iterator will be the object itself, since we can call pull-one on it to access every member in turn; .iterator will thus return just self; this is possible since the object will be, at the same time, Iterable and Iterator.

This need not always be the case, and in most cases .iterator will have to build an iterator type to be returned (that will, for instance, keep track of the iteration state, which we are doing now in the main class), such as we did in the previous example; however, this example shows the minimal code needed to build a class that fulfills the iterator and iterable roles.

How to iterate: contextualizing and topic variables

for and other loops place the item produced in every iteration into the topic variable $_, or capture them into the variables that are declared along with the block. These variables can be directly used inside the loop, without needing to declare them, by using the ^ twigil.

Implicit iteration occurs when using the sequence operator.

say 1,1,1, { $^a²+2*$^b+$^c } … * > 300; # OUTPUT: «(1 1 1 4 7 16 46 127 475)

The generating block is being run once while the condition to finish the sequence, in this case the term being bigger than 300, is not met. This has the side effect of running a loop, but also creating a list that is output.

This can be done more systematically through the use of the gather/take blocks, which are a different kind of iterating construct that instead of running in sink context, returns an item every iteration. This Advent Calendar tutorial explains use cases for this kind of loops; in fact, gather is not so much a looping construct, but a statement prefix that collects the items produced by take and creates a list out of them.

Classic loops and why we do not like them

Classic for loops, with a loop variable being incremented, can be done in Perl 6 through the loop keyword. Other repeat and while loops are also possible.

However, in general, they are discouraged. Perl 6 is a functional and concurrent language; when coding in Perl 6, you should look at loops in a functional way: processing, one by one, the items produced by an iterator, that is, feeding an item to a block without any kind of secondary effects. This functional view allows also easy parallelization of the operation via the hyper or race auto-threading methods.

If you feel more comfortable with your good old loops, the language allows you to use them. However, it is considered more p6y to try and use, whenever possible, functional and concurrent iterating constructs.

*Note: Since version 6.d loops can produce a list of values from the values of last statements.*

26 Module development utilities

What can help you write/test/improve your module(s)

Here is a list of modules that you can find in the Perl 6 ecosystem which aim to make the experience of developing Perl 6 modules more fun.

Module builder and authoring tools

Some modules and tools to help you with generating files that are part of a module distribution.

Tests

Some tests of module quality.

NativeCall

Here some modules to help you work with NativeCall.

Sample modules

Modules that exist only as minimalist examples, tests for installers, or skeletons.

27 Module packages

Creating module packages for code reuse

N.B. "Module" is an overloaded term in Perl 6; this document focuses on use of the module declarator.

What are modules?

Modules, like classes and grammars, are a kind of package. Module objects are instances of the ModuleHOW metaclass; this provides certain capabilities useful for creating namespaces, versioning, delegation and data encapsulation (see also class and role).

To create a module, use the module declarator:

module M {}
say M.HOW;   # OUTPUT: «Perl6::Metamodel::ModuleHOW.new␤»

Here we define a new module named M; introspection with HOW confirms that the metaclass underlying M is Perl6::Metamodel::ModuleHOW.

When to use modules

Modules are primarily useful for encapsulating code and data that do not belong inside a class or role definition. Module contents (classes, subroutines, variables, etc.) can be exported from a module with the is export trait; these are available in the caller's namespace once the module has been imported with import or use. A module can also selectively expose symbols within its namespace for qualified reference via our.

Working with modules

To illustrate module scoping and export rules, let's begin by defining a simple module M:

module M {
  sub greeting ($name = 'Camelia') { "Greetings, $name!" }
  our sub loud-greeting (--> Str)  { greeting().uc       }
  sub friendly-greeting is export  { greeting('friend')  }
}

Recall that subroutines are lexically scoped unless otherwise specified (declarator sub is equivalent to my sub), so greeting in the above example is lexically scoped to the module and inaccessible outside of it. We've also defined loud-greeting with the our declarator, which means that in addition to being lexically scoped it is aliased in the module's symbol table. Finally, friendly-greeting is marked for export; it will be registered in the caller's symbol table when the module is imported:

import M;               # import the module 
 say M::loud-greeting;   # OUTPUT: «GREETINGS, CAMELIA!␤» 
 say friendly-greeting;  # OUTPUT: «Greetings, friend!␤» 

Modules on disk

While .pm and .pm6 files (hereafter: .pm6) are sometimes referred to as "modules", they are really just normal files that are loaded and compiled when you write need, use or require.

For a .pm6 file to provide a module in the sense that we've been using, it needs to declare one with module as documented above. For example, by placing module M inside Foo.pm6, we can load and use the module as follows:

use Foo;                # find Foo.pm6, run need followed by import 
 say M::loud-greeting;   # OUTPUT: «GREETINGS, CAMELIA!␤» 
 say friendly-greeting;  # OUTPUT: «Greetings, friend!␤» 

Note the decoupling between file and module names—a .pm6 file can declare zero or more modules with arbitrary identifiers.

File and module naming

Often we want a .pm6 file to provide a single module and nothing more. Here a common convention is for the file basename to match the module name. Returning to Foo.pm6, it is apparent that it only provides a single module, M; in this case, we might want to rename M to Foo. The amended file would then read:

module Foo { 
   sub greeting ($name = 'Camelia') { "Greetings, $name!" } 
   our sub loud-greeting (--> Str)  { greeting().uc       } 
   sub friendly-greeting is export  { greeting('friend')  } 
 } 

which can be used more consistently by the caller (note the relationship between the use Foo and Foo::):

use Foo; 
 say Foo::loud-greeting;  # OUTPUT: «GREETINGS, CAMELIA!␤» 
 say friendly-greeting;   # OUTPUT: «Greetings, friend!␤» 

If Foo.pm6 is placed deeper within the source tree, e.g. at lib/Utils/Foo.pm6, we can elect to name the module Utils::Foo to maintain consistency.

The unit keyword

Files that only provide a single module can be written more concisely with the unit keyword; unit module specifies that the rest of the compilation unit is part of the declared module. Here's Foo.pm6 rewritten with unit:

unit module Foo; 
 
 sub greeting ($name = 'Camelia') { "Greetings, $name!" } 
 our sub loud-greeting (--> Str)  { greeting().uc       } 
 sub friendly-greeting is export  { greeting('friend')  } 

Everything following the unit declaration is part of the Foo module specification.

(Note that unit can also be used with class, grammar and role.)

What happens if I omit module?

To better understand what the module declarator is doing in Foo.pm6, let's contrast it with a variant file, Bar.pm6, that omits the declaration. The subroutine definitions below are almost identical (the only difference is in the body of greeting, modified for clarity):

sub greeting ($name = 'Camelia') { "Greetings from Bar, $name!" } 
 our sub loud-greeting (--> Str)  { greeting().uc                } 
 sub friendly-greeting is export  { greeting('friend')           } 

As a reminder, here's how we used Foo.pm6 before,

use Foo; 
 say Foo::loud-greeting;  # OUTPUT: «GREETINGS, CAMELIA!␤» 
 say friendly-greeting;   # OUTPUT: «Greetings, friend!␤» 

and here's how we use Bar.pm6,

use Bar; 
 say loud-greeting;       # OUTPUT: «GREETINGS FROM BAR, CAMELIA!␤» 
 say friendly-greeting;   # OUTPUT: «Greetings from Bar, friend!␤» 

Note the use of loud-greeting rather than Bar::loud-greeting as Bar is not a known symbol (we didn't create a module of that name in Bar.pm6). But why is loud-greeting callable even though we didn't mark it for export? The answer is simply that Bar.pm6 doesn't create a new package namespace—$?PACKAGE is still set to GLOBAL—so when we declare loud-greeting as our, it is registered in the GLOBAL symbol table.

Lexical aliasing and safety

Thankfully, Perl 6 protects us from accidentally clobbering call site definitions (e.g. builtins). Consider the following addition to Bar.pm6:

our sub say ($ignored) { print "oh dear\n" }

This creates a lexical alias, hiding the say builtin inside Bar.pm6 but leaving the caller's say unchanged. Consequently, the following call to say still works as expected:

use Bar; 
 say 'Carry on, carry on...';  # OUTPUT: «Carry on, carry on...␤» 

28 Modules

How to create, use and distribute Perl 6 modules

Creating and using modules

A module is usually a source file or set of source files that expose Perl 6 constructs.

Technically a module is a set of compunits which are usually files but could come from anywhere as long as there is a compunit repository that can provide it. See S11 .

Modules are typically packages (classes, roles, grammars), subroutines, and sometimes variables. In Perl 6 module can also refer to a type of package declared with the module keyword (see Module Packages and the examples below) but here we mostly mean "module" as a set of source files in a namespace.

Looking for and installing modules.

zef is the application used for installing modules in Perl 6. Modules are listed in the Perl 6 ecosystem and can be searched there or from the command line using zef search:

zef search WWW 

will return a list of modules that includes WWW in their name, for instance. Then,

zef install WWW 

will install the module with that particular name, if it is not already installed.

If it's installed, it will reinstall only if the version of the module is newer than the one installed

Basic structure

Module distributions (in the set of related source files sense) in Perl 6 have the same structure as any distribution in the Perl family of languages: there is a main project directory containing a README and a LICENSE file, a lib directory for the source files, which may be individually referred to as modules and/or may themselves define modules with the module keyword

As synopsis S11 says: Confusing? Yes it is.
, a t directory for tests, and possibly a bin directory for executable programs and scripts.

Source files generally use the .pm6 extension, and scripts or executables use the .p6. Test files use the .t extension. Files which contain documentation use the .pod6 extension.

Loading and basic importing

Loading a module makes the packages in the same namespace declared within available in the file scope of the loader. Importing from a module makes the symbols exported available in the lexical scope of the importing statement.

need

need loads a compunit at compile time.

need MyModule; 

Any packages in the namespace defined within will also be available.

# MyModule.pm6 
 unit module MyModule; 
 
 class Class {} 

MyModule::Class will be defined when MyModule is loaded, and you can use it directly employing its fully qualified name (FQN). Classes and other types defined that way are not automatically exported; you will need to explicitly export it if you want to use it by its short name:

# MyModule.pm6 
 unit module MyModule; 
 
 class Class is export {} 

And then

use MyModule; 
 
 my $class = Class.new(); 
 say $class.perl; 

use

use loads and then imports from a compunit at compile time. It will look for files that end in .pm6 (.pm is also supported, but discouraged). See here for where the runtime will look for modules.

use MyModule; 

This is equivalent to:

need  MyModule; 
 import MyModule; 

See also selective importing to restrict what you import.

require

require loads a compunit and imports definite symbols at runtime.

say "loading MyModule";
require MyModule;

The compunit name can be in a runtime variable if you put it inside an indirect lookup.

my $name = 'MyModule';
require ::($name);

The symbols provided by the loaded module will not be imported into the current scope. You may use dynamic lookup or dynamic subsets to use them by providing the fully qualified name of a symbol, for instance:

require ::("Test");
my &mmk = ::("Test::EXPORT::DEFAULT::&ok");
mmk('oi‽'); # OUTPUT: «ok 1 - ␤»

The FQN of ok is Test::EXPORT::DEFAULT::&ok. We are aliasing it to mmk so that we can use that symbol provided by Test in the current scope.

To import symbols you must define them at compile time. NOTE: require is lexically scoped:

sub do-something {
   require MyModule <&something>;
   say ::('MyModule'); # MyModule symbol exists here
   something() # &something will be defined here
}
say ::('MyModule'); # This will NOT contain the MyModule symbol
do-something();
# &something will not be defined here

If MyModule doesn't export &something then require will fail.

A require with compile-time symbol will install a placeholder package that will be updated to the loaded module, class, or package. Note that the placeholder will be kept, even if require failed to load the module. This means that checking if a module loaded like this is wrong:

# *** WRONG: ***
try require Foo;
if ::('Foo') ~~ Failure { say "Failed to load Foo!"; }
# *** WRONG: ***

As the compile-time installed package causes ::('Foo') to never be a Failure. The correct way is:

# Use return value to test whether loading succeeded:
(try require Foo) === Nil and say "Failed to load Foo!";

# Or use a runtime symbol lookup with require, to avoid compile-time
# package installation:
try require ::('Foo');
if ::('Foo') ~~ Failure {
    say "Failed to load Foo!";
}

Lexical module loading

Perl 6 takes great care to avoid global state, i.e. whatever you do in your module, it should not affect other code. For instance, that's why subroutine definitions are lexically (my) scoped by default. If you want others to see them, you need to explicitly make them our scoped or export them.

Classes are exported by default on the assumption that loading a module will not be of much use when you cannot access the classes it contains. Loaded classes are thus registered only in the scope which loaded them in the first place

This change was introduced in late 2016. If you are using versions older than this, behavior will be different
. This means that we will have to use a class in every scope in which we actually employ it.

use Foo;           # Foo has "use Bar" somewhere. 
 use Bar; 
 my $foo = Foo.new; 
 my $bar = Bar.new; 

Exporting and selective importing

is export

Packages, subroutines, variables, constants and enums are exported by marking them with the is export trait (also note the tags available for indicating authors and versions).

unit module MyModule:ver<1.0.3>:auth<John Hancock (jhancock@example.com)>; 
 our $var is export = 3; 
 sub foo is export { ... }; 
 constant FOO is export = "foobar"; 
 enum FooBar is export <one two three>; 
 
 # for multi methods, if you declare a proto you 
 # only need to mark the proto with is export 
 proto sub quux(Str $x, |) is export { * }; 
 multi sub quux(Str $x) { ... }; 
 multi sub quux(Str $x, $y) { ... }; 
 
 # for multi methods, you only need to mark one with is export 
 # but the code is most consistent if all are marked 
 multi sub quux(Str $x) is export { ... }; 
 multi sub quux(Str $x, $y) is export { ... }; 
 
 # Packages like classes can be exported too 
 class MyClass is export {}; 
 
 # If a subpackage is in the namespace of the current package 
 # it doesn't need to be explicitly exported 
 class MyModule::MyClass {}; 

As with all traits, if applied to a routine, is export should appear after any argument list.

sub foo(Str $string) is export { ... } 

You can pass named parameters to is export to group symbols for exporting so that the importer can pick and choose. There are three predefined tags: ALL, DEFAULT and MANDATORY.

# lib/MyModule.pm6 
 unit module MyModule; 
 sub bag        is export             { ... } 
 # objects with tag ':MANDATORY' are always exported 
 sub pants      is export(:MANDATORY) { ... } 
 sub sunglasses is export(:day)       { ... } 
 sub torch      is export(:night)     { ... } 
 sub underpants is export(:ALL)       { ... } 
# main.p6 
 use lib 'lib'; 
 use MyModule;          # bag, pants 
 use MyModule :DEFAULT; # the same 
 use MyModule :day;     # pants, sunglasses 
 use MyModule :night;   # pants, torch 
 use MyModule :ALL;     # bag, pants, sunglasses, torch, underpants 

Note: there currently is no way for the user to import a single object if the module author hasn't made provision for that, and it is not an easy task at the moment (see RT #127305). One way the author can provide such access is to give each export trait its own unique tag. (And the tag can be the object name!). Then the user can either (1) import all objects:

use Foo :ALL; 

or (2) import one or more objects selectively:

use Foo :bar, :s5; 

Notes:

1. The :MANDATORY tag on an exported sub ensures it will be exported no matter whether the using program adds any tag or not.

2. All exported subs without an explicit tag are implicitly :DEFAULT.

3. The space after the module name and before the tag is mandatory.

4. Multiple import tags may be used (separated by commas). For example:

# main.p6 
 use lib 'lib'; 
 use MyModule :day, :night; # pants, sunglasses, torch 

5. Multiple tags may be used in the export trait, but they must all be separated by either commas, or whitespace, but not both.

sub foo() is export(:foo :s2 :net) {} 
 sub bar() is export(:bar, :s3, :some) {} 

UNIT::EXPORT::*

Beneath the surface, is export is adding the symbols to a UNIT scoped package in the EXPORT namespace. For example, is export(:FOO) will add the target to the UNIT::EXPORT::FOO package. This is what Perl 6 is really using to decide what to import.

unit module MyModule; 
 
 sub foo is export { ... } 
 sub bar is export(:other) { ... } 

Is the same as:

unit module MyModule; 
 
 my package EXPORT::DEFAULT { 
     our sub foo { ... } 
 } 
 
 my package EXPORT::other { 
     our sub bar { ... } 
 } 

For most purposes, is export is sufficient but the EXPORT packages are useful when you want to produce the exported symbols dynamically. For example:

# lib/MyModule.pm6 
 unit module MyModule; 
 
 my package EXPORT::DEFAULT { 
    for <zero one two three four>.kv -> $number, $name { 
       for <sqrt log> -> $func { 
          OUR::{'&' ~ $func ~ '-of-' ~ $name } := sub { $number."$func"() }; 
       } 
    } 
 } 
 
# main.p6 
 use MyModule; 
 say sqrt-of-four; # OUTPUT: «2␤» 
 say log-of-zero;  # OUTPUT: «-Inf␤» 

EXPORT

You can export arbitrary symbols with an EXPORT sub. EXPORT must return a Map, where the keys are the symbol names and the values are the desired values. The names should include the sigil (if any) for the associated type.

# lib/MyModule.pm6 
 
 class MyModule::Class { } 
 
 sub EXPORT { 
     %( 
       '$var'      => 'one', 
       '@array'    => <one two three>, 
       '%hash'     => %( one => 'two', three => 'four' ), 
       '&doit'     => sub { say 'Greetings from exported sub' }, 
       'ShortName' => MyModule::Class 
     ) 
 } 
# main.p6 
 use lib 'lib'; 
 use MyModule; 
 say $var;          # OUTPUT: «one␤» 
 say @array;        # OUTPUT: «(one two three)␤» 
 say %hash;         # OUTPUT: «{one => two, three => four}␤» 
 doit();            # OUTPUT: «Greetings from exported sub␤» 
 say ShortName.new; # OUTPUT: «MyModule::Class.new␤» 

Note, EXPORT can't be declared inside a package because it is part of the compunit rather than the package.

Whereas UNIT::EXPORT packages deal with the named parameters passed to use, the EXPORT sub handles positional parameters. If you pass positional parameters to use, they will be passed to EXPORT. If a positional is passed, the module no longer exports default symbols. You may still import them explicitly by passing :DEFAULT to use along with your positional parameters.

# lib/MyModule 
 
 class MyModule::Class {} 
 
 sub EXPORT($short_name?) { 
     %( 
       do $short_name => MyModule::Class if $short_name 
     ) 
 } 
 
 sub always is export(:MANDATORY) { say "works" } 
 
 #import with :ALL or :DEFAULT to get 
 sub shy is export { say "you found me!" } 
# main.p6 
 use lib 'lib'; 
 use MyModule 'foo'; 
 say foo.new(); # OUTPUT: «MyModule::Class.new␤» 
 
 always();      # OK   - is imported 
 shy();         # FAIL - won't be imported 

You can combine EXPORT with type captures for interesting effect. This example creates a ? postfix which will only work on Cools.

# lib/MakeQuestionable.pm6 
 sub EXPORT(::Questionable) { 
     my multi postfix:<?>(Questionable $_) { .so }; 
     %( 
       '&postfix:<?>' => &postfix:<?>, 
     ) 
 } 
use MakeQuestionable Cool; 
 say ( 0?, 1?, {}?, %( a => "b" )? ).join(' '); # OUTPUT: «False True False True␤» 

Introspection

To list exported symbols of a module first query the export tags supported by the module.

use URI::Escape;
say URI::Escape::EXPORT::.keys;
# OUTPUT: «(DEFAULT ALL)␤»

Then use the tag you like and pick the symbol by its name.

say URI::Escape::EXPORT::DEFAULT::.keys;
# OUTPUT: «(&uri-escape &uri-unescape &uri_escape &uri_unescape)␤»
my &escape-uri = URI::Escape::EXPORT::DEFAULT::<&uri_escape>;

Be careful not to put sub EXPORT after unit declarator. If you do so, it'll become just a sub inside your package, rather than the special export sub:

unit module Bar; 
 sub EXPORT { %(Foo => &say) } # WRONG!!! Sub is scoped wrong 
sub EXPORT { %(Foo => &say) } # RIGHT!!! Sub is outside the module 
 unit module Bar; 

Finding installed modules

It is up to the module installer to know where compunit expects modules to be placed. There will be a location provided by the distribution and in the current home directory. In any case, letting the module installer deal with your modules is a safe bet.

cd your-module-dir 
 zef --force install . 

A user may have a collection of modules not found in the normal ecosystem, maintained by a module or package manager, but needed regularly. Instead of using the use lib pragma one can use the PERL6LIB environment variable to point to module locations. For example:

export PERL6LIB=/path/to/my-modules,/path/to/more/modules 

Note that the comma (',') is used as the directory separator.

The include path will be searched recursively for any modules when Rakudo is started. Directories that start with a dot are ignored and symlinks are followed.

Distributing modules

If you've written a Perl 6 module and would like to share it with the community, we'd be delighted to have it listed in the Perl 6 modules directory. :)

Currently there are two different module ecosystems (module distribution networks) available:

The process of sharing your module consists of two steps, preparing the module and uploading the module to one of the ecosystems.

Preparing the module

For a module to work in any of the ecosystems, it needs to follow a certain structure. Here is how to do that:

Upload your module to CPAN

Uploading a module to CPAN is the preferred way of distributing Perl 6 modules.

A prerequisite for this is a PAUSE user account. If you don't have an account already, you can create one here The process takes about 5 minutes and some e-mail back and forth.

Upload your module to p6c

If you want to use the p6c ecosystem you need to use git for your module's version control. The instructions herein assume that you have a GitHub account so that your module can be shared from its GitHub repository, however another provider such as GitLab should work as long as it works in a similar way.

That's it! Thanks for contributing to the Perl 6 community!

If you'd like to try out installing your module, use the zef module installer tool which is included with Rakudo Star Perl 6:

zef install Vortex::TotalPerspective 

This will download your module to its own working directory (~/.zef), build it there, and install the module into your local Perl 6 installation directory.

To use Vortex::TotalPerspective from your scripts, just write use Vortex::TotalPerspective, and your Perl 6 implementation will know where to look for the module file(s).

Modules and tools related to module authoring

You can find a list of modules and tools that aim to improve the experience of writing/test modules at Modules Extra

Contact information

To discuss module development in general, or if your module would fill a need in the ecosystem, naming, etc., you can use the #perl6 on irc.freenode.net IRC channel.

To discuss toolchain specific questions, you can use the #perl6-toolchain on irc.freenode.net IRC channel. A repository to discuss tooling issues is also available at https://github.com/perl6/toolchain-bikeshed.

29 Creating operators

A short tutorial on how to declare operators and create new ones.

Operators are declared by using the sub keyword followed by prefix, infix, postfix, circumfix, or postcircumfix; then a colon and the operator name in a quote construct. For (post-)circumfix operators separate the two parts by white space.

sub hello {
    say "Hello, world!";
}

say &hello.^name;   # OUTPUT: «Sub␤»
hello;              # OUTPUT: «Hello, world!␤»

my $s = sub ($a, $b) { $a + $b };
say $s.^name;       # OUTPUT: «Sub␤»
say $s(2, 5);       # OUTPUT: «7␤»

# Alternatively we could create a more
# general operator to sum n numbers
sub prefix:<Σ>( *@number-list ) {
    [+] @number-list
}

say Σ (13, 16, 1); # OUTPUT: «30␤»

sub infix:<:=:>( $a is rw, $b is rw ) {
    ($a, $b) = ($b, $a)
}

my ($num, $letter) = ('A', 3);
say $num;          # OUTPUT: «A␤»
say $letter;       # OUTPUT: «3␤»

# Swap two variables' values
$num :=: $letter;

say $num;          # OUTPUT: «3␤»
say $letter;       # OUTPUT: «A␤»

sub postfix:<!>( Int $num where * >= 0 ) { [*] 1..$num }
say 0!;            # OUTPUT: «1␤»
say 5!;            # OUTPUT: «120␤»

sub postfix:<♥>( $a ) { say „I love $a!“ }
42♥;               # OUTPUT: «I love 42!␤»

sub postcircumfix:<⸨ ⸩>( Positional $a, Whatever ) {
    say $a[0], '…', $a[*-1]
}

[1,2,3,4]⸨*⸩;      # OUTPUT: «1…4␤»

constant term:<♥> = "♥"; # We don't want to quote "love", do we?
sub circumfix:<α ω>( $a ) {
    say „$a is the beginning and the end.“
};

α♥ω;               # OUTPUT: «♥ is the beginning and the end.␤»

These operators use the extended identifier syntax; that is what enables the use of any kind of codepoint to refer to them.

30 Regexes: best practices and gotchas

Some tips on regexes and grammars

To help with robust regexes and grammars, here are some best practices for code layout and readability, what to actually match, and avoiding common pitfalls.

Code layout

Without the :sigspace adverb, whitespace is not significant in Perl 6 regexes. Use that to your own advantage and insert whitespace where it increases readability. Also, insert comments where necessary.

Compare the very compact

my regex float { <[+-]>?\d*'.'\d+[e<[+-]>?\d+]? }

to the more readable

my regex float {
     <[+-]>?        # optional sign
     \d*            # leading digits, optional
     '.'
     \d+
     [              # optional exponent
        e <[+-]>?  \d+
     ]?
}

As a rule of thumb, use whitespace around atoms and inside groups; put quantifiers directly after the atom; and vertically align opening and closing square brackets and parentheses.

When you use a list of alternations inside parentheses or square brackets, align the vertical bars:

my regex example {
    <preamble>
    [
    || <choice_1>
    || <choice_2>
    || <choice_3>
    ]+
    <postamble>
}

Keep it small

Regexes are often more compact than regular code. Because they do so much with so little, keep regexes short.

When you can name a part of a regex, it's usually best to put it into a separate, named regex.

For example, you could take the float regex from earlier:

my regex float {
     <[+-]>?        # optional sign
     \d*            # leading digits, optional
     '.'
     \d+
     [              # optional exponent
        e <[+-]>?  \d+
     ]?
}

And decompose it into parts:

my token sign { <[+-]> }
my token decimal { \d+ }
my token exponent { 'e' <sign>? <decimal> }
my regex float {
    <sign>?
    <decimal>?
    '.'
    <decimal>
    <exponent>?
}

That helps, especially when the regex becomes more complicated. For example, you might want to make the decimal point optional in the presence of an exponent.

my regex float {
    <sign>?
    [
    || <decimal>?  '.' <decimal> <exponent>?
    || <decimal> <exponent>
    ]
}

What to match

Often the input data format has no clear-cut specification, or the specification is not known to the programmer. Then, it's good to be liberal in what you expect, but only so long as there are no possible ambiguities.

For example, in ini files:

[section] 
 key=value 

What can be inside the section header? Allowing only a word might be too restrictive. Somebody might write [two words], or use dashes, etc. Instead of asking what's allowed on the inside, it might be worth asking instead: what's not allowed?

Clearly, closing square brackets are not allowed, because [a]b] would be ambiguous. By the same argument, opening square brackets should be forbidden. This leaves us with

token header { '[' <-[ \[\] ]>+ ']' }

which is fine if you are only processing one line. But if you're processing a whole file, suddenly the regex parses

[with a 
 newline in between] 

which might not be a good idea. A compromise would be

token header { '[' <-[ \[\] \n ]>+ ']' }

and then, in the post-processing, strip leading and trailing spaces and tabs from the section header.

Matching whitespace

The :sigspace adverb (or using the rule declarator instead of token or regex) is very handy for implicitly parsing whitespace that can appear in many places.

Going back to the example of parsing ini files, we have

my regex kvpair { \s* <key=identifier> '=' <value=identifier> \n+ }

which is probably not as liberal as we want it to be, since the user might put spaces around the equals sign. So, then we may try this:

my regex kvpair { \s* <key=identifier> \s* '=' \s* <value=identifier> \n+ }

But that's looking unwieldy, so we try something else:

my rule kvpair { <key=identifier> '=' <value=identifier> \n+ }

But wait! The implicit whitespace matching after the value uses up all whitespace, including newline characters, so the \n+ doesn't have anything left to match (and rule also disables backtracking, so no luck there).

Therefore, it's important to redefine your definition of implicit whitespace to whitespace that is not significant in the input format.

This works by redefining the token ws; however, it only works for grammars:

grammar IniFormat {
    token ws { <!ww> \h* }
    rule header { \s* '[' (\w+) ']' \n+ }
    token identifier  { \w+ }
    rule kvpair { \s* <key=identifier> '=' <value=identifier> \n+ }
    token section {
        <header>
        <kvpair>*
    }

    token TOP {
        <section>*
    }
}

my $contents = q:to/EOI/;
    [passwords]
        jack = password1
        joy = muchmoresecure123
    [quotas]
        jack = 123
        joy = 42
EOI
say so IniFormat.parse($contents);

Besides putting all regexes into a grammar and turning them into tokens (because they don't need to backtrack anyway), the interesting new bit is

token ws { <!ww> \h* }

which gets called for implicit whitespace parsing. It matches when it's not between two word characters (<!ww> , negated "within word" assertion), and zero or more horizontal space characters. The limitation to horizontal whitespace is important, because newlines (which are vertical whitespace) delimit records and shouldn't be matched implicitly.

Still, there's some whitespace-related trouble lurking. The regex \n+ won't match a string like "\n \n", because there's a blank between the two newlines. To allow such input strings, replace \n+ with \n\s*.

31 General reference

~

32 About the docs

Meta-documentation

This document collection represents the on-going effort to document the Perl 6 programming language with the goals of being: comprehensive, easy to use, easy to navigate, and useful to both newcomers and experienced Perl 6 programmers.

An HTML version of the documentation is located online at https://docs.perl6.org.

The official source for this documentation is located at perl6/doc on GitHub.

This particular document is a quick overview of the process described in more detail in CONTRIBUTING on GitHub. This document also provides a short introduction to writing Perl 6 Pod files, which can be rendered into HTML and other formats.

Structure

All of the documentation is written in Perl 6 Pod and kept in the doc/ directory, and the doc/Language/ and doc/Type/ sub-directories. These files are processed as collections of definitions or "documentables", which are then post-processed and linked together.

Generating HTML from Pod

To generate HTML from the Pod files, you'll need:

To generate the documentation into the html/ folder, run:

perl6 htmlify.p6 

To host the documentation from a web server, have Perl 5 and Mojolicious::Lite installed, then run:

perl app.pl daemon 

Contributing

The documentation is written in Perl 6 Pod.

For a quick introduction to Perl 6 Pod, see Perl 6 Pod.

For full details about the Perl 6 Pod specification, see Synopsis 26, Documentation.

Adding definitions

Documentables can be defined using an =headN Pod directive, where N is greater than zero (e.g., =head1, =head2, …).

All of the paragraphs and blocks following that directive, up until the next directive of the same level, will be considered part of the documentable. So, in:

    =head2  My Definition 
 
     Some paragraphs, followed by some code: 
 
     =begin code 
     my Code $examples = "amazing"; 
     =end code 
 
     Mind === blown. 
 
     =head3 Minor details about  My Definition 
 
     It's fantastic. 
 
     =head2 And now, for something completely different 
 
     … 
 

The documentable My Definition extends down to the =head2 And now….

Documentables may contain other documentables. Class documentables, for example, often contain the methods the class implements.

Definitions must be in one of the following forms to be recognized as the start of a documentable named, say, þ. First the code in the document source:

=item X<C<How to use the þ infix> | infix,þ> (This a special case, which 
 is always considered a definition) 
 
 =item C<The þ Infix> 
 
 =item B<The C<þ> Infix> 
 
 =item C<Infix þ> 
 
 =item B<Infix C<þ>> 
 
 =item C<trait is cached> (A special case for the L<trait|/language/functions#Traits> documentables) 
 

Then the results on the rendered page:

These items should now be searchable by using the search field in the HTML docs.

You can add emphasis with bold ( B<> ) or italicized ( I<> ), with or without code formatting ( C<> ). Due to current parser limitations, special steps have to be taken to use X<> with other formatting codes; for example:

=item X<B<foo>|foo> a fancy subroutine 

renders like this

Notice that text after a pipe ('|') has no formatting. Also note that C<> preserves spaces and treats text as verbatim.

33 Community

Information about the people working on and using Perl 6

Overview

"Perl 5 was my rewrite of Perl. I want Perl 6 to be the community's rewrite of Perl and of the community." - Larry Wall

The Perl 6 community

Online communities

There is a large presence on the #perl6 channel on freenode.net, who are happy to provide support and answer questions, or just use as a friendly place to hang out. Check out this IRC lingo resource for the abbreviations frequently used there. StackOverflow is also a great resource for asking questions and helping others with their Perl 6 problems and challenges. More resources can be found in the perl6.org community page.

Offline communities

Perl 6 is also a common topic at Perl conferences and Perl Monger meetings and other meetups. If you prefer in-person meetings, these are warmly recommended!

Other resources

Camelia, the multi-color butterfly with P 6 in her wings, is the symbol of this diverse and welcoming community.

Perl 6 Weekly

Elizabeth Mattijsen usually posts in the "Perl 6 Weekly" blog, a summary of Perl 6 posts, tweets, comments and other interesting tidbits. If you want a single resource to know what is going on in the Perl community now, this is your best resource.

Perl 6 Advent calendar

The Perl 6 community publishes every December an Advent Calendar, with Perl 6 tutorials every day until Christmas. Organization and assignment of days is done through the different Perl 6 channels and the Perl6/advent repository. If you want to participate, its organization starts by the end of October, so check out the channels above to keep up to date.

HOW TO WRITE: One topic/point/idea per sentence, one sentence per line - to make diffs & translation easier.

34 FAQ

Frequently asked questions about Perl 6

General

What's the difference between Raku, Rakudo and Perl 6?

Properly speaking, Rakudo is an implementation of Perl 6. It's currently the most developed, but there have been other implementations in the past and there will likely be others in the future. Perl 6 (which can also be called "Raku") is the definition of the language. When talking about the current interpreter, Rakudo and Perl 6 can be used interchangeably.

When was Perl 6 released?

The Rakudo 2015.12 implementation version was released on December 25th 2015.

Is there a Perl 6 version 6.0.0?

No. The first stable language specification version is v6.c ("Christmas"). Future versions of the spec may have point releases (e.g. v6.d.2) or major releases (e.g., v6.e).

Running perl6 -v will display the language version your compiler implements:

$ perl6 -v 
 This is Rakudo version 2017.07 built on MoarVM version 2017.07 
 implementing Perl 6.c. 

When was v6.d released?

The v6.d Specification was released on Diwali 2018, which was November 6–7 2018, in a convenient time zone. 6.d was enabled by default in the Rakudo compiler release of 2018.11.

The vast majority of 6.d features were already implemented and available in the Rakudo compiler without requiring any special pragmas, as they did not conflict with the 6.c specification. A smaller set of features and behaviors is available automatically if you have the use v6.d pragma at the top of the file. The rest of about 3100 new commits to the language specification simply clarify previously undefined behavior.

As a Perl 6 user, what should I install?

Mac users can use the latest Rakudo Star DMG binary installer at https://rakudo.org/downloads/star

Windows users can use the Rakudo Star MSI binary installer. You will need Windows Git and Strawberry Perl 5 to use zef to install library modules.

Linux users probably want to download Rakudo Star and follow the compilation instructions at https://www.perl6.org/downloads/.

There should be Linux and Mac binaries available from vendors and third parties, although vendor versions may be outdated. Versions before Rakudo release of 2015.12 should be avoided.

There's an official Rakudo Star docker image at https://hub.docker.com/_/rakudo-star/

As an advanced user I want to track Rakudo development.

An option is to clone the repository and build it. This will install work in progress which is minimally-tested and may contain severe bugs. If you're interested in contributing to Rakudo Perl 6 compiler, you may find Z-Script helper tool useful.

To install the last official monthly release, check out the tag visible at https://raw.githubusercontent.com/rakudo/rakudo/master/VERSION or set up a helper command.

Some users choose to use rakudobrew, which allows installation of multiple versions of rakudo. Be sure to read its documentation.

In either case you will probably need to also install zef and p6doc from the ecosystem.

Where can I find good documentation on Perl 6?

See the official documentation website (especially its "Language" section) as well as the Resources page. You can also consult this great cheatsheet.

perl6book.com contains a list of dead tree and electronic books.

Be mindful of publication dates when reading third-party articles. Anything published before December, 2015 likely describes a pre-release version of Perl 6.

You can always get help from a live human in our help chat or search the chat logs to find previous conversations and discussions.

Can I get some books about Perl 6?

Here are some available books, in alphabetical order:

A list of books published or in progress is maintained in perl6.org.

What is the Perl 6 specification?

The specification refers to the official test suite for Perl 6. It's called roast and is hosted on github. Any compiler that passes the tests is deemed to implement that version of the Perl 6 specification.

Roast's master branch corresponds to the latest development that isn't necessarily part of any specification yet. Other branches correspond to specific versions; for example, "6.c-errata".

So 6.c-errata is a released language version we don't change other than to fix errors in tests (the "errata") whereas master is the unreleased work-in-progress that may become the next language version. Its current state is not necessarily prescriptive of the next language version's behavior since new additions will be reviewed for inclusion into the release.

Yes, see glossary.

I'm a Perl 5 programmer. Where is a list of differences between Perl 5 and Perl 6?

There are several Perl 5 to Perl 6 guides in the Language section of the documentation, most notable of which is the Overview.

I'm a Ruby programmer looking for quickstart type docs?

See the rb-nutshell guide.

Modules

Is there a CPAN (repository of third party library modules) for Perl 6?

Yes, it's the same CPAN as for Perl 5! The only difference is when using PAUSE to upload the module, you'd select Perl 6 as the target directory and the uploaded modules show up on modules.perl6.org instead of MetaCPAN. The App::Mi6 tool can simplify the uploading process. Latest versions of zef module installer automatically check for latest versions of a module on CPAN as well as our GitHub-based ecosystem.

Is there a perldoc (command line documentation viewer) for Perl 6?

Yes, it's called p6doc and is present in the ecosystem under that name. It comes bundled in with Rakudo Star but needs to be manually installed with zef if you are using a Rakudo monthly release.

Can I use Perl 5 modules from Perl 6?

Yes, with Inline::Perl5, which works well with most Perl 5 modules. It can even run Perl 5 Catalyst and DBI.

Can I use C and C++ from Perl 6?

Nativecall makes this particularly easy.

Nativecall can't find libfoo.so and I only have libfoo.so.1.2!

This is commonly seen on Debian-like systems. You need to install libfoo-dev package, to set a symlink for the missing file.

Where have all the traditional UNIX library functions gone?

It's fairly easy to use NativeCall to access them.

An ecosystem module POSIX is also available.

Does Rakudo have a core standard library?

Rakudo Star distribution does come with many useful modules.

Rakudo compiler-only release includes only a couple of the most basic modules.

Many more modules can be found in the ecosystem.

Is there something like B::Deparse/How can I get hold of the AST?

Use --target=optimize command line option to view the AST of your program, e.g., perl6 --target=optimize -e 'say "hi"'

The target optimize gives the AST after the static optimizer does its job, while target ast gives the AST before that step. To get the full list of available targets, run perl6 --stagestats -e ""

What is precompilation?

When you load a module for the first time, Rakudo compiles it into bytecode. Then, Rakudo both stores the compiled bytecode on disk and uses it, because that tends to be significantly faster.

Can I have circular dependencies between modules?

No, you can't have circular dependencies, and you should get a Circular module loading detected error if you have them between your modules.

Very likely you can accomplish what you are trying to do using roles. Instead of A.pm6 depending on B.pm6 and B.pm6 depending on A.pm6, you can have A-Role.pm6 and B-Role.pm6 and classes in A.pm6 and B.pm6 implementing these roles respectively. Then you can depend on A-Role.pm6 and B-Role.pm6 without the need for the circular dependency.

One of the reasons why circular dependencies do not work in Perl 6 is one pass parsing. We have to know what A means when we parse B, and we have to know what B means when we parse A, which is clearly an infinite loop.

Note that Perl 6 has no “1 file = 1 class” limitation, and circular dependencies within a single compilation unit (e.g. file) are possible through stubbing. Therefore another possible solution is to move classes into the same compilation unit.

Language features

How can I dump Perl 6 data structures (like Perl 5 Data::Dumper and similar)?

Typical options are to use the say routine that uses the gist method which gives the "gist" of the object being dumped. More detailed output can be obtained by calling the perl method that typically returns an object's representation in EVAL-able code.

If you're using the rakudo implementation, you can use the rakudo-specific dd routine for dumping, whose output is similar to perl, but with more information.

Examples:

my $foo = %( foo => 'bar' ); 
 say $foo.perl;   # OUTPUT: «${:foo("bar")}␤» 
 say $foo;        # OUTPUT: «{foo => bar}␤» 
 
 # non-standard routine available in rakudo implementation: 
 dd $foo;         # OUTPUT: «Hash $foo = ${:foo("bar")}␤» 

There are also several ecosystem modules that provide more control over how data structures are dumped, including support for colored output.

How can I get command line history in the Perl 6 prompt (REPL)?

Install Linenoise from the ecosystem.

An alternative for UNIX-like systems is to install rlwrap. This can be done on Debian-ish systems by running:

sudo apt-get install rlwrap 

Why is the Rakudo compiler so apologetic?

If SORRY! is present in the output, the error is a compile time error. Otherwise, it's a runtime error.

Example:

sub foo( Int $a, Int $b ) {...} 
 foo(1)     # ===SORRY!=== Error while compiling ... 
say 1/0;   # Attempt to divide 1 by zero using div 

What is (Any)?

Any is a top level class most objects inherit from. The Any type object is the default value on variables and parameters without an explicit type constraint, which means you'll likely see (Any) printed when you output a gist of a variable without any value by using, for instance, the say routine:

my $foo; 
 say $foo; # OUTPUT: «(Any)␤» 
 
 my Int $baz; 
 say $baz; # OUTPUT: «(Int)␤» 
 
 my $bar = 70; 
 say $bar; # OUTPUT: «70␤» 

To test whether a variable has any defined values, see DEFINITE and defined routines. Several other constructs exist that test for definiteness, such as with , orwith , and without statements, //, andthen, notandthen, and orelse operators, as well as type constraint smileys.

What is so?

so is a loose precedence operator that coerces to Bool.

It has the same semantics as the ? prefix operator, just like and is the low-precedence version of &&.

Example:

say so 1|2 == 2;    # OUTPUT: «True␤» 

In this example, the result of the comparison (which is a Junction), is converted to Bool before being printed.

What are those :D and :U things in signatures?

In Perl 6, classes and other types are objects and pass type checks of their own type.

For example, if you declare a variable

my Int $x = 42; 

then not only can you assign integers (that is, instances of class Int) to it, but the Int type object itself:

$x = Int 

If you want to exclude type objects, you can append the :D type smiley, which stands for "definite":

my Int:D $x = 42; 
 $x = Int; 
 
 # dies with: 
 # Type check failed in assignment to $x; 
 # expected Int:D but got Int 

Likewise, :U constrains to undefined values, that is, type objects.

To explicitly allow either type objects or instances, you can use :_.

What is the --> thing in the signature?

--> is a return constraint, either a type or a definite value.

Example of a type constraint:

sub divide-to-int( Int $a, Int $b --> Int ) { 
         return ($a / $b).narrow; 
 } 
 
 divide-to-int(3, 2) 
 # Type check failed for return value; expected Int but got Rat 

Example of a definite return value:

sub discard-random-number( --> 42 ) { rand } 
 say discard-random-number; 
 # OUTPUT: «42␤» 

In this case, the final value is thrown away because the return value is already specified in the signature.

How can I extract the values from a Junction?

If you want to extract the values (eigenstates) from a Junction, you are probably doing something wrong and should be using a Set instead.

Junctions are meant as matchers, not for doing algebra with them.

If you want to do it anyway, you can abuse autothreading for that:

sub eigenstates(Mu $j) { 
     my @states; 
     -> Any $s { @states.push: $s }.($j); 
     @states; 
 } 
 
 say eigenstates(1|2|3).join(', '); 
 # prints 1, 2, 3 or a permutation thereof 

If Str is immutable, how does s/// work? If Int is immutable, how does $i++ work?

In Perl 6, values of many basic types are immutable, but the variables holding them are not. The s/// operator works on a variable, into which it puts a newly created string object. Likewise, $i++ works on the $i variable, not just on the value in it.

Knowing this, you would not try to change a literal string (e.g. like 'hello' ~~ s/h/H/;), but you might accidentally do something equivalent using map as follows.

my @foo = <hello world>.map: { s/h/H/ }; 
 
 # dies with 
 # Cannot modify an immutable Str (hello) 
 
 my @bar = <hello world>».subst-mutate: 'h', 'H'; 
 
 # dies with 
 # Cannot resolve caller subst-mutate(Str: Str, Str); 
 # the following candidates match the type but require 
 # mutable arguments: ... 

Instead of modifying the original value in place, use a routine or operator that returns a new value:

my @foo = <hello world>.map: { S/h/H/ };  # ['Hello','world'] 
 my @bar = <hello world>».subst: 'h', 'H'; # ['Hello','world'] 

See the documentation on containers for more information.

What's up with array references and automatic dereferencing? Do I need the @ sigil?

In Perl 6, nearly everything is a reference, so talking about taking references doesn't make much sense. Scalar variables can also contain arrays directly:

my @a = 1, 2, 3; 
 say @a;                 # OUTPUT: «[1 2 3]␤» 
 say @a.^name;           # OUTPUT: «Array␤» 
 
 my $scalar = @a; 
 say $scalar;            # OUTPUT: «[1 2 3]␤» 
 say $scalar.^name;      # OUTPUT: «Array␤» 

The big difference is that arrays inside a scalar act as one value in list context, whereas arrays will be happily iterated over.

my @a = 1, 2, 3; 
 my $s = @a; 
 
 for @a { ... }          # loop body executed 3 times 
 for $s { ... }          # loop body executed only once 
 
 my @flat = flat @a, @a; 
 say @flat.elems;            # OUTPUT: «6␤» 
 
 my @nested = flat $s, $s; 
 say @nested.elems;          # OUTPUT: «2␤» 

You can force list context with @( ... ) or by calling the .list method on an expression, and item context with $( ... ) or by calling the .item method on an expression.

See the Perl 6: Sigils, Variables, and Containers article to learn more.

Why sigils? Couldn't you do without them?

There are several reasons:

"Type Str does not support associative indexing."

You likely tried to mix string interpolation and key characters, like HTML tags:

my $foo = "abc"; 
 say "$foo<html-tag>"; 

Perl 6 thinks $foo to be a Hash and <html-tag> to be a string literal hash key. Use a closure to help it to understand you.

my $foo = "abc"; 
 say "{$foo}<html-tag>"; 

Does Perl 6 have coroutines? What about yield?

Perl 6 has no yield statement like Python does, but it does offer similar functionality through lazy lists. There are two popular ways to write routines that return lazy lists:

# first method, gather/take 
 my @values = gather while have_data() { 
     # do some computations 
     take some_data(); 
     # do more computations 
 } 
 
 # second method, use .map or similar method 
 # on a lazy list 
 my @squares = (1..*).map(-> \x { x² }); 

Why can't I initialize private attributes from the new method, and how can I fix this?

The say statement in the following code sample

class A { 
     has $!x; 
     method show-x { 
         return $!x; 
     } 
 } 
 say A.new(x => 5).show-x; 

does not print 5. Private attributes are private, which means invisible to the outside world. If the default constructor could initialize them, they would leak into the public API. Thus, in this particular code sample the attribute $!x isn't initialized during object construction by the default constructor.

If you still want to initialize private attributes with the default constructor, you can add a submethod BUILD to achieve such task:

class B { 
     has $!x; 
     submethod BUILD(:$!x) { } 
     method show-x { 
         return $!x; 
     } 
 } 
 say B.new(x => 5).show-x; 

BUILD is called by the default constructor (indirectly, see Object Construction for more details) with all the named arguments that the user passes to the constructor. :$!x is a named parameter with name x, and when called with a named argument of name x, its value is bound to the attribute $!x.

However, you shouldn't do that. If the attribute is declared as private, then it shouldn't be exposed to the environment outside the class (e.g., during object construction). On the other hand, if the attribute is public, there is no downside to declaring it that way with $.x since the external view is read-only by default, and you can still access it internally with $!x.

How and why do say, put and print differ?

The most obvious difference is that say and put append a newline at the end of the output, and print does not.

But there's another difference: print and put convert its arguments to a string by calling the Str method on each item passed to them while say uses the gist method. The gist method, which you can also create for your own classes, is intended to create a Str for human interpretation. So it is free to leave out information about the object deemed unimportant to understanding the essence of the object.

Or phrased differently, $obj.Str gives a string representation, $obj.gist provides a short summary of that object suitable for fast recognition by a human, and $obj.perl gives a Perlish representation from which the object could be re-created.

For example, when the Str method is invoked on a type object, also known as an "undefined value", the type is stringified to an empty string and a warning is thrown. On the other hand, the gist method returns the name of the type between parentheses (to indicate there's nothing in that value except the type).

my Date $x;     # $x now contains the Date type object 
 print $x;       # empty string plus warning 
 say $x;         # OUTPUT: «(Date)␤» 

If you'd like to show a debugging version of an object, it is probably better to use the rakudo-specific dd routine. It essentially does a $obj.perl and shows that on STDERR rather than STDOUT, so it won't interfere with any "normal" output of your program.

In short, say is optimized for casual human interpretation, dd is optimized for casual debugging output and print and put are more generally suitable for producing output.

put is thus a hybrid of print and say; like print, it calls the Str method on the object. And like say, it adds a newline at the end of the output.

What's the difference between token and rule ?

regex, token and rule introduce regexes, but with slightly different semantics.

token implies the :ratchet or :r modifier, which prevents the rule from backtracking.

rule implies both the :ratchet and :sigspace (short :s) modifier, which means a rule doesn't backtrace, and it treats whitespace in the text of the regex as <.ws> calls (i.e., matches whitespace, which is optional except between two word characters). Whitespace at the start of the regex and at the start of each branch of an alternation is ignored.

regex declares a plain regex without any implied modifiers.

What's the difference between die and fail?

die throws an exception.

fail returns a Failure object. (If the caller has declared use fatal; in the calling lexical scope, fail throws an exception instead of returning it.)

A Failure is an "unthrown" or "lazy" exception. It's an object that contains the exception, and throws the exception if you try to use the Failure as an ordinary object or ignore it in sink context.

A Failure returns False from a defined check, and you can extract the exception with the exception method.

What's the difference between Pointer and OpaquePointer?

OpaquePointer is deprecated and has been replaced with Pointer.

You can have colonpairs in identifiers. What's the justification?

Identifiers can include colon pairs, which become part of their name. According to Larry Wall's answer to the issue, We already had the colon pair mechanism available, so it was a no-brainer to use that to extend any name that needs to be able to quote uniquefying but non-standard characters (or other information with a unique stringification to such characters).

How do most people enter unicode characters?

It depends on the operating system, windowing environment and/or editors. This page on entering Unicode characters specifies how it is done in the most popular operating systems and editors.

Perl 6 implementation

What Perl 6 implementations are available?

Currently the best developed is Rakudo (using multiple Virtual Machine backends). Historic implementations include Niecza (.NET) and Pugs (Haskell). Others are listed at Perl 6 Compilers

What language is Rakudo written in?

A short answer is that Rakudo is written almost entirely in Perl 6. A more detailed answer is that Rakudo is written in a mixture of Perl 6 and NQP ("Not Quite Perl"). NQP is a lightweight Perl 6-like environment for virtual machines; it's designed to be a high-level way to create compilers and libraries for virtual machines (such as MoarVM and JVM) using Perl 6 syntax.

What language is NQP written in?

NQP is a mixture of (1) NQP code, (2) whatever language the underlying virtual machine is using, (3) some third-party C and Java libraries, and (4) some bootstrapping files created by earlier runs of the build process.

Is Perl 6 Lisp?

(not (not Nil)) 

Can I compile my script to a standalone executable?

Tools like App::InstallerMaker::WiX allow you to create an installer that will package the compiler and your script. However, the currently available compilers do not support creating a standalone executable yet.

If you wish to help out, the Rakudo compiler on MoarVM backend has https://github.com/MoarVM/MoarVM/issues/875 Issue opened as a place to discuss this problem.

Perl 6 distribution

When will the next version of Rakudo Star be released?

A Rakudo Star release is typically produced quarterly, with release announcements posted on rakudo.org.

Meta questions and advocacy

Why is Perl 6 called Perl?

… As opposed to some other name that didn't imply all the things that the higher number might indicate on other languages.

The short answer is that it was Larry's choice under Rule 1.

The community considers Perl 5 and Perl 6 sister languages - they have a lot in common, address many of the same problem spaces, but Perl 6 is not intended to replace Perl 5. In fact, both languages interoperate with each other.

When will Perl 6 be ready? Is it ready now?

Readiness of programming languages and their compilers is not a binary decision. As the language and the implementations evolve, they grow steadily more usable. Depending on your needs, Perl 6 and its compilers may or may not be ready for you.

That said, version 6.c (Christmas 2015) is the first official release of Perl 6 as a language, along with a validation suite and a compiler that passes it.

Why should I learn Perl 6? What's so great about it?

Perl 6 unifies many great ideas that aren't usually found in other programming languages. While several other languages offer some of these features, none of them offer all of them.

Please see the feature comparison matrix for an overview of implemented features.

Is Perl 6 fast enough for me?

That depends on what you are doing. Rakudo has been developed with the philosophy of "make it work right then make it work fast". It's fast for some things already but needs work for others. Since Perl 6 provides lots of clues to the JIT that other dynamic languages don't, we think we'll have a lot of headroom for performance improvements.

The following crude benchmarks, with all the usual caveats about such things, show that Perl 6 can be faster than Perl 5 for similar tasks if the big weaponry is included, that is, if Perl 6 features are used to its full extent; at the same time, Perl 5 can be faster if only the bare bones are included. Similar situation can be observed when comparing Perl 6 to other languages.

Try it on your system. You may be pleasantly surprised!

Examples:

# Perl 6 version 
 use v6.c; 
 
 class Foo { has $.i is rw }; 
 
 for 1..1_000_000 -> $i { 
     my $obj = Foo.new; 
     $obj.i = $i; 
 } 
# Perl 5 version 
 package Foo; 
 use Moose; 
 
 has i => (is => 'rw'); 
 
 __PACKAGE__->meta->make_immutable; 
 
 for my $i (1..1_000_000) { 
     my $obj = Foo->new; 
     $obj->i($i); 
 } 
 
 1; 
 
 # Another Perl 5 version that offers bare-bones set of features 
 # compared to Moose/Perl 6's version but those are not needed in this 
 # specific, simple program anyway. 
 package Foo; 
 use Mojo::Base -base; 
 
 has 'i'; 
 
 for my $i (1..1_000_000) { 
     my $obj = Foo->new; 
     $obj->i($i); 
 } 
 
 1; 

You might want to use this program for comparing performance, too. It works under both languages, as long as perl -Mbigint is used for invocation for Perl 5.

my ($prev, $current) = (1, 0); 
 
 for (0..100_000) { 
     ($prev, $current) = ($current, $prev + $current); 
 } 
 print $current; 

35 Glossary

Glossary of Perl 6 terminology

Abstract class

The generic Computer Science term "abstract class" defines the interface or API of a class. In Perl 6, this is implemented using roles with stubbed methods.

role Canine {
    method bark { ... }          # the ... indicates a stub
}

class Dog does Canine {
    method bark { say "woof" }   # *MUST* be implemented by class
}

Advent calendar

In the context of Perl 6, a yearly set of blog posts for each day from the 1st until the 25th of December, to be found at https://perl6advent.wordpress.com.

Adverb

Generically, an adverb is a named argument to a function. There are also some specific syntax forms that allow adverbs to be tucked into some convenient places:

q:w"foo bar";   # ":w" is a Quotelike form modifier adverb 
 m:g/a|b|c/;     # ":g" is too 
 @h{3}:exists;   # ":exists" is too, but is known as a subscript adverb 

Adverbs are usually expressed with colon pair notation, and for this reason colon pair notation is also known as the adverbial pair form:

:a(4)          # Same as "a" => 4

Some other forms that use a colon in ways that have adverb-like semantics are called adverbial forms. One special form starts with an integer value, followed by a name (for the key):

:20seconds     # same as seconds => 20

Also see #Colon pair and colon list.

Adverbial pair

A generalized form of pair notation. They all start with the colon, as shown in the following examples:

adverbial pair pair notation
:foo<bar> foo => 'bar'
:foo(42) foo => 42
:42foo foo => 42
:$foo foo => $foo
:foo foo => True
:!foo foo => False

Also see #Adverb and #Colon pair and colon list.

Allomorph

A type that has two related values which may be used depending on the context. For example IntStr allomorph is both an Int and a Str, so it will be accepted by anything that expects an Int, a Str, or an IntStr. Keep in mind that certain constructs, such as sets, bags, and mixes care about object identity, and so will not accept an allomorph as equivalent of its components alone.

The allomorph types IntStr, NumStr, RatStr and ComplexStr may be created as a result of parsing a quoted string:

say <42>.^name;     # OUTPUT: «IntStr␤»
say <42.1e0>.^name; # OUTPUT: «NumStr␤»
say <42.1>.^name;   # OUTPUT: «RatStr␤»

Note: angle brackets can also be used to create literals for which you'd normally need to use some operator (e.g. / for Rat or + for Complex). This allows you to use such literals in places where expressions are not allowed, for example, as literals in signatures:

# Wrong, can't use an operator there: 
 multi foo (1/3) { say "It's one third!" } 
# Right, a Rat literal: 
 multi foo (<1/3>) { say "It's one third!" } 

If you do want an allomorph and not a literal Numeric, then include whitespace around angle brackets:

say <42/1>.^name;    # OUTPUT: «Rat␤»
say <42+0i>.^name;   # OUTPUT: «Complex␤»
say < 42+0i >.^name; # OUTPUT: «ComplexStr␤»
say < 42/1 >.^name;  # OUTPUT: «RatStr␤»

Please see the Numerics page for a more complete description on how to work with these allomorphs.

Anonymous

A subroutine, method or submethod is called anonymous if it can't be called by name.

# named subroutine
sub double($x) { 2 * $x };

# anonymous subroutine, stored in a named scalar
my $double = sub ($x) { 2 * $x };

Note that it is still allowed to have a name, but you cannot call it by that name:

# anonymous, but knows its own name 
 my $s = anon sub triple($x) { 3 * $x } 
 say $s.name;        # OUTPUT: «triple␤» 
say triple(42);     # OUTPUT: «Undeclared routine: triple␤» 

API

Application Programming Interface. Ideally, someone using your system or library should be able to do so with knowledge only of the API, but not necessarily knowing anything about the internals or the implementation details.

See also #Abstract class.

Apocalypse

A document originally written by #TimToady, in which he processed the initial barrage of RFCs that came out of the Perl community. Now only kept as a historical document for reference. See also #Exegesis and #Synopsis.

Arity

The number of positional operands expected by an operator, subroutine, method or callable block.

sub infix:<+>(Foo $a, Foo $b) { $a.Int + $b.Int }  # arity of "+" is 2 
 sub frobnicate($x) { ... }                         # arity of 1 
 sub the-answer() { 42 }                            # arity of 0 
 -> $key, $value { ... }                            # arity of 2 

The arity of a Callable is one of the main selectors in multi-dispatch.

ASCII operator

“Texas” was used in the past but is now discouraged. Remove the link when “Texas” goes completely out of use.

The ASCII variant of a non-ASCII Unicode operator or symbol. For instance, (elem) corresponds to the ("Is this an element of that set?") operator that comes from set theory. ASCII operators are a workaround to the problem that people don't know how to type Unicode yet. Culturally, while we encourage people to use the Unicode symbols in a vague sort of way, we do not disparage the use of the ASCII variants. Well, maybe just a little...

Autothreading

Autothreading is what happens if you pass a Junction to a subroutine that expects a parameter of type Any or a subtype thereof (such as anything Cool). The call is then executed for each value of the junction. The result of these calls is assembled in a new junction of the same type as the original junction.

sub f($x) { 2 * $x };
say f(1|2|3) == 4;    # OUTPUT: «any(False, True, False)␤»

Here f() is a sub with one parameter, and since it has no explicit type, it is implicitly typed as Any. The Junction argument causes the f(1|2|3) call to be internally executed as f(1)|f(2)|f(3), and the resulting junction is 2|4|6. These are then all compared to 4, resulting in a junction False|True|False. This process of separating junction arguments into multiple calls to a function is called autothreading.

If you use the resulting junction in a boolean context, such as with an if, it collapses into a single boolean which is True if any of the values in the junction are True.

if f(1|2|3) == 4 {    # fires because f(2) == 4 is true 
     say 'success'; 
 } 

Backtracking

Backtracking is the default way a regexp is matched. The engine is allowed to explore several ways moving backward in the string characters in order to allow every piece of a regexp to match something. For more information, see Regexp Backtracking section.

binder

When you pass an argument list to a function (or any other callable, like a method or a block), the argument list gets bound to the parameters in the signature. The code that does this is called the binder.

block

Blocks are code object with its own lexical scope, which allows them to define variables without interfering with other in the containing block.

bytecode

Although Perl 6 looks like an interpreted language, since it uses the #! form to run its scripts (and they are called scripts), it is actually compiled to run in a virtual machine so the compiler (currently Rakudo) generates bytecode that runs either in MoarVM or the Java Virtual Machine, the two VMs currently supported.

Camelia

A butterfly image intended primarily to represent Perl 6, The Language.

Colon pair and colon list

A colon pair is a shorthand syntax used to create or visually present a Pair object. The two most common forms are:

:a(4)          # Same as "a" => 4,   same as Pair.new("a", 4)
:a<4>          # Same as "a" => "4", same as Pair.new("a", val("4"))

This is also known as the adverbial pair form.

Note: when the part after the colon and before the balanced delimiters is not a legal identifier, other semantics apply, not all of which produce Pair objects.

Two other common forms are:

:a             # Same as :a(True)
:!a            # Same as :a(False)

A colon list just means that a list that contains only colon pairs, does not need commas, or even spaces:

:a(4):c:!d:c   # Same as a => 4, c => True, d => False, c => True

Finally, if there is a variable with the same name as an intended adverbial pair, you don't have to specify the name twice, but just specify the adverb with the appropriate sigil:

variable only same as
:$foo foo => $foo
:@bar bar => @bar
:%mapper mapper => %mapper
:&test test => &test

See also #Adverb.

Community

See https://perl6.org/community/ for information about how to participate in the friendly Perl 6 community.

Damian Conway

Original author of the #Exegesis (among many other things). See also https://en.wikipedia.org/wiki/Damian_Conway.

decont

Short for "decontainerize", meaning to remove an item from its Scalar container, often to obtain a different behavior for items that have it.

diffy

See operator. It means the type of the operator result is sufficiently different from its arguments that op= makes little sense.

Exegesis

A document originally written by #TheDamian, in which he tried to explain the Apocalypses to the common (wo)man. Now only kept as an historical document for reference. See also #Synopsis.

fiddly

Too complicated to apply a meta-op to. See operator.

Handle

A handle is a data structure used to store information about some input/output operation such as file or socket reading or writing. Perl 6 uses IO::Handle as a base class for filehandles, and IO::Socket for sockets.

Huffmanize

With reference to Huffman coding, "huffmanizing" is making things that are commonly used easier, and often shorter, to type. With things that are used less frequently it's both less of a bother to type longer pieces of code and often longer, more descriptive naming is necessary to easily be reminded of what the rarely-used feature does.

For example, printing output is a common task, while performing thread-safe atomic addition on native atomicity-safe integers is much less so. There's a need to "huffmanize" the task printing and that's why you can do it by just typing three letters put. But there's no need to "huffmanize" the rarely-needed atomic operators, which is why you type the lengthier names, such as atomic-inc-fetch. The name put is a bit vague, but because it's commonly used, it's easy to learn what it does. On the other hand, the name atomic-inc-fetch is rarer, and the more descriptive name helps recall its purpose better.

iffy

Often used as a boolean value. See operator. Made via the use keyword.

import

Include functions from a module in the current namespace.

Instance

An instance of a class is also called an object in some other programming languages. It has storage for attributes and is often the return value of a call to a method called new, or a literal.

Instances of most types are defined to be True e.g., defined($instance) is True.

my Str $str = "hello";  ## this is with builtin types, e.g. Str
if defined($str) {
    say "Oh, yeah. I'm defined.";
}
else {
    say "No. Something off? ";
}

## if you wanted objects...
class A {
    # nothing here for now.
}

my $an_instance = A.new;
say $an_instance.defined.perl;# defined($an_instance) works too.

To put things another way, a class contains the blueprints of methods and attributes, and an instance carries it into the real world.

Interface

An interface is an abstract class.

Invocant

Caller, the one who calls or invokes. The invocant of a method would be the object on which that method is being called, or, in some cases, the class itself. Invocant is used instead of caller because the latter refers to the scope.

IRC

Internet Relay Chat. Perl 6 developers and users usually hang out on the #perl6 channel of irc.freenode.org. This channel is also populated by a host of friendly bots that allow you to interact with Perl 6 and its codebase, as well as send delayed messages and other goodies. Check the full list in the community page of perl6.org.

IRC lingo

The following terms are often used on the Perl 6 related #IRC channels:

ALAP

As Late As Possible

autopun

A self-referencing pun, e.g. "Are you ignorant or apathetic?" - "I don't know, and I don't care."

backlog

That part of a discussion on an #IRC channel that you've missed. If it is not or no longer available in your IRC client, you can go to sites such as http://colabti.org/irclogger/irclogger_logs/perl6 to see what has been logged for you.

Bot

A program that does automatic tasks on one or more #IRC channels by acting like a regular user (as far as the IRC server is concerned) and performing some tasks that may involve answering to users requests. Examples are #camelia, #dalek and #yoleaux.

Compilation unit or compunit

A compunit is a piece of Perl 6 code that is analyzed and compiled as a single unit. Typically, this piece of code will be contained in a single file, but code inside an EVAL is also considered a compunit.

DWIM

Do What I Mean. A programming language designer motto. The opposite of a DWIM is a #WAT.

flap

Sometimes a test will fail under some conditions, but not others; when this test passes in some test runs and fails in others, it's called flapping.

fossil

Something in a generally current document that is no longer true but which has not yet been fixed by correcting or removing it.

FSVO

For Some Value Of...

FTFY

Fixed That For You

gradual typing

You don't have to specify types of variables and parameters, but if you do, it helps in early determination of impossible dispatches and better optimization. See also https://en.wikipedia.org/wiki/Gradual_typing.

IIRC

If I Read (or Remember) Correctly.

IMHO

In My Humble Opinion.

IWBN

It Would Be Nice

LHF

Low Hanging Fruit. Usually used in the context of a (relatively) simple task to be performed by a (relative) newbie.

LGTM

Looks Good To Me

LTA

Less Than Awesome. Usually used in the context of an error message that is rather non-descriptive or unrelated to the actual error.

NST

No Such Thing

Opt

Short for "optimization", usually in either the context of spesh or JIT.

PB

Short for "problem". As in "that's not the pb".

PR

See #Pull Request.

P5

Perl 5

P6

Perl 6

RSN

Real Soon Now.

RT

Request Tracker (https://rt.perl.org/). The place where all the bugs related to #Rakudo used to live. Nowadays, the Github issue tracker of the rakudo/rakudo repository is used for that.

TIMTOWTDI

An alternative form of #TMTOWTDI, explicitly including the "is" from the contraction "There's".

TMI

Too Much Information.

TMTOWTDI

"There's More Than One Way To Do It", the Perl motto.

UGT

"Universal Greeting Time" - i.e., it's always "morning".

WFM

Works For Me

WIP

Work In Progress

WP

Wikipedia

WW

Short for wrong window. When on #IRC, someone types something in a channel that was intended for another channel, or for a private message.

Larry Wall

Perl's benevolent dictator for life, among many other things. See also https://en.wikipedia.org/wiki/Larry_Wall.

Lexing

Performing lexical analysis, a step which usually precedes parsing.

Literal

A literal is a piece of code that directly stands for an (often built-in) object and also refers to the object itself.

my $x = 2;      # the 2 is a literal
say $x;         # $x is not a literal, but a variable
my $s = "Foo";  # the "Foo" is a literal, the $s is a variable

Different types of literals are described in the syntax document.

LHS

As an acronym left-hand side, it usually refers to the left hand side of an expression, and more specifically to the left-hand side of expressions such as $lhs = "this would be the right-hand side". Since the left hand side of these expressions modify their value, when something behaves as a LHS it means that it can be read and written to.

lvalue

An lvalue, or a left value, is anything that can appear on the left-hand side of the assignment operator =. It is anything you can assign to.

Typical lvalues are variables, private and is rw attributes, lists of variables and lvalue subroutines.

Examples of lvalues:

Declaration lvalue Comments
my $x; $x
my ($a, $b); ($a, $b)
has $!attribute; $!attribute Only inside classes
has $.attrib is rw; $.attrib
sub a is rw { $x }; a()

Examples of things that are not lvalues:

3 literals
constant x = 3; constants
has $.attrib; attributes; you can only assign to $!attrib
sub f { }; f(); "normal" subs are not writable
sub f($x) { $x = 3 }; error - parameters are read-only by default

These are typically called rvalues.

Mainline

The mainline is the program text that is not part of any kind of block.

use v6.c;     # mainline 
 sub f { 
               # not in mainline, in sub f 
 } 
 f();          # in mainline again 

You can also have the mainline of any package-like declarator, such as class, module, grammar, etc. These are typically run just after the class/module/grammar have been compiled (or when loaded from a precompiled file).

Mayspec

Stands for "Maybe Specification". Usually refers to existing tests in the language specification. The speaker is indicating they did not check whether the test is a spectest or a propspec test; i.e. whether the test is included in a released language specification or is a new test, proposed for the next version of the spec.

MoarVM

MoarVM is short for Metamodel On A Runtime Virtual Machine. It's a virtual machine designed specifically for #NQP and its MOP: #6model. A document about the purpose of MoarVM. MoarVM has some similarities with the Hotspot VM so you may peruse its glossary for entries missing from the present one.

Multi-dispatch

The process of picking a candidate for calling of a set of methods or subs that come by the same name but with different arguments. The most narrow candidate wins. In case of an ambiguity, a routine with is default trait will be chosen if one exists, otherwise an exception is thrown.

multi-method

A method that has multiple candidates going by the same name and are subject to Multi-Dispatch.

NFG

Normal Form Grapheme is the way Perl 6 implements graphemes, using a normal form in which strings with the same graphemes can be easily compared in constant time. More on that on this article in 6guts and an explanation of how NFG works in this IRC log.

Niecza

An implementation of Perl 6 targeting the .NET platform. No longer actively maintained.

Not Quite Perl

See #NQP.

NQP

NQP is a primitive language for writing subroutines and methods using a subset of the Perl 6 syntax. It's not intended to be a full-fledged programming language, nor does it provide a runtime environment beyond the basic VM primitives. Compilers (such as #Rakudo) typically use NQP to compile action methods that convert a parse tree into its equivalent abstract syntax tree representation.

NYI

Not Yet Implemented

opcode

An opcode, or operation code, is a bytecode operation, that is, a command of the language actually used on the virtual machine. They are not usually intended for human consumption, but they are usually specified somewhere, like this document for MoarVM.

Operator

An expression is made of operators and operands. More precisely it is made of an operator and operands that can be subexpressions or #values. Operators are an alternative syntax for a #multi-method. With that syntax, what would be the arguments of the function are named operands instead. Operators are classified into categories of categories. A category has a precedence, an arity, and can be #fiddly, #iffy, #diffy. Perl 6 is very creative as to what is an operator, so there are many categories. Operators are made of many tokens, possibly with a subexpression. For example, @a[0] belongs to the postcircumfix category, is broken into the operand @a and the postcircumfix operator [0] where 0 is the postcircumfixed subexpression.

The <O(I<...>)> construction gives information about an operator that completes the information provided by its category. Below %conditional is the category, :reducecheck<ternary> , which specifies calling .ternary to post-process the parse subtree and :pasttype<if> specifies the NQP #opcode generated in the AST from the parse subtree.

<O('%conditional, :reducecheck<ternary>, :pasttype<if>')>

Parse tree

A parse tree represents the structure of a string or sentence according to a grammar. Grammars in Perl 6 output parse trees when they successfully match a string.

Parameter

Parameter is a class to define parameters to subroutines, method and a callable blocks. As opposed to the arguments you specify when calling a subroutine/method/callable block.

sub foo($bar) { say $bar }     # $bar is a parameter
foo(42);                       # 42 is an argument

Parrot

A virtual machine designed to run Perl 6 and other dynamic languages. No longer actively maintained.

PAST

#Parrot AST.

Perl

The Perl programming language in its many forms.

PERL

A way to describe Perl as a language, considered to be improper by many in the Perl Community.

POD

Plain Ol' Documentation, a documentation format understood by Perl 6. See here for further information.

POV

Stands for "Proof Of Viability". To be included in the language specification, a "proof of viability" implementation of the feature must exist in at least one mostly-compliant Perl 6 compiler.

Propspec

Stands for "Proposed Specification". Usually refers to existing tests in the language specification that are proposed for inclusion in the next release.

Pull request

A feature of GitHub and other git hosts like GitLab that allows you to make patches to be easily applied using the GitHub web user interface. It means you request someone to do a git pull from your repository to hers. PR is its usual acronym.

property

In this context, it either refers to an object property, which is the value of an instance variable, or an Unicode property which are codepoint features that allow programs to identify what kind of entity they represent, that is, if they are a letter, or a number, or something completely different like a control character.

pugs

pugs was one of the first interpreters/compilers written for Perl 6. It was written in Haskell by Audrey Tang.

p6y

Retronym for the "Perl 6 way" of doing things, as in idiomatic expressions or definitions. First known use with this meaning by sorear in the #perl6 IRC channel in 2010.

QAST

Successor to #PAST ('Q' being the next letter after 'P').

Raku

Raku is an alternative name for Perl 6 language and can be used interchangeably.

Rakudo

Rakudo is the name of a Perl 6 implementation that runs on #MoarVM and the JVM. It is an abbreviation of Rakuda-do, which, when translated from Japanese, means "The Way of the Camel". Also, in Japanese, "Rakudo" means "Paradise."

Reify

In the English language, reify means "to convert into or regard as a concrete thing." Its meaning in Perl 6 is very similar, in that conceptual things, like "elements of an infinite list", get reified when you try to operate on some of them. In general, reification means turning a potential element (be it an element in a lazy list that has not been computed yet or a element in a container that has not been extracted) into its actual value.

Repository

A filesystem under control of a source control management application, usually git, that holds the sources for a project, library or application. This file, for instance, is in a GitHub repository. Repositories store not only files, but also history of changes and can be used by the developing or writing team for interaction through issues or comments to code.

In Perl 6 context, however, a repository is also a short name for compilation unit repository and constitutes a system that locates and loads modules, managing their installation and precompilation. They are structured as linked lists, including chain of repositories ending in the default Compunit::Repository::Installation.

RHS

Acronym for Right-Hand Side, usually refers to the right-hand side of assignment expressions such as my $bound := $rhs.

roast

The Perl 6 specification tests, which live here: https://github.com/perl6/roast/. Originally developed for #pugs, it now serves all Perl 6 implementations. Why roast? It's the repository of all spec tests.

Roles

Roles, mix-ins or traits define interfaces and/or implementation of those interfaces as well as instance variables using them, and are mixed-in when declaring classes that follow that interface. Abstract classes are particular examples of Roles where the actual implementation is deferred to the class that uses that Role.

Roles are part of Perl 6's object system, and are declared using the role keyword and used in class declaration via does.

rule

(Used in regular expressions)

rvalue

A value that can be used on the right-hand side of an assignment. See also #lvalue.

SAP

Stands for "Specification APpendices". The SAP includes optional tests that implementations may choose to follow, but don't necessarily have to.

Can be used as a verb. To SAP something is to place it into Specification Appendices.

Semilist

A semilist is a semicolon-separated list like this one: 1;3;5, and is actually a list of lists, with each component of the semilist being a slice of a particular dimension. @array[1;3;5] would be equivalent to @array[1][3][5].

Sigil

In Perl, the sigil is the first character of a variable name. It must be either $, @, %, or & respectively for a scalar, array, hash, or code variable. See also Twigil and role. Also sigiled variables allow short conventions for variable interpolation in a double quoted string, or even postcircumfix expressions starting with such a variable.

Sigilless variable

Sigilless variables are actually aliases to the value it is assigned to them, since they are not containers. Once you assign a sigilless variable (using the escape \), its value cannot be changed.

Spesh

A functionality of the #MoarVM platform that uses runtime gathered data to improve commonly used pieces of #bytecode. It is much like a JIT compiler, except that those usually output machine code rather than bytecode.

STD

STD.pm is the "standard" Perl 6 grammar definition (see https://github.com/perl6/std/) that was used to implement Perl 6. STD.pm is no longer really a "specification" in a proscriptive sense: it's more of a guideline or model for Perl 6 implementations to follow.

Stub

Stubs define name and signature of methods whose implementation is deferred to other classes.

role Canine {
    method bark { ... }          # the ... indicates a stub
}

Classes with stubs are Abstract classes.

Symbol

Fancy alternative way to denote a name. Generally used in the context of modules linking, be it in the OS level, or at the Perl 6 #Virtual_machine level for modules generated from languages targeting these VMs. The set of imported or exported symbols is called the symbol table.

Synopsis

The current human-readable description of the Perl 6 language. Still in development. Much more a community effort than the Apocalypses and Exegeses were. The current state of the language is reflected by #roast, its #test suite, not the synopses where speculative material is not always so flagged or more recent additions have not been documented. This is even more true of material that has not been yet implemented.

Syntax analysis

A syntax or syntactic analysis is equivalent to parsing a string to generate its parse tree.

Test suite

The Perl 6 test suite is #roast.

TheDamian

#IRC screen name for #Damian Conway, writer of the original Exegeses.

TimToady

#IRC screen name for #Larry Wall, creator of Perl. The name comes from the pronunciation of #TIMTOWTDI as a word.

token

In this context, a token is a regex that does not backtrack. In general, tokens are extracted from the source program while lexing.

Thunk

A piece of code that isn't immediately executed, but doesn't have an independent scope.

Tight and loose precedence

In this context, tight or tighter refers to precedence rules and is the opposite of looser. Precedence rules for new terms are always expressed in relationship with other terms, so is tighter implies that operands with that operator will be grouped before operands with the looser operator. Operators with tight precedence are grouped with priority to others and are generally tighter than most others; loose exactly the opposite, so it is always convenient to be aware of the exact precedence of all operators used in an expression.

twine

A data structure used to hold a POD string with embedded formatting codes. For example:

=begin pod 
 C<foo> 
 =end pod 
 say $=pod[0].contents[0].contents.perl; 

The output will be:

["", Pod::FormattingCode.new(type => "C", meta => [], config => {}, contents => ["foo"]),""] 

The twine is an array with an odd number of elements beginning with a simple string, alternating with formatting code objects and simple strings, and ending with a simple string; the formatting code objects are inter twine d with the strings. The strings may be empty (as shown in the example). A twine with no formatting code will contain one simple string.

Type objects

A type object is an object that is used to represent a type or a class. Since in object oriented programming everything is an object, classes are objects too, and they inherit from Mu.

value

A value is what is actually contained in a container such as a variable. Used in expressions such as lvalue, to indicate that that particular container can be assigned to.

UB

Stands for "Undefined Behavior". In other words, it is something that is not explicitly specified by the language specification.

Value type

A type is known as a value type if it is immutable and any instance of that type is interchangeable with any other instance "of the same value"—that is, any instance constructed in the same way. An instance of a value type is often called a value (but should not be confused with #lvalues or #rvalues).

For example, numbers are value types, so a number constructed one place in your program with, for instance, the literal 3 can't be changed in any way—it simply is 3—and any later use of the literal 3 can safely be pointed at the same place in memory as the first with no ill consequences.

Classes doing the roles Numeric and Stringy are among a few examples of built-in value types.

A value type is created by ensuring that an instance of the value type is immutable (i.e., its attributes cannot be modified after construction) and that its WHICH method returns the same thing every time an instance with the same value is constructed (and conversely returns a different thing every time an instance with a different value is constructed).

The language is free to optimize based on the assumption that equivalent instances of value types are interchangeable, but you should not depend on any such optimization. For instance, if you want clone to return an instance of self, or you want instance construction to be memoized so that re-construction of a previously-constructed value always returns the same instance, you currently must override this behavior yourself.

(The same would hold true of object finalization, but if your instances need special destruction behavior, you almost certainly do not actually have a value type. Values should be thought of as "timeless" and existing in some ideal form outside of your program's memory, like natural values are.)

Variable

A variable is a name for a container.

Variable interpolation

The value of variables is interpolated into strings by simply inserting that variable into the string:

my $polation="polation";
say "inter$polation";     # OUTPUT: «interpolation␤»

This might need curly braces in case it precedes some alphanumeric characters

my $inter="inter";
say "{$inter}polation"; # OUTPUT: «interpolation␤»

Interpolation occurs in string context, so a valid stringification method must exist for the class. More general interpolation can be achieved using the double q quoting constructs.

Virtual machine

A virtual machine is the Perl compiler entity that executes the bytecode. It can optimize the bytecode or generate machine code Just in Time. Examples are #MoarVM, #Parrot (who are intended to run Perl 6) and more generic virtual machines such as JVM and Javascript.

WAT

The opposite of a #DWIM; counter-intuitive behavior. It is said that to every DWIM there is a corresponding WAT. See also https://www.destroyallsoftware.com/talks/wat.

whitespace

A character or group of blank characters, used to separate words. An example is the space character « ».

6model

6model is used in the MoarVM, and provides primitives used to create an object system. It is described in this presentation by Jonathan Worthington and implemented here in MoarVM.

36 Pod6

An easy-to-use markup language for documenting Perl modules and programs

Pod6 is an easy-to-use markup language. It can be used for writing language documentation, for documenting programs and modules, as well as for other types of document composition.

Every Pod6 document has to begin with =begin pod and end with =end pod. Everything between these two delimiters will be processed and used to generate documentation.

=begin pod 
 
 A very simple Pod6 document 
 
 =end pod 

Block structure

A Pod6 document may consist of multiple Pod6 blocks. There are four ways to define a block: delimited, paragraph, abbreviated, and declarator; the first three yield the same result but the fourth differs. You can use whichever form is most convenient for your particular documentation task.

Delimited blocks

Delimited blocks are bounded by =begin and =end markers, both of which are followed by a valid Perl 6 identifier, which is the typename of the block. Typenames that are entirely lowercase (for example: =begin head1) or entirely uppercase (for example: =begin SYNOPSIS) are reserved.

=begin head1 
 Top Level Heading 
 =end head1 

Configuration information

After the typename, the rest of the =begin marker line is treated as configuration information for the block. This information is used in different ways by different types of blocks, but is always specified using Perl6-ish option pairs. That is, any of:

Value is... Specify with... Or with... Or with...
List :key[$e1, $e2, ...] :key($e1, $e2, ...) :key<$e1 $e2 ...>
Hash :key{$k1=>$v1, $k2=>$v2}
Boolean (true) :key :key(True) :key[True]
Boolean (false) :!key :key(False) :key[False]
String :key<str> :key('str') :key("str")
Int :key(42) :key[42] :42key
Number :key(2.3) :key[2.3]

Where '$e1, $e2, ...' are list elements of type String, Int, Number, or Boolean. Lists may have mixed element types. Note that one-element lists are converted to the type of their element (String, Int, Number, or Boolean). Also note that "bigints" can be used if required.

For hashes, '$k1, $k2, ...' are keys of type Str and '$v1, $v2, ...' are values of type String, Int, Number, or Boolean.

Strings are delimited by single or double quotes. Whitespace is not significant outside of strings. Hash keys need not be quote-delimited unless they contain significant whitespace. Strings entered inside angle brackets become lists if any whitespace is used inside the angle brackets.

All option keys and values must, of course, be constants since Pod6 is a specification language, not a programming language. Specifically, option values cannot be closures. See Synopsis 2 for details of the various Perl 6 pair notations.

The configuration section may be extended over subsequent lines by starting those lines with an = in the first (virtual) column followed by a whitespace character.

This feature is not yet completely implemented. All configuration information currently must be provided on the same line as the =begin marker line or =for name for paragraph blocks.

Paragraph blocks

Paragraph blocks begin by a =for marker and end by the next Pod6 directive or the first blank line. The =for marker is followed by the typename of the block plus, optionally, any configuration data as in the delimited blocks described above.

=for head1 
 Top Level Heading 

Abbreviated blocks

Abbreviated blocks begin by an '=' sign, which is followed immediately by the typename of the block. All following data are part of the contents of the block, thus configuration data cannot be specified for an abbreviated block. The block ends at the next Pod6 directive or the first blank line.

=head1 Top level heading 

Declarator blocks

Declarator blocks differ from the others by not having a specific type, instead they are attached to some source code.

Declarator blocks are introduced by a special comment: either #| or #=, which must be immediately followed by either a space or an opening curly brace. If followed by a space, the block is terminated by the end of line; if followed by one or more opening curly braces, the block is terminated by the matching sequence of closing curly braces.

Blocks starting with #| are attached to the code after them, and blocks starting with #= are attached to the code before them.

Since declarator blocks are attached to source code, they can be used to document classes, roles, subroutines and in general any statement or block.

The WHY method can be used on these classes, roles, subroutines etc. to return the attached Pod6 value.

#| Base class for magicians 
 class Magician { 
   has Int $.level; 
   has Str @.spells; 
 } 
 
 #| Fight mechanics 
 sub duel(Magician $a, Magician $b) { 
 } 
 #= Magicians only, no mortals. 
 
 say Magician.WHY; # OUTPUT: «Base class for magicians␤» 
 say &duel.WHY.leading; # OUTPUT: «Fight mechanics␤» 
 say &duel.WHY.trailing; # OUTPUT: «Magicians only, no mortals.␤» 

These declarations can extend multiple blocks:

#|( This is an example of stringification: 
     * Numbers turn into strings 
     * Regexes operate on said strings 
     * C<with> topicalizes and places result into $_ 
 ) 
 sub search-in-seq( Int $end, Int $number ) { 
     with (^$end).grep( /^$number/ ) { 
         .say for $_<>; 
     } 
 } 
 #=« Uses 
     * topic 
     * decont operator 
 » 

By using a matched pair of parenthesis constructs such as () or «» the comments can extend multiple lines. This format, however, will not translate to a multi-line display by perl6 -doc.

Block types

Pod6 offers a wide range of standard block types.

Headings

Headings can be defined using =headN, where N is greater than zero (e.g., =head1, =head2, …).

=head1 A top level heading 
 
 =head2 A second level heading 
 
 =head3 A third level heading 

Ordinary paragraphs

An ordinary paragraph consists of text that is to be formatted into a document at the current level of nesting, with whitespace squeezed, lines filled, and any special inline mark-up applied.

Ordinary paragraphs consist of one or more consecutive lines of text, each of which starts with a non-whitespace character. The paragraph is terminated by the first blank line or block directive.

For example:

=head1 This is a heading block 
 
 This is an ordinary paragraph. 
 Its text  will   be     squeezed     and 
 short lines filled. It is terminated by 
 the first blank line. 
 
 This is another ordinary paragraph. 
 Its     text    will  also be squeezed and 
 short lines filled. It is terminated by 
 the trailing directive on the next line. 
 
 =head2 This is another heading block 
 
 This is yet another ordinary paragraph, 
 at the first virtual column set by the 
 previous directive 

Ordinary paragraphs do not require an explicit marker or delimiters.

Alternatively, there is also an explicit =para marker that can be used to explicitly mark a paragraph.

=para 
 This is an ordinary paragraph. 
 Its text  will   be     squeezed     and 
 short lines filled. 

In addition, the longer =begin para and =end para form can be used.

For example:

=begin para 
 This is an ordinary paragraph. 
 Its text  will   be     squeezed     and 
 short lines filled. 
 
 This is still part of the same paragraph, 
 which continues until an... 
 =end para 

As demonstrated by the previous example, within a delimited =begin para and =end para block, any blank lines are preserved.

Code blocks

Code blocks are used to specify source code, which should be rendered without re-justification, without whitespace-squeezing, and without recognizing any inline formatting codes. Typically these blocks are used to show examples of code, mark-up, or other textual specifications, and are rendered using a fixed-width font.

A code block may be implicitly specified as one or more lines of text, each of which starts with a whitespace character. The implicit code block is then terminated by a blank line.

For example:

This ordinary paragraph introduces a code block: 
 
     my $name = 'John Doe'; 
     say $name; 

Code blocks can also be explicitly defined by enclosing them in =begin code and =end code

    =begin code 
     my $name = 'John Doe'; 
     say $name; 
     =end code 

I/O blocks

Pod6 provides blocks for specifying the input and output of programs.

The =input block is used to specify pre-formatted keyboard input, which should be rendered without re-justification or squeezing of whitespace.

The =output block is used to specify pre-formatted terminal or file output, which should also be rendered without re-justification or whitespace-squeezing.

Lists

Unordered lists

Lists in Pod6 are specified as a series of =item blocks.

For example:

The three suspects are: 
 
 =item  Happy 
 =item  Sleepy 
 =item  Grumpy 

The three suspects are:

Definition lists

Lists that define terms or commands use =defn, equivalent to the DL lists in HTML

=defn Happy 
 When you're not blue. 
 
 =defn Blue 
 When you're not happy. 

will be rendered as

Happy

When you're not blue.

Blue

When you're not happy.

Multi-level lists

Lists may be multi-level, with items at each level specified using the =item1, =item2, =item3, etc. blocks.

Note that =item is just an abbreviation for =item1.

For example:

=item1  Animal 
 =item2     Vertebrate 
 =item2     Invertebrate 
 
 =item1  Phase 
 =item2     Solid 
 =item2     Liquid 
 =item2     Gas 

Multi-paragraph lists

Using the delimited form of the =item block (=begin item and =end item), we can specify items that contain multiple paragraphs.

For example:

Let's consider two common proverbs: 
 
 =begin item 
 I<The rain in Spain falls mainly on the plain.> 
 
 This is a common myth and an unconscionable slur on the Spanish 
 people, the majority of whom are extremely attractive. 
 =end item 
 
 =begin item 
 I<The early bird gets the worm.> 
 
 In deciding whether to become an early riser, it is worth 
 considering whether you would actually enjoy annelids 
 for breakfast. 
 =end item 
 
 As you can see, folk wisdom is often of dubious value. 

Let's consider two common proverbs:

As you can see, folk wisdom is often of dubious value.

Tables

Check out this page for documentation related to Tables

Pod6 comments

Pod6 comments are comments that Pod6 renderers ignore.

Comments are useful for meta-documentation (documenting the documentation). Single-line comments use the =comment marker:

=comment Add more here about the algorithm 

For multi-line comments, use a delimited comment block:

=begin comment 
 This comment is 
 multi-line. 
 =end comment 

Semantic blocks

All uppercase block typenames are reserved for specifying standard documentation, publishing, source components, or meta-information.

=NAME 
 =AUTHOR 
 =VERSION 
 =TITLE 
 =SUBTITLE 

Formatting codes

Formatting codes provide a way to add inline mark-up to a piece of text.

All Pod6 formatting codes consist of a single capital letter followed immediately by a set of single or double angle brackets; Unicode double angle brackets may be used.

Formatting codes may nest other formatting codes.

The following codes are available: B, C, E, I, K, L, N, P, R, T, U, V, X, and Z.

Bold

To format a text in bold enclose it in B< >

Perl 6 is B<awesome> 

Perl 6 is awesome

Italic

To format a text in italic enclose it in I< >

Perl 6 is I<awesome> 

Perl 6 is awesome

Underlined

To underline a text enclose it in U< >

Perl 6 is U<awesome> 

Code

To flag text as code and treat it verbatim enclose it in C< >

C<my $var = 1; say $var;> 

my $var = 1; say $var;

To create a link enclose it in L< >

A vertical bar (optional) separates label and target.

The target location can be an URL (first example) or a local Pod6 document (second example). Local file names are relative to the base of the project, not the current document.

Perl 6 homepage L<https://perl6.org> 
 L<Perl 6 homepage|https://perl6.org> 

Perl 6 homepage https://perl6.org

Perl 6 homepage

Structure L</language/about#Structure|/language/about#Structure> 
 L<Structure|/language/about#Structure> 

Structure /language/about#Structure

Structure

To create a link to a section in the same document:

Comments L<#Comments> 
 L<Comments|#Comments> 

Comments #Comments

Comments

This code is not implemented in Pod::To::HTML, but is partially implemented in Pod::To::BigPage.

A second kind of link — the P<> or placement link — works in the opposite direction. Instead of directing focus out to another document, it allows you to assimilate the contents of another document into your own.

In other words, the P<> formatting code takes a URI and (where possible) inserts the contents of the corresponding document inline in place of the code itself.

P<> codes are handy for breaking out standard elements of your documentation set into reusable components that can then be incorporated directly into multiple documents. For example:

=COPYRIGHT 
 P<file:/shared/docs/std_copyright.pod> 
 
 =DISCLAIMER 
 P<http://www.MegaGigaTeraPetaCorp.com/std/disclaimer.txt> 

might produce:

Copyright

This document is copyright (c) MegaGigaTeraPetaCorp, 2006. All rights reserved.

Disclaimer

ABSOLUTELY NO WARRANTY IS IMPLIED. NOT EVEN OF ANY KIND. WE HAVE SOLD YOU THIS SOFTWARE WITH NO HINT OF A SUGGESTION THAT IT IS EITHER USEFUL OR USABLE. AS FOR GUARANTEES OF CORRECTNESS...DON'T MAKE US LAUGH! AT SOME TIME IN THE FUTURE WE MIGHT DEIGN TO SELL YOU UPGRADES THAT PURPORT TO ADDRESS SOME OF THE APPLICATION'S MANY DEFICIENCIES, BUT NO PROMISES THERE EITHER. WE HAVE MORE LAWYERS ON STAFF THAN YOU HAVE TOTAL EMPLOYEES, SO DON'T EVEN *THINK* ABOUT SUING US. HAVE A NICE DAY.

If a renderer cannot find or access the external data source for a placement link, it must issue a warning and render the URI directly in some form, possibly as an outwards link. For example:

Copyright

See: file:/shared/docs/std_copyright.pod

Disclaimer

See: http://www.MegaGigaTeraPetaCorp.com/std/disclaimer.txt

You can use any of the following URI forms (see #Links) in a placement link.

Comments

A comment is text that is never rendered.

To create a comment enclose it in Z< >

Perl 6 is awesome Z<Of course it is!> 

Perl 6 is awesome

Notes

Notes are rendered as footnotes.

To create a note enclose it in N< >

Perl 6 is multi-paradigmatic N<Supporting Procedural, Object Oriented, and Functional programming> 

Keyboard input

To flag text as keyboard input enclose it in K< >

Enter your name K<John Doe> 

Replaceable

The R<> formatting code specifies that the contained text is a replaceable item, a placeholder, or a metasyntactic variable. It is used to indicate a component of a syntax or specification that should eventually be replaced by an actual value. For example:

The basic ln command is: ln source_file target_file

or:

Then enter your details at the prompt: 
 
 =for input 
     Name:  your surname 
       ID:  your employee number 
     Pass:  your 36-letter password 

Terminal output

To flag text as terminal output enclose it in T< >

Hello T<John Doe> 

Unicode

To include Unicode code points or HTML5 character references in a Pod6 document, enclose them in E< >

E< > can enclose a number, which is treated as the decimal Unicode value for the desired code point. It can also enclose explicit binary, octal, decimal, or hexadecimal numbers using the Perl 6 notations for explicitly based numbers.

Perl 6 makes considerable use of the E<171> and E<187> characters. 
 
 Perl 6 makes considerable use of the E<laquo> and E<raquo> characters. 
 
 Perl 6 makes considerable use of the E<0b10101011> and E<0b10111011> characters. 
 
 Perl 6 makes considerable use of the E<0o253> and E<0o273> characters. 
 
 Perl 6 makes considerable use of the E<0d171> and E<0d187> characters. 
 
 Perl 6 makes considerable use of the E<0xAB> and E<0xBB> characters. 

Perl 6 makes considerable use of the « and » characters.

Verbatim text

This code is not implemented by Pod::To::HTML, but is implemented in Pod::To::BigPage.

The V<> formatting code treats its entire contents as being verbatim, disregarding every apparent formatting code within it. For example:

The B<V< V<> >> formatting code disarms other codes 
 such as V< I<>, C<>, B<>, and M<> >. 

Note, however that the V<> code only changes the way its contents are parsed, not the way they are rendered. That is, the contents are still wrapped and formatted like plain text, and the effects of any formatting codes surrounding the V<> code are still applied to its contents. For example the previous example is rendered as:

The V<> formatting code disarms other codes such as I<>, C<>, B<>, and M<> .

Indexing terms

Anything enclosed in an X<> code is an index entry. The contents of the code are both formatted into the document and used as the (case-insensitive) index entry:

An  X<array>  is an ordered list of scalars indexed by number, 
 starting with 0. A  X<hash>  is an unordered collection of scalar 
 values indexed by their associated string key. 

You can specify an index entry in which the indexed text and the index entry are different, by separating the two with a vertical bar:

An  X<array|arrays>  is an ordered list of scalars indexed by number, 
 starting with 0. A  X<hash|hashes>  is an unordered collection of 
 scalar values indexed by their associated string key. 

In the two-part form, the index entry comes after the bar and is case-sensitive.

You can specify hierarchical index entries by separating indexing levels with commas:

An X<array| arrays, definition of > is an ordered list of scalars 
 indexed by number, starting with 0. A X<hash| hashes, definition of > 
 is an unordered collection of scalar values indexed by their 
 associated string key. 

You can specify two or more entries for a single indexed text, by separating the entries with semicolons:

A X<hash| hashes, definition of; associative arrays > 
 is an unordered collection of scalar values indexed by their 
 associated string key. 

The indexed text can be empty, creating a "zero-width" index entry:

X<|puns, deliberate> This is called the "Orcish Maneuver" 
 because you "OR" the "cache". 

Rendering Pod

HTML

In order to generate HTML from Pod, you need the Pod::To::HTML module.

If it is not already installed, install it by running the following command: zef install Pod::To::HTML

Once installed, run the following command in the terminal:

perl6 --doc=HTML input.pod6 > output.html 

Markdown

In order to generate Markdown from Pod, you need the Pod::To::Markdown module.

If it is not already installed, install it by running the following command: zef install Pod::To::Markdown

Once installed, run the following command in the terminal:

perl6 --doc=Markdown input.pod6 > output.md 

Text

In order to generate Text from Pod, you can use the default Pod::To::Text module.

Using the terminal, run the following command:

perl6 --doc=Text input.pod6 > output.txt 

You can omit the =Text portion:

perl6 --doc input.pod6 > output.txt 

You can even embed Pod6 directly in your program and add the traditional Unix command line "--man" option to your program with a multi MAIN subroutine like this:

multi MAIN(Bool :$man) { 
     run $*EXECUTABLE, '--doc', $*PROGRAM; 
 } 

Now myprogram --man will output your Pod6 rendered as a man page.

Accessing Pod

In order to access Pod6 documentation from within a Perl 6 program the special = twigil, as documented in the variables section, must be used.

The = twigil provides the introspection over the Pod6 structure, providing a Pod::Block tree root from which it is possible to access the whole structure of the Pod6 document.

As an example, the following piece of code introspects its own Pod6 documentation:

=begin pod 
 
 =head1 This is a head1 title 
 
 This is a paragraph. 
 
 =head2 Subsection 
 
 Here some text for the subsection. 
 
 =end pod 
 
 for $=pod -> $pod-item { 
     for $pod-item.contents -> $pod-block { 
       $pod-block.perl.say; 
     } 
 } 

producing the following output:

Pod::Heading.new(level => 1, config => {}, contents => [Pod::Block::Para.new(config => {}, contents => ["This is a head1 title"])]); 
 Pod::Block::Para.new(config => {}, contents => ["This is a paragraph."]); 
 Pod::Heading.new(level => 2, config => {}, contents => [Pod::Block::Para.new(config => {}, contents => ["Subsection"])]); 
 Pod::Block::Para.new(config => {}, contents => ["Here some text for the subsection."]); 

37 Pod 6 tables

The good, the bad and the ugly

The official specification for Perl 6 POD tables is located in the Documentation specification here: Tables. Although Pod 6 specifications are not completely handled properly yet, several projects are ongoing to correct the situation; one such project is ensuring the proper handling of Pod 6 tables.

As part of that effort, this document explains the current state of Pod 6 tables by example: valid tables, invalid tables, and ugly tables (i.e., valid tables that, because of sloppy construction, may result in something different than the user expects).

Restrictions

1. The only valid column separators are either visible (' | ' or ' + ') (note at least one space is required before and after the visible column separators) or invisible [two or more contiguous whitespace (WS) characters (e.g., '  ')]. Column separators are not normally recognized as such at the left or right side of a table, but one on the right side may result in one or more empty cells depending upon the number of the cells in other rows. (Note that a pipe or plus character meant as part of cell data will result in an unintended extra column unless the character is escaped with a backslash, e.g., '\|' or '\+'.)

2. Mixing visible and invisible column separators in the same table is illegal.

3. The only valid row separator characters are '_', '-', '+', ' ', '|', and '='.

4. Consecutive interior row-separator lines are illegal.

5. Leading and trailing row-separator lines generate a warning.

6. Formatting blocks in table cells currently are ignored and treated as plain text.

HINT: During development, use of the environment variable RAKUDO_POD6_TABLE_DEBUG will show you how Rakudo interprets your pod tables before they are passed to renderers such as Pod::To::HTML, Pod::To::Text, and Pod::To::Markdown.

Best practices

HINT: Not adhering to the following best practices may require more table processing due to additional looping over table rows.

1. Use of WS for column separators is fragile, and they should only be used for simple tables. The Ugly Tables section below illustrates the problem.

2. Align table columns and rows carefully. See the examples in later best practices.

3. Don't use visual borders on the table.

4. For tables with a heading and single- or multi-line content, use one or more contiguous equal signs ('=') as the row separator after the heading, and use one or more contiguous hyphens ('-') as the row separator in the content portion of the table. For example,

=begin table 
  hdr col 0 | hdr col 1 
  ====================== 
  row 0     | row 0 
  col 0     | col 1 
  ---------------------- 
  row 1     | row 1 
  col 0     | col 1 
  ---------------------- 
 =end table 
=begin table 
  hdr col 0   | hdr col 1 
  ====================== 
  row 0 col 0 | row 0 col 1 
  row 1 col 0 | row 1 col 1 
 =end table 

5. For tables with no header and multi-line content, use one or more contiguous hyphens ('-') as the row separator in the content portion of the table. For example,

=begin table 
  row 0       | row 0 
  col 0       | col 1 
  ---------------------- 
  row 1 col 0 | row 1 col 1 
 =end table 

6. For tables with many rows and no multi-line content, using no row separators is fine. However, with one or more rows with multi-line content, it is easier to ensure proper results by using a row separator line (visible or invisible) between every content row.

7. Ensure intentionally empty cells have column separators, otherwise expect a warning about short rows being filled with empty cells. (Tables rows will always have the same number of cells as the row with the most cells. Short rows are padded on the right with empty cells and generate a warning.)

8. Adding a caption to a table is possible using the =begin table line as in this example:

=begin table :caption<My Tasks> 
 mow lawn 
 take out trash 
 =end table 

Although not a good practice, currently there is in use an alternate method of defining a caption as shown in this example:

=begin table :config{caption => "My Tasks"} 
 mow lawn 
 take out trash 
 =end table 

Note the alternative method of putting the caption in the config hash was necessary before the :caption method was implemented, but that method is now considered to be deprecated. The practice will generate a warning in the upcoming version 6.d, and it will raise an exception in version 6.e.

Good tables

Following are examples of valid (Good) tables (taken from the current Specification Tests).

=begin table 
         The Shoveller   Eddie Stevens     King Arthur's singing shovel 
         Blue Raja       Geoffrey Smith    Master of cutlery 
         Mr Furious      Roy Orson         Ticking time bomb of fury 
         The Bowler      Carol Pinnsler    Haunted bowling ball 
 =end table 
=table 
     Constants           1 
     Variables           10 
     Subroutines         33 
     Everything else     57 
 
=for table 
     mouse    | mice 
     horse    | horses 
     elephant | elephants 
 
=table 
     Animal | Legs |    Eats 
     ======================= 
     Zebra  +   4  + Cookies 
     Human  +   2  +   Pizza 
     Shark  +   0  +    Fish 
 
=table 
         Superhero     | Secret          | 
                       | Identity        | Superpower 
         ==============|=================|================================ 
         The Shoveller | Eddie Stevens   | King Arthur's singing shovel 
 
=begin table 
 
                         Secret 
         Superhero       Identity          Superpower 
         =============   ===============   =================== 
         The Shoveller   Eddie Stevens     King Arthur's 
                                           singing shovel 
 
         Blue Raja       Geoffrey Smith    Master of cutlery 
 
         Mr Furious      Roy Orson         Ticking time bomb 
                                           of fury 
 
         The Bowler      Carol Pinnsler    Haunted bowling ball 
 
 =end table 
=table 
     X | O | 
    ---+---+--- 
       | X | O 
    ---+---+--- 
       |   | X 
 
=table 
     X   O 
    =========== 
         X   O 
    =========== 
             X 
 
=begin table 
 
 foo 
 bar 
 
 =end table 

Bad tables

Following are examples of invalid (Bad) tables, and they should trigger an unhandled exception during parsing.

=begin table 
 r0c0 +  r0c1 | r0c3 
 =end table 
=begin table 
 r0c0 +  r0c1 | r0c3 
 r1c0    r0c1   r0c3 
 =end table 
=begin table 
 r0c0 |  r0c1 
 ============ 
 ============ 
 r1c0 |  r1c1 
 =end table 

Ugly tables

Following are examples of valid tables that are probably intended to be two columns, but the columns are not aligned well so each will parse as a single-column table.

Notice the second row has the two words separated by only one WS character, while it takes at least two adjacent WS characters to define a column separation. This is a valid table but will be parsed as a single-column table.

=begin table 
 r0c0    r0c1 
  r1c0 r0c1 
 =end table 

Notice the second row has the two words separated by a visible character ('|') but the character is not recognized as a column separator because it doesn't have an adjacent WS character on both sides of it. Although this is a legal table, the result will not be what the user intended because the first row has two columns while the second row has only one column, and it will thus have an empty second column.

=begin table 
 r0c0  |  r0c1 
  r1c0 |r0c1 
 =end table 

38 Terms

Perl 6 terms

Most syntactic constructs in Perl 6 can be categorized in terms and operators.

Here you can find an overview of different kinds of terms.

Literals

Int

42 
 12_300_00 
 :16<DEAD_BEEF> 

Int literals consist of digits and can contain underscores between any two digits.

To specify a base other than ten, use the colonpair form :radix<number> .

Rat

12.34 
 1_200.345_678 

Rat literals (rational numbers) contain two integer parts joined by a dot.

Note that trailing dots are not allowed, so you have to write 1.0 instead of 1. (this rule is important because there are infix operators starting with a dot, for example the .. Range operator).

Num

12.3e-32 
 3e8 

Num literals (floating point numbers) consist of Rat or Int literals followed by an e and a (possibly negative) exponent. 3e8 constructs a Num with value 3 * 10**8.

Str

'a string' 
 'I\'m escaped!' 
 "I don't need to be" 
 "\"But I still can be,\" he said." 
 q|Other delimiters can be used too!| 

String literals are most often created with ' or ", however strings are actually a powerful sub-language of Perl 6. See Quoting Constructs.

Regex

/ match some text / 
 rx/slurp \s rest (.*) $/ 

These forms produce regex literals. See quoting constructs.

Pair

a => 1 
 'a' => 'b' 
 :identifier 
 :!identifier 
 :identifier<value> 
 :identifier<value1 value2> 
 :identifier($value) 
 :identifier['val1', 'val2'] 
 :identifier{key1 => 'val1', key2 => 'value2'} 
 :valueidentifier 
 :$item 
 :@array 
 :%hash 
 :&callable 

Pair objects can be created either with infix:«=>» (which auto-quotes the left-hand side if it is an identifier), or with the various colon-pair forms. Those almost always start with a colon and then are followed either by an identifier or the name of an already existing variable (whose name without the sigil is used as the key and value of the variable is used as the value of the pair). There is a special form where an integer value is immediately after the colon and the key is immediately after the value.

In the identifier form of a colon-pair, the optional value can be any circumfix. If it is left blank, the value is Bool::True. The value of the :!identifier form is Bool::False.

If used in an argument list, all of these forms count as named arguments, with the exception of 'quoted string' => $value .

List

() 
 1, 2, 3 
 <a b c> 
 «a b c» 
 qw/a b c/ 

List literals are: the empty pair of parentheses (), a comma-separated list, or several quoting constructs.

term *

Creates an object of type Whatever. See Whatever documentation for more details.

Identifier terms

There are built-in identifier terms in Perl 6, which are listed below. In addition one can add new identifier terms with the syntax:

sub term:<forty-two> { 42 };
say forty-two

or as constants:

constant forty-two = 42;
say forty-two;

term self

Inside a method, self refers to the invocant (i.e. the object the method was called on). If used in a context where it doesn't make sense, a compile-time exception of type X::Syntax::NoSelf is thrown.

term now

Returns an Instant object representing the current time. It includes leap seconds and as such a few dozen seconds larger than time:

say (now - time).Int; # OUTPUT: «37␤»

term time

Returns the current POSIX time as an Int. See now for high-resolution timestamp that includes leap seconds.

term rand

Returns a pseudo-random Num in the range 0..^1.

term π

Returns the number π at codepoint U+03C0 (GREEK SMALL LETTER PI), i.e. the ratio between circumference and diameter of a circle. The ASCII equivalent of π is pi.

term pi

Returns the number π, i.e., the ratio between circumference and diameter of a circle. pi is the ASCII equivalent of π.

term τ

Returns the number τ at codepoint U+03C4 (GREEK SMALL LETTER TAU), i.e. the ratio between circumference and radius of a circle. The ASCII equivalent of τ is tau.

term tau

Returns the number τ, i.e. the ratio between circumference and radius of a circle. tau is the ASCII equivalent of τ.

term 𝑒

Returns Euler's number at codepoint U+1D452 (MATHEMATICAL ITALIC SMALL E). The ASCII equivalent of 𝑒 is e.

term e

Returns Euler's number. e is the ASCII equivalent of 𝑒.

term i

Returns the imaginary unit (for Complex numbers).

term ∅

Returns set(), aka the empty set, at codepoint U+2205 (EMPTY SET).

Variables

Variables are discussed in the variable language docs.

Constants

Constants are similar to variables without a container, and thus cannot be rebound. However, their initializers are evaluated at BEGIN time:

constant speed-of-light = 299792458; # m/s
constant @foo  = 1, 2, 3;
constant &talk = &say;
talk speed-of-light²; # OUTPUT: «89875517873681764␤»
talk @foo;            # OUTPUT: «(1 2 3)␤»

Compile-time evaluation means you should be careful with using constants inside modules, which get automatically precompiled, and so the value of the constant would not change even between multiple executions of the program:

# Foo.pm6 
 unit module Foo; 
 constant comp-time = DateTime.now; 
# The value of the constant remains the same even though our script 
 # is executed multiple times: 
 $ perl6 -I. -MFoo -e 'say Foo::comp-time' 
 2018-06-17T18:18:50.021484-04:00 
 $ perl6 -I. -MFoo -e 'say Foo::comp-time' 
 2018-06-17T18:18:50.021484-04:00 

Constants are declared with keyword constant followed by an identifier with an optional sigil. Constants are our scoped by default.

    constant foo  = 42; 
 my  constant $baz = rand; 
 our constant @foo = 1, 2, 3; 
     constant %bar = %(:42foo, :100bar); 

NOTE: if you're using the Rakudo compiler, you need version 2018.08 or newer for type constraints and auto-coercion on constants to be available. Auto-coercion on %-sigiled constants requires 6.d

An optional type constraint can be used, in which case the use of scope declarator is required:

# !!WRONG!! missing scope declarator before type: 
 Int constant bar = 42; 
 
 # RIGHT: 
 our Int constant bar = 42; 

Unlike variables, you cannot parameterize @-, %-, and &-sigiled constants by specifying the parameterization type in the declarator itself:

# !!WRONG!! cannot parameterize @-sigiled constant with Int 
 our Int constant @foo = 42; 
 
 # OK: parameterized types as values are fine 
 constant @foo = Array[Int].new: 42; 

The reason for the restriction is that constants with @ and % sigils default to List and Map types, which cannot be parameterized. To keep things simple and consistent, parameterization was simply disallowed in these constructs.

The @-, %-, and &-sigiled constants specify implied typecheck of the given value for Positional, Associative, and Callable roles respectively. The @-sigiled constants—and as of 6.d language version, the %-sigiled constants as well—perform auto-coercion of the value if it does not pass the implied typecheck. The @-sigiled constants will coerce using method cache and %-sigiled constants coerce using method Map.

constant @foo = 42; 
 @foo.perl.say; # OUTPUT: «(42,)» 
 
 constant @bar = [<a b c>]; 
 @bar.perl.say; # OUTPUT: «["a", "b", "c"]» 
use v6.d.PREVIEW; 
 constant %foo = <foo bar>; 
 %foo.perl.say; # OUTPUT: «Map.new((:foo("bar")))» 
 
 constant %bar = {:10foo, :72bar}; 
 %bar.perl.say; # OUTPUT: «{:bar(72), :foo(10)}» 
 
 # Pair is already Associative, so it remains a Pair 
 constant %baz = :72baz; 
 %baz.perl.say; # OUTPUT: «:baz(72)» 

For convenience and consistency reasons, you can use the binding operator ( := ) instead of the assignment operator, use backslash before sigilless name of the constant variable (same as with sigilless variables), and even omit the name of the constant entirely to have an anonymous constant. Since you can't refer to anonymous entities, you may be better off using a BEGIN phaser instead, for clarity.

constant %foo := :{:42foo};
constant \foo = 42;
constant = 'anon';

39 Testing

Writing and running tests in Perl 6

Testing code is an integral part of software development. Tests provide automated, repeatable verifications of code behavior, and ensures your code works as expected.

In Perl 6, the Test module provides a testing framework, used also by Perl 6's official spectest suite.

The testing functions emit output conforming to the Test Anything Protocol. In general, they are used in sink context:

ok check-name($meta, :$relaxed-name), "name has a hyphen rather than '::'" 

but all functions also return as a Boolean if the test has been successful or not, which can be used to print a message if the test fails:

ok check-name($meta, :$relaxed-name), "name has a hyphen rather than '::'" \ 
   or diag "\nTo use hyphen in name, pass :relaxed-name to meta-ok\n"; 

Writing tests

As with any Perl project, the tests live under the t directory in the project's base directory.

A typical test file looks something like this:

use Test;      # a Standard module included with Rakudo 
 use lib 'lib'; 
 
 plan $num-tests; 
 
 # .... tests 
 
 done-testing;  # optional with 'plan' 

We ensure that we're using Perl 6, via the use v6.c pragma, then we load the Test module and specify where our libraries are. We then specify how many tests we plan to run (such that the testing framework can tell us if more or fewer tests were run than we expected) and when finished with the tests, we use done-testing to tell the framework we are done.

Thread safety

Note that routines in Test module are not thread-safe. This means you should not attempt to use the testing routines in multiple threads simultaneously, as the TAP output might come out of order and confuse the program interpreting it.

There are no current plans to make it thread safe. If threaded-testing is crucial to you, you may find some suitable ecosystem modules to use instead of Test for your testing needs.

Running tests

Tests can be run individually by specifying the test filename on the command line:

$ perl6 t/test-filename.t 

To run all tests in the directory recursively, prove6 application can be used.

You have to install it before using with zef:

$ zef install App::Prove6 

You can run prove6 in a distribution directory this way:

$ prove6 --lib t/ 

The t/ argument specified directory that contains tests and the --lib option is passed to include lib directory into Perl 6 distribution path, it is an equivalent of -Ilib argument of perl6 command.

For more documentation regarding prove6 usage refer to its page.

To abort the test suite upon first failure, set the PERL6_TEST_DIE_ON_FAIL environmental variable:

$ PERL6_TEST_DIE_ON_FAIL=1 perl6 t/test-filename.t 

The same variable can be used within the test file. Set it before loading the Test module:

BEGIN %*ENV<PERL6_TEST_DIE_ON_FAIL> = 1;
use Test;
...

Test plans

Tests plans use plan for declaring how many plans are going to be done or, as might be the case, skipped. If no plan is declared, done-testing is used to declare the end of the tests.

Testing return values

The Test module exports various functions that check the return value of a given expression and produce standardized test output.

In practice, the expression will often be a call to a function or method that you want to unit-test. ok and nok will match True and False. However, where possible it's better to use one of the specialized comparison test functions below, because they can print more helpful diagnostics output in case the comparison fails.

By string comparison

is and nok test for equality using the proper operator, depending on the object (or class) it's handled.

By approximate numeric comparison

is-approx compares numbers with a certain precision, which can be absolute or relative. It can be useful for numeric values whose precision will depend on the internal representation.

By structural comparison

Structures can be also compared using is-deeply, which will check that internal structures of the objects compared is the same.

By arbitrary comparison

You can use any kind of comparison with cmp-ok, which takes as an argument the function or operator that you want to be used for comparing.

By object type

isa-ok tests whether an object is of a certain type.

By method name

can-ok is used on objects to check whether they have that particular method.

By role

does-ok checks whether the given variable can do a certain Role.

By regex

like and unlike check using regular expressions; in the first case passes if a match exists, in the second case when it does not.

Testing modules

Modules are tentatively loaded with use-ok, which fails if they fail to load.

Testing exceptions

dies-ok and lives-ok are opposites ways of testing code; the first checks that it throws an exception, the second that it does not; throws-like checks that the code throws the specific exception it gets handed as an argument; fails-like, similarly, checks if the code returns a specific type of Failure. eval-dies-ok and eval-lives-ok work similarly on strings that are evaluated prior to testing.

Grouping tests

The result of a group of subtests is only ok if all subtests are ok; they are grouped using subtest.

Skipping tests

Sometimes tests just aren't ready to be run, for instance a feature might not yet be implemented, in which case tests can be marked as todo. Or it could be the case that a given feature only works on a particular platform - in which case one would skip the test on other platforms; skip-rest will skip the remaining tests instead of a particular number given as argument; bail-out will simply exit the tests with a message.

Manual control

If the convenience functionality documented above does not suit your needs, you can use the following functions to manually direct the test harness output; pass will say a test has passed, and diag will print a (possibly) informative message.

40 Traps to avoid

Traps to avoid when getting started with Perl 6

When learning a programming language, possibly with the background of being familiar with another programming language, there are always some things that can surprise you and might cost valuable time in debugging and discovery.

This document aims to show common misconceptions in order to avoid them.

During the making of Perl 6 great pains were taken to get rid of warts in the syntax. When you whack one wart, though, sometimes another pops up. So a lot of time was spent finding the minimum number of warts or trying to put them where they would rarely be seen. Because of this, Perl 6's warts are in different places than you may expect them to be when coming from another language.

Variables and constants

Constants are computed at compile time

Constants are computed at compile time, so if you use them in modules keep in mind that their values will be frozen due to precompilation of the module itself:

# WRONG (most likely): 
 unit module Something::Or::Other; 
 constant $config-file = "config.txt".IO.slurp; 

The $config-file will be slurped during precompilation and changes to config.txt file won't be re-loaded when you start the script again; only when the module is re-compiled.

Avoid using a container and prefer binding a value to a variable that offers a behavior similar to a constant, but allowing the value to get updated:

# Good; file gets updated from 'config.txt' file on each script run: 
 unit module Something::Or::Other; 
 my $config-file := "config.txt".IO.slurp; 

Assigning to Nil produces a different value, usually Any

Actually, assigning to Nil reverts the variable to its default value. So:

my @a = 4, 8, 15, 16; 
 @a[2] = Nil; 
 say @a; # OUTPUT: «[4 8 (Any) 16]␤» 

In this case, Any is the default value of an Array element.

You can purposefully assign Nil as a default value:

my %h is default(Nil) = a => Nil; 
 say %h; # OUTPUT: «Hash %h = {:a(Nil)}␤» 

Or bind a value to Nil if that is the result you want:

@a[3] := Nil; 
 say @a; # OUTPUT: «[4 8 (Any) Nil]␤» 

This trap might be hidden in the result of functions, such as matches:

my $result2 = 'abcdef' ~~ / dex /; 
 say "Result2 is { $result2.^name }"; # OUTPUT: «Result2 is Any␤» 

A Match will be Nil if it finds nothing; however it assigning Nil to $result2 above will result in its default value, which is Any as shown.

Using a block to interpolate anon state vars

The programmer intended for the code to count the number of times the routine is called, but the counter is not increasing:

sub count-it { say "Count is {$++}" } 
 count-it; 
 count-it; 
 
 # OUTPUT: 
 # Count is 0 
 # Count is 0 

When it comes to state variables, the block in which the vars are declared gets cloned —and vars get initialized anew— whenever that block's block is re-entered. This lets constructs like the one below behave appropriately; the state variable inside the loop gets initialized anew each time the sub is called:

sub count-it { 
     for ^3 { 
         state $count = 0; 
         say "Count is $count"; 
         $count++; 
     } 
 } 
 
 count-it; 
 say "…and again…"; 
 count-it; 
 
 
 # OUTPUT: 
 # Count is 0 
 # Count is 1 
 # Count is 2 
 # …and again… 
 # Count is 0 
 # Count is 1 
 # Count is 2 

The same layout exists in our buggy program. The { } inside a double-quoted string isn't merely an interpolation to execute a piece of code. It's actually its own block, which is just as in the example above gets cloned each time the sub is entered, re-initializing our state variable. To get the right count, we need to get rid of that inner block, using a scalar contextualizer to interpolate our piece of code instead:

sub count-it { say "Count is $($++)" } 
 count-it; 
 count-it; 
 
 # OUTPUT: 
 # Count is 0 
 # Count is 1 

Alternatively, you can also use the concatenation operator instead:

sub count-it { say "Count is " ~ $++ } 

Using set subroutines on Associative when the value is falsy

Using (cont), , , (elem), , or on classes implementing Associative will return False if the value of the key is falsy:

enum Foo «a b»; 
 say Foo.enums ∋ 'a'; 
 
 # OUTPUT: 
 # False 

Instead, use :exists:

enum Foo «a b»; 
 say Foo.enums<a>:exists; 
 
 # OUTPUT: 
 # True 

Blocks

Beware of empty "blocks"

Curly braces are used to declare blocks. However, empty curly braces will declare a hash.

$ = {say 42;} # Block 
 $ = {;}       # Block 
 $ = {…}       # Block 
 $ = { }       # Hash 

You can use the second form if you effectively want to declare an empty block:

my &does-nothing = {;};
say does-nothing(33); # OUTPUT: «Nil␤»

Objects

Assigning to attributes

Newcomers often think that, because attributes with accessors are declared as has $.x, they can assign to $.x inside the class. That's not the case.

For example

class Point { 
     has $.x; 
     has $.y; 
     method double { 
         $.x *= 2;   # WRONG 
         $.y *= 2;   # WRONG 
         self; 
     } 
 } 
 
 say Point.new(x => 1, y => -2).double.x 
 # OUTPUT: «Cannot assign to an immutable value␤» 

the first line inside the method double is marked with # WRONG because $.x, short for $( self.x ), is a call to a read-only accessor.

The syntax has $.x is short for something like has $!x; method x() { $!x }, so the actual attribute is called $!x, and a read-only accessor method is automatically generated.

Thus the correct way to write the method double is

method double { 
     $!x *= 2; 
     $!y *= 2; 
     self; 
 } 

which operates on the attributes directly.

BUILD prevents automatic attribute initialization from constructor arguments

When you define your own BUILD submethod, you must take care of initializing all attributes by yourself. For example

class A { 
     has $.x; 
     has $.y; 
     submethod BUILD { 
         $!y = 18; 
     } 
 } 
 
 say A.new(x => 42).x;       # OUTPUT: «Any␤» 

leaves $!x uninitialized, because the custom BUILD doesn't initialize it.

Note: Consider using TWEAK instead. Rakudo supports TWEAK method since release 2016.11.

One possible remedy is to explicitly initialize the attribute in BUILD:

submethod BUILD(:$x) { 
     $!y = 18; 
     $!x := $x; 
 } 

which can be shortened to:

submethod BUILD(:$!x) { 
     $!y = 18; 
 } 

Whitespace

Whitespace in regexes does not match literally

say 'a b' ~~ /a b/; # OUTPUT: «False␤» 

Whitespace in regexes is, by default, considered an optional filler without semantics, just like in the rest of the Perl 6 language.

Ways to match whitespace:

Ambiguities in parsing

While some languages will let you get away with removing as much whitespace between tokens as possible, Perl 6 is less forgiving. The overarching mantra is we discourage code golf, so don't scrimp on whitespace (the more serious underlying reason behind these restrictions is single-pass parsing and ability to parse Perl 6 programs with virtually no backtracking).

The common areas you should watch out for are:

Block vs. Hash slice ambiguity

# WRONG; trying to hash-slice a Bool: 
 while ($++ > 5){ .say } 
# RIGHT: 
 while ($++ > 5) { .say } 
 
 # EVEN BETTER; Perl 6 does not require parentheses there: 
 while $++ > 5 { .say } 

Reduction vs. Array constructor ambiguity

# WRONG; ambiguity with `[<]` meta op: 
 my @a = [[<foo>],]; 
# RIGHT; reductions cannot have spaces in them, so put one in: 
 my @a = [[ <foo>],]; 
 
 # No ambiguity here, natural spaces between items suffice to resolve it: 
 my @a = [[<foo bar ber>],]; 

Less than vs. Word quoting/Associative indexing

# WRONG; trying to index 3 associatively: 
 say 3<5>4 
# RIGHT; prefer some extra whitespace around infix operators: 
 say 3 < 5 > 4 

Exclusive sequences vs. sequences with Ranges

See the section on operator traps for more information about how the ...^ operator can be mistaken for the ... operator with a ^ operator immediately following it. You must use whitespace correctly to indicate which interpretation will be followed.

Captures

Containers versus values in a capture

Beginners might expect a variable in a Capture to supply its current value when that Capture is later used. For example:

my $a = 2; say join ",", ($a, ++$a);  # OUTPUT: «3,3␤» 

Here the Capture contained the container pointed to by $a and the value of the result of the expression ++$a. Since the Capture must be reified before &say can use it, the ++$a may happen before &say looks inside the container in $a (and before the List is created with the two terms) and so it may already be incremented.

Instead, use an expression that produces a value when you want a value.

my $a = 2; say join ",", (+$a, ++$a); # OUTPUT: «2,3␤» 

Or even simpler

my $a = 2; say  "$a, {++$a}"; # OUTPUT: «2, 3␤» 

The same happens in this case:

my @arr; 
 my ($a, $b) = (1,1); 
 for ^5 { 
     ($a,$b) = ($b, $a+$b); 
     @arr.push: ($a, $b); 
     say @arr 
 }; 

Outputs «[(1 2)]␤[(2 3) (2 3)]␤[(3 5) (3 5) (3 5)]␤.... $a and $b are not reified until say is called, the value that they have in that precise moment is the one printed. To avoid that, decontainerize values or take them out of the variable in some way before using them.

my @arr; 
 my ($a, $b) = (1,1); 
 for ^5 { 
     ($a,$b) = ($b, $a+$b); 
     @arr.push: ($a.item, $b.item); 
     say @arr 
 }; 

With item, the container will be evaluated in item context, its value extracted, and the desired outcome achieved.

Cool tricks

Perl 6 includes a Cool class, which provides some of the DWIM behaviors we got used to by coercing arguments when necessary. However, DWIM is never perfect. Especially with Lists, which are Cool, there are many methods that will not do what you probably think they do, including contains, starts-with or index. Please see some examples in the section below.

Strings are not Lists, so beware indexing

In Perl 6, strings are not lists of characters. One cannot iterate over them or index into them as you can with lists, despite the name of the .index routine.

Lists become strings, so beware .index()ing

List inherits from Cool, which provides access to .index. Because of the way .index coerces a List into a Str, this can sometimes appear to be returning the index of an element in the list, but that is not how the behavior is defined.

my @a = <a b c d>; 
 say @a.index(‘a’);    # 0 
 say @a.index('c');    # 4 -- not 2! 
 say @a.index('b c');  # 2 -- not undefined! 
 say @a.index(<a b>);  # 0 -- not undefined! 

These same caveats apply to .rindex.

Lists become strings, so beware .contains()

Similarly, .contains does not look for elements in the list.

my @menu = <hamburger fries milkshake>; 
 say @menu.contains('hamburger');            # True 
 say @menu.contains('hot dog');              # False 
 say @menu.contains('milk');                 # True! 
 say @menu.contains('er fr');                # True! 
 say @menu.contains(<es mi>);                # True! 

If you actually want to check for the presence of an element, use the (cont) operator for single elements, and the superset and strict superset), _infix_⊃> operators for multiple elements.

my @menu = <hamburger fries milkshake>; 
 say @menu (cont) 'fries';                   # True 
 say @menu (cont) 'milk';                    # False 
 say @menu (>) <hamburger fries>;            # True 
 say @menu (>) <milkshake fries>;            # True (! NB: order doesn't matter) 

If you are doing a lot of element testing, you may be better off using a Set.

Numeric literals are parsed before coercion

Experienced programmers will probably not be surprised by this, but Numeric literals will be parsed into their numeric value before being coerced into a string, which may create nonintuitive results.

say 0xff.contains(55);      # True 
 say 0xff.contains(0xf);     # False 
 say 12_345.contains("23");  # True 
 say 12_345.contains("2_");  # False 

Getting a random item from a List

A common task is to retrieve one or more random elements from a collection, but List.rand isn't the way to do that. Cool provides rand, but that first coerces the List into the number of items in the list, and returns a random real number between 0 and that value. To get random elements, see pick and roll.

my @colors = <red orange yellow green blue indigo violet>; 
 say @colors.rand;       # 2.21921955680514 
 say @colors.pick;       # orange 
 say @colors.roll;       # blue 
 say @colors.pick(2);    # yellow violet  (cannot repeat) 
 say @colors.roll(3);    # red green red  (can repeat) 

Lists numify to their number of elements in numeric context

You want to check whether a number is divisible by any of a set of numbers:

say 42 %% <11 33 88 55 111 20325>; # OUTPUT: «True␤»

What? There's no single number 42 should be divisible by. However, that list has 6 elements, and 42 is divisible by 6. That's why the output is true. In this case, you should turn the List into a Junction:

say 42 %% <11 33 88 55 111 20325>.any; 
 # OUTPUT: «any(False, False, False, False, False, False)␤» 

which will clearly reveal the falsehood of the divisiveness of all the numbers in the list, which will be numified separately.

Arrays

Referencing the last element of an array

In some languages one could reference the last element of an array by asking for the "-1th" element of the array, e.g.:

my @array = qw{victor alice bob charlie eve}; 
 say @array[-1];    # OUTPUT: «eve␤» 

In Perl 6 it is not possible to use negative subscripts, however the same is achieved by actually using a function, namely *-1. Thus, accessing the last element of an array becomes:

my @array = qw{victor alice bob charlie eve}; 
 say @array[*-1];   # OUTPUT: «eve␤» 

Yet another way is to utilize the array's tail method:

my @array = qw{victor alice bob charlie eve}; 
 say @array.tail;      # OUTPUT: «eve␤» 
 say @array.tail(2);   # OUTPUT: «(charlie eve)␤» 

Typed array parameters

Quite often new users will happen to write something like:

sub foo(Array @a) { ... } 

...before they have gotten far enough in the documentation to realize that this is asking for an Array of Arrays. To say that @a should only accept Arrays, use instead:

sub foo(@a where Array) { ... } 

It is also common to expect this to work, when it does not:

sub bar(Int @a) { 42.say }; 
 bar([1, 2, 3]);             # expected Positional[Int] but got Array 

The problem here is that [1, 2, 3] is not an Array[Int], it is a plain old Array that just happens to have Ints in it. To get it to work, the argument must also be an Array[Int].

my Int @b = 1, 2, 3; 
 bar(@b);                    # OUTPUT: «42␤» 
 bar(Array[Int].new(1, 2, 3)); 

This may seem inconvenient, but on the upside it moves the type-check on what is assigned to @b to where the assignment happens, rather than requiring every element to be checked on every call.

Using «» quoting when you don't need it

This trap can be seen in different varieties. Here are some of them:

my $x = ‘hello’; 
 my $y = ‘foo bar’; 
 
 my %h = $x => 42, $y => 99; 
 say %h«$x»;   # ← WRONG; assumption that $x has no whitespace 
 say %h«$y»;   # ← WRONG; splits ‘foo bar’ by whitespace 
 say %h«"$y"»; # ← KINDA OK; it works but there is no good reason to do that 
 say %h{$y};   # ← RIGHT; this is what should be used 
 
 run «touch $x»;        # ← WRONG; assumption that only one file will be created 
 run «touch $y»;        # ← WRONG; will touch file ‘foo’ and ‘bar’ 
 run «touch "$y"»;      # ← WRONG; better, but has a different issue if $y starts with - 
 run «touch -- "$y"»;   # ← KINDA OK; it works but there is no good enough reason to do that 
 run ‘touch’, ‘--’, $y; # ← RIGHT; explicit and *always* correct 
 run <touch -->, $y;    # ← RIGHT; < > are OK, this is short and correct 

Basically, «» quoting is only safe to use if you remember to always quote your variables. The problem is that it inverts the default behavior to unsafe variant, so just by forgetting some quotes you are risking to introduce either a bug or maybe even a security hole. To stay on the safe side, refrain from using «».

Strings

Some problems that might arise when dealing with strings.

Quotes and interpolation

Interpolation in string literals can be too clever for your own good.

# "HTML tags" interpreted as associative indexing: 
 "$foo<html></html>" eq 
 "$foo{'html'}{'/html'}" 
# Parentheses interpreted as call with argument: 
 "$foo(" ~ @args ~ ")" eq 
 "$foo(' ~ @args ~ ')" 

You can avoid those problems using non-interpolating single quotes and switching to more liberal interpolation with \qq[] escape sequence:

my $a = 1; 
 say '\qq[$a]()$b()'; 
 # OUTPUT: «1()$b()␤» 

Another alternative is to use Q:c quoter, and use code blocks {} for all interpolation:

my $a = 1; 
 say Q:c«{$a}()$b()»; 
 # OUTPUT: «1()$b()␤» 

Strings are not iterable

There are methods that Str inherits from Any that work on iterables like lists. Iterators on strings contain one element that is the whole string. To use list-based methods like sort, reverse, you need to convert the string into a list first.

say "cba".sort;              # OUTPUT: «(cba)␤» 
 say "cba".comb.sort.join;    # OUTPUT: «abc␤» 

.chars gets the number of graphemes, not Codepoints

In Perl 6, .chars returns the number of graphemes, or user visible characters. These graphemes could be made up of a letter plus an accent for example. If you need the number of codepoints, you should use .codes. If you need the number of bytes when encoded as UTF8, you should use .encode.bytes to encode the string as UTF8 and then get the number of bytes.

say "\c[LATIN SMALL LETTER J WITH CARON, COMBINING DOT BELOW]"; # OUTPUT: «ǰ̣»
say 'ǰ̣'.codes;        # OUTPUT: «2»
say 'ǰ̣'.chars;        # OUTPUT: «1»
say 'ǰ̣'.encode.bytes; # OUTPUT: «4»

For more information on how strings work in Perl 6, see the Unicode page.

All text is normalized by default

Perl 6 normalizes all text into Unicode NFC form (Normalization Form Canonical). Filenames are the only text not normalized by default. If you are expecting your strings to maintain a byte for byte representation as the original, you need to use UTF8-C8 when reading or writing to any filehandles.

Allomorphs generally follow numeric semantics

Str "0" is True, while Numeric is False. So what's the Bool value of allomorph <0>?

In general, allomorphs follow Numeric semantics, so the ones that numerically evaluate to zero are False:

say so   <0>; # OUTPUT: «False␤»
say so <0e0>; # OUTPUT: «False␤»
say so <0.0>; # OUTPUT: «False␤»

To force comparison being done for the Stringy part of the allomorph, use prefix ~ operator or the Str method to coerce the allomorph to Str, or use the chars routine to test whether the allomorph has any length:

say so      ~<0>;     # OUTPUT: «True␤»
say so       <0>.Str; # OUTPUT: «True␤»
say so chars <0>;     # OUTPUT: «True␤»

Case-insensitive comparison of strings

In order to do case-insensitive comparison, you can use .fc (fold-case). The problem is that people tend to use .lc or .uc, and it does seem to work within the ASCII range, but fails on other characters. This is not just a Perl 6 trap, the same applies to other languages.

say ‘groß’.lc eq ‘GROSS’.lc; # ← WRONG; False 
 say ‘groß’.uc eq ‘GROSS’.uc; # ← WRONG; True, but that's just luck 
 say ‘groß’.fc eq ‘GROSS’.fc; # ← RIGHT; True 

If you are working with regexes, then there is no need to use .fc and you can use :i (:ignorecase) adverb instead.

Pairs

Constants on the left-hand side of pair notation

Consider this code:

enum Animals <Dog Cat>; 
 my %h := :{ Dog => 42 }; 
 say %h{Dog}; # OUTPUT: «(Any)␤» 

The :{ … } syntax is used to create object hashes. The intentions of someone who wrote that code were to create a hash with Enum objects as keys (and say %h{Dog} attempts to get a value using the Enum object to perform the lookup). However, that's not how pair notation works.

For example, in Dog => 42 the key will be a Str. That is, it doesn't matter if there is a constant, or an enumeration with the same name. The pair notation will always use the left-hand side as a string literal, as long as it looks like an identifier.

To avoid this, use (Dog) => 42 or ::Dog => 42.

Scalar values within Pair

When dealing with Scalar values, the Pair holds the container to the value. This means that it is possible to reflect changes to the Scalar value from outside the Pair:

my $v = 'value A'; 
 my $pair = Pair.new( 'a', $v ); 
 $pair.say;  # OUTPUT: a => value A 
 
 $v = 'value B'; 
 $pair.say; # OUTPUT: a => value B 

Use the method freeze to force the removal of the Scalar container from the Pair. For more details see the documentation about Pair.

Sets, bags and mixes

Sets, bags and mixes do not have a fixed order

When iterating over this kind of objects, an order is not defined.

my $set = <a b c>.Set; 
 .say for $set.list; # OUTPUT: «a => True␤c => True␤b => True␤» 
 # OUTPUT: «a => True␤c => True␤b => True␤» 
 # OUTPUT: «c => True␤b => True␤a => True␤» 

Every iteration might (and will) yield a different order, so you cannot trust a particular sequence of the elements of a set. If order does not matter, just use them that way. If it does, use sort

my $set = <a b c>.Set;
.say for $set.list.sort;  # OUTPUT: «a => True␤b => True␤c => True␤»

In general, sets, bags and mixes are unordered, so you should not depend on them having a particular order.

Operators

Some operators commonly shared among other languages were repurposed in Perl 6 for other, more common, things:

Junctions

The ^, |, and & are not bitwise operators, they create Junctions. The corresponding bitwise operators in Perl 6 are: +^, +|, +& for integers and ?^, ?|, ?& for booleans.

Exclusive sequence operator

Lavish use of whitespace helps readability, but keep in mind infix operators cannot have any whitespace in them. One such operator is the sequence operator that excludes right point: ...^ (or its Unicode equivalent …^).

say 1... ^5; # OUTPUT: «(1 0 1 2 3 4)␤»
say 1...^5;  # OUTPUT: «(1 2 3 4)␤»

If you place whitespace between the ellipsis () and the caret (^), it's no longer a single infix operator, but an infix inclusive sequence operator () and a prefix Range operator (^). Iterables are valid endpoints for the sequence operator, so the result you'll get might not be what you expected.

String ranges/Sequences

In some languages, using strings as range end points, considers the entire string when figuring out what the next string should be; loosely treating the strings as numbers in a large base. Here's Perl 5 version:

say join ", ", "az".."bc"; 
 # OUTPUT: «az, ba, bb, bc␤» 

Such a range in Perl 6 will produce a different result, where each letter will be ranged to a corresponding letter in the end point, producing more complex sequences:

say join ", ", "az".."bc"; 
 #`{ OUTPUT: « 
     az, ay, ax, aw, av, au, at, as, ar, aq, ap, ao, an, am, al, ak, aj, ai, ah, 
     ag, af, ae, ad, ac, bz, by, bx, bw, bv, bu, bt, bs, br, bq, bp, bo, bn, bm, 
     bl, bk, bj, bi, bh, bg, bf, be, bd, bc 
 ␤»} 
say join ", ", "r2".."t3"; 
 # OUTPUT: «r2, r3, s2, s3, t2, t3␤» 

To achieve simpler behavior, similar to the Perl 5 example above, use a sequence operator that calls .succ method on the starting string:

say join ", ", ("az", *.succ ... "bc"); 
 # OUTPUT: «az, ba, bb, bc␤» 

Topicalizing operators

The smartmatch operator ~~ and andthen set the topic $_ to their left-hand-side. In conjunction with implicit method calls on the topic this can lead to surprising results.

my &method = { note $_; $_ }; 
 $_ = 'object'; 
 say .&method; 
 # OUTPUT: «object␤object␤» 
 say 'topic' ~~ .&method; 
 # OUTPUT: «topic␤True␤» 

In many cases flipping the method call to the LHS will work.

my &method = { note $_; $_ }; 
 $_ = 'object'; 
 say .&method; 
 # OUTPUT: «object␤object␤» 
 say .&method ~~ 'topic'; 
 # OUTPUT: «object␤False␤» 

Fat arrow and constants

The fat arrow operator => will turn words on its left-hand side to Str without checking the scope for constants or \-sigiled variables. Use explicit scoping to get what you mean.

constant V = 'x'; 
 my %h = V => 'oi‽', ::V => 42; 
 say %h.perl 
 # OUTPUT: «{:V("oi‽"), :x(42)}␤» 

Infix operator assignment

Infix operators, both built in and user defined, can be combined with the assignment operator as this addition example demonstrates:

my $x = 10;
$x += 20;
say $x;     # OUTPUT: «30␤»

For any given infix operator op, L op= R is equivalent to L = L op R (where L and R are the left and right arguments, respectively). This means that the following code may not behave as expected:

my @a = 1, 2, 3;
@a += 10;
say @a;  # OUTPUT: «[13]␤»

Coming from a language like C++, this might seem odd. It is important to bear in mind that += isn't defined as method on the left hand argument (here the @a array) but is simply shorthand for:

my @a = 1, 2, 3;
@a = @a + 10;
say @a;  # OUTPUT: «[13]␤»

Here @a is assigned the result of adding @a (which has three elements) and 10; 13 is therefore placed in @a.

Use the hyper form of the assignment operators instead:

my @a = 1, 2, 3;
@a »+=» 10;
say @a;  # OUTPUT: «[11 12 13]␤»

Regexes

$x vs <$x>, and $(code) vs <{code}>

Perl 6 offers several constructs to generate regexes at runtime through interpolation (see their detailed description here). When a regex generated this way contains only literals, the above constructs behave (pairwise) identically, as if they are equivalent alternatives. As soon as the generated regex contains metacharacters, however, they behave differently, which may come as a confusing surprise.

The first two constructs that may easily be confused with each other are $variable and <$variable>:

my $variable = 'camelia';
say ‘I ♥ camelia’ ~~ /  $variable  /;   # OUTPUT: 「camelia」
say ‘I ♥ camelia’ ~~ / <$variable> /;   # OUTPUT: 「camelia」

Here they act the same because the value of $variable consists of literals. But when the variable is changed to comprise regex metacharacters the outputs become different:

my $variable = '#camelia';
say ‘I ♥ #camelia’ ~~ /  $variable  /;   # OUTPUT: 「#camelia」
say ‘I ♥ #camelia’ ~~ / <$variable> /;   # !! Error: malformed regex

What happens here is that the string #camelia contains the metacharacter #. In the context of a regex, this character should be quoted to match literally; without quoting, the # is parsed as the start of a comment that runs until the end of the line, which in turn causes the regex not to be terminated, and thus to be malformed.

Two other constructs that must similarly be distinguished from one another are $(code) and <{code}>. Like before, as long as the (stringified) return value of code comprises only literals, there is no distinction between the two:

my $variable = 'ailemac';
say ‘I ♥ camelia’ ~~ / $($variable.flip)   /;   # OUTPUT: 「camelia」
say ‘I ♥ camelia’ ~~ / <{$variable.flip}>  /;   # OUTPUT: 「camelia」

But when the return value is changed to comprise regex metacharacters, the outputs diverge:

my $variable = 'ailema.';
say ‘I ♥ camelia’ ~~ / $($variable.flip)   /;   # OUTPUT: Nil
say ‘I ♥ camelia’ ~~ / <{$variable.flip}>  /;   # OUTPUT: 「camelia」

In this case the return value of the code is the string .amelia, which contains the metacharacter .. The above attempt by $(code) to match the dot literally fails; the attempt by <{code}> to match the dot as a regex wildcard succeeds. Hence the different outputs.

| vs ||: which branch will win

To match one of several possible alternatives, || or | will be used. But they are so different.

When there are multiple matching alternations, for those separated by ||, the first matching alternation wins; for those separated by |, which to win is decided by LTM strategy. See also: documentation on || and documentation on |.

For simple regexes just using || instead of | will get you familiar semantics, but if writing grammars then it's useful to learn about LTM and declarative prefixes and prefer |. And keep yourself away from using them in one regex. When you have to do that, add parentheses and ensure that you know how LTM strategy works to make the code do what you want.

The trap typically arises when you try to mix both | and || in the same regex:

say 42 ~~ / [  0 || 42 ] | 4/; # OUTPUT: «「4」␤» 
 say 42 ~~ / [ 42 ||  0 ] | 4/; # OUTPUT: «「42」␤» 

The code above may seem like it is producing a wrong result, but the implementation is actually right.

$/ changes each time a regular expression is matched

Each time a regular expression is matched against something, the special variable $/ holding the result Match object is changed accordingly to the result of the match (that could also be Nil).

The $/ is changed without any regard to the scope the regular expression is matched within.

For further information and examples please see the related section in the Regular Expressions documentation.

<foo> vs. < foo>: named rules vs. quoted lists

Regexes can contain quoted lists; longest token matching is performed on the list's elements as if a | alternation had been specified (see here for further information).

Within a regex, the following are lists with a single item, 'foo':

say 'foo' ~~ /< foo >/;  # OUTPUT: «「foo」␤»
say 'foo' ~~ /< foo>/;   # OUTPUT: «「foo」␤»

but this is a call to the named rule foo:

say 'foo' ~~ /<foo>/; 
 # OUTPUT: «No such method 'foo' for invocant of type 'Match'␤ in block <unit> at <unknown file> line 1␤» 

Be wary of the difference; if you intend to use a quoted list, ensure that whitespace follows the initial <.

Non-capturing, non-global matching in list context

Unlike Perl 5, non-capturing and non-global matching in list context doesn't produce any values:

if  'x' ~~ /./ { say 'yes' }  # OUTPUT: «yes␤»
for 'x' ~~ /./ { say 'yes' }  # NO OUTPUT

This is because its 'list' slot (inherited from Capture class) doesn't get populated with the original Match object:

say ('x' ~~ /./).list  # OUTPUT: «()␤»

To achieve the desired result, use global matching, capturing parentheses or a list with a trailing comma:

for 'x' ~~ m:g/./ { say 'yes' }  # OUTPUT: «yes␤»
for 'x' ~~ /(.)/  { say 'yes' }  # OUTPUT: «yes␤»
for ('x' ~~ /./,) { say 'yes' }  # OUTPUT: «yes␤»

Common precedence mistakes

Adverbs and precedence

Adverbs do have a precedence that may not follow the order of operators that is displayed on your screen. If two operators of equal precedence are followed by an adverb it will pick the first operator it finds in the abstract syntax tree. Use parentheses to help Perl 6 understand what you mean or use operators with looser precedence.

my %x = a => 42; 
 say !%x<b>:exists;            # dies with X::AdHoc 
 say %x<b>:!exists;            # this works 
 say !(%x<b>:exists);          # works too 
 say not %x<b>:exists;         # works as well 
 say True unless %x<b>:exists; # avoid negation altogether 

Ranges and precedence

The loose precedence of .. can lead to some errors. It is usually best to parenthesize ranges when you want to operate on the entire range.

1..3.say;    # says "3" (and warns about useless "..") 
 (1..3).say;  # says "1..3" 

Loose boolean operators

The precedence of and, or, etc. is looser than routine calls. This can have surprising results for calls to routines that would be operators or statements in other languages like return, last and many others.

sub f { 
     return True and False; 
     # this is actually 
     # (return True) and False; 
 } 
 say f; # OUTPUT: «True␤» 

Exponentiation operator and prefix minus

say -1²;   # OUTPUT: «-1␤» 
 say -1**2; # OUTPUT: «-1␤» 

When performing a regular mathematical calculation, the power takes precedence over the minus; so -1² can be written as -(1²). Perl 6 matches these rules of mathematics and the precedence of ** operator is tighter than that of the prefix -. If you wish to raise a negative number to a power, use parentheses:

say (-1)²;   # OUTPUT: «1␤» 
 say (-1)**2; # OUTPUT: «1␤» 

Method operator calls and prefix minus

Prefix minus binds looser than dotty method op calls. The prefix minus will be applied to the return value from the method. To ensure the minus gets passed as part of the argument, enclose in parenthesis.

say  -1.abs;  # OUTPUT: «-1␤» 
 say (-1).abs; # OUTPUT: «1␤» 

Subroutine and method calls

Subroutine and method calls can be made using one of two forms:

foo(...); # function call form, where ... represent the required arguments 
 foo ...;  # list op form, where ... represent the required arguments 

The function call form can cause problems for the unwary when whitespace is added after the function or method name and before the opening parenthesis.

First we consider functions with zero or one parameter:

sub foo() { say 'no arg' } 
 sub bar($a) { say "one arg: $a" } 

Then execute each with and without a space after the name:

foo();    # okay: no arg 
 foo ();   # FAIL: Too many positionals passed; expected 0 arguments but got 1 
 bar($a);  # okay: one arg: 1 
 bar ($a); # okay: one arg: 1 

Now declare a function of two parameters:

sub foo($a, $b) { say "two args: $a, $b" } 

Execute it with and without the space after the name:

foo($a, $b);  # okay: two args: 1, 2 
 foo ($a, $b); # FAIL: Too few positionals passed; expected 2 arguments but got 1 

The lesson is: "be careful with spaces following sub and method names when using the function call format." As a general rule, good practice might be to avoid the space after a function name when using the function call format.

Note that there are clever ways to eliminate the error with the function call format and the space, but that is bordering on hackery and will not be mentioned here. For more information, consult Functions.

Finally, note that, currently, when declaring the functions whitespace may be used between a function or method name and the parentheses surrounding the parameter list without problems.

Named parameters

Many built-in subroutines and method calls accept named parameters and your own code may accept them as well, but be sure the arguments you pass when calling your routines are actually named parameters:

sub foo($a, :$b) { ... } 
 foo(1, 'b' => 2); # FAIL: Too many positionals passed; expected 1 argument but got 2 

What happened? That second argument is not a named parameter argument, but a Pair passed as a positional argument. If you want a named parameter it has to look like a name to Perl:

foo(1, b => 2); # okay 
 foo(1, :b(2));  # okay 
 foo(1, :b<it>); # okay 
 
 my $b = 2; 
 foo(1, :b($b)); # okay, but redundant 
 foo(1, :$b);    # okay 
 
 # Or even... 
 my %arg = 'b' => 2; 
 foo(1, |%arg);  # okay too 

That last one may be confusing, but since it uses the | prefix on a Hash, which is a special compiler construct indicating you want to use the contents of the variable as arguments, which for hashes means to treat them as named arguments.

If you really do want to pass them as pairs you should use a List or Capture instead:

my $list = ('b' => 2),; # this is a List containing a single Pair 
 foo(|$list, :$b);       # okay: we passed the pair 'b' => 2 to the first argument 
 foo(1, |$list);         # FAIL: Too many positionals passed; expected 1 argument but got 2 
 foo(1, |$list.Capture); # OK: .Capture call converts all Pair objects to named args in a Capture 
my $cap = \('b' => 2); # a Capture with a single positional value 
 foo(|$cap, :$b); # okay: we passed the pair 'b' => 2 to the first argument 
 foo(1, |$cap);   # FAIL: Too many positionals passed; expected 1 argument but got 2 

A Capture is usually the best option for this as it works exactly like the usual capturing of routine arguments during a regular call.

The nice thing about the distinction here is that it gives the developer the option of passing pairs as either named or positional arguments, which can be handy in various instances.

Argument count limit

While it is typically unnoticeable, there is a backend-dependent argument count limit. Any code that does flattening of arbitrarily sized arrays into arguments won't work if there are too many elements.

my @a = 1 xx 9999; 
 my @b; 
 @b.push: |@a; 
 say @b.elems # OUTPUT: «9999␤» 
my @a = 1 xx 999999; 
 my @b; 
 @b.push: |@a; # OUTPUT: «Too many arguments in flattening array.␤  in block <unit> at <tmp> line 1␤␤» 

Avoid this trap by rewriting the code so that there is no flattening. In the example above, you can replace push with append. This way, no flattening is required because the array can be passed as is.

my @a = 1 xx 999999; 
 my @b; 
 @b.append: @a; 
 say @b.elems # OUTPUT: «999999␤» 

Phasers and implicit return

sub returns-ret () { 
     CATCH { 
         default {} 
     } 
     "ret"; 
 } 
 
 sub doesn't-return-ret () { 
     "ret"; 
     CATCH { 
         default {} 
     } 
 } 
 
 say returns-ret;        # OUTPUT: «ret» 
 say doesn't-return-ret; 
 # BAD: outputs «Nil» and a warning «Useless use of constant string "ret" in sink context (line 13)» 

Code for returns-ret and doesn't-return-ret might look exactly the same, since in principle it does not matter where the CATCH block goes. However, a block is an object and the last object in a sub will be returned, so the doesn't-return-ret will return Nil, and, besides, since "ret" will be now in sink context, it will issue a warning. In case you want to place phasers last for conventional reasons, use the explicit form of return.

sub explicitly-return-ret () { 
     return "ret"; 
     CATCH { 
         default {} 
     } 
 } 

Input and output

Closing open filehandles and pipes

Unlike some other languages, Perl 6 does not use reference counting, and so the filehandles are NOT closed when they go out of scope. You have to explicitly close them either by using close routine or using the :close argument several of IO::Handle's methods accept. See IO::Handle.close for details.

The same rules apply to IO::Handle's subclass IO::Pipe, which is what you operate on when reading from a Proc you get with routines run and shell.

The caveat applies to IO::CatHandle type as well, though not as severely. See IO::CatHandle.close for details.

IO::Path stringification

Partly for historical reasons and partly by design, an IO::Path object stringifies without considering its CWD attribute, which means if you chdir and then stringify an IO::Path, or stringify an IO::Path with custom $!CWD attribute, the resultant string won't reference the original filesystem object:

with 'foo'.IO { 
     .Str.say;       # OUTPUT: «foo␤» 
     .relative.say;  # OUTPUT: «foo␤» 
 
     chdir "/tmp"; 
     .Str.say;       # OUTPUT: «foo␤» 
     .relative.say   # OUTPUT: «../home/camelia/foo␤» 
 } 
 
 # Deletes ./foo, not /bar/foo 
 unlink IO::Path.new("foo", :CWD</bar>).Str 

The easy way to avoid this issue is to not stringify an IO::Path object at all. Core routines that work with paths can take an IO::Path object, so you don't need to stringify the paths.

If you do have a case where you need a stringified version of an IO::Path, use absolute or relative methods to stringify it into an absolute or relative path, respectively.

If you are facing this issue because you use chdir in your code, consider rewriting it in a way that does not involve changing the current directory. For example, you can pass cwd named argument to run without having to use chdir around it.

Splitting the input data into lines

There is a difference between using .lines on IO::Handle and on a Str. The trap arises if you start assuming that both split data the same way.

say $_.perl for $*IN.lines # .lines called on IO::Handle 
 # OUTPUT: 
 # "foox" 
 # "fooy\rbar" 
 # "fooz" 

As you can see in the example above, there was a line which contained \r (“carriage return” control character). However, the input is split strictly by \n, so \r was kept as part of the string.

On the other hand, Str.lines attempts to be “smart” about processing data from different operating systems. Therefore, it will split by all possible variations of a newline.

say $_.perl for $*IN.slurp(:bin).decode.lines # .lines called on a Str 
 # OUTPUT: 
 # "foox" 
 # "fooy" 
 # "bar" 
 # "fooz" 

The rule is quite simple: use IO::Handle.lines when working with programmatically generated output, and Str.lines when working with user-written texts.

Use $data.split(“\n”) in cases where you need the behavior of IO::Handle.lines but the original IO::Handle is not available.

RT#132154

Note that if you really want to slurp the data first, then you will have to use .IO.slurp(:bin).decode.split(“\n”). Notice how we use :bin to prevent it from doing the decoding, only to call .decode later anyway. All that is needed because .slurp is assuming that you are working with text and therefore it attempts to be smart about newlines.

RT#131923

If you are using Proc::Async, then there is currently no easy way to make it split data the right way. You can try reading the whole output and then using Str.split (not viable if you are dealing with large data) or writing your own logic to split the incoming data the way you need. Same applies if your data is null-separated.

Proc::Async and print

When using Proc::Async you should not assume that .print (or any other similar method) is synchronous. The biggest issue of this trap is that you will likely not notice the problem by running the code once, so it may cause a hard-to-detect intermittent fail.

Here is an example that demonstrates the issue:

loop { 
     my $proc = Proc::Async.new: :w, ‘head’, ‘-n’, ‘1’; 
     my $got-something; 
     react { 
         whenever $proc.stdout.lines { $got-something = True } 
         whenever $proc.start        { die ‘FAIL!’ unless $got-something } 
 
         $proc.print: “one\ntwo\nthree\nfour”; 
         $proc.close-stdin; 
     } 
     say $++; 
 } 

And the output it may produce:

0 
 1 
 2 
 3 
 An operation first awaited: 
   in block <unit> at print.p6 line 4 
 
 Died with the exception: 
     FAIL! 
       in block  at print.p6 line 6 

Resolving this is easy because .print returns a promise that you can await on. The solution is even more beautiful if you are working in a react block:

whenever $proc.print: “one\ntwo\nthree\nfour” { 
     $proc.close-stdin; 
 } 

Using .stdout without .lines

Method .stdout of Proc::Async returns a supply that emits chunks of data, not lines. The trap is that sometimes people assume it to give lines right away.

my $proc = Proc::Async.new(‘cat’, ‘/usr/share/dict/words’); 
 react { 
     whenever $proc.stdout.head(1) { .say } # ← WRONG (most likely) 
     whenever $proc.start { } 
 } 

The output is clearly not just 1 line:

A 
 A's 
 AMD 
 AMD's 
 AOL 
 AOL's 
 Aachen 
 Aachen's 
 Aaliyah 
 Aaliyah's 
 Aaron 
 Aaron's 
 Abbas 
 Abbas's 
 Abbasid 
 Abbasid's 
 Abbott 
 Abbott's 
 Abby 

If you want to work with lines, then use $proc.stdout.lines. If you're after the whole output, then something like this should do the trick: whenever $proc.stdout { $out ~= $_ }.

Exception handling

Sunk Proc

Some methods return a Proc object. If it represents a failed process, Proc itself won't be exception-like, but sinking it will cause an X::Proc::Unsuccessful exception to be thrown. That means this construct will throw, despite the try in place:

try run("perl6", "-e", "exit 42"); 
 say "still alive"; 
 # OUTPUT: «The spawned process exited unsuccessfully (exit code: 42)␤» 

This is because try receives a Proc and returns it, at which point it sinks and throws. Explicitly sinking it inside the try avoids the issue and ensures the exception is thrown inside the try:

try sink run("perl6", "-e", "exit 42"); 
 say "still alive"; 
 # OUTPUT: «still alive␤» 

If you're not interested in catching any exceptions, then use an anonymous variable to keep the returned Proc in; this way it'll never sink:

$ = run("perl6", "-e", "exit 42"); 
 say "still alive"; 
 # OUTPUT: «still alive␤» 

Using shortcuts

The ^ twigil

Using the ^ twigil can save a fair amount of time and space when writing out small blocks of code. As an example:

for 1..8 -> $a, $b { say $a + $b; } 

can be shortened to just

for 1..8 { say $^a + $^b; } 

The trouble arises when a person wants to use more complex names for the variables, instead of just one letter. The ^ twigil is able to have the positional variables be out of order and named whatever you want, but assigns values based on the variable's Unicode ordering. In the above example, we can have $^a and $^b switch places, and those variables will keep their positional values. This is because the Unicode character 'a' comes before the character 'b'. For example:

# In order 
 sub f1 { say "$^first $^second"; } 
 f1 "Hello", "there";    # OUTPUT: «Hello there␤» 
# Out of order 
 sub f2 { say "$^second $^first"; } 
 f2 "Hello", "there";    # OUTPUT: «there Hello␤» 

Due to the variables allowed to be called anything, this can cause some problems if you are not accustomed to how Perl 6 handles these variables.

# BAD NAMING: alphabetically `four` comes first and gets value `1` in it: 
 for 1..4 { say "$^one $^two $^three $^four"; }    # OUTPUT: «2 4 3 1␤» 
 
 # GOOD NAMING: variables' naming makes it clear how they sort alphabetically: 
 for 1..4 { say "$^a $^b $^c $^d"; }               # OUTPUT: «1 2 3 4␤» 

Using » and map interchangeably

While » may look like a shorter way to write map, they differ in some key aspects.

First, the » includes a hint to the compiler that it may autothread the execution, thus if you're using it to call a routine that produces side effects, those side effects may be produced out of order (the result of the operator is kept in order, however). Also if the routine being invoked accesses a resource, there's the possibility of a race condition, as multiple invocations may happen simultaneously, from different threads.

This is an actual output from Rakudo 2015.09
<a b c d>».say # OUTPUT: «d␤b␤c␤a␤» 

Second, » checks the nodality of the routine being invoked and based on that will use either deepmap or nodemap to map over the list, which can be different from how a map call would map over it:

say ((1, 2, 3), [^4], '5')».Numeric;       # OUTPUT: «((1 2 3) [0 1 2 3] 5)␤» 
 say ((1, 2, 3), [^4], '5').map: *.Numeric; # OUTPUT: «(3 4 5)␤» 

The bottom line is that map and » are not interchangeable, but using one instead of the other is OK as long as you understand the differences.

Word splitting in « »

Keep in mind that « » performs word splitting similarly to how shells do it, so many shell pitfalls apply here as well (especially when using in combination with run):

my $file = ‘--my arbitrary filename’;
run ‘touch’, ‘--’, $file;  # RIGHT
run <touch -->, $file;     # RIGHT

run «touch -- "$file"»;    # RIGHT but WRONG if you forget quotes
run «touch -- $file»;      # WRONG; touches ‘--my’, ‘arbitrary’ and ‘filename’
run ‘touch’, $file;        # WRONG; error from `touch`
run «touch "$file"»;       # WRONG; error from `touch`

Note that -- is required for many programs to disambiguate between command-line arguments and filenames that begin with hyphens.

Scope

Using a once block

The once block is a block of code that will only run once when its parent block is run. As an example:

my $var = 0; 
 for 1..10 { 
     once { $var++; } 
 } 
 say "Variable = $var";    # OUTPUT: «Variable = 1␤» 

This functionality also applies to other code blocks like sub and while, not just for loops. Problems arise though, when trying to nest once blocks inside of other code blocks:

my $var = 0; 
 for 1..10 { 
     do { once { $var++; } } 
 } 
 say "Variable = $var";    # OUTPUT: «Variable = 10␤» 

In the above example, the once block was nested inside of a code block which was inside of a for loop code block. This causes the once block to run multiple times, because the once block uses state variables to determine whether it has run previously. This means that if the parent code block goes out of scope, then the state variable the once block uses to keep track of if it has run previously, goes out of scope as well. This is why once blocks and state variables can cause some unwanted behavior when buried within more than one code block.

If you want to have something that will emulate the functionality of a once block, but still work when buried a few code blocks deep, we can manually build the functionality of a once block. Using the above example, we can change it so that it will only run once, even when inside the do block by changing the scope of the state variable.

my $var = 0; 
 for 1..10 { 
     state $run-code = True; 
     do { if ($run-code) { $run-code = False; $var++; } } 
 } 
 say "Variable = $var";    # OUTPUT: «Variable = 1␤» 

In this example, we essentially manually build a once block by making a state variable called $run-code at the highest level that will be run more than once, then checking to see if $run-code is True using a regular if. If the variable $run-code is True, then make the variable False and continue with the code that should only be completed once.

The main difference between using a state variable like the above example and using a regular once block is what scope the state variable is in. The scope for the state variable created by the once block, is the same as where you put the block (imagine that the word 'once' is replaced with a state variable and an if to look at the variable). The example above using state variables works because the variable is at the highest scope that will be repeated; whereas the example that has a once block inside of a do, made the variable within the do block which is not the highest scope that is repeated.

Using a once block inside a class method will cause the once state to carry across all instances of that class. For example:

class A { 
     method sayit() { once say 'hi' } 
 } 
 my $a = A.new; 
 $a.sayit;      # OUTPUT: «hi␤» 
 my $b = A.new; 
 $b.sayit;      # nothing 

LEAVE phaser and exit

Using LEAVE phaser to perform graceful resource termination is a common pattern, but it does not cover the case when the program is stopped with exit.

The following nondeterministic example should demonstrate the complications of this trap:

my $x = say ‘Opened some resource’; 
 LEAVE say ‘Closing the resource gracefully’ with $x; 
 
 exit 42 if rand < ⅓; # ① 「exit」 is bad 
 die ‘Dying because of unhandled exception’ if rand < ½; # ② 「die」 is ok 
 # fallthru ③ 

There are three possible results:

① 
 Opened some resource 
 
 ② 
 Opened some resource 
 Closing the resource gracefully 
 Dying because of unhandled exception 
   in block <unit> at print.p6 line 5 
 
 ③ 
 Opened some resource 
 Closing the resource gracefully 

A call to exit is part of normal operation for many programs, so beware unintentional combination of LEAVE phasers and exit calls.

LEAVE phaser may run sooner than you think

Parameter binding is executed when we're "inside" the routine's block, which means LEAVE phaser would run when we leave that block if parameter binding fails when wrong arguments are given:

sub foo(Int) { 
     my $x = 42; 
     LEAVE say $x.Int; # ← WRONG; assumes that $x is set 
 } 
 say foo rand; # OUTPUT: «No such method 'Int' for invocant of type 'Any'␤» 

A simple way to avoid this issue is to declare your sub or method a multi, so the candidate is eliminated during dispatch and the code never gets to binding anything inside the sub, thus never entering the routine's body:

multi foo(Int) { 
     my $x = 42; 
     LEAVE say $x.Int; 
 } 
 say foo rand; # OUTPUT: «Cannot resolve caller foo(Num); none of these signatures match: (Int)␤» 

Another alternative is placing the LEAVE into another block (assuming it's appropriate for it to be executed when that block is left, not the routine's body:

sub foo(Int) { 
     my $x = 42; 
     { LEAVE say $x.Int; } 
 } 
 say foo rand; # OUTPUT: «Type check failed in binding to parameter '<anon>'; expected Int but got Num (0.7289418947969465e0)␤» 

You can also ensure LEAVE can be executed even if the routine is left due to failed argument binding. In our example, we check $x is defined before doing anything with it.

sub foo(Int) { 
     my $x = 42; 
     LEAVE $x andthen .Int.say; 
 } 
 say foo rand; # OUTPUT: «Type check failed in binding to parameter '<anon>'; expected Int but got Num (0.8517160389079508e0)␤» 

Grammars

Using regexes within grammar's actions

grammar will-fail { 
     token TOP {^ <word> $} 
     token word { \w+ } 
 } 
 
 class will-fail-actions { 
     method TOP ($/) { my $foo = ~$/; say $foo ~~ /foo/;  } 
 } 

Will fail with Cannot assign to a readonly variable ($/) or a value on method TOP. The problem here is that regular expressions also affect $/. Since it is in TOP's signature, it is a read-only variable, which is what produces the error. You can safely either use another variable in the signature or add is copy, this way:

method TOP ($/ is copy) { my $foo = ~$/; my $v = $foo ~~ /foo/;  } 

Using certain names for rules/token/regexes

Grammars are actually a type of classes.

grammar G {};
say G.^mro; # OUTPUT: «((G) (Grammar) (Match) (Capture) (Cool) (Any) (Mu))␤»

^mro prints the class hierarchy of this empty grammar, showing all the superclasses. And these superclasses have their very own methods. Defining a method in that grammar might clash with the ones inhabiting the class hierarchy:

grammar g { 
     token TOP { <item> }; 
     token item { 'defined' } 
 }; 
 say g.parse('defined'); 
 # OUTPUT: «Too many positionals passed; expected 1 argument but got 2␤  in regex item at /tmp/grammar-clash.p6 line 3␤  in regex TOP at /tmp/grammar-clash.p6 line 2␤  in block <unit> at /tmp/grammar-clash.p6 line 5» 

item seems innocuous enough, but it is a sub defined in class Mu. The message is a bit cryptic and totally unrelated to that fact, but that is why this is listed as a trap. In general, all subs defined in any part of the hierarchy are going to cause problems; some methods will too. For instance, CREATE, take and defined (which are defined in Mu). In general, multi methods and simple methods will not have any problem, but it might not be a good practice to use them as rule names.

Also avoid phasers for rule/token/regex names: TWEAK, BUILD, BUILD-ALL will throw another kind of exception if you do that: Cannot find method 'match': no method cache and no .^find_method, once again only slightly related to what is actually going on.

Unfortunate generalization

:exists with more than one key

Let's say you have a hash and you want to use :exists on more than one element:

my %h = a => 1, b => 2; 
 say ‘a exists’ if %h<a>:exists;   # ← OK; True 
 say ‘y exists’ if %h<y>:exists;   # ← OK; False 
 say ‘Huh‽’     if %h<x y>:exists; # ← WRONG; returns a 2-item list 

Did you mean “if any of them exists”, or did you mean that all of them should exist? Use any or all Junction to clarify:

my %h = a => 1, b => 2; 
 say ‘x or y’     if any %h<x y>:exists;   # ← RIGHT (any); False 
 say ‘a, x or y’  if any %h<a x y>:exists; # ← RIGHT (any); True 
 say ‘a, x and y’ if all %h<a x y>:exists; # ← RIGHT (all); False 
 say ‘a and b’    if all %h<a b>:exists;   # ← RIGHT (all); True 

The reason why it is always True (without using a junction) is that it returns a list with Bool values for each requested lookup. Non-empty lists always give True when you Boolify them, so the check always succeeds no matter what keys you give it.

Using […] metaoperator with a list of lists

Every now and then, someone gets the idea that they can use [Z] to create the transpose of a list-of-lists:

my @matrix = <X Y>, <a b>, <1 2>; 
 my @transpose = [Z] @matrix; # ← WRONG; but so far so good ↙ 
 say @transpose;              # [(X a 1) (Y b 2)] 

And everything works fine, until you get an input @matrix with exactly one row (child list):

my @matrix = <X Y>,; 
 my @transpose = [Z] @matrix; # ← WRONG; ↙ 
 say @transpose;              # [(X Y)] – not the expected transpose [(X) (Y)] 

This happens partly because of the single argument rule, and there are other cases when this kind of a generalization may not work.

Using [~] for concatenating a list of blobs

The ~ infix operator can be used to concatenate Strs or Blobs. However, an empty list will always be reduced to an empty Str. This is due to the fact that, in the presence of a list with no elements, the reduction metaoperator returns the identity element for the given operator. Identity element for ~ is an empty string, regardless of the kind of elements the list could be populated with.

my Blob @chunks; 
 say ([~] @chunks).perl; # OUTPUT: «""␤» 

This might cause a problem if you attempt to use the result while assuming that it is a Blob:

my Blob @chunks; 
 say ([~] @chunks).decode; 
 # OUTPUT: «No such method 'decode' for invocant of type 'Str'. Did you mean 'encode'?␤…» 

There are many ways to cover that case. You can avoid [ ] metaoperator altogether:

my @chunks; 
 # … 
 say Blob.new: |«@chunks; # OUTPUT: «Blob:0x<>␤» 

Alternatively, you can initialize the array with an empty Blob:

my @chunks = Blob.new; 
 # … 
 say [~] @chunks; # OUTPUT: «Blob:0x<>␤» 

Or you can utilize || operator to make it use an empty Blob in case the list is empty:

my @chunks; 
 # … 
 say [~] @chunks || Blob.new; # OUTPUT: «Blob:0x<>␤» 

Please note that a similar issue may arise when reducing lists with other operators.

Maps

Beware of nesting Maps in sink context

Maps apply an expression to every element of a List and return a Seq:

say <þor oðin loki>.map: *.codes; # OUTPUT: «(3 4 4)␤»

Maps are often used as a compact substitute for a loop, performing some kind of action in the map code block:

<þor oðin loki>.map: *.codes.say; # OUTPUT: «3␤4␤4␤»

The problem might arise when maps are nested and in a sink context.

<foo bar ber>.map: { $^a.comb.map: { $^b.say}}; # OUTPUT: «»

You might expect the innermost map to bubble the result up to the outermost map, but it simply does nothing. Maps return Seqs, and in sink context the innermost map will iterate and discard the produced values, which is why it yields nothing.

Simply using say at the beginning of the sentence will save the result from sink context:

say <foo bar ber>.map: *.comb.map: *.say ;
# OUTPUT: «f␤o␤o␤b␤a␤r␤b␤e␤r␤((True True True) (True True True) (True True True))␤»

However, it will not be working as intended; the first f␤o␤o␤b␤a␤r␤b␤e␤r␤ is the result of the innermost say, but then say returns a Bool, True in this case. Those Trues are what get printed by the outermost say, one for every letter. A much better option would be to flatten the outermost sequence:

<foo bar ber>.map({ $^a.comb.map: { $^b.say}}).flat
# OUTPUT: «f␤o␤o␤b␤a␤r␤b␤e␤r␤»

Of course, saving say for the result will also produce the intended result, as it will be saving the two nested sequences from void context:

say <foo bar ber>.map: { $^þ.comb }; # OUTPUT: « ((f o o) (b a r) (b e r))»

Smartmatching

The smartmatch operator shortcuts to the right hand side accepting the left hand side. This may cause some confusion.

Smartmatch and WhateverCode

Using WhateverCode in the left hand side of a smartmatch does not work as expected, or at all:

my @a = <1 2 3>; 
 say @a.grep( *.Int ~~ 2 ); 
 # OUTPUT: «Cannot use Bool as Matcher with '.grep'.  Did you mean to 
 # use $_ inside a block?␤␤␤» 

The error message does not make a lot of sense. It does, however, if you put it in terms of the ACCEPTS method: that code is equivalent to 2.ACCEPTS( *.Int ), but *.Int cannot be coerced to Numeric, being as it is a Block.

Solution: don't use WhateverCode in the left hand side of a smartmatch:

my @a = <1 2 3>; 
 say @a.grep( 2 ~~ *.Int ); # OUTPUT: «(2)␤» 

41 Fundamental topics

~

42 Containers

A low-level explanation of Perl 6 containers

This section explains the levels of indirection involved in dealing with variables and container elements. The different types of containers used in Perl 6 are explained and the actions applicable to them like assigning, binding and flattening. More advanced topics like self-referential data, type constraints and custom containers are discussed at the end.

What is a variable?

Some people like to say "everything is an object", but in fact a variable is not a user-exposed object in Perl 6.

When the compiler encounters a variable declaration like my $x, it registers it in some internal symbol table. This internal symbol table is used to detect undeclared variables and to tie the code generation for the variable to the correct scope.

At runtime, a variable appears as an entry in a lexical pad, or lexpad for short. This is a per-scope data structure that stores a pointer for each variable.

In the case of my $x, the lexpad entry for the variable $x is a pointer to an object of type Scalar, usually just called the container.

Scalar containers

Although objects of type Scalar are everywhere in Perl 6, you rarely see them directly as objects, because most operations decontainerize, which means they act on the Scalar container's contents instead of the container itself.

In code like

my $x = 42;
say $x;

the assignment $x = 42 stores a pointer to the Int object 42 in the scalar container to which the lexpad entry for $x points.

The assignment operator asks the container on the left to store the value on its right. What exactly that means is up to the container type. For Scalar it means "replace the previously stored value with the new one".

Note that subroutine signatures allow passing around of containers:

sub f($a is rw) {
    $a = 23;
}
my $x = 42;
f($x);
say $x;         # OUTPUT: «23␤»

Inside the subroutine, the lexpad entry for $a points to the same container that $x points to outside the subroutine. Which is why assignment to $a also modifies the contents of $x.

Likewise a routine can return a container if it is marked as is rw:

my $x = 23;
sub f() is rw { $x };
f() = 42;
say $x;         # OUTPUT: «42␤»

For explicit returns, return-rw instead of return must be used.

Returning a container is how is rw attribute accessors work. So

class A {
    has $.attr is rw;
}

is equivalent to

class A {
    has $!attr;
    method attr() is rw { $!attr }
}

Scalar containers are transparent to type checks and most kinds of read-only accesses. A .VAR makes them visible:

my $x = 42;
say $x.^name;       # OUTPUT: «Int␤»
say $x.VAR.^name;   # OUTPUT: «Scalar␤»

And is rw on a parameter requires the presence of a writable Scalar container:

sub f($x is rw) { say $x };
f 42;
CATCH { default { say .^name, ': ', .Str } };
# OUTPUT: «X::Parameter::RW: Parameter '$x' expected a writable container, but got Int value␤»

Callable containers

Callable containers provide a bridge between the syntax of a Routine call and the actual call of the method CALL-ME of the object that is stored in the container. The sigil & is required when declaring the container and has to be omitted when executing the Callable. The default type constraint is Callable.

my &callable = -> $ν { say "$ν is", $ν ~~ Int??" whole"!!" not whole" }
callable(⅓);
callable(3);

The sigil has to be provided when referring to the value stored in the container. This in turn allows Routines to be used as arguments to calls.

sub f() {}
my &g = sub {}
sub caller(&c1, &c2){ c1, c2 }
caller(&f, &g);

Binding

Next to assignment, Perl 6 also supports binding with the := operator. When binding a value or a container to a variable, the lexpad entry of the variable is modified (and not just the container it points to). If you write

my $x := 42;

then the lexpad entry for $x directly points to the Int 42. Which means that you cannot assign to it anymore:

my $x := 42;
$x = 23;
CATCH { default { say .^name, ': ', .Str } };
# OUTPUT: «X::AdHoc: Cannot assign to an immutable value␤»

You can also bind variables to other variables:

my $a = 0;
my $b = 0;
$a := $b;
$b = 42;
say $a;         # OUTPUT: «42␤»

Here, after the initial binding, the lexpad entries for $a and $b both point to the same scalar container, so assigning to one variable also changes the contents of the other.

You've seen this situation before: it is exactly what happened with the signature parameter marked as is rw.

Sigilless variables and parameters with the trait is raw always bind (whether = or := is used):

my $a = 42;
my \b = $a;
b++;
say $a;         # OUTPUT: «43␤»

sub f($c is raw) { $c++ }
f($a);
say $a;         # OUTPUT: «44␤»

Scalar containers and listy things

There are a number of positional container types with slightly different semantics in Perl 6. The most basic one is List, which is created by the comma operator.

say (1, 2, 3).^name;    # OUTPUT: «List␤»

A list is immutable, which means you cannot change the number of elements in a list. But if one of the elements happens to be a scalar container, you can still assign to it:

my $x = 42;
($x, 1, 2)[0] = 23;
say $x;                 # OUTPUT: «23␤»
($x, 1, 2)[1] = 23;     # Cannot modify an immutable value
CATCH { default { say .^name, ': ', .Str } };
# OUTPUT: «X::Assignment::RO: Cannot modify an immutable Int␤»

So the list doesn't care about whether its elements are values or containers, they just store and retrieve whatever was given to them.

Lists can also be lazy; in that case, elements at the end are generated on demand from an iterator.

An Array is just like a list, except that it forces all its elements to be containers, which means that you can always assign to elements:

my @a = 1, 2, 3;
@a[0] = 42;
say @a;         # OUTPUT: «[42 2 3]␤»

@a actually stores three scalar containers. @a[0] returns one of them, and the assignment operator replaces the integer value stored in that container with the new one, 42.

Assigning and binding to array variables

Assignment to a scalar variable and to an array variable both do the same thing: discard the old value(s), and enter some new value(s).

Nevertheless, it's easy to observe how different they are:

my $x = 42; say $x.^name;   # OUTPUT: «Int␤»
my @a = 42; say @a.^name;   # OUTPUT: «Array␤»

This is because the Scalar container type hides itself well, but Array makes no such effort. Also assignment to an array variable is coercive, so you can assign a non-array value to an array variable.

To place a non-Array into an array variable, binding works:

my @a := (1, 2, 3);
say @a.^name;               # OUTPUT: «List␤»

Binding to array elements

As a curious side note, Perl 6 supports binding to array elements:

my @a = (1, 2, 3);
@a[0] := my $x;
$x = 42;
say @a;                     # OUTPUT: «[42 2 3]␤»

If you've read and understood the previous explanations, it is now time to wonder how this can possibly work. After all, binding to a variable requires a lexpad entry for that variable, and while there is one for an array, there aren't lexpad entries for each array element, because you cannot expand the lexpad at runtime.

The answer is that binding to array elements is recognized at the syntax level and instead of emitting code for a normal binding operation, a special method (called BIND-KEY) is called on the array. This method handles binding to array elements.

Note that, while supported, one should generally avoid directly binding uncontainerized things into array elements. Doing so may produce counter-intuitive results when the array is used later.

my @a = (1, 2, 3);
@a[0] := 42;         # This is not recommended, use assignment instead.
my $b := 42;
@a[1] := $b;         # Nor is this.
@a[2] = $b;          # ...but this is fine.
@a[1, 2] := 1, 2;    # runtime error: X::Bind::Slice
CATCH { default { say .^name, ': ', .Str } };
# OUTPUT: «X::Bind::Slice: Cannot bind to Array slice␤»

Operations that mix Lists and Arrays generally protect against such a thing happening accidentally.

Flattening, items and containers

The % and @ sigils in Perl 6 generally indicate multiple values to an iteration construct, whereas the $ sigil indicates only one value.

my @a = 1, 2, 3;
for @a { };         # 3 iterations
my $a = (1, 2, 3);
for $a { };         # 1 iteration

@-sigiled variables do not flatten in list context:

my @a = 1, 2, 3;
my @b = @a, 4, 5;
say @b.elems;               # OUTPUT: «3␤»

There are operations that flatten out sublists that are not inside a scalar container: slurpy parameters (*@a) and explicit calls to flat:

my @a = 1, 2, 3;
say (flat @a, 4, 5).elems;  # OUTPUT: «5␤»

sub f(*@x) { @x.elems };
say f @a, 4, 5;             # OUTPUT: «5␤»

You can also use | to create a Slip, introducing a list into the other.

my @l := 1, 2, (3, 4, (5, 6)), [7, 8, (9, 10)];
say (|@l, 11, 12);    # OUTPUT: «(1 2 (3 4 (5 6)) [7 8 (9 10)] 11 12)␤»
say (flat @l, 11, 12) # OUTPUT: «(1 2 3 4 5 6 7 8 (9 10) 11 12)␤»

In the first case, every element of @l is slipped as the corresponding elements of the resulting list. flat, in the other hand, flattens all elements including the elements of the included array, except for (9 10).

As hinted above, scalar containers prevent that flattening:

sub f(*@x) { @x.elems };
my @a = 1, 2, 3;
say f $@a, 4, 5;            # OUTPUT: «3␤»

The @ character can also be used as a prefix to coerce the argument to a list, thus removing a scalar container:

my $x = (1, 2, 3);
.say for @$x;               # 3 iterations

However, the decont operator <> is more appropriate to decontainerize items that aren't lists:

my $x = ^Inf .grep: *.is-prime;
say "$_ is prime" for @$x;  # WRONG! List keeps values, thus leaking memory
say "$_ is prime" for $x<>; # RIGHT. Simply decontainerize the Seq

my $y := ^Inf .grep: *.is-prime; # Even better; no Scalars involved at all

Methods generally don't care whether their invocant is in a scalar, so

my $x = (1, 2, 3);
$x.map(*.say);              # 3 iterations

maps over a list of three elements, not of one.

Self-referential data

Container types, including Array and Hash, allow you to create self-referential structures.

my @a;
@a[0] = @a;
put @a.perl;
# OUTPUT: «((my @Array_75093712) = [@Array_75093712,])␤»

Although Perl 6 does not prevent you from creating and using self-referential data, by doing so you may end up in a loop trying to dump the data. As a last resort, you can use Promises to handle timeouts.

Type constraints

Any container can have a type constraint in the form of a type object or a subset. Both can be placed between a declarator and the variable name or after the trait of. The constraint is a property of the variable, not the container.

subset Three-letter of Str where .chars == 3;
my Three-letter $acronym = "ÞFL";

In this case, the type constraint is the (compile-type defined) subset Three-letter.

Variables may have no container in them, yet still offer the ability to re-bind and typecheck that rebind. The reason for that is in such cases the binding operator := performs the typecheck:

my Int \z = 42;
z := 100; # OK
z := "x"; # Typecheck failure

The same isn't the case when, say, binding to a Hash key, as the binding is then handled by a method call (even though the syntax remains the same, using := operator).

The default type constraint of a Scalar container is Mu. Introspection of type constraints on containers is provided by .VAR.of method, which for @ and % sigiled variables gives the constraint for values:

my Str $x;
say $x.VAR.of;  # OUTPUT: «(Str)␤»
my Num @a;
say @a.VAR.of;  # OUTPUT: «(Num)␤»
my Int %h;
say %h.VAR.of;  # OUTPUT: «(Int)␤»

Definedness constraints

A container can also enforce a variable to be defined. Put a smiley in the declaration:

my Int:D $def = 3;
say $def;   # OUTPUT: «3␤»
$def = Int; # Typecheck failure

You'll also need to initialize the variable in the declaration, it can't be left undefined after all.

It's also possible to have this constraint enforced in all variables declared in a scope with the default defined variables pragma. People coming from other languages where variables are always defined will want to have a look.

Custom containers

To provide custom containers Perl 6 provides the class Proxy. It takes two methods that are called when values are stored or fetched from the container. Type checks are not done by the container itself and other restrictions like readonlyness can be broken. The returned value must therefore be of the same type as the type of the variable it is bound to. We can use type captures to work with types in Perl 6.

sub lucky(::T $type) {
    my T $c-value; # closure variable
    return Proxy.new(
        FETCH => method () { $c-value },
        STORE => method (T $new-value) {
            X::OutOfRange.new(what => 'number', got => '13', range => '-∞..12, 14..∞').throw
                if $new-value == 13;
            $c-value = $new-value;
        }
    );
}

my Int $a := lucky(Int);
say $a = 12;    # OUTPUT: «12␤»
say $a = 'FOO'; # X::TypeCheck::Binding
say $a = 13;    # X::OutOfRange
CATCH { default { say .^name, ': ', .Str } };

43 Contexts and contextualizers

What are contexts and how to switch into them

A context is needed, in many occasions, to interpret the value of a container. In Perl 6, we will use context to coerce the value of a container into some type or class, or in general decide what to do with it, as in the case of the sink context. In general, recognizing an object that is in a certain context will force an implicit coercion by calling a specific method on it.

Sink

The sink context is equivalent to what in other languages is called void context, that is, a context in which we throw (down the sink, as it were) the result of an operation or the return value from a block. In general, this context will be invoked in warnings and errors when a statement does not know what to do with that value.

my $sub = -> $a { return $a² }; 
 $sub; # OUTPUT: «WARNINGS:␤Useless use of $sub in sink context (line 1)␤» 

You can force that sink context on Iterators, by using the sink-all method. Procs can also be sunk via the sink method, forcing them to raise an exception and not returning anything.

In general, blocks will warn if evaluated in sink context; however, gather/take blocks are explicitly evaluated in sink context, with values returned explicitly using take; however, sinking will explicitly throw away those values, so use sink only if you want to run a gather statement for the side effects.

In sink context, an object will call its sink method if present:

sub foo { 
     return [<a b c>] does role { 
         method sink { say "sink called" } 
     } 
 } 
 foo; # OUTPUT: sink called 

Number

This context, and probably all other contexts except sink above, are conversion or interpretation contexts in the sense that they take an untyped or typed variable and duck-type it to whatever is needed to perform the operation. In some cases that will imply a conversion (from Str to Numeric, for instance); in other cases simply an interpretation (IntStr will be interpreted as Int or as Str).

Number context is called whenever we need to apply a numerical operation on a variable.

my $not-a-string = "1                 "; 
 my $neither-a-string = "3                        "; 
 say $not-a-string + $neither-a-string; # OUTPUT: «4␤» 

In the code above, strings will be interpreted in numeric context as long as there are only a few digits and no other characters. It can have any number of leading or trailing whitespace, however.

Numeric context can be forced by using arithmetic operators such as + or -. In that context, the Numeric method will be called if available and the value returned used as the numeric value of the object.

my $t = True; 
 my $f = False; 
 say $t + $f;      # OUTPUT: «1␤» 
 say $t.Numeric;   # OUTPUT: «1␤» 
 say $f.Numeric;   # OUTPUT: «0␤» 
 my $list= <a b c>; 
 say True + $list; # OUTPUT: «4␤» 

In the case of listy things, the numeric value will be in general equivalent to .elems; in some cases, like Thread it will return an unique thread identifier.

String

In a string context, values can be manipulated as strings. This context is used, for instance, for coercing non-string values so that they can be printed to standard output.

put $very-complicated-and-hairy-object; # OUTPUT: something meaningful 

Or when smartmatching to a regular expression:

put 333444777 ~~ /(3+)/; # OUTPUT: «「333」␤ 0 => 「333」␤»

In general, the Str routine will be called on a variable to contextualize it; since this method is inherited from Mu, it is always present, but it is not always guaranteed to work. In some core classes it will issue a warning.

~ is the (unary) string contextualizer. As an operator, it concatenates strings, but as a prefix operator it becomes the string context operator.

my @array = [ [1,2,3], [4,5,6]]; 
 say ~@array; # OUTPUT: «1 2 3 4 5 6␤» 

This will happen also in a reduction context, when [~] is applied to a list

say [~] [ 3, 5+6i, Set(<a b c>), [1,2,3] ]; # OUTPUT: «35+6ic a b1 2 3␤»

In that sense, empty lists or other containers will stringify to an empty string:

say [~] [] ; # OUTPUT: «␤»

Since ~ acts also as buffer concatenation operator, it will have to check that every element is not empty, since a single empty buffer in string context will behave as a string, thus yielding an error.

say [~] Buf.new(0x3,0x33), Buf.new(0x2,0x22);
# OUTPUT: «Buf:0x<03 33 02 22>␤»

However,

my $non-empty = Buf.new(0x3, 0x33); 
 my $empty = []; 
 my $non-empty-also = Buf.new(0x2,0x22); 
 say [~] $non-empty, $empty, $non-empty-also; 
 # OUTPUT: «Cannot use a Buf as a string, but you called the Stringy method on it 

Since ~ is putting in string context the second element of this list, ~ is going to be using the second form that applies to strings, thus yielding the shown error. Simply making sure that everything you concatenate is a buffer will avoid this problem.

my $non-empty = Buf.new(0x3, 0x33); 
 my $empty = Buf.new(); 
 my $non-empty-also = Buf.new(0x2,0x22); 
 say [~] $non-empty, $empty, $non-empty-also; # OUTPUT: «Buf:0x<03 33 02 22>␤» 

In general, a context will coerce a variable to a particular type by calling the contextualizer; in the case of mixins, if the context class is mixed in, it will behave in that way.

my $described-number = 1i but 'Unity in complex plane';
put $described-number; # OUTPUT: «Unity in complex plane␤»

but creates a mixin, which endows the complex number with a Str method. put contextualizes it into a string, that is, it calls Str, the string contextualizer, with the result shown above.

Boolean

This context will force a variable to be interpreted as True or False.

say "Hey" if 7;  # OUTPUT: «Hey␤»
say "Ahoy" if "";

This context appears in expressions such as if or while, and is equivalent to calling so on these values.

say "Hey" if 7.so;          # OUTPUT: «Hey␤» 
 say "Ahoy" if not set().so; # OUTPUT: «Ahoy␤» 

In general, non-zero, non-empty will be converted to True; zero or empty will be equivalent to False. But .so can be defined to return any Boolean value we want, so this is just a rule of thumb.

? and ! are the Boolean context operator and its negation respectively. They will force this context on an object.

say ? 0i;    # OUTPUT: «False␤» 
 say ! :true; # OUTPUT: «False␤» 

List

There are actually several different list contexts, which are better explained in that page. In general, the list contextualizer is the comma ,

say (3,).^name; # OUTPUT: «List␤»

and the method called in that case is also .list

Any.list.^name;   # OUTPUT: «List␤» 
 say 3.list.^name; # OUTPUT: «List␤» 
 say (^3).list;    # OUTPUT: «(0 1 2)␤» 

44 Control flow

Statements used to control the flow of execution

statements

Perl 6 programs consist of one or more statements. Simple statements are separated by semicolons. The following program will say "Hello" and then say "World" on the next line.

say "Hello";
say "World";

In most places where spaces appear in a statement, and before the semicolon, it may be split up over many lines. Also, multiple statements may appear on the same line. It would be awkward, but the above example could also be written as:

say
"Hello"; say "World";

Blocks

Like many other languages, Perl 6 uses blocks enclosed by { and } to turn a sequence of statements into a single one. It is OK to skip the semicolon between the last statement in a block and the closing }.

{ say "Hello"; say "World" }

When a block stands alone as a statement, it will be entered immediately after the previous statement finishes, and the statements inside it will be executed.

say 1;                    # OUTPUT: «1␤»
{ say 2; say 3 };         # OUTPUT: «2␤3␤»
say 4;                    # OUTPUT: «4␤»

Unless it stands alone as a statement, a block simply creates a closure. The statements inside are not executed immediately. Closures are another topic and how they are used is explained elsewhere. For now it is just important to understand when blocks run and when they do not:

say "We get here"; { say "then here." }; { say "not here"; 0; } or die; 

In the above example, after running the first statement, the first block stands alone as a second statement, so we run the statement inside it. The second block is a closure, so instead, it makes an object of type Block but does not run it. Object instances are usually considered to be true, so the code does not die, even though that block would evaluate to 0, were it to be executed. The example does not say what to do with the Block object, so it just gets thrown away.

Most of the flow control constructs covered below are just ways to tell Perl 6 when, how, and how many times, to enter blocks like that second block.

Before we go into those, an important side-note on syntax: If there is nothing (or nothing but comments) on a line after a closing curly brace where you would normally put semicolon, then you do not need the semicolon:

# All three of these lines can appear as a group, as is, in a program
{ 42.say }                # OUTPUT: «42␤»
{ 43.say }                # OUTPUT: «43␤»
{ 42.say }; { 43.say }    # OUTPUT: «42␤43␤»

...but:

{ 42.say }  { 43.say }    # Syntax error 
 { 42.say; } { 43.say }    # Also a syntax error, of course 

So, be careful when you backspace in a line-wrapping editor:

{ "Without semicolons line-wrapping can be a bit treacherous.".say } \ 
 { 43.say } # Syntax error 

You have to watch out for this in most languages anyway to prevent things from getting accidentally commented out. Many of the examples below may have unnecessary semicolons for clarity.

Class bodies behave like simple blocks for any top level expression; same goes to roles and other packages, like grammars (which are actually classes) or modules.

class C { 
     say "I live"; 
     die "I will never live!" 
 }; 
 my $c = C.new;                              │ 
 # OUTPUT: Fails and writes «I live␤I will never live!␤ 

This block will first run the first statement, and then die printing the second statement. $c will never get a value.

Phasers

Blocks may have phasers: special labeled blocks that break their execution into phases that run in particular phases. See the page phasers for the details.

do

The simplest way to run a block where it cannot be a stand-alone statement is by writing do before it:

# This dies half of the time 
 do { say "Heads I win, tails I die."; Bool.pick } or die; say "I win."; 

Note that you need a space between the do and the block.

The whole do {...} evaluates to the final value of the block. The block will be run when that value is needed in order to evaluate the rest of the expression. So:

False and do { 42.say };

...will not say 42. However, the block is only evaluated once each time the expression it is contained in is evaluated:

# This says "(..1 ..2 ..3)" not "(..1 ...2 ....3)"
my $f = "."; say do { $f ~= "." } X~ 1, 2, 3;

In other words, it follows the same reification rules as everything else.

Technically, do is a loop which runs exactly one iteration.

A do may also be used on a bare statement (without curly braces) but this is mainly just useful for avoiding the syntactical need to parenthesize a statement if it is the last thing in an expression:

3, do if 1 { 2 }  ; # OUTPUT: «(3, 2)␤» 
 3,   (if 1 { 2 }) ; # OUTPUT: «(3, 2)␤» 
3,    if 1 { 2 }  ; # Syntax error 

start

The simplest way to run a block asynchronously is by writing start before it:

start { sleep 1; say "done" } 
 say "working"; 
 # working, done 

Note that you need a space between the start and the block. In the example above, the start block is in sink context, since it's not assigned to a variable. From version 6.d, these kind of blocks have an exception handler attached:

start { die "We're dead"; } 
 say "working"; 
 sleep 10; 

This code will print Unhandled exception in code scheduled on thread 4 We're dead in version 6.d, while it will simply get out after waiting for 10 seconds in version 6.c.

The start {...} immediately returns a Promise that can be safely ignored if you are not interested in the result of the block. If you are interested in the final value of the block, you can call the .result method on the returned promise. So:

my $promise = start { sleep 10; 42 }
# ... do other stuff
say "The result is $promise.result()";

If the code inside the block has not finished, the call to .result will wait until it is done.

A start may also be used on a bare statement (without curly braces). This is mainly useful when calling a subroutine / method on an object is the only thing to do asynchronously.

sub get42 { 42 }
my $promise = start get42;
say $promise.result; # OUTPUT: «42␤»

Note that code executed this way does not have access to the special variables $! and $/ of its outer block, but receives new ones, so every asynchronous task has its per-task state.

Thus, try expressions and regex matches executed in the asynchronous task have their per-task state.

'a' ~~ /a/; # $/ is set to 「a」
try die;    # $! is defined now with an anonymous AdHoc exception
# as a code block
await start { say $! }; # OUTPUT: «Nil␤»
await start { say $/ }; # OUTPUT: «Nil␤»
# as a single statement
await start $!.say;     # OUTPUT: «Nil␤»
await start $/.say;     # OUTPUT: «Nil␤»

if

To conditionally run a block of code, use an if followed by a condition. The condition, an expression, will be evaluated immediately after the statement before the if finishes. The block attached to the condition will only be evaluated if the condition means True when coerced to Bool. Unlike some languages the condition does not have to be parenthesized, instead the { and } around the block are mandatory:

if 1 { "1 is true".say }  ; # says "1 is true" 
if 1   "1 is true".say    ; # syntax error, missing block 
if 0 { "0 is true".say }  ; # does not say anything, because 0 is false 
if 42.say and 0 { 43.say }; # says "42" but does not say "43" 

There is also a form of if called a "statement modifier" form. In this case, the if and then the condition come after the code you want to run conditionally. Do note that the condition is still always evaluated first:

43.say if 42.say and 0;     # says "42" but does not say "43"
43.say if 42.say and 1;     # says "42" and then says "43"
say "It is easier to read code when 'if's are kept on left of screen"
    if True;                # says the above, because it is true
{ 43.say } if True;         # says "43" as well

The statement modifier form is probably best used sparingly.

The if statement itself will either slip us an empty list, if it does not run the block, or it will return the value which the block produces:

my $d = 0; say (1, (if 0 { $d += 42; 2; }), 3, $d); # says "(1 3 0)"
my $c = 0; say (1, (if 1 { $c += 42; 2; }), 3, $c); # says "(1 2 3 42)"
say (1, (if 1 { 2, 2 }), 3);         # does not slip, says "(1 (2 2) 3)"

For the statement modifier it is the same, except you have the value of the statement instead of a block:

say (1, (42 if True) , 2); # says "(1 42 2)"
say (1, (42 if False), 2); # says "(1 2)"
say (1,  42 if False , 2); # says "(1 42)" because "if False, 2" is true

The if does not change the topic ($_) by default. In order to access the value which the conditional expression produced, you have to ask for it more strongly:

$_ = 1; if 42 { $_.say }                ; # says "1"
$_ = 1; if 42 -> $_ { $_.say }          ; # says "42"
$_ = 1; if 42 -> $a { $_.say;  $a.say } ; # says "1" then says "42"
$_ = 1; if 42       { $_.say; $^a.say } ; # says "1" then says "42"

else/elsif

A compound conditional may be produced by following an if conditional with else to provide an alternative block to run when the conditional expression is false:

if 0 { say "no" } else { say "yes" }   ; # says "yes" 
 if 0 { say "no" } else{ say "yes" }    ; # says "yes", space is not required 

The else cannot be separated from the conditional statement by a semicolon, but as a special case, it is OK to have a newline.

if 0 { say "no" }; else { say "yes" }  ; # syntax error 
if 0 { say "no" } 
 else { say "yes" }                     ; # says "yes" 

Additional conditions may be sandwiched between the if and the else using elsif. An extra condition will only be evaluated if all the conditions before it were false, and only the block next to the first true condition will be run. You can end with an elsif instead of an else if you want.

if 0 { say "no" } elsif False { say "NO" } else { say "yes" } # says "yes"
if 0 { say "no" } elsif True { say "YES" } else { say "yes" } # says "YES"

if 0 { say "no" } elsif False { say "NO" } # does not say anything

sub right { "Right!".say; True }
sub wrong { "Wrong!".say; False }
if wrong() { say "no" } elsif right() { say "yes" } else { say "maybe" }
# The above says "Wrong!" then says "Right!" then says "yes"

You cannot use the statement modifier form with else or elsif:

42.say if 0 else { 43.say }            # syntax error 

All the same rules for semicolons and newlines apply, consistently

if 0 { say 0 }; elsif 1 { say 1 }  else { say "how?" } ; # syntax error 
 if 0 { say 0 }  elsif 1 { say 1 }; else { say "how?" } ; # syntax error 
if 0 { say 0 }  elsif 1 { say 1 }  else { say "how?" } ; # says "1" 
if 0 { say 0 } elsif 1 { say 1 }
else { say "how?" }                                    ; # says "1"

if 0 { say 0 }
elsif 1 { say 1 } else { say "how?" }                  ; # says "1"

if        0 { say "no" }
elsif False { say "NO" }
else        { say "yes" }                              ; # says "yes"

The whole thing either slips us an empty list (if no blocks were run) or returns the value produced by the block that did run:

my $d = 0; say (1,
                (if 0 { $d += 42; "two"; } elsif False { $d += 43; 2; }),
                3, $d); # says "(1 3 0)"
my $c = 0; say (1,
                (if 0 { $c += 42; "two"; } else { $c += 43; 2; }),
                3, $c); # says "(1 2 3 43)"

It's possible to obtain the value of the previous expression inside an else, which could be from if or the last elsif if any are present:

$_ = 1; if 0     { } else -> $a { "$_ $a".say } ; # says "1 0"
$_ = 1; if False { } else -> $a { "$_ $a".say } ; # says "1 False"

if False { } elsif 0 { } else -> $a { $a.say }  ; # says "0"

unless

When you get sick of typing "if not (X)" you may use unless to invert the sense of a conditional statement. You cannot use else or elsif with unless because that ends up getting confusing. Other than those two differences unless works the same as #if:

unless 1 { "1 is false".say }  ; # does not say anything, since 1 is true 
unless 1   "1 is false".say    ; # syntax error, missing block 
unless 0 { "0 is false".say }  ; # says "0 is false" 
unless 42.say and 1 { 43.say } ; # says "42" but does not say "43"
43.say unless 42.say and 0;      # says "42" and then says "43"
43.say unless 42.say and 1;      # says "42" but does not say "43"

$_ = 1; unless 0 { $_.say }           ; # says "1"
$_ = 1; unless 0 -> $_ { $_.say }     ; # says "0"
$_ = 1; unless False -> $a { $a.say } ; # says "False"

my $c = 0; say (1, (unless 0 { $c += 42; 2; }), 3, $c); # says "(1 2 3 42)"
my $d = 0; say (1, (unless 1 { $d += 42; 2; }), 3, $d); # says "(1 3 0)"

with orwith without

The with statement is like if, but tests for definedness rather than truth, and it topicalizes on the condition, much like given:

with "abc".index("a") { .say }      # prints 0

Similarly to elsif, orwith may be used to chain definedness tests:

# The below code says "Found a at 0"
my $s = "abc";
with   $s.index("a") { say "Found a at $_" }
orwith $s.index("b") { say "Found b at $_" }
orwith $s.index("c") { say "Found c at $_" }
else                 { say "Didn't find a, b or c" }

You may intermix if-based and with-based clauses.

# This says "Yes"
if 0 { say "No" } orwith Nil { say "No" } orwith 0 { say "Yes" };

As with unless, you may use without to check for undefinedness, but you may not add an else clause:

my $answer = Any;
without $answer { warn "Got: {$_.perl}" }

There are also with and without statement modifiers:

my $answer = (Any, True).roll;
say 42 with $answer;
warn "undefined answer" without $answer;

As with the other chainable constructs, an else completing a with/if..orwith/elsif chain will itself topicalize to the value of the prior (failed) condition's topic (either the topic of with or the final orwith or elsif).

In the case of an else following a with or orwith, topicalizing a value guaranteed to be undefined may seem useless. But it makes for a useful idiom when used in conjunction with operations that may fail, because Failure values are always undefined:

sub may_fail( --> Numeric:D ) { 
   my $value = (^10).pick || fail "Zero is unacceptable"; 
   fail "Odd is also not okay" if $value % 2; 
   return $value; 
 } 
 
 with may_fail() -> $value { # defined, so didn't fail 
   say "I know $value isn't zero or odd." 
 } else { # undefined, so failed, and the Failure is the topic 
   say "Uh-oh: {.exception.message}." 
 } 

Note that while topicalizing a Failure marks it handled—so you can use the with/else to proceed safely with execution—it doesn't make the Failure value itself safe. Even within the else clause, if you try to use the value directly, it will result in your else clause itself failing (or, in Rakudo, "promoting" the Failure into a thrown exception).

But as seen above, you can use the methods of a handled Failure object the else topicalizes, such as exception, if you wish to provide diagnostics or interrogate the underlying Exception.

when

The when block is similar to an if block and either or both can be used in an outer block; they also both have a "statement modifier" form. But there is a difference in how following code in the same, outer block is handled: When the when block is executed, control is passed to the enclosing block and following statements are ignored; but when the if block is executed, following statements are executed.

There are other ways to modify their default behavior; they are discussed in other sections.
The following examples should illustrate the if or when block's default behavior assuming no special exit or other side effect statements are included in the if or when blocks:

{ 
     if X {...} # if X is true in boolean context, block is executed 
     # following statements are executed regardless 
 } 
 { 
     when X {...} # if X is true in boolean context, block is executed 
                  # and control passes to the outer block 
     # following statements are NOT executed 
 } 

Should the if and when blocks above appear at file scope, following statements would be executed in each case.

There is one other feature when has that if doesn't: the when's boolean context test defaults to $_ ~~ while the if's does not. That has an effect on how one uses the X in the when block without a value for $_ (it's Any in that case and Any smartmatches on True: Any ~~ True yields True). Consider the following:

{ 
     my $a = 1; 
     my $b = True; 
     when $a    { say 'a' }; # no output 
     when so $a { say 'a' }  # a (in "so $a" 'so' coerces $a to Boolean context True 
                             # which matches with Any) 
     when $b    { say 'b' }; # no output (this statement won't be run) 
 } 

Finally, when's statement modifier form does not affect execution of following statements either inside or outside of another block:

say "foo" when X; # if X is true statement is executed 
                   # following statements are not affected 

Since a successful match will exit the block, the behavior of this piece of code:

$_ = True; 
 my $a; 
 { 
     $a = do when .so { "foo" } 
 }; 
 say $a; # OUTPUT: «(Any)␤» 

is explained since the do block is abandoned before any value is stored or processed. However, in this case:

$_ = False; 
 my $a; 
 { 
     $a = do when .so { "foo" } 
 }; 
 say $a; # OUTPUT: «False␤» 

the block is not abandoned since the comparison is false, so $a will actually get a value.

for

The for loop iterates over a list, running the statements inside a block once on each iteration. If the block takes parameters, the elements of the list are provided as arguments.

my @foo = 1..3;
for @foo { $_.print } # prints each value contained in @foo
for @foo { .print }   # same thing, because .print implies a $_ argument
for @foo { 42.print } # prints 42 as many times as @foo has elements

Pointy block syntax or a placeholder may be used to name the parameter, of course.

my @foo = 1..3;
for @foo -> $item { print $item }
for @foo { print $^item }            # same thing

Multiple parameters can be declared, in which case the iterator takes as many elements from the list as needed before running the block.

my @foo = 1..3;
for @foo.kv -> $idx, $val { say "$idx: $val" }
my %hash = <a b c> Z=> 1,2,3;
for %hash.kv -> $key, $val { say "$key => $val" }
for 1, 1.1, 2, 2.1 { say "$^x < $^y" }  # says "1 < 1.1" then says "2 < 2.1"

Parameters of a pointy block can have default values, allowing to handle lists with missing elements.

my @list = 1,2,3,4;
for @list -> $a, $b = 'N/A', $c = 'N/A' {
    say "$a $b $c"
}
# OUTPUT: «1 2 3␤4 N/A N/A␤»

If the postfix form of for is used, a block is not required and the topic is set for the statement list.

say „I $_ butterflies!“ for <♥ ♥ ♥>;
# OUTPUT«I ♥ butterflies!␤I ♥ butterflies!␤I ♥ butterflies!␤»

A for may be used on lazy lists – it will only take elements from the list when they are needed, so to read a file line by line, you could use:

for $*IN.lines -> $line { .say } 

Iteration variables are always lexical, so you don't need to use my to give them the appropriate scope. Also, they are read-only aliases. If you need them to be read-write, use <-> instead of ->. If you need to make $_ read-write in a for loop, do so explicitly.

my @foo = 1..3;
for @foo <-> $_ { $_++ }

A for loop can produce a List of the values produced by each run of the attached block. To capture these values, put the for loop in parenthesis or assign them to an array:

(for 1, 2, 3 { $_ * 2 }).say;              # OUTPUT «(2 4 6)␤»
my @a = do for 1, 2, 3 { $_ * 2 }; @a.say; # OUTPUT «[2 4 6]␤»
my @b = (for 1, 2, 3 { $_ * 2 }); @b.say;  # OUTPUT: «[2 4 6]␤»

The Empty constant will act as a no-op for a loop:

say "Not here" for Empty; 

Will not do anything. This constant is equivalent to a empty Slip or List.

Undefined values will behave in the same way:

my @array := Empty; 
 .say for @array; 
 say @array; # OUTPUT: «()␤» 

Assigning Empty will effectively undefine an Array, using for over an undefined array will not even enter the loop, as shown, effectively behaving in the same way as above when Empty was used directly.

With hyper and race, the for loop is potentially iterated in parallel. See also the documentation for hyper and race in class Map.

my $primes_h = hyper for ^10_000 -> $number { $number if $number.is-prime }; 
 say $primes_h.elems;   # OUTPUT: «1229␤» 
 say $primes_h.tail: 5; # OUTPUT: «(9931 9941 9949 9967 9973)␤» 

with hyper the order of elements is preserved.

my $primes_r = race for ^10_000 -> $number { $number if $number.is-prime }; 
 say $primes_r.elems; # OUTPUT: «1229␤» 

Unlike hyper, race does not preserve the order of elements.

gather/take

gather is a statement or block prefix that returns a sequence of values. The values come from calls to take in the dynamic scope of the gather block.

my @a = gather {
    take 1;
    take 5;
    take 42;
}
say join ', ', @a;          # OUTPUT: «1, 5, 42␤»

gather/take can generate values lazily, depending on context. If you want to force lazy evaluation use the lazy subroutine or method. Binding to a scalar or sigilless container will also force laziness.

For example

my @vals = lazy gather {
    take 1;
    say "Produced a value";
    take 2;
}
say @vals[0];
say 'between consumption of two values';
say @vals[1];

# OUTPUT:
# 1
# between consumption of two values
# Produced a value
# 2

gather/take is scoped dynamically, so you can call take from subs or methods that are called from within gather:

sub weird(@elems, :$direction = 'forward') {
    my %direction = (
        forward  => sub { take $_ for @elems },
        backward => sub { take $_ for @elems.reverse },
        random   => sub { take $_ for @elems.pick(*) },
    );
    return gather %direction{$direction}();
}

say weird(<a b c>, :direction<backward> );          # OUTPUT: «(c b a)␤»

If values need to be mutable on the caller side, use take-rw.

Note that gather/take also work for hashes. The return value is still a Seq but the assignment to a hash in the following example makes it a hash.

my %h = gather { take "foo" => 1; take "bar" => 2};
say %h;                                             # OUTPUT: «{bar => 2, foo => 1}␤»

supply/emit

Emits the invocant into the enclosing supply:

my $supply = supply {
    emit $_ for "foo", 42, .5;
}
$supply.tap: {
    say "received {.^name} ($_)";
}

# OUTPUT:
# received Str (foo)
# received Int (42)
# received Rat (0.5)

given

The given statement is Perl 6's topicalizing keyword in a similar way that switch topicalizes in languages such as C. In other words, given sets $_ inside the following block. The keywords for individual cases are when and default. The usual idiom looks like this:

my $var = (Any, 21, any <answer lie>).pick;
given $var {
    when 21 { say $_ * 2 }
    when 'lie' { .say }
    default { say 'default' }
}

The given statement is often used alone:

given 42 { .say; .Numeric; }

This is a lot more understandable than:

{ .say; .Numeric; }(42)

default and when

A block containing a default statement will be left immediately when the sub-block after the default statement is left. It is as though the rest of the statements in the block are skipped.

given 42 {
    "This says".say;
    $_ == 42 and ( default { "This says, too".say; 43; } );
    "This never says".say;
}
# The above block evaluates to 43

A when statement will also do this (but a when statement modifier will not.)

In addition, when statements smartmatch the topic ($_) against a supplied expression such that it is possible to check against values, regular expressions, and types when specifying a match.

for 42, 43, "foo", 44, "bar" {
    when Int { .say }
    when /:i ^Bar/ { .say }
    default  { say "Not an Int or a Bar" }
}
# OUTPUT: «42␤43␤Not an Int or a Bar␤44␤Bar␤»

In this form, the given/when construct acts much like a set of if/elsif/else statements. Be careful with the order of the when statements. The following code says "Int" not 42.

given 42 {
    when Int { say "Int" }
    when 42  { say 42 }
    default  { say "huh?" }
}
# OUTPUT: «Int␤»

When a when statement or default statement causes the outer block to return, nesting when or default blocks do not count as the outer block, so you can nest these statements and still be in the same "switch" just so long as you do not open a new block:

given 42 {
    when Int {
      when 42  { say 42 }
      say "Int"
    }
    default  { say "huh?" }
}
# OUTPUT: «42»

when statements can smartmatch against Signatures.

proceed

succeed

Both proceed and succeed are meant to be used only from inside when or default blocks.

The proceed statement will immediately leave the when or default block, skipping the rest of the statements, and resuming after the block. This prevents the when or default from exiting the outer block.

given * { 
     default { 
         proceed; 
         "This never says".say 
     } 
 } 
 "This says".say; 

This is most often used to enter multiple when blocks. proceed will resume matching after a successful match, like so:

given 42 {
    when Int   { say "Int"; proceed }
    when 42    { say 42 }
    when 40..* { say "greater than 40" }
    default    { say "huh?" }
}
# OUTPUT: «Int␤»
# OUTPUT: «42␤»

Note that the when 40..* match didn't occur. For this to match such cases as well, one would need a proceed in the when 42 block.

This is not like a C switch statement, because the proceed does not merely enter the directly following block, it attempts to match the given value once more, consider this code:

given 42 {
    when Int { "Int".say; proceed }
    when 43  { 43.say }
    when 42  { 42.say }
    default  { "got change for an existential answer?".say }
}
# OUTPUT: «Int␤»
# OUTPUT: «42␤»

...which matches the Int, skips 43 since the value doesn't match, matches 42 since this is the next positive match, but doesn't enter the default block since the when 42 block doesn't contain a proceed.

By contrast, the succeed keyword short-circuits execution and exits the entire given block at that point. It may also take an argument to specify a final value for the block.

given 42 {
    when Int {
        say "Int";
        succeed "Found";
        say "never this!";
    }
    when 42 { say 42 }
    default { say "dunno?" }
}
# OUTPUT: «Int␤»

If you are not inside a when or default block, it is an error to try to use proceed or succeed.Also remember, the when statement modifier form does not cause any blocks to be left, and any succeed or proceed in such a statement applies to the surrounding clause, if there is one:

given 42 {
    { say "This says" } when Int;
    "This says too".say;
    when * > 41 {
       { "And this says".say; proceed } when * > 41;
       "This never says".say;
    }
    "This also says".say;
}

given as a statement

given can follow a statement to set the topic in the statement it follows.

.say given "foo";
# OUTPUT: «foo␤»

printf "%s %02i.%02i.%i",
        <Mo Tu We Th Fr Sa Su>[.day-of-week - 1],
        .day,
        .month,
        .year
    given DateTime.now;
# OUTPUT: «Sa 03.06.2016»

loop

The loop statement takes three statements in parentheses separated by ; that take the role of initializer, conditional and incrementer. The initializer is executed once and any variable declaration will spill into the surrounding block. The conditional is executed once per iteration and coerced to Bool, if False the loop is stopped. The incrementer is executed once per iteration.

loop (my $i = 0; $i < 10; $i++) {
    say $i;
}

The infinite loop does not require parentheses.

loop { say 'forever' } 

The loop statement may be used to produce values from the result of each run of the attached block if it appears in lists:

(loop ( my $i = 0; $i++ < 3;) { $i * 2 }).say;               # OUTPUT: «(2 4 6)␤»
my @a = (loop ( my $j = 0; $j++ < 3;) { $j * 2 }); @a.say;   # OUTPUT: «[2 4 6]␤»
my @b = do loop ( my $k = 0; $k++ < 3;) { $k * 2 }; @b.say;  # same thing

Unlike a for loop, one should not rely on whether returned values are produced lazily. It would probably be best to use eager to guarantee that a loop whose return value may be used actually runs:

sub heads-in-a-row {
    (eager loop (; 2.rand < 1;) { "heads".say })
}

while, until

The while statement executes the block as long as its condition is true. So

my $x = 1;
while $x < 4 {
    print $x++;
}
print "\n";

# OUTPUT: «123␤»

Similarly, the until statement executes the block as long as the expression is false.

my $x = 1;
until $x > 3 {
    print $x++;
}
print "\n";

# OUTPUT: «123␤»

The condition for while or until can be parenthesized, but there must be a space between the keyword and the opening parenthesis of the condition.

Both while and until can be used as statement modifiers. E. g.

my $x = 42;
$x-- while $x > 12

Also see repeat/while and repeat/until below.

All these forms may produce a return value the same way loop does.

repeat/while, repeat/until

Executes the block at least once and, if the condition allows, repeats that execution. This differs from while/until in that the condition is evaluated at the end of the loop, even if it appears at the front.

my $x = -42;
repeat {
    $x++;
} while $x < 5;
$x.say; # OUTPUT: «5␤»

repeat {
    $x++;
} while $x < 5;
$x.say; # OUTPUT: «6␤»

repeat while $x < 10 {
    $x++;
}
$x.say; # OUTPUT: «10␤»

repeat while $x < 10 {
    $x++;
}
$x.say; # OUTPUT: «11␤»

repeat {
    $x++;
} until $x >= 15;
$x.say; # OUTPUT: «15␤»

repeat {
    $x++;
} until $x >= 15;
$x.say; # OUTPUT: «16␤»

repeat until $x >= 20 {
    $x++;
}
$x.say; # OUTPUT: «20␤»

repeat until $x >= 20 {
    $x++;
}
$x.say; # OUTPUT: «21␤»

All these forms may produce a return value the same way loop does.

return

The sub return will stop execution of a subroutine or method, run all relevant phasers and provide the given return value to the caller. The default return value is Nil. If a return type constraint is provided it will be checked unless the return value is Nil. If the type check fails the exception X::TypeCheck::Return is thrown. If it passes a control exception is raised and can be caught with CONTROL.

Any return in a block is tied to the first Routine in the outer lexical scope of that block, no matter how deeply nested. Please note that a return in the root of a package will fail at runtime. A return in a block that is evaluated lazily (e.g. inside map) may find the outer lexical routine gone by the time the block is executed. In almost any case last is the better alternative. Please check the functions documentation for more information on how return values are handled and produced.

return-rw

The sub return will return values, not containers. Those are immutable and will lead to runtime errors when attempted to be mutated.

sub s(){ my $a = 41; return $a };
say ++s();
CATCH { default { say .^name, ': ', .Str } };
# OUTPUT: «X::Multi::NoMatch.new(dispatcher …

To return a mutable container, use return-rw.

sub s(){ my $a = 41; return-rw $a };
say ++s();
# OUTPUT: «42␤»

The same rules as for return regarding phasers and control exceptions apply.

fail

Leaves the current routine and returns the provided Exception or Str wrapped inside a Failure, after all relevant phasers are executed. If the caller activated fatal exceptions via the pragma use fatal;, the exception is thrown instead of being returned as a Failure.

sub f { fail "WELP!" };
say f;
CATCH { default { say .^name, ': ', .Str } }
# OUTPUT: «X::AdHoc: WELP!␤»

once

A block prefix with once will be executed exactly once, even if placed inside a loop or a recursive routine.

my $guard = 3;
loop {
    last if $guard-- <= 0;
    once { put 'once' };
    print 'many'
} # OUTPUT: «once␤manymanymany»

This works per "clone" of the containing code object, so:

({ once 42.say } xx 3).map: {$_(), $_()}; # says 42 thrice

Note that this is not a thread-safe construct when the same clone of the same block is run by multiple threads. Also remember that methods only have one clone per class, not per object.

quietly

A quietly block will suppress all warnings generated in it.

quietly { warn 'kaput!' };
warn 'still kaput!';
# OUTPUT: «still kaput! [...]␤»

Any warning generated from any routine called from within the block will also be suppressed:

sub told-you { warn 'hey...' };
quietly { told-you; warn 'kaput!' };
warn 'Only telling you now!'
# OUTPUT: «Only telling you now!␤ [...] ␤»

LABELs

while, until, loop and for loops can all take a label, which can be used to identify them for next, last, and redo. Nested loops are supported, for instance:

OUTAHERE: while True  {
    for 1,2,3 -> $n {
        last OUTAHERE if $n == 2;
    }
}

Labels can be used also within nested loops to name each loop, for instance:

OUTAHERE: 
 loop ( my $i = 1; True; $i++ ) { 
   OUTFOR: 
     for 1,2,3 -> $n { 
       # exits the for loop before its natural end 
       last OUTFOR if $n == 2; 
   } 
 
   # exits the infinite loop 
   last OUTAHERE if $i >= 2; 
 } 

next

The next command starts the next iteration of the loop. So the code

my @x = 1, 2, 3, 4, 5; 
 for @x -> $x { 
     next if $x == 3; 
     print $x; 
 } 

prints "1245".

If the NEXT phaser is present, it runs before the next iteration:

my Int $i = 0; 
 while ($i < 10) { 
   if ($i % 2 == 0) { 
     next; 
   } 
 
   say "$i is odd."; 
 
   NEXT { 
     $i++; 
   } 
 } 
 # OUTPUT: «1 is odd.␤3 is odd.␤5 is odd.␤7 is odd.␤9 is odd.␤» 

In a whenever block, next immediately exits the block for the current value:

react {
    whenever Supply.interval(1) {
        next if .is-prime;
        say $_;
        done if $_ == 4;
    }
}

prints "0", "1" and "4" - integers from 0 to 4 with primes skipped.

*Since version 6.d, the next command in a loop that collects its last statement values returns Empty for the iterations they run on.*

last

The last command immediately exits the loop in question.

my @x = 1, 2, 3, 4, 5; 
 for @x -> $x { 
     last if $x == 3; 
     print $x; 
 } 

prints "12".

If the LAST phaser is present, it runs before exiting the loop:

my Int $i = 1; 
 while ($i < 10) { 
   if ($i % 5 == 0) { 
     last; 
   } 
 
   LAST { 
     say "The last number was $i."; 
   } 
   NEXT { 
     $i++; 
   } 
 } 
 # OUTPUT: «The last number was 5.␤» 

*Since version 6.d, the last command in a loop that collects its last statement values returns Empty for the iterations they run on.*

redo

The redo command restarts the loop block without evaluating the conditional again.

loop { 
     my $x = prompt("Enter a number"); 
     redo unless $x ~~ /\d+/; 
     last; 
 } 

45 Data structures

How Perl 6 deals with data structures and what we can expect from them

Scalar structures

Some classes do not have any internal structure and to access parts of them, specific methods have to be used. Numbers, strings, and some other monolithic classes are included in that class. They use the $ sigil, although complex data structures can also use it.

my $just-a-number = 7;
my $just-a-string = "8";

There is a Scalar class, which is used internally to assign a default value to variables declared with the $ sigil.

my $just-a-number = 333;
say $just-a-number.VAR.^name; # OUTPUT: «Scalar␤»

Any complex data structure can be scalarized by using the item contextualizer $:

(1, 2, 3, $(4, 5))[3].VAR.^name.say; # OUTPUT: «Scalar␤»

However, this means that it will be treated as such in the context they are. You can still access its internal structure.

(1, 2, 3, $(4, 5))[3][0].say; # OUTPUT: «4␤»

An interesting side effect, or maybe intended feature, is that scalarization conserves identity of complex structures.

for ^2 {
     my @list = (1, 1);
     say @list.WHICH;
} # OUTPUT: «Array|93947995146096␤Array|93947995700032␤»

Every time (1, 1) is assigned, the variable created is going to be different in the sense that === will say it is; as it is shown, different values of the internal pointer representation are printed. However

for ^2 {
  my $list = (1, 1);
  say $list.WHICH
} # OUTPUT: «List|94674814008432␤List|94674814008432␤»

In this case, $list is using the Scalar sigil and thus will be a Scalar. Any scalar with the same value will be exactly the same, as shown when printing the pointers.

Complex data structures

Complex data structures fall in two different broad categories: Positional, or list-like and Associative, or key-value pair like, according to how you access its first-level elements. In general, complex data structures, including objects, will be a combination of both, with object properties assimilated to key-value pairs. While all objects subclass Mu, in general complex objects are instances of subclasses of Any. While it is theoretically possible to mix in Positional or Associative without doing so, most methods applicable to complex data structures are implemented in Any.

Navigating these complex data structures is a challenge, but Perl 6 provides a couple of functions that can be used on them: deepmap and duckmap. While the former will go to every single element, in order, and do whatever the block passed requires,

say [[1, 2, [3, 4]],[[5, 6, [7, 8]]]].deepmap( *.elems );
# OUTPUT: «[[1 1 [1 1]] [1 1 [1 1]]]␤»

which returns 1 because it goes to the deeper level and applies elems to them, deepmap can perform more complicated operations:

say [[1, 2, [3, 4]], [[5, 6, [7, 8]]]].duckmap:
   -> $array where .elems == 2 { $array.elems };
# OUTPUT: «[[1 2 2] [5 6 2]]␤»

In this case, it dives into the structure, but returns the element itself if it does not meet the condition in the block (1, 2), returning the number of elements of the array if it does (the two 2s at the end of each subarray).

Since deepmap and duckmap are Any methods, they also apply to Associative arrays:

say %( first => [1, 2], second => [3,4] ).deepmap( *.elems );
# OUTPUT: «{first => [1 1], second => [1 1]}␤»

Only in this case, they will be applied to every list or array that is a value, leaving the keys alone.

Positional and Associative can be turned into each other.

say %( first => [1, 2], second => [3,4] ).list[0];
# OUTPUT: «second => [3 4]␤»

However, in this case, and for Rakudo >= 2018.05, it will return a different value every time it runs. A hash will be turned into a list of the key-value pairs, but it is guaranteed to be disordered. You can also do the operation in the opposite direction, as long as the list has an even number of elements (odd number will result in an error):

say <a b c d>.Hash # OUTPUT: «{a => b, c => d}␤»

But

say <a b c d>.Hash.kv # OUTPUT: «(c d a b)␤»

will obtain a different value every time you run it; kv turns every Pair into a list.

Complex data structures are also generally Iterable. Generating an iterator out of them will allow the program to visit the first level of the structure, one by one:

.say for 'א'..'ס'; # OUTPUT: «א␤ב␤ג␤ד␤ה␤ו␤ז␤ח␤ט␤י␤ך␤כ␤ל␤ם␤מ␤ן␤נ␤ס␤»

'א'..'ס' is a Range, a complex data structure, and with for in front it will iterate until the list is exhausted. You can use for on your complex data structures by overriding the iterator method (from role Iterable):

class SortedArray is Array {
  method iterator() {
    self.sort.iterator
  }
};
my @thing := SortedArray.new([3,2,1,4]);
.say for @thing; # OUTPUT: «1␤2␤3␤4␤»

for calls directly the iterator method on @thing making it return the elements of the array in order. Much more on iterating on the page devoted to it.

Functional structures

Perl 6 is a functional language and, as such, functions are first-class data structures. Functions follow the Callable role, which is the 4th element in the quartet of fundamental roles. Callable goes with the & sigil, although in most cases it is elided for the sake of simplicity; this sigil elimination is always allowed in the case of Callables.

my &a-func= { (^($^þ)).Seq };
say a-func(3), a-func(7); # OUTPUT: «(0 1 2)(0 1 2 3 4 5 6)␤»

Blocks are the simplest callable structures, since Callables cannot be instantiated. In this case we implement a block that logs events and can retrieve them:

my $logger = -> $event, $key = Nil  {
  state %store;
  if ( $event ) {
    %store{ DateTime.new( now ) } = $event;
  } else {
    %store.keys.grep( /$key/ )
  }
}
$logger( "Stuff" );
$logger( "More stuff" );
say $logger( Nil, "2018-05-28" ); # OUTPUT: «(Stuff More stuff)␤»

A Block has a Signature, in this case two arguments, the first of which is the event that is going to be logged, and the second is the key to retrieve the events. They will be used in an independent way, but its intention is to showcase the use of a state variable that is kept from every invocation to the next. This state variable is encapsulated within the block, and cannot be accessed from outside except by using the simple API the block provides: calling the block with a second argument. The two first invocations log two events, the third invocation at the bottom of the example use this second type of call to retrieve the stored values. Blocks can be cloned:

my $clogger = $logger.clone; 
 $clogger( "Clone stuff" ); 
 $clogger( "More clone stuff" ); 
 say $clogger( Nil, "2018-05-28" ); 
 # OUTPUT: «(Clone stuff More clone stuff)␤» 

And cloning will reset the state variable; instead of cloning, we can create façades that change the API. For instance, eliminate the need to use Nil as first argument to retrieve the log for a certain date:

my $gets-logs = $logger.assuming( Nil, * ); 
 $logger( %(changing => "Logs") ); 
 say $gets-logs( "2018-05-28" ); 
 # OUTPUT: «({changing => Logs} Stuff More stuff)␤» 

assuming wraps around a block call, giving a value (in this case, Nil) to the arguments we need, and passing on the arguments to the other arguments we represent using *. In fact, this corresponds to the natural language statement "We are calling $logger assuming the first argument is Nil". We can slightly change the appearance of these two Blocks to clarify they are actually acting on the same block:

my $Logger = $logger.clone; 
 my $Logger::logs = $Logger.assuming( *, Nil ); 
 my $Logger::get = $Logger.assuming( Nil, * ); 
 $Logger::logs( <an array> ); 
 $Logger::logs( %(key => 42) ); 
 say $Logger::get( "2018-05-28" ); 

Although :: is generally used for invocation of class methods, it is actually a valid part of the name of a variable. In this case we use them conventionally to simply indicate $Logger::logs and $Logger::get are actually calling $Logger, which we have capitalized to use a class-like appearance. The point of this tutorial is that using functions as first-class citizens, together with the use of state variables, allows the use of certain interesting design patterns such as this one.

As such first class data structures, callables can be used anywhere another type of data can.

my @regex-check = ( /<alnum>/, /<alpha>/, /<punct>/ );
say @regex-check.map: "33af" ~~ *;
# OUTPUT: «(「3」␤ alnum => 「3」 「a」␤ alpha => 「a」 Nil)␤»

Regexes are actually a type of callable:

say /regex/.does( Callable ); # OUTPUT: «True␤»

And in the example above we are calling regexes stored in an array, and applying them to a string literal.

Callables are composed by using the function composition operator ∘:

my $typer = -> $thing { $thing.^name ~ ' → ' ~ $thing }; 
 my $Logger::withtype = $Logger::logs ∘ $typer; 
 $Logger::withtype( Pair.new( 'left', 'right' ) ); 
 $Logger::withtype( ¾ ); 
 say $Logger::get( "2018-05-28" ); 
 # OUTPUT: «(Pair → left right Rat → 0.75)␤» 

We are composing $typer with the $Logger::logs function defined above, obtaining a function that logs an object preceded by its type, which can be useful for filtering, for instance. $Logger::withtype is, in fact, a complex data structure composed of two functions which are applied in a serial way, but every one of the callables composed can keep state, thus creating complex transformative callables, in a design pattern that is similar to object composition in the object oriented realm. You will have to choose, in every particular case, what is the programming style which is most suitable for your problem.

Defining and constraining data structures

Perl 6 has different ways of defining data structures, but also many ways to constrain them so that you can create the most adequate data structure for every problem domain. but, for example, mixes roles or values into a value or a variable:

my %not-scalar := %(2 => 3) but Associative[Int, Int]; 
 say %not-scalar.^name; # OUTPUT: «Hash+{Associative[Int, Int]}␤» 
 say %not-scalar.of;    # OUTPUT: «Associative[Int, Int]␤» 
 %not-scalar{3} = 4; 
 %not-scalar<thing> = 3; 
 say %not-scalar;       # OUTPUT: «{2 => 3, 3 => 4, thing => 3}␤» 

In this case, but is mixing in the Associative[Int, Int] role; please note that we are using binding so that the type of the variable is the one defined, and not the one imposed by the % sigil; this mixed-in role shows in the name surrounded by curly braces. What does that really mean? That role includes two methods, of and keyof; by mixing the role in, the new of will be called (the old of would return Mu, which is the default value type for Hashes). However, that is all it does. It is not really changing the type of the variable, as you can see since we are using any kind of key and values in the next few statements.

However, we can provide new functionality to a variable using this type of mixin:

role Lastable { 
   method last() { 
     self.sort.reverse[0] 
   } 
 } 
 my %hash-plus := %( 3 => 33, 4 => 44) but Lastable; 
 say %hash-plus.sort[0]; # OUTPUT: «3 => 33␤» 
 say %hash-plus.last;    # OUTPUT: «4 => 44␤» 

In Lastable we use the universal self variable to refer to whatever object this particular role is mixed in; in this case it will contain the hash it is mixed in with; it will contain something else (and possibly work some other way) in other case. This role will provide the last method to any variable it's mixed with, providing new, attachable, functionalities to regular variables. Roles can even be added to existing variables using the does keyword.

Subsets can also be used to constrain the possible values a variable might hold; they are Perl 6 attempt at gradual typing; it is not a full attempt, because subsets are not really types in a strict sense, but they allow runtime type checking. It adds type-checking functionality to regular types, so it helps create a richer type system, allowing things like the one shown in this code:

subset OneOver where (1/$_).Int == 1/$_; 
 my OneOver $one-fraction = ⅓; 
 say $one-fraction; # OUTPUT: «0.333333␤» 

On the other hand, my OneOver $ = ⅔; will cause a type-check error. Subsets can use Whatever, that is, *, to refer to the argument; but this will be instantiated every time you use it to a different argument, so if we use it twice in the definition we would get an error. In this case we are using the topic single variable, $_, to check the instantiation. Subsetting can be done directly, without the need of declaring it, in signatures.

Infinite structures and laziness

It might be assumed that all the data contained in a data structure is actually there. That is not necessarily the case: in many cases, for efficiency reasons or simply because it is not possible, the elements contained in a data structure only jump into existence when they are actually needed. This computation of items as they are needed is called reification or vivification.

# A list containing infinite number of un-reified Fibonacci numbers: 
 my @fibonacci = 1, 1, * + * … ∞; 
 
 # We reify 10 of them, looking up the first 10 of them with array index: 
 say @fibonacci[^10]; # OUTPUT: «(1 1 2 3 5 8 13 21 34 55)␤» 
 
 # We reify 5 more: 10 we already reified on previous line, and we need to 
 # reify 5 more to get the 15th element at index 14. Even though we need only 
 # the 15th element, the original Seq still has to reify all previous elements: 
 say @fibonacci[14]; # OUTPUT: «987␤» 

Above we were reifying a Seq we created with the sequence operator, but other data structures use the concept as well. For example, an un-reified Range is just the two end points. In some languages, calculating the sum of a huge range is a lengthy and memory-consuming process, but Perl 6 calculates it instantly:

say sum 1 .. 9_999_999_999_999; # OUTPUT: «49999999999995000000000000␤»

Why? Because the sum can be calculated without vivifying the Range; that is, without figuring out all the elements it contains. This is why this feature exists. You can even make your own things reify-on-demand, using gather and take:

my $seq = gather {
    say "About to make 1st element"; take 1;
    say "About to make 2nd element"; take 2;
}
say "Let's reify an element!";
say $seq[0];
say "Let's reify more!";
say $seq[1];
say "Both are reified now!";
say $seq[^2];

# OUTPUT:
# Let's reify an element!
# About to make 1st element
# 1
# Let's reify more!
# About to make 2nd element
# 2
# Both are reified now!
# (1 2)

Following the output above, you can see the print statements inside the gather got executed only when we reified the individual elements while looking up an element. Also note that the elements got reified just once. When we printed the same elements again on the last line of the example, the messages inside gather was no longer printed. This is because the construct used already-reified elements from the Seq's cache.

Note that above we assigned the gather to a Scalar container (the $ sigil), not the Positional one (the @ sigil). The reason is that the @-sigiled variables are mostly eager. What this means is they reify the stuff assigned to them right away most of the time. The only time they don't do it is when the items are known to be is-lazy, like our sequence generated with infinity as the end point. Were we to assign the gather to a @-variable, the say statements inside of it would've been printed right away.

Another way to vivify the list fully is by calling .elems on it. This is the reason why checking whether a list contains any items is best done by using .Bool method (or just using if @array { … }), since you don't need to reify all the elements to find out if there are any of them.

There are times where you do want to fully-reify a list before doing something. For example, the IO::Handle.lines returns a Seq. The following code contains a bug; keeping reification in mind, try to spot it:

my $fh = "/tmp/bar".IO.open; 
 my $lines = $fh.lines; 
 close $fh; 
 say $lines[0]; 

We open a filehandle, then assign return of .lines to a Scalar variable, so the returned Seq does not get reified right away. We then close the filehandle, and try to print an element from $lines.

The bug in the code is by the time we reify the $lines Seq on the last line, we've already closed the filehandle. When the Seq's iterator tries to generate the item we've requested, it results in the error about attempting to read from a closed handle. So, to fix the bug we can either assign to a @-sigiled variable or call .elems on $lines before closing the handle:

my $fh = "/tmp/bar".IO.open; 
 my @lines = $fh.lines; 
 close $fh; 
 say @lines[0]; # no problem! 

We can also use any function whose side effect is reification, like .elems mentioned above:

my $fh = "/tmp/bar".IO.open; 
 my $lines = $fh.lines; 
 say "Read $lines.elems() lines"; # reifying before closing handle 
 close $fh; 
 say $lines[0]; # no problem! 

Using eager will also reify the whole sequence:

my $fh = "/tmp/bar".IO.open; 
 my $lines = eager $fh.lines; # Uses eager for reification. 
 close $fh; 
 say $lines[0]; 

Introspection

Languages that allow introspection like Perl 6 have functionalities attached to the type system that let the developer access container and value metadata. This metadata can be used in a program to carry out different actions depending on their value. As it is obvious from the name, metadata are extracted from a value or container via the metaclass.

my $any-object = "random object";
my $metadata = $any-object.HOW;
say $metadata.^mro;                   # OUTPUT: «((ClassHOW) (Any) (Mu))␤»
say $metadata.can( $metadata, "uc" ); # OUTPUT: «(uc uc)␤»

With the first say we show the class hierarchy of the metamodel class, which in this case is Metamodel::ClassHOW. It inherits directly from Any, meaning any method there can be used; it also mixes in several roles which can give you information about the class structure and functions. But one of the methods of that particular class is can, which we can use to look up whether the object can use the uc (uppercase) method, which it obviously can. However, it might not be so obvious in some other cases, when roles are mixed in directly into a variable. For instance, in the case of %hash-plus defined above:

say %hash-plus.^can("last"); # OUTPUT: «(last)␤» 

In this case we are using the syntactic sugar for HOW.method, ^method, to check if your data structure responds to that method; the output, which shows the name of the methods that match, certifies that we can use it.

See also this article on class introspection on how to access class properties and methods, and use it to generate test data for a class; this Advent Calendar article describes the meta-object protocol extensively.

46 Date and time functions

Processing date and time in Perl 6

Perl 6 includes several classes that deal with temporal information: Date, DateTime, Instant and Duration. The three first are dateish, so they mix in the Dateish role, which defines all methods and properties that classes that deal with date should assume. It also includes a class hierarchy of exceptions rooted in X::Temporal.

We will try to illustrate these classes in the next (somewhat extended) example, which can be used to process all files in a directory (by default .) with a particular extension (by default .p6) in a directory, sort them according to their age, and compute how many files have been created per month and how many were modified in certain periods expressed in ranges of months:

sub MAIN( $path = ".", $extension = "p6" ) { 
     my DateTime $right = DateTime.now; 
     my %metadata; 
     my %files-month; 
     my %files-period; 
     for dir($path).grep( / \.$extension $/ ) -> $file { 
         CATCH { 
             when X::Temporal { say "Date-related problem", .payload } 
             when X::IO { say "File-related problem", .payload } 
             default { .payload.say } 
         } 
         my Instant $modified = $file.modified; 
         my Instant $accessed = $file.accessed; 
         my Duration $duration = $accessed - $modified; 
         my $age = $right - DateTime($accessed); 
         my $time-of-day = $file.changed.DateTime.hh-mm-ss but Dateish; 
         my $file-changed-date =  $file.changed.Date; 
         %metadata{$file} = %( modified => $modified, 
                               accessed => $accessed, 
                               age => $age, 
                               difference => $duration, 
                               changed-tod => $time-of-day, 
                               changed-date => $file-changed-date); 
         %files-month{$file-changed-date.month}++; 
         given $file-changed-date { 
             when Date.new("2018-01-01")..^Date.new("2018-04-01") { %files-period<pre-grant>++} 
             when Date.new("2018-04-01")..Date.new("2018-05-31") { %files-period<grant>++} 
             default { %files-period<post-grant>++}; 
         } 
     } 
 
     %metadata.sort( { $^a.value<age> <=> $^b.value<age> } ).map: { 
         say $^x.key, ", ", 
         $^x.value<accessed modified age difference changed-tod changed-date>.join(", "); 
     }; 
     %files-month.keys.sort.map: { 
         say "Month $^x → %files-month{$^x}" 
     }; 
 
     %files-period.keys.map: { 
         say "Period $^x → %files-period{$^x}" 
     }; 
 } 

DateTime is used in line 6 to contain the current date and time returned by now.

A CATCH phaser is declared in lines 11 to 15. Its main mission is to distinguish between DateTime-related exceptions and other types. These kind of exception can arise from invalid formats or timezone clashes. Barring some corruption of the file attributes, both are impossible, but in any case they should be caught and separated from other types of exceptions.

We use Instants in lines 16-17 to represent the moment in which the files where accessed and modified. An Instant is measured in atomic seconds, and is a very low-level description of a time event; however, the Duration declared in line 18 represent the time transcurred among two different Instants, and we will be using it to represent the age.

For some variables we might be interested in dealing with them with some dateish traits. $time-of-day contains the time of the day the file was changed; changed will return an Instant, but it is converted into a Date (which is Dateish while Instant is not) and then the time of day is extracted from that. $time-of-day will have «Str+{Dateish}␤» type.

We will use the date in this variable to find out the period when the files were changed.

Date.new("2018-01-01")..^Date.new("2018-04-01")

creates a date Range and $file-changed-date is smartmatched against it. Dates can be used this way; in this case it creates a Range that excludes its last element.

This very variable is also used to compute the month of the year when the file was modified. Date is obviously Dateish and then has the month method to extract that property from it.

Duration objects can be compared. This is used in

%metadata.sort({ 
     $^a.value<age> <=> $^b.value<age> 
 }); 

to sort the files by age.

47 Enumeration

An example using the enum type

The enum type is much more complex in Perl 6 than in some other languages, and the details are found in its type description.

This short document will give a simple example of its use as is the usual practice in C-like languages.

Say we have a program that needs to write to various directories; we want a function that, given a directory name, tests it for (1) its existence and (2) whether it can be written to by the user of the program; this implies that there are three possible states from the user perspective: either you can write (CanWrite), or there is no directory (NoDir) or the directory exists, but you cannot write (NoWrite). The results of the test will determine what actions the program takes next.

enum DirStat <CanWrite NoDir NoWrite>; 
 sub check-dir-status($dir --> DirStat) { 
     if $dir.IO.d { 
         # dir exists, can the program user write to it? 
         my $f = "$dir/.tmp"; 
         spurt $f, "some text"; 
         CATCH { 
             # unable to write for some reason 
             return NoWrite; 
         } 
         # if we get here we must have successfully written to the dir 
         unlink $f; 
         return CanWrite; 
     } 
     # if we get here the dir must not exist 
     return NoDir; 
 } 
 
 # test each of three directories by a non-root user 
 my $dirs = 
     '/tmp',  # normally writable by any user 
     '/',     # writable only by root 
     '~/tmp'; # a non-existent dir in the user's home dir 
 for $dirs -> $dir { 
     my $stat = check-dir-status $dir; 
     say "status of dir '$dir': $stat"; 
     if $stat ~~ CanWrite { 
         say "  user can write to dir: $dir"; 
     } 
 } 
 # output 
 #   status of dir '/tmp': CanWrite 
 #     user can write to dir: /tmp 
 #   status of dir '/': NoWrite 
 #   status of dir '~/tmp': NoDir 

48 Exceptions

Using exceptions in Perl 6

Exceptions in Perl 6 are objects that hold information about errors. An error can be, for example, the unexpected receiving of data or a network connection no longer available, or a missing file. The information that an exception object stores is, for instance, a human-readable message about the error condition, the backtrace of the raising of the error, and so on.

All built-in exceptions inherit from Exception, which provides some basic behavior, including the storage of a backtrace and an interface for the backtrace printer.

Ad hoc exceptions

Ad hoc exceptions can be used by calling die with a description of the error:

die "oops, something went wrong";
# RESULT: «oops, something went wrong in block <unit> at my-script.p6:1␤»

It is worth noting that die prints the error message to the standard error $*ERR.

Typed exceptions

Typed exceptions provide more information about the error stored within an exception object.

For example, if while executing .zombie copy on an object, a needed path foo/bar becomes unavailable, then an X::IO::DoesNotExist exception can be raised:

die X::IO::DoesNotExist.new(:path("foo/bar"), :trying("zombie copy"))

# RESULT: «Failed to find 'foo/bar' while trying to do '.zombie copy'
#          in block <unit> at my-script.p6:1»

Note how the object has provided the backtrace with information about what went wrong. A user of the code can now more easily find and correct the problem.

Catching exceptions

It's possible to handle exceptional circumstances by supplying a CATCH block:

die X::IO::DoesNotExist.new(:path("foo/bar"), :trying("zombie copy"));

CATCH {
    when X::IO { $*ERR.say: "some kind of IO exception was caught!" }
}

# OUTPUT: «some kind of IO exception was caught!»

Here, we are saying that if any exception of type X::IO occurs, then the message some kind of IO exception was caught! will be sent to stderr, which is what $*ERR.say does, getting displayed on whatever constitutes the standard error device in that moment, which will probably be the console by default.

A CATCH block uses smartmatching similar to how given/when smartmatches on options, thus it's possible to catch and handle various categories of exceptions inside a when block.

To handle all exceptions, use a default statement. This example prints out almost the same information as the normal backtrace printer.

CATCH {
     default {
         $*ERR.say: .message;
         for .backtrace.reverse {
             next if .file.starts-with('SETTING::');
             next unless .subname;
             $*ERR.say: "  in block {.subname} at {.file} line {.line}";
         }
     }
}

Note that the match target is a role. To allow user defined exceptions to match in the same manner, they must implement the given role. Just existing in the same namespace will look alike but won't match in a CATCH block.

Exception handlers and enclosing blocks

After a CATCH has handled the exception, the block enclosing the CATCH block is exited.

In other words, even when the exception is handled successfully, the rest of the code in the enclosing block will never be executed.

die "something went wrong ...";

CATCH {
    # will definitely catch all the exception
    default { .Str.say; }
}

say "This won't be said.";   # but this line will be never reached since
                             # the enclosing block will be exited immediately
# OUTPUT: «something went wrong ...␤»

Compare with this:

CATCH {

  CATCH {
      default { .Str.say; }
  }

  die "something went wrong ...";

}

say "Hi! I am at the outer block!"; # OUTPUT: «Hi! I am at the outer block!␤»

See Resuming of exceptions, for how to return control back to where the exception originated.

try blocks

A try block is a normal block which implicitly turns on the use fatal pragma and includes an implicit CATCH block that drops the exception, which means you can use it to contain them. Caught exceptions are stored inside the $! variable, which holds a value of type Exception.

A normal block like this one will simply fail:

{ 
     my $x = +"a"; 
     say $x.^name; 
 } # OUTPUT: «Failure␤» 

However, a try block will contain the exception and put it into the $! variable:

try { 
     my $x = +"a"; 
     say $x.^name; 
 } 
 
 if $! { say "Something failed!" } # OUTPUT: «Something failed!␤» 
 say $!.^name;                     # OUTPUT: «X::Str::Numeric␤» 

Any exception that is thrown in such a block will be caught by a CATCH block, either implicit or provided by the user. In the latter case, any unhandled exception will be rethrown. If you choose not to handle the exception, they will be contained by the block.

try { 
     die "Tough luck"; 
     say "Not gonna happen"; 
 } 
 
 try { 
     fail "FUBAR"; 
 } 

In both try blocks above, exceptions will be contained within the block, but the say statement will not be run. We can handle them, though:

class E is Exception { method message() { "Just stop already!" } }

try {
    E.new.throw; # this will be local

    say "This won't be said.";
}

say "I'm alive!";

try {
    CATCH {
        when X::AdHoc { .Str.say; .resume }
    }

    die "No, I expect you to DIE Mr. Bond!";

    say "I'm immortal.";

    E.new.throw;

    say "No, you don't!";
}

Which would output:

I'm alive! 
 No, I expect you to DIE Mr. Bond! 
 I'm immortal. 
 Just stop already! 
   in block <unit> at exception.p6 line 21 

Since the CATCH block is handling just the X::AdHoc exception thrown by the die statement, but not the E exception. In the absence of a CATCH block, all exceptions will be contained and dropped, as indicated above. resume will resume execution right after the exception has been thrown; in this case, in the die statement. Please consult the section on resuming of exceptions for more information on this.

A try-block is a normal block and as such treats its last statement as the return value of itself. We can therefore use it as a right-hand side.

say try { +"99999" } // "oh no"; # OUTPUT: «99999␤» 
 say try { +"hello" } // "oh no"; # OUTPUT: «oh no␤» 

Try blocks support else blocks indirectly by returning the return value of the expression or Nil if an exception was thrown.

with try +"♥" {
    say "this is my number: $_"
} else {
    say "not my number!"
}
# OUTPUT: «not my number!␤»

try can also be used with a statement instead of a block, that is, as a statement prefix:

say try "some-filename.txt".IO.slurp // "sane default"; 
 # OUTPUT: «sane default␤» 

What try actually causes is, via the use fatal pragma, an immediate throw of the exceptions that happen within its scope, but by doing so the CATCH block is invoked from the point where the exception is thrown, which defines its scope.

my $error-code = "333"; 
 sub bad-sub { 
     die "Something bad happened"; 
 } 
 try { 
     my $error-code = "111"; 
     bad-sub; 
 
     CATCH { 
         default { 
             say "Error $error-code ", .^name, ': ',.Str 
         } 
     } 
 } 
 # OUTPUT: «Error 111 X::AdHoc: Something bad happened␤» 

Throwing exceptions

Exceptions can be thrown explicitly with the .throw method of an Exception object.

This example throws an AdHoc exception, catches it and allows the code to continue from the point of the exception by calling the .resume method.

{
    X::AdHoc.new(:payload<foo>).throw;
    "OHAI".say;
    CATCH {
        when X::AdHoc { .resume }
    }
}

"OBAI".say;

# OUTPUT: «OHAI␤OBAI␤»

If the CATCH block doesn't match the exception thrown, then the exception's payload is passed on to the backtrace printing mechanism.

{
    X::AdHoc.new(:payload<foo>).throw;
    "OHAI".say;
    CATCH {  }
}

"OBAI".say;

# RESULT: «foo
#          in block <unit> at my-script.p6:1»

This next example doesn't resume from the point of the exception. Instead, it continues after the enclosing block, since the exception is caught, and then control continues after the CATCH block.

{
    X::AdHoc.new(:payload<foo>).throw;
    "OHAI".say;
    CATCH {
        when X::AdHoc { }
    }
}

"OBAI".say;

# OUTPUT: «OBAI␤»

throw can be viewed as the method form of die, just that in this particular case, the sub and method forms of the routine have different names.

Resuming of exceptions

Exceptions interrupt control flow and divert it away from the statement following the statement that threw it. Any exception handled by the user can be resumed and control flow will continue with the statement following the statement that threw the exception. To do so, call the method .resume on the exception object.

CATCH { when X::AdHoc { .resume } }         # this is step 2

die "We leave control after this.";         # this is step 1

say "We have continued with control flow."; # this is step 3

Resuming will occur right after the statement that has caused the exception, and in the innermost call frame:

sub bad-sub { 
     die "Something bad happened"; 
     return "not returning"; 
 } 
 
 { 
     my $return = bad-sub; 
     say "Returned $return"; 
     CATCH { 
         default { 
             say "Error ", .^name, ': ',.Str; 
             $return = '0'; 
             .resume; 
 
         } 
     } 
 } 
 # OUTPUT: 
 # Error X::AdHoc: Something bad happened 
 # Returned not returning 

In this case, .resume is getting to the return statement that happens right after the die statement. Please note that the assignment to $return is taking no effect, since the CATCH statement is happening inside the call to bad-sub, which, via the return statement, assigns the not returning value to it.

Uncaught exceptions

If an exception is thrown and not caught, it causes the program to exit with a non-zero status code, and typically prints a message to the standard error stream of the program. This message is obtained by calling the gist method on the exception object. You can use this to suppress the default behavior of printing a backtrace along with the message:

class X::WithoutLineNumber is X::AdHoc {
    multi method gist(X::WithoutLineNumber:D:) {
        $.payload
    }
}
die X::WithoutLineNumber.new(payload => "message")

# prints "message\n" to $*ERR and exits, no backtrace

Control exceptions

Control exceptions are raised when throwing an Exception which does the X::Control role (since Rakudo 2019.03). They are usually thrown by certain keywords and are handled either automatically or by the appropriate phaser. Any unhandled control exception is converted to a normal exception.

{ return; CATCH { default { $*ERR.say: .^name, ': ', .Str } } } 
 # OUTPUT: «X::ControlFlow::Return: Attempt to return outside of any Routine␤» 
 # was CX::Return 

49 Functions

Functions and functional programming in Perl 6

Routines are one of the means Perl 6 has to reuse code. They come in several forms, most notably methods, which belong in classes and roles and are associated with an object; and functions (also called subroutines or subs, for short), which can be called independently of objects.

Subroutines default to lexical (my) scoping, and calls to them are generally resolved at compile time.

Subroutines can have a signature, also called parameter list, which specifies which, if any, arguments the signature expects. It can specify (or leave open) both the number and types of arguments, and the return value.

Introspection on subroutines is provided via Routine.

Defining/Creating/Using functions

Subroutines

The basic way to create a subroutine is to use the sub declarator followed by an optional identifier:

sub my-func { say "Look ma, no args!" }
my-func;

The sub declarator returns a value of type Sub that can be stored in any container:

my &c = sub { say "Look ma, no name!" }
c;     # OUTPUT: «Look ma, no name!␤»

my Any:D $f = sub { say 'Still nameless...' }
$f();  # OUTPUT: «Still nameless...␤»

my Code \a = sub { say ‚raw containers don't implement postcircumfix:<( )>‘ };
a.();  # OUTPUT: «raw containers don't implement postcircumfix:<( )>␤»

The declarator sub will declare a new name in the current scope at compile time. As such, any indirection has to be resolved at compile time:

constant aname = 'foo';
sub ::(aname) { say 'oi‽' };
foo;

This will become more useful once macros are added to Perl 6.

To have the subroutine take arguments, a signature goes between the subroutine's name and its body, in parentheses:

sub exclaim  ($phrase)  { 
     say $phrase ~ "!!!!" 
 } 
 exclaim "Howdy, World"; 

By default, subroutines are lexically scoped. That is, sub foo {...} is the same as my sub foo {...} and is only defined within the current scope.

sub escape($str) { 
     # Puts a slash before non-alphanumeric characters 
     S:g[<-alpha -digit>] = "\\$/" given $str 
 } 
 
 say escape 'foo#bar?'; # OUTPUT: «foo\#bar\?␤» 
 
 { 
     sub escape($str) { 
         # Writes each non-alphanumeric character in its hexadecimal escape 
         S:g[<-alpha -digit>] = "\\x[{ $/.ord.base(16) }]" given $str 
     } 
 
     say escape 'foo#bar?' # OUTPUT: «foo\x[23]bar\x[3F]␤» 
 } 
 
 # Back to original escape function 
 say escape 'foo#bar?'; # OUTPUT: «foo\#bar\?␤» 

Subroutines don't have to be named. If unnamed, they're called anonymous subroutines.

say sub ($a, $b) { $a ** 2 + $b ** 2 }(3, 4) # OUTPUT: «25␤»

But in this case, it's often desirable to use the more succinct block syntax. Subroutines and blocks can be called in place, as in the example above.

say -> $a, $b { $a ** 2 + $b ** 2 }(3, 4)    # OUTPUT: «25␤»

Or even

say { $^a ** 2 + $^b ** 2 }(3, 4)            # OUTPUT: «25␤»

Blocks and lambdas

Whenever you see something like { $_ + 42 }, -> $a, $b { $a ** $b }, or { $^text.indent($:spaces) }, that's Block syntax; the -> is considered also part of the block. Statements such as if, for, while are followed by these kind of blocks.

for 1, 2, 3, 4 -> $a, $b {
    say $a ~ $b;
}
# OUTPUT: «12␤34␤»

They can also be used on their own as anonymous blocks of code.

say { $^a ** 2 + $^b ** 2}(3, 4) # OUTPUT: «25␤»

Please note that this implies that, despite the fact that statements such as if do not define a topic variable, they actually can:

my $foo = 33; 
 if $foo ** 33 -> $a { 
     say "$a is not null"; # 
 } # OUTPUT: «129110040087761027839616029934664535539337183380513 is not null␤» 

For block syntax details, see the documentation for the Block type.

Signatures

The parameters that a function accepts are described in its signature.

sub format (Str $s)  { ... } 
 ->  $a, $b  { ... } 

Details about the syntax and use of signatures can be found in the documentation on the Signature class.

Automatic signatures

If no signature is provided but either of the two automatic variables @_ or %_ are used in the function body, a signature with *@_ or *%_ will be generated. Both automatic variables can be used at the same time.

sub s { say @_, %_ };
say &s.signature # OUTPUT: «(*@_, *%_)␤»

Arguments

Arguments are supplied as a comma separated list. To disambiguate nested calls, use parentheses:

sub f(&c){ c() * 2 }; # call the function reference c with empty parameter list
sub g($p){ $p - 2 };
say(g(42), 45);       # pass only 42 to g()

When calling a function, positional arguments should be supplied in the same order as the function's signature. Named arguments may be supplied in any order, but it's considered good form to place named arguments after positional arguments. Inside the argument list of a function call, some special syntax is supported:

sub f(|c){};
f :named(35);     # A named argument (in "adverb" form)
f named => 35;    # Also a named argument
f :35named;       # A named argument using abbreviated adverb form
f 'named' => 35;  # Not a named argument, a Pair in a positional argument
my \c = <a b c>.Capture;
f |c;             # Merge the contents of Capture $c as if they were supplied

Arguments passed to a function are conceptually first collected in a Capture container. Details about the syntax and use of these containers can be found in the documentation on the Capture class.

When using named arguments, note that normal List "pair-chaining" allows one to skip commas between named arguments.

sub f(|c){};
f :dest</tmp/foo> :src</tmp/bar> :lines(512);
f :32x :50y :110z;   # This flavor of "adverb" works, too
f :a:b:c;            # The spaces are also optional.

Return values

Any Block or Routine will provide the value of its last expression as a return value to the caller. If either return or return-rw is called, then its parameter, if any, will become the return value. The default return value is Nil.

sub a { 42 };
sub b { say a };
sub c { };
b;     # OUTPUT: «42␤»
say c; # OUTPUT: «Nil␤»

Multiple return values are returned as a list or by creating a Capture. Destructuring can be used to untangle multiple return values.

sub a { 42, 'answer' };
put a.perl;
# OUTPUT: «(42, "answer")␤»

my ($n, $s) = a;
put [$s, $n];
# OUTPUT: «answer 42␤»

sub b { <a b c>.Capture };
put b.perl;
# OUTPUT: «\("a", "b", "c")␤»

Return type constraints

Perl 6 has many ways to specify a function's return type:

sub foo(--> Int)      {}; say &foo.returns; # OUTPUT: «(Int)␤» 
sub foo() returns Int {}; say &foo.returns; # OUTPUT: «(Int)␤» 
sub foo() of Int      {}; say &foo.returns; # OUTPUT: «(Int)␤» 
my Int sub foo()      {}; say &foo.returns; # OUTPUT: «(Int)␤» 

Attempting to return values of another type will cause a compilation error.

sub foo() returns Int { "a"; }; foo; # Type check fails 

returns and of are equivalent, and both take only a Type since they are declaring a trait of the Callable. The last declaration is, in fact, a type declaration, which obviously can take only a type. In the other hand, --> can take either undefined or definite values.

Note that Nil and Failure are exempt from return type constraints and can be returned from any routine, regardless of its constraint:

sub foo() returns Int { fail   }; foo; # Failure returned 
 sub bar() returns Int { return }; bar; # Nil returned 

Multi-dispatch

Perl 6 allows for writing several routines with the same name but different signatures. When the routine is called by name, the runtime environment determines the proper candidate and invokes it.

Each candidate is declared with the multi keyword. Dispatch happens depending on the number (arity), type and name of arguments. Consider the following example:

# version 1 
 multi happy-birthday( $name ) { 
     say "Happy Birthday $name !"; 
 } 
 
 # version 2 
 multi happy-birthday( $name, $age ) { 
     say "Happy {$age}th Birthday $name !"; 
 } 
 
 # version 3 
 multi happy-birthday( :$name, :$age, :$title  = 'Mr' ) { 
     say "Happy {$age}th Birthday $title $name !"; 
 } 
 
 
 # calls version 1 (arity) 
 happy-birthday 'Larry';                        # OUTPUT: «Happy Birthday Larry !␤» 
 # calls version 2 (arity) 
 happy-birthday 'Luca', 40;                     # OUTPUT: «Happy 40th Birthday Luca !␤» 
 # calls version 3 
 # (named arguments win against arity) 
 happy-birthday( age => '50', name => 'John' ); # OUTPUT: «Happy 50th Birthday Mr John !␤» 
 # calls version 2 (arity) 
 happy-birthday( 'Jack', 25 );                  # OUTPUT: «Happy 25th Birthday Jack !␤» 
 

The first two versions of the happy-birthday sub differs only in the arity (number of arguments), while the third version uses named arguments and is chosen only when named arguments are used, even if the arity is the same of another multi candidate.

When two sub have the same arity, the type of the arguments drive the dispatch; when there are named arguments they drive the dispatch even when their type is the same as another candidate:

multi happy-birthday( Str $name, Int $age ) { 
     say "Happy {$age}th Birthday $name !"; 
 } 
 
 multi happy-birthday( Str $name, Str $title ) { 
     say "Happy Birthday $title $name !"; 
 } 
 
 multi happy-birthday( Str :$name, Int :$age ) { 
     say "Happy Birthday $name, you turned $age !"; 
 } 
 
 happy-birthday 'Luca', 40;                 # OUTPUT: «Happy 40th Birthday Luca !␤» 
 happy-birthday 'Luca', 'Mr';               # OUTPUT: «Happy Birthday Mr Luca !␤» 
 happy-birthday age => 40, name => 'Luca';  # OUTPUT: «Happy Birthday Luca, you turned 40 !␤» 
 

Named parameters participate in the dispatch even if they are not provided in the call. Therefore a multi candidate with named parameters will be given precedence.

For more information about type constraints see the documentation for the Signature class.

multi as-json(Bool $d) { $d ?? 'true' !! 'false'; }
multi as-json(Real $d) { ~$d }
multi as-json(@d)      { sprintf '[%s]', @d.map(&as-json).join(', ') }

say as-json( True );                        # OUTPUT: «true␤»
say as-json( 10.3 );                        # OUTPUT: «10.3␤»
say as-json( [ True, 10.3, False, 24 ] );   # OUTPUT: «[true, 10.3, false, 24]␤»

multi without any specific routine type always defaults to a sub, but you can use it on methods as well. The candidates are all the multi methods of the object:

class Congrats {
    multi method congratulate($reason, $name) {
        say "Hooray for your $reason, $name";
    }
}

role BirthdayCongrats {
    multi method congratulate('birthday', $name) {
        say "Happy birthday, $name";
    }
    multi method congratulate('birthday', $name, $age) {
        say "Happy {$age}th birthday, $name";
    }
}

my $congrats = Congrats.new does BirthdayCongrats;

$congrats.congratulate('promotion','Cindy'); # OUTPUT: «Hooray for your promotion, Cindy␤»
$congrats.congratulate('birthday','Bob');    # OUTPUT: «Happy birthday, Bob␤»

Unlike sub, if you use named parameters with multi methods, the parameters must be required parameters to behave as expected.

Please note that a non-multi sub or operator will hide multi candidates of the same name in any parent scope or child scope. The same is true for imported non-multi candidates.

proto

proto is a way to formally declare commonalities between multi candidates. It acts as a wrapper that can validate but not modify arguments. Consider this basic example:

proto congratulate(Str $reason, Str $name, |) {*}
multi congratulate($reason, $name) {
   say "Hooray for your $reason, $name";
}
multi congratulate($reason, $name, Int $rank) {
   say "Hooray for your $reason, $name -- got rank $rank!";
}

congratulate('being a cool number', 'Fred');     # OK
congratulate('being a cool number', 'Fred', 42); # OK
congratulate('being a cool number', 42);         # Proto match error 

The proto insists that all multi congratulate subs conform to the basic signature of two strings, optionally followed by further parameters. The | is an un-named Capture parameter, and allows a multi to take additional arguments. The first two calls succeed, but the third fails (at compile time) because 42 doesn't match Str.

say &congratulate.signature # OUTPUT: «(Str $reason, Str $name, | is raw)␤» 

You can give the proto a function body, and place the {*} where you want the dispatch to be done.

# attempts to notify someone -- False if unsuccessful
proto notify(Str $user, Str $msg) {
   my \hour = DateTime.now.hour;
   if hour > 8 or hour < 22 {
      return {*};
   } else {
      # we can't notify someone when they might be sleeping
      return False;
   }
}

{*} always dispatches to candidates with the parameters it's called with. Parameter defaults and type coercions will work but are not passed on.

proto mistake-proto(Str() $str, Int $number = 42) {*} 
 multi mistake-proto($str, $number) { say $str.^name } 
 mistake-proto(7, 42);  # OUTPUT: «Int␤» -- not passed on 
mistake-proto('test'); # fails -- not passed on 

only

The only keyword preceding sub or method indicates that it will be the only function with that name that inhabits a given namespace.

only sub you () {"Can make all the world seem right"};

This will make other declarations in the same namespace, such as

sub you ( $can ) { "Make the darkness bright" }

fail with an exception of type X::Redeclaration. only is the default value for all subs; in the case above, not declaring the first subroutine as only will yield exactly the same error; however, nothing prevents future developers from declaring a proto and preceding the names with multi. Using only before a routine is a defensive programming feature that declares the intention of not having routines with the same name declared in the same namespace in the future.

(exit code 1) 
 ===SORRY!=== Error while compiling /tmp/only-redeclaration.p6 
 Redeclaration of routine 'you' (did you mean to declare a multi-sub?) 
 at /tmp/only-redeclaration.p6:3 
 ------> <BOL>⏏<EOL> 

Anonymous sub cannot be declared only. only sub {}' will throw an error of type, surprisingly, X::Anon::Multi.

Conventions and idioms

While the dispatch system described above provides a lot of flexibility, there are some conventions that most internal functions, and those in many modules, will follow.

Slurpy conventions

Perhaps the most important one of these conventions is the way slurpy list arguments are handled. Most of the time, functions will not automatically flatten slurpy lists. The rare exceptions are those functions that don't have a reasonable behavior on lists of lists (e.g., chrs) or where there is a conflict with an established idiom (e.g., pop being the inverse of push).

If you wish to match this look and feel, any Iterable argument must be broken out element-by-element using a **@ slurpy, with two nuances:

This can be achieved by using a slurpy with a + or +@ instead of **:

sub grab(+@a) { "grab $_".say for @a }

which is shorthand for something very close to:

multi sub grab(**@a) { "grab $_".say for @a }
multi sub grab(\a) {
    a ~~ Iterable and a.VAR !~~ Scalar ?? nextwith(|a) !! nextwith(a,)
}

This results in the following behavior, which is known as the "single argument rule" and is important to understand when invoking slurpy functions:

grab(1, 2);      # OUTPUT: «grab 1␤grab 2␤» 
 grab((1, 2));    # OUTPUT: «grab 1␤grab 2␤» 
 grab($(1, 2));   # OUTPUT: «grab 1 2␤» 
 grab((1, 2), 3); # OUTPUT: «grab 1 2␤grab 3␤» 

This also makes user-requested flattening feel consistent whether there is one sublist, or many:

grab(flat (1, 2), (3, 4));   # OUTPUT: «grab 1␤grab 2␤grab 3␤grab 4␤» 
 grab(flat $(1, 2), $(3, 4)); # OUTPUT: «grab 1 2␤grab 3 4␤» 
 grab(flat (1, 2));           # OUTPUT: «grab 1␤grab 2␤» 
 grab(flat $(1, 2));          # OUTPUT: «grab 1␤grab 2␤» 

It's worth noting that mixing binding and sigilless variables in these cases requires a bit of finesse, because there is no Scalar intermediary used during binding.

my $a = (1, 2);  # Normal assignment, equivalent to $(1, 2) 
 grab($a);        # OUTPUT: «grab 1 2␤» 
 my $b := (1, 2); # Binding, $b links directly to a bare (1, 2) 
 grab($b);        # OUTPUT: «grab 1␤grab 2␤» 
 my \c = (1, 2);  # Sigilless variables always bind, even with '=' 
 grab(c);         # OUTPUT: «grab 1␤grab 2␤» 

Functions are first-class objects

Functions and other code objects can be passed around as values, just like any other object.

There are several ways to get hold of a code object. You can assign it to a variable at the point of declaration:

my $square = sub (Numeric $x) { $x * $x }
# and then use it:
say $square(6);    # OUTPUT: «36␤»

Or you can reference an existing named function by using the &-sigil in front of it.

sub square($x) { $x * $x };

# get hold of a reference to the function:
my $func = &square

This is very useful for higher order functions, that is, functions that take other functions as input. A simple one is map, which applies a function to each input element:

sub square($x) { $x * $x };
my @squared = map &square,  1..5;
say join ', ', @squared;        # OUTPUT: «1, 4, 9, 16, 25␤»

Infix form

To call a subroutine with 2 arguments like an infix operator, use a subroutine reference surrounded by [ and ].

sub plus { $^a + $^b };
say 21 [&plus] 21;
# OUTPUT: «42␤»

Closures

All code objects in Perl 6 are closures, which means they can reference lexical variables from an outer scope.

sub generate-sub($x) {
    my $y = 2 * $x;
    return sub { say $y };
    #      ^^^^^^^^^^^^^^  inner sub, uses $y
}
my $generated = generate-sub(21);
$generated(); # OUTPUT: «42␤»

Here, $y is a lexical variable inside generate-sub, and the inner subroutine that is returned uses it. By the time that inner sub is called, generate-sub has already exited. Yet the inner sub can still use $y, because it closed over the variable.

Another closure example is the use of map to multiply a list of numbers:

my $multiply-by = 5;
say join ', ', map { $_ * $multiply-by }, 1..5;     # OUTPUT: «5, 10, 15, 20, 25␤»

Here, the block passed to map references the variable $multiply-by from the outer scope, making the block a closure.

Languages without closures cannot easily provide higher-order functions that are as easy to use and powerful as map.

Routines

Routines are code objects that conform to type Routine, most notably Sub, Method, Regex and Submethod.

They carry extra functionality in addition to what a Block supplies: they can come as multis, you can wrap them, and exit early with return:

my $keywords = set <if for unless while>;

sub has-keyword(*@words) {
    for @words -> $word {
        return True if $word (elem) $keywords;
    }
    False;
}

say has-keyword 'not', 'one', 'here';       # OUTPUT: «False␤»
say has-keyword 'but', 'here', 'for';       # OUTPUT: «True␤»

Here, return doesn't just leave the block inside which it was called, but the whole routine. In general, blocks are transparent to return, they attach to the outermost routine.

Routines can be inlined and as such provide an obstacle for wrapping. Use the pragma use soft; to prevent inlining to allow wrapping at runtime.

sub testee(Int $i, Str $s){
    rand.Rat * $i ~ $s;
}

sub wrap-to-debug(&c){
    say "wrapping {&c.name} with arguments {&c.signature.perl}";
    &c.wrap: sub (|args){
        note "calling {&c.name} with {args.gist}";
        my \ret-val := callwith(|args);
        note "returned from {&c.name} with return value {ret-val.perl}";
        ret-val
    }
}

my $testee-handler = wrap-to-debug(&testee);
# OUTPUT: «wrapping testee with arguments :(Int $i, Str $s)»

say testee(10, "ten");
# OUTPUT: «calling testee with \(10, "ten")␤returned from testee with return value "6.151190ten"␤6.151190ten»
&testee.unwrap($testee-handler);
say testee(10, "ten");
# OUTPUT: «6.151190ten␤»
Important ones: candidates, wrap, unwrap, assuming, arity, count

Defining operators

Operators are just subroutines with funny names. The funny names are composed of the category name (infix, prefix, postfix, circumfix, postcircumfix), followed by a colon, and a list of the operator name or names (two components in the case of circumfix and postcircumfix).

This works both for adding multi candidates to existing operators and for defining new ones. In the latter case, the definition of the new subroutine automatically installs the new operator into the grammar, but only in the current lexical scope. Importing an operator via use or import also makes it available.

# adding a multi candidate to an existing operator: 
 multi infix:<+>(Int $x, "same") { 2 * $x }; 
 say 21 + "same";            # OUTPUT: «42␤» 
 
 # defining a new operator 
 sub postfix:<!>(Int $x where { $x >= 0 }) { [*] 1..$x }; 
 say 6!;                     # OUTPUT: «720␤» 

The operator declaration becomes available as soon as possible, so you can recurse into a just-defined operator:

sub postfix:<!>(Int $x where { $x >= 0 }) { 
     $x == 0 ?? 1 !! $x * ($x - 1)! 
 } 
 say 6!;                     # OUTPUT: «720␤» 

Circumfix and postcircumfix operators are made of two delimiters, one opening and one closing.

sub circumfix:<START END>(*@elems) { 
     "start", @elems, "end" 
 } 
 
 say START 'a', 'b', 'c' END;        # OUTPUT: «(start [a b c] end)␤» 

Postcircumfixes also receive the term after which they are parsed as an argument:

sub postcircumfix:<!! !!>($left, $inside) { 
     "$left -> ( $inside )" 
 } 
 say 42!! 1 !!;      # OUTPUT: «42 -> ( 1 )␤» 

Blocks can be assigned directly to operator names. Use a variable declarator and prefix the operator name with a &-sigil.

my &infix:<ieq> = -> |l { [eq] l>>.fc };
say "abc" ieq "Abc";
# OUTPUT: «True␤»

Precedence

Operator precedence in Perl 6 is specified relative to existing operators. The traits is tighter, is equiv and is looser can be provided with an operator to indicate how the precedence of the new operator is related to other, existing ones. More than one trait can be applied.

For example, infix:<*> has a tighter precedence than infix:<+>, and squeezing one in between works like this:

sub infix:<!!>($a, $b) is tighter(&infix:<+>) { 
     2 * ($a + $b) 
 } 
 
 say 1 + 2 * 3 !! 4;     # OUTPUT: «21␤» 

Here, the 1 + 2 * 3 !! 4 is parsed as 1 + ((2 * 3) !! 4), because the precedence of the new !! operator is between that of + and *.

The same effect could have been achieved with:

sub infix:<!!>($a, $b) is looser(&infix:<*>) { ... }

To put a new operator on the same precedence level as an existing operator, use is equiv(&other-operator) instead.

Associativity

When the same operator appears several times in a row, there are multiple possible interpretations. For example:

1 + 2 + 3

could be parsed as

(1 + 2) + 3         # left associative

or as

1 + (2 + 3)         # right associative

For addition of real numbers, the distinction is somewhat moot, because + is mathematically associative.

But for other operators it matters a great deal. For example, for the exponentiation/power operator, infix:<**>:

say 2 ** (2 ** 3);      # OUTPUT: «256␤»
say (2 ** 2) ** 3;      # OUTPUT: «64␤»

Perl 6 has the following possible associativity configurations:

A Assoc Meaning of $a ! $b ! $c
L left ($a ! $b) ! $c
R right $a ! ($b ! $c)
N non ILLEGAL
C chain ($a ! $b) and ($b ! $c)
X list infix:<!>($a; $b; $c)

You can specify the associativity of an operator with the is assoc trait, where left is the default associativity.

sub infix:<§>(*@a) is assoc<list> { 
     '(' ~ @a.join('|') ~ ')'; 
 } 
 
 say 1 § 2 § 3;      # OUTPUT: «(1|2|3)␤» 

Traits

Traits are subroutines that run at compile time and modify the behavior of a type, variable, routine, attribute, or other language object.

Examples of traits are:

class ChildClass is ParentClass { ... } 
 #                ^^ trait, with argument ParentClass 
 has $.attrib is rw; 
 #            ^^^^^  trait with name 'rw' 
 class SomeClass does AnotherRole { ... } 
 #               ^^^^ trait 
 has $!another-attribute handles <close>; 
 #                       ^^^^^^^ trait 

... and also is tighter, is looser, is equiv and is assoc from the previous section.

Traits are subs declared in the form trait_mod<VERB>, where VERB stands for the name like is, does or handles. It receives the modified thing as argument, and the name as a named argument. See Sub for details.

multi sub trait_mod:<is>(Routine $r, :$doubles!) { 
     $r.wrap({ 
         2 * callsame; 
     }); 
 } 
 
 sub square($x) is doubles { 
     $x * $x; 
 } 
 
 say square 3;       # OUTPUT: «18␤» 

See type Routine for the documentation of built-in routine traits.

Re-dispatching

There are cases in which a routine might want to call the next method from a chain. This chain could be a list of parent classes in a class hierarchy, or it could be less specific multi candidates from a multi dispatch, or it could be the inner routine from a wrap.

Fortunately, we have a series of re-dispatching tools that help us to make it easy.

sub callsame

callsame calls the next matching candidate with the same arguments that were used for the current candidate and returns that candidate's return value.

proto a(|) {*} 
 
 multi a(Any $x) { 
     say "Any $x"; 
     return 5; 
 } 
 
 multi a(Int $x) { 
     say "Int $x"; 
     my $res = callsame; 
     say "Back in Int with $res"; 
 } 
 
 a 1;        # OUTPUT: «Int 1␤Any 1␤Back in Int with 5␤» 

sub callwith

callwith calls the next candidate matching the original signature, that is, the next function that could possibly be used with the arguments provided by users and returns that candidate's return value.

proto a(|) {*} 
 
 multi a(Any $x) { 
     say "Any $x"; 
     return 5; 
 } 
 multi a(Int $x) { 
     say "Int $x"; 
     my $res = callwith($x + 1); 
     say "Back in Int with $res"; 
 } 
 
 a 1;        # OUTPUT: «Int 1␤Any 2␤Back in Int with 5␤» 

Here, a 1 calls the most specific Int candidate first, and callwith re-dispatches to the less specific Any candidate. Note that although our parameter $x + 1 is an Int, still we call the next candidate in the chain.

In this case, for example:

proto how-many(|) {*} 
 
 multi how-many( Associative $a ) { 
     say "Associative $a "; 
     my $calling = callwith( 1 => $a ); 
     return $calling; 
 } 
 
 multi how-many( Pair $a ) { 
     say "Pair $a "; 
     return "There is $a " 
 
 } 
 
 multi how-many( Hash $a ) { 
     say "Hash $a"; 
     return "Hashing $a"; 
 } 
 
 my $little-piggy = little => 'piggy'; 
 say $little-piggy.^name;        # OUTPUT: «Pair␤» 
 say &how-many.cando( \( $little-piggy )); 
 # OUTPUT: «(sub how-many (Pair $a) { #`(Sub|68970512) ... } sub how-many (Associative $a) { #`(Sub|68970664) ... })␤» 
 say how-many( $little-piggy  ); # OUTPUT: «Pair little     piggy␤There is little piggy␤» 

the only candidates that take the Pair argument supplied by the user are the two functions defined first. Although a Pair can be easily coerced to a Hash, here is how signatures match:

say :( Pair ) ~~ :( Associative ); # OUTPUT: «True␤» 
 say :( Pair ) ~~ :( Hash );        # OUTPUT: «False␤» 

The arguments provided by us are a Pair. It does not match a Hash, so the corresponding function is thus not included in the list of candidates, as can be seen by the output of &how-many.cando( \( $little-piggy ));.

sub nextsame

nextsame calls the next matching candidate with the same arguments that were used for the current candidate and never returns.

proto a(|) {*} 
 
 multi a(Any $x) { 
     say "Any $x"; 
     return 5; 
 } 
 multi a(Int $x) { 
     say "Int $x"; 
     nextsame; 
     say "never executed because nextsame doesn't return"; 
 } 
 
 a 1;        # OUTPUT: «Int 1␤Any 1␤» 

sub nextwith

nextwith calls the next matching candidate with arguments provided by users and never returns.

proto a(|) {*} 
 
 multi a(Any $x) { 
     say "Any $x"; 
     return 5; 
 } 
 multi a(Int $x) { 
     say "Int $x"; 
     nextwith($x + 1); 
     say "never executed because nextsame doesn't return"; 
 } 
 
 a 1;        # OUTPUT: «Int 1␤Any 2␤» 

sub samewith

samewith calls current candidate again with arguments provided by users and returns return value of the new instance of current candidate.

proto a(|) {*} 
 
 multi a(Int $x) { 
   return 1 unless $x > 1; 
   return $x * samewith($x-1); 
 } 
 
 say (a 10); # OUTPUT: «36288002␤» 

sub nextcallee

Redispatch may be required to call a block that is not the current scope what provides nextsame and friends with the problem to referring to the wrong scope. Use nextcallee to capture the right candidate and call it at the desired time.

proto pick-winner(|) {*} 
 
 multi pick-winner (Int \s) { 
     my &nextone = nextcallee; 
     Promise.in(π²).then: { nextone s } 
 } 
 multi pick-winner { say "Woot! $^w won" } 
 
 with pick-winner ^5 .pick -> \result { 
     say "And the winner is..."; 
     await result; 
 } 
 
 # OUTPUT: 
 # And the winner is... 
 # Woot! 3 won 

The Int candidate takes the nextcallee and then fires up a Promise to be executed in parallel, after some timeout, and then returns. We can't use nextsame here, because it'd be trying to nextsame the Promise's block instead of our original routine.

Wrapped routines

Besides those already mentioned above, re-dispatch is helpful in many more situations. For instance, for dispatching to wrapped routines:

# enable wrapping: 
 use soft; 
 
 # function to be wrapped: 
 sub square-root($x) { $x.sqrt } 
 
 &square-root.wrap(sub ($num) { 
    nextsame if $num >= 0; 
    1i * callwith(abs($num)); 
 }); 
 
 say square-root(4);     # OUTPUT: «2␤» 
 say square-root(-4);    # OUTPUT: «0+2i␤» 

Routines of parent class

Another use case is to re-dispatch to methods from parent classes.

say Version.new('1.0.2') # OUTPUT: v1.0.2 
class LoggedVersion is Version { 
     method new(|c) { 
         note "New version object created with arguments " ~ c.perl; 
         nextsame; 
     } 
 } 
 
 say LoggedVersion.new('1.0.2'); 
 
 # OUTPUT: 
 # New version object created with arguments \("1.0.2") 
 # v1.0.2 

Coercion types

Coercion types force a specific type for routine arguments while allowing the routine itself to accept a wider input. When invoked, the arguments are narrowed automatically to the stricter type, and therefore within the routine the arguments have always the desired type.

In the case the arguments cannot be converted to the stricter type, a Type Check error is thrown.

sub double(Int(Cool) $x) { 
     2 * $x 
 } 
 
 say double '21';# OUTPUT: «42␤» 
 say double  21; # OUTPUT: «42␤» 
 say double Any; # Type check failed in binding $x; expected 'Cool' but got 'Any' 

In the above example, the Int is the target type to which the argument $x will be coerced, and Cool is the type that the routine accepts as wider input.

If the accepted wider input type is Any, it is possible to abbreviate the coercion Int(Any) by omitting the Any type, thus resulting in Int().

The coercion works by looking for a method with the same name as the target type: if such method is found on the argument, it is invoked to convert the latter to the expected narrow type. From the above, it is clear that it is possible to provide coercion among user types just providing the required methods:

class Bar { 
    has $.msg; 
 } 
 
 class Foo { 
    has $.msg = "I'm a foo!"; 
 
    # allows coercion from Foo to Bar 
    method Bar { 
        Bar.new(:msg($.msg ~ ' But I am now Bar.')); 
    } 
 } 
 
 # wants a Bar, but accepts Any 
 sub print-bar(Bar() $bar) { 
    say $bar.^name; # OUTPUT: «Bar␤» 
    say $bar.msg;   # OUTPUT: «I'm a foo! But I am now Bar.␤» 
 } 
 
 print-bar Foo.new; 

In the above code, once a Foo instance is passed as argument to print-bar, the Foo.Bar method is called and the result is placed into $bar.

Coercion types are supposed to work wherever types work, but Rakudo currently (2018.05) only implements them in signatures, for both parameters and return types.

Non-parameter coercion types will theoretically be working in 6.2. Updated the reference above to latest version.

Coercion also works with return types:

sub are-equal (Int $x, Int $y --> Bool(Int) ) { $x - $y }; 
 
 for (2,4) X (1,2) -> ($a,$b) { 
     say "Are $a and $b equal? ", are-equal($a, $b); 
 } #  OUTPUT: «Are 2 and 1 equal? True␤Are 2 and 2 equal? False␤Are 4 and 1 equal? True␤Are 4 and 2 equal? True␤» 

In this case, we are coercing an Int to a Bool, which is then printed (put into a string context) in the for loop that calls the function.

sub MAIN

Declaring a sub MAIN is not compulsory in Perl 6 scripts, but you can provide one to create a command line interface for your script.

50 Grammars

Parsing and interpreting text

Grammar is a powerful tool used to destructure text and often to return data structures that have been created by interpreting that text.

For example, Perl 6 is parsed and executed using a Perl 6-style grammar.

An example that's more practical to the common Perl 6 user is the JSON::Tiny module, which can deserialize any valid JSON file; however, the deserializing code is written in less than 100 lines of simple, extensible code.

If you didn't like grammar in school, don't let that scare you off grammars. Grammars allow you to group regexes, just as classes allow you to group methods of regular code.

Named Regexes

The main ingredient of grammars is named regexes. While the syntax of Perl 6 Regexes is outside the scope of this document, named regexes have a special syntax, similar to subroutine definitions:

In fact, named regexes can even take extra arguments, using the same syntax as subroutine parameter lists

my regex number { \d+ [ \. \d+ ]? } 

In this case, we have to specify that the regex is lexically scoped using the my keyword, because named regexes are normally used within grammars.

Being named gives us the advantage of being able to easily reuse the regex elsewhere:

say so "32.51" ~~ &number;                         # OUTPUT: «True␤» 
 say so "15 + 4.5" ~~ /<number>\s* '+' \s*<number>/ # OUTPUT: «True␤» 

regex isn't the only declarator for named regexes. In fact, it's the least common. Most of the time, the token or rule declarators are used. These are both ratcheting, which means that the match engine won't back up and try again if it fails to match something. This will usually do what you want, but isn't appropriate for all cases:

my regex works-but-slow { .+ q } 
 my token fails-but-fast { .+ q } 
 my $s = 'Tokens won\'t backtrack, which makes them fail quicker!'; 
 say so $s ~~ &works-but-slow; # OUTPUT: «True␤» 
 say so $s ~~ &fails-but-fast; # OUTPUT: «False␤» 
                               # the entire string get taken by the .+ 

Note that non-backtracking works on terms, that is, as the example below, if you have matched something, then you will never backtrack. But when you fail to match, if there is another candidate introduced by | or ||, you will retry to match again.

my token tok-a { .* d  }; 
 my token tok-b { .* d | bd }; 
 say so "bd" ~~ &tok-a;        # OUTPUT: «False␤» 
 say so "bd" ~~ &tok-b;        # OUTPUT: «True␤» 

Rules

The only difference between the token and rule declarators is that the rule declarator causes :sigspace to go into effect for the Regex:

my token non-space-y { 'once' 'upon' 'a' 'time' } 
 my rule space-y { 'once' 'upon' 'a' 'time' } 
 say so 'onceuponatime'    ~~ &non-space-y; # OUTPUT: «True␤» 
 say so 'once upon a time' ~~ &non-space-y; # OUTPUT: «False␤» 
 say so 'onceuponatime'    ~~ &space-y;     # OUTPUT: «False␤» 
 say so 'once upon a time' ~~ &space-y;     # OUTPUT: «True␤» 

Creating grammars

Grammar is the superclass that classes automatically get when they are declared with the grammar keyword instead of class. Grammars should only be used to parse text; if you wish to extract complex data, you can add actions within the grammar, or an action object is recommended to be used in conjunction with the grammar. If action objects are not used, .parse returns a Match object and sets, by default, the default match object $/, to the same value.

Proto regexes

Grammars are composed of rules, tokens and regexes; these are actually methods, since grammars are classes.

They are actually a special kind of class, but for the rest of the section, they behave in the same way as a normal class would

These methods can share a name and functionality in common, and thus can use proto.

For instance, if you have a lot of alternations, it may become difficult to produce readable code or subclass your grammar. In the Actions class below, the ternary in method TOP is less than ideal and it becomes even worse the more operations we add:

grammar Calculator {
    token TOP { [ <add> | <sub> ] }
    rule  add { <num> '+' <num> }
    rule  sub { <num> '-' <num> }
    token num { \d+ }
}

class Calculations {
    method TOP ($/) { make $<add> ?? $<add>.made !! $<sub>.made; }
    method add ($/) { make [+] $<num>; }
    method sub ($/) { make [-] $<num>; }
}

say Calculator.parse('2 + 3', actions => Calculations).made;

# OUTPUT: «5␤»

To make things better, we can use proto regexes that look like :sym<...> adverbs on tokens:

grammar Calculator {
    token TOP { <calc-op> }

    proto rule calc-op          {*}
          rule calc-op:sym<add> { <num> '+' <num> }
          rule calc-op:sym<sub> { <num> '-' <num> }

    token num { \d+ }
}

class Calculations {
    method TOP              ($/) { make $<calc-op>.made; }
    method calc-op:sym<add> ($/) { make [+] $<num>; }
    method calc-op:sym<sub> ($/) { make [-] $<num>; }
}

say Calculator.parse('2 + 3', actions => Calculations).made;

# OUTPUT: «5␤»

In this grammar the alternation has now been replaced with <calc-op>, which is essentially the name of a group of values we'll create. We do so by defining a rule prototype with proto rule calc-op. Each of our previous alternations have been replaced by a new rule calc-op definition and the name of the alternation is attached with :sym<> adverb.

In the class that declares actions, we now got rid of the ternary operator and simply take the .made value from the $<calc-op> match object. And the actions for individual alternations now follow the same naming pattern as in the grammar: method calc-op:sym<add> and method calc-op:sym<sub>.

The real beauty of this method can be seen when you subclass the grammar and action classes. Let's say we want to add a multiplication feature to the calculator:

grammar BetterCalculator is Calculator { 
     rule calc-op:sym<mult> { <num> '*' <num> } 
 } 
 
 class BetterCalculations is Calculations { 
     method calc-op:sym<mult> ($/) { make [*] $<num> } 
 } 
 
 say BetterCalculator.parse('2 * 3', actions => BetterCalculations).made; 
 
 # OUTPUT: «6␤» 

All we had to add are an additional rule and action to the calc-op group and the thing works—all thanks to proto regexes.

Special tokens

TOP

grammar Foo {
    token TOP { \d+ }
}

The TOP token is the default first token attempted to match when parsing with a grammar. Note that if you're parsing with the .parse method, token TOP is automatically anchored to the start and end of the string. If you don't want to parse the whole string, look up .subparse.

Using rule TOP or regex TOP is also acceptable.

A different token can be chosen to be matched first using the :rule named argument to .parse, .subparse, or .parsefile. These are all Grammar methods.

ws

The default ws matches zero or more whitespace characters, as long as that point is not within a word (in code form, that's regex ws { <!ww> \s* }):

# First <.ws> matches word boundary at the start of the line
# and second <.ws> matches the whitespace between 'b' and 'c'
say 'ab   c' ~~ /<.ws> ab <.ws> c /; # OUTPUT: «「ab   c」␤»

# Failed match: there is neither any whitespace nor a word
# boundary between 'a' and 'b'
say 'ab' ~~ /. <.ws> b/;             # OUTPUT: «Nil␤»

# Successful match: there is a word boundary between ')' and 'b'
say ')b' ~~ /. <.ws> b/;             # OUTPUT: «「)b」␤»

Please bear in mind that we're preceding ws with a dot to avoid capturing, which we are not interested in. Since in general whitespace is a separator, this is how it's mostly found.

When rule is used instead of token, :sigspace is enabled by default and any whitespace after terms and closing parenthesis/brackets are turned into a non-capturing call to ws, written as <.ws> where . means non-capturing. That is to say:

rule entry { <key> '=' <value> }

Is the same as:

token entry { <key> <.ws> '=' <.ws> <value> <.ws> }

You can also redefine the default ws token:

grammar Foo {
    rule TOP { \d \d }
}.parse: "4   \n\n 5"; # Succeeds

grammar Bar {
    rule TOP { \d \d }
    token ws { \h*   }
}.parse: "4   \n\n 5"; # Fails

And even capture it, but you need to use it explicitly:

grammar Foo { rule TOP {\d <ws> \d} }; 
 my $parsed = Foo.parse: "3 3"; 
 say $parsed<ws>; # OUTPUT: «「」␤» 

sym

The <sym> token can be used inside proto regexes to match the string value of the :sym adverb for that particular regex:

grammar Foo {
    token TOP { <letter>+ }
    proto token letter {*}
          token letter:sym<P> { <sym> }
          token letter:sym<e> { <sym> }
          token letter:sym<r> { <sym> }
          token letter:sym<l> { <sym> }
          token letter:sym<*> {   .   }
}.parse("I ♥ Perl", actions => class {
    method TOP($/) { make $<letter>.grep(*.<sym>).join }
}).made.say; # OUTPUT: «Perl␤»

This comes in handy when you're already differentiating the proto regexes with the strings you're going to match, as using <sym> token prevents repetition of those strings.

"Always succeed" assertion

The <?> is the always succeed assertion. When used as a grammar token, it can be used to trigger an Action class method. In the following grammar we look for Arabic digits and define a succ token with the always succeed assertion.

In the action class, we use calls to the succ method to do set up (in this case, we prepare a new element in @!numbers). In the digit method, we use the Arabic digit as an index into a list of Devanagari digits and add it to the last element of @!numbers. Thanks to succ, the last element will always be the number for the currently parsed digit digits.

grammar Digifier {
    rule TOP {
        [ <.succ> <digit>+ ]+
    }
    token succ   { <?> }
    token digit { <[0..9]> }
}

class Devanagari {
    has @!numbers;
    method digit ($/) { @!numbers.tail ~= <०  १  २  ३  ४  ५  ६  ७  ८  ९>[$/] }
    method succ  ($)  { @!numbers.push: ''     }
    method TOP   ($/) { make @!numbers[^(*-1)] }
}

say Digifier.parse('255 435 777', actions => Devanagari.new).made;
# OUTPUT: «(२५५ ४३५ ७७७)␤»

Methods in grammars

It's fine to use methods instead of rules or tokens in a grammar, as long as they return a Match:

grammar DigitMatcher {
    method TOP (:$full-unicode) {
        $full-unicode ?? self.num-full !! self.num-basic;
    }
    token num-full  { \d+ }
    token num-basic { <[0..9]>+ }
}

The grammar above will attempt different matches depending on the argument provided to the subparse methods:

say +DigitMatcher.subparse: '12७१७९०९', args => \(:full-unicode); 
 # OUTPUT: «12717909␤» 
 
 say +DigitMatcher.subparse: '12७१७९०९', args => \(:!full-unicode); 
 # OUTPUT: «12␤» 

Dynamic variables in grammars

Variables can be defined in tokens by prefixing the lines of code defining them with :. Arbitrary code can be embedded anywhere in a token by surrounding it with curly braces. This is useful for keeping state between tokens, which can be used to alter how the grammar will parse text. Using dynamic variables (variables with $*, @*, &*, %* twigils) in tokens cascades down through all tokens defined thereafter within the one where it's defined, avoiding having to pass them from token to token as arguments.

One use for dynamic variables is guards for matches. This example uses guards to explain which regex classes parse whitespace literally:

grammar GrammarAdvice {
    rule TOP {
        :my Int $*USE-WS;
        "use" <type> "for" <significance> "whitespace by default"
    }
    token type {
        | "rules"   { $*USE-WS = 1 }
        | "tokens"  { $*USE-WS = 0 }
        | "regexes" { $*USE-WS = 0 }
    }
    token significance {
        | <?{ $*USE-WS == 1 }> "significant"
        | <?{ $*USE-WS == 0 }> "insignificant"
    }
}

Here, text such as "use rules for significant whitespace by default" will only match if the state assigned by whether rules, tokens, or regexes are mentioned matches with the correct guard:

say GrammarAdvice.subparse("use rules for significant whitespace by default"); 
 # OUTPUT: «use rules for significant whitespace by default» 
 
 say GrammarAdvice.subparse("use tokens for insignificant whitespace by default"); 
 # OUTPUT: «use tokens for insignificant whitespace by default» 
 
 say GrammarAdvice.subparse("use regexes for insignificant whitespace by default"); 
 # OUTPUT: «use regexes for insignificant whitespace by default» 
 
 say GrammarAdvice.subparse("use regexes for significant whitespace by default") 
 # OUTPUT: #<failed match> 

Attributes in grammars

Attributes may be defined in grammars. However, they can only be accessed by methods. Attempting to use them from within a token will throw an exception because tokens are methods of Match, not of the grammar itself. Note that mutating an attribute from within a method called in a token will only modify the attribute for that token's own match object! Grammar attributes can be accessed in the match returned after parsing if made public:

grammar HTTPRequest { 
     has Bool $.invalid; 
 
     token TOP { 
         <type> <path> 'HTTP/1.1' \r\n 
         [<field> \r\n]+ 
         \r\n 
         $<body>=.* 
     } 
 
     token type { 
         | GET | POST | OPTIONS | HEAD | PUT | DELETE | TRACE | CONNECT 
         | \S+ <.error> 
     } 
 
     token path { 
         | '/' [[\w+]+ % \/] [\.\w+]? 
         | '*' 
         | \S+ <.error> 
     } 
 
     token field { 
         | $<name>=\w+ : $<value>=<-[\r\n]>* 
         | <-[\r\n]>+ <.error> 
     } 
 
     method error(--> ::?CLASS:D) { 
         $!invalid = True; 
         self; 
     } 
 } 
 
 my $header = "MEOWS / HTTP/1.1\r\nHost: docs.perl6.org\r\nsup lol\r\n\r\n"; 
 my $/ = HTTPRequest.parse($header); 
 say $<type>.invalid; 
 # OUTPUT: True 
 say $<path>.invalid; 
 # OUTPUT: (Bool) 
 say $<field>».invalid; 
 # OUTPUT: [(Bool) True] 

Passing arguments into grammars

To pass arguments into a grammar, you can use the named argument of :args on any of the parsing methods of grammar. The arguments passed should be in a list.

grammar demonstrate-arguments { 
     rule TOP ($word) { 
     "I like" $word 
     } 
 } 
 
 # Notice the comma after "sweets" when passed to :args to coerce it to a list 
 say demonstrate-arguments.parse("I like sweets", :args(("sweets",))); 
 # OUTPUT: «「I like sweets」␤» 

Once the arguments are passed in, they can be used in a call to a named regex inside the grammar.

grammar demonstrate-arguments-again { 
     rule TOP ($word) { 
     <phrase-stem><added-word($word)> 
     } 
 
     rule phrase-stem { 
        "I like" 
     } 
 
     rule added-word($passed-word) { 
        $passed-word 
     } 
 } 
 
 say demonstrate-arguments-again.parse("I like vegetables", :args(("vegetables",))); 
 # OUTPUT: 「I like vegetables」␤» 
 # OUTPUT:  «phrase-stem => 「I like 」␤» 
 # OUTPUT:  «added-word => 「vegetables」␤» 

Alternatively, you can initialize dynamic variables and use any arguments that way within the grammar.

grammar demonstrate-arguments-dynamic { 
    rule TOP ($*word, $*extra) { 
       <phrase-stem><added-words> 
    } 
    rule phrase-stem { 
       "I like" 
    } 
    rule added-words { 
       $*word $*extra 
    } 
 } 
 
 say demonstrate-arguments-dynamic.parse("I like everything else", 
   :args(("everything", "else"))); 
 # OUTPUT: «「I like everything else」␤» 
 # OUTPUT:  «phrase-stem => 「I like 」␤» 
 # OUTPUT:  «added-words => 「everything else」␤» 

Action objects

A successful grammar match gives you a parse tree of Match objects, and the deeper that match tree gets, and the more branches in the grammar are, the harder it becomes to navigate the match tree to get the information you are actually interested in.

To avoid the need for diving deep into a match tree, you can supply an actions object. After each successful parse of a named rule in your grammar, it tries to call a method of the same name as the grammar rule, giving it the newly created Match object as a positional argument. If no such method exists, it is skipped.

Here is a contrived example of a grammar and actions in action:

grammar TestGrammar { 
     token TOP { \d+ } 
 } 
 
 class TestActions { 
     method TOP($/) { 
         $/.make(2 + $/); 
     } 
 } 
 
 my $match = TestGrammar.parse('40', actions => TestActions.new); 
 say $match;         # OUTPUT: «「40」␤» 
 say $match.made;    # OUTPUT: «42␤» 

An instance of TestActions is passed as named argument actions to the parse call, and when token TOP has matched successfully, it automatically calls method TOP, passing the match object as an argument.

To make it clear that the argument is a match object, the example uses $/ as a parameter name to the action method, though that's just a handy convention, nothing intrinsic. $match would have worked too. (Though using $/ does give the advantage of providing $<capture> as a shortcut for $/<capture>).

A slightly more involved example follows:

grammar KeyValuePairs { 
     token TOP { 
         [<pair> \n+]* 
     } 
 
     token ws { 
         \h* 
     } 
 
     rule pair { 
         <key=.identifier> '=' <value=.identifier> 
     } 
     token identifier { 
         \w+ 
     } 
 } 
 
 class KeyValuePairsActions { 
     method pair      ($/) { 
         $/.make: $<key>.made => $<value>.made 
     } 
     method identifier($/) { 
         # subroutine `make` is the same as calling .make on $/ 
         make ~$/ 
     } 
     method TOP ($match) { 
         # can use any variable name for parameter, not just $/ 
         $match.make: $match<pair>».made 
     } 
 } 
 
 my $actions = KeyValuePairsActions; 
 my $res = KeyValuePairs.parse(q:to/EOI/, :$actions).made; 
     second=b 
     hits=42 
     perl=6 
     EOI 
 
 for @$res -> $p { 
     say "Key: $p.key()\tValue: $p.value()"; 
 } 

This produces the following output:

Key: second     Value: b 
 Key: hits       Value: 42 
 Key: perl       Value: 6 

Rule pair, which parsed a pair separated by an equals sign, aliases the two calls to token identifier to separate capture names to make them available more easily and intuitively. The corresponding action method constructs a Pair object, and uses the .made property of the sub match objects. So it (like the action method TOP too) exploits the fact that action methods for submatches are called before those of the calling/outer regex. So action methods are called in post-order.

The action method TOP simply collects all the objects that were .made by the multiple matches of the pair rule, and returns them in a list.

Also note that KeyValuePairsActions was passed as a type object to method parse, which was possible because none of the action methods use attributes (which would only be available in an instance).

In other cases, action methods might want to keep state in attributes. Then of course you must pass an instance to method parse.

Note that token ws is special: when :sigspace is enabled (and it is when we are using rule), it replaces certain whitespace sequences. This is why the spaces around the equals sign in rule pair work just fine and why the whitespace before closing } does not gobble up the newlines looked for in token TOP.

51 Hashes and maps

Working with associative arrays/dictionaries/hashes

The associative role and associative classes

The Associative role underlies hashes and maps, as well as other classes such as MixHash. It defines the two types that will be used in associative classes; by default, you can use anything (literally, since any class that subclasses Any can be used) as a key, although it will be coerced to a string, and any object as value. You can access these types using the of and keyof methods.

By default, any object declared with the % sigil will get the Associative role, and will by default behave like a hash, but this role will only provide the two methods above, as well as the default Hash behavior.

say (%).^name ; # OUTPUT: «Hash␤»

Inversely, you cannot use the % sigil if the Associative role is not mixed in, but since this role does not have any associated properties, you will have to redefine the behavior of the hash subscript operator. In order to do that, there are several functions you will have to override:

class Logger does Associative[Cool,DateTime] { 
     has %.store; 
 
     method log( Cool $event ) { 
         %.store{ DateTime.new( now ) } = $event; 
     } 
 
     multi method AT-KEY ( ::?CLASS:D: $key) { 
         my @keys = %.store.keys.grep( /$key/ ); 
         %.store{ @keys }; 
     } 
 
     multi method EXISTS-KEY (::?CLASS:D: $key) { 
         %.store.keys.grep( /$key/ )??True!!False; 
     } 
 
     multi method DELETE-KEY (::?CLASS:D: $key) { 
         X::Assignment::RO.new.throw; 
     } 
 
     multi method ASSIGN-KEY (::?CLASS:D: $key, $new) { 
         X::Assignment::RO.new.throw; 
     } 
 
     multi method BIND-KEY (::?CLASS:D: $key, \new){ 
         X::Assignment::RO.new.throw; 
     } 
 } 
 say Logger.of;                   # OUTPUT: «(Cool)» 
 my %logger := Logger.new; 
 say %logger.of;                  # OUTPUT: «(Cool)» 
 
 %logger.log( "Stuff" ); 
 %logger.log( "More stuff"); 
 
 say %logger<2018-05-26>;         # OUTPUT: «(More stuff Stuff)» 
 say %logger<2018-04-22>:exists;  # OUTPUT: «False» 
 

In this case, we are defining a logger with Associative semantics that will be able to use dates (or a part of them) as keys. Since we are parameterizing Associative to those particular classes, of will return the value type we have used, Cool in this case (we can log lists or strings only). Mixing the Associative role gives it the right to use the % sigil; binding is needed in the definition since %-sigiled variables get by default the Hash type.

This log is going to be append-only, which is why we escape the associative array metaphor to use a log method to add new events to the log. Once they have been added, however, we can retrieve them by date or check if they exist. For the first we have to override the AT-KEY multi method, for the latter EXIST-KEY. In the last two statements, we show how the subscript operation invokes AT-KEY, while the :exists adverb invokes EXISTS-KEY.

We override DELETE-KEY, ASSIGN-KEY and BIND-KEY, but only to throw an exception. Attempting to assign, delete, or bind a value to a key will result in a Cannot modify an immutable Str (value) exception thrown.

Making classes associative provides a very convenient way of using and working with them using hashes; an example can be seen in Cro, which uses it extensively for the convenience of using hashes to define structured requests and express its response.

Mutable hashes and immutable maps

A Hash is a mutable mapping from keys to values (called dictionary, hash table or map in other programming languages). The values are all scalar containers, which means you can assign to them. Maps are, on the other hand, immutable. Once a key has been paired with a value, this pairing cannot be changed.

Maps and hashes are usually stored in variables with the percent % sigil, which is used to indicate they are Associative.

Hash and map elements are accessed by key via the { } postcircumfix operator:

say %*ENV{'HOME', 'PATH'}.perl;
# OUTPUT: «("/home/camelia", "/usr/bin:/sbin:/bin")␤»

The general Subscript rules apply providing shortcuts for lists of literal strings, with and without interpolation.

my %h = oranges => 'round', bananas => 'bendy';
say %h<oranges bananas>;
# OUTPUT: «(round bendy)␤»

my $fruit = 'bananas';
say %h«oranges "$fruit"»;
# OUTPUT: «(round bendy)␤»

You can add new pairs simply by assigning to an unused key:

my %h;
%h{'new key'} = 'new value';

Hash assignment

Assigning a list of elements to a hash variable first empties the variable, and then iterates the elements of the right-hand side. If an element is a Pair, its key is taken as a new hash key, and its value as the new hash value for that key. Otherwise the value is coerced to Str and used as a hash key, while the next element of the list is taken as the corresponding value.

my %h = 'a', 'b', c => 'd', 'e', 'f';

Same as

my %h = a => 'b', c => 'd', e => 'f';

or

my %h = <a b c d e f>;

or even

my %h = %( a => 'b', c => 'd', e => 'f' );

or

my %h = [ a => 'b', c => 'd', e => 'f' ]; # This format is NOT recommended.
                                          # It cannot be a constant and there
                                          # will be problems with nested hashes

or

my $h = { a => 'b', c => 'd', e => 'f'};

Please note that curly braces are used only in the case that we are not assigning it to a %-sigiled variable; in case we use it for a %-sigiled variable we will get an Potential difficulties:␤ Useless use of hash composer on right side of hash assignment; did you mean := instead? error. As this error indicates, however, we can use curly braces as long as we use also binding:

my %h := { a => 'b', c => 'd', e => 'f'};
say %h; # OUTPUT: «{a => b, c => d, e => f}␤»

Nested hashes can also be defined using the same syntax:

my %h =  e => f => 'g';
say %h<e><f>; # OUTPUT: «g␤»

However, what you are defining here is a key pointing to a Pair, which is fine if that is what you want and your nested hash has a single key. But %h<e> will point to a Pair which will have these consequences:

my %h =  e => f => 'g'; 
 %h<e><q> = 'k'; 
 # OUTPUT: «Pair␤Cannot modify an immutable Str (Nil)␤  in block <unit>» 

This, however, will effectively define a nested hash:

my %h =  e => { f => 'g' };
say %h<e>.^name;  # OUTPUT: «Hash␤»
say %h<e><f>;     # OUTPUT: «g␤»

If a Pair is encountered where a value is expected, it is used as a hash value:

my %h = 'a', 'b' => 'c';
say %h<a>.^name;            # OUTPUT: «Pair␤»
say %h<a>.key;              # OUTPUT: «b␤»

If the same key appears more than once, the value associated with its last occurrence is stored in the hash:

my %h = a => 1, a => 2;
say %h<a>;                  # OUTPUT: «2␤»

To assign a hash to a variable which does not have the % sigil, you may use the %() hash constructor:

my $h = %( a => 1, b => 2 );
say $h.^name;               # OUTPUT: «Hash␤»
say $h<a>;                  # OUTPUT: «1␤»

If one or more values reference the topic variable, $_, the right-hand side of the assignment will be interpreted as a Block, not a Hash:

my @people = [ 
     %( id => "1A", firstName => "Andy", lastName => "Adams" ), 
     %( id => "2B", firstName => "Beth", lastName => "Burke" ), 
     # ... 
 ]; 
 
 sub lookup-user (Hash $h) { #`(Do something...) $h } 
 
 my @names = map { 
     # While this creates a hash: 
     my  $query = { name => "$person<firstName> $person<lastName>" }; 
     say $query.^name;      # OUTPUT: «Hash␤» 
 
     # Doing this will create a Block. Oh no! 
     my  $query2 = { name => "$_<firstName> $_<lastName>" }; 
     say $query2.^name;       # OUTPUT: «Block␤» 
     say $query2<name>;       # fails 
 
     CATCH { default { put .^name, ': ', .Str } }; 
     # OUTPUT: «X::AdHoc: Type Block does not support associative indexing.␤» 
     lookup-user($query); 
     # Type check failed in binding $h; expected Hash but got Block 
 }, @people; 

This would have been avoided if you had used the %() hash constructor. Only use curly braces for creating Blocks.

Hash slices

You can assign to multiple keys at the same time with a slice.

my %h; %h<a b c> = 2 xx *; %h.perl.say;  # OUTPUT: «{:a(2), :b(2), :c(2)}␤»
my %h; %h<a b c> = ^3;     %h.perl.say;  # OUTPUT: «{:a(0), :b(1), :c(2)}␤»

Non-string keys (object hash)

By default keys in { } are forced to strings. To compose a hash with non-string keys, use a colon prefix:

my $when = :{ (now) => "Instant", (DateTime.now) => "DateTime" };

Note that with objects as keys, you often cannot use the <...> construct for key lookup, as it creates only strings and allomorphs. Use the {...} instead:

:{  0  => 42 }<0>.say;   # Int    as key, IntStr in lookup; OUTPUT: «(Any)␤»
:{  0  => 42 }{0}.say;   # Int    as key, Int    in lookup; OUTPUT: «42␤»
:{ '0' => 42 }<0>.say;   # Str    as key, IntStr in lookup; OUTPUT: «(Any)␤»
:{ '0' => 42 }{'0'}.say; # Str    as key, Str    in lookup; OUTPUT: «42␤»
:{ <0> => 42 }<0>.say;   # IntStr as key, IntStr in lookup; OUTPUT: «42␤»

Note: Rakudo implementation currently erroneously applies the same rules for :{ } as it does for { } and can construct a Block in certain circumstances. To avoid that, you can instantiate a parameterized Hash directly. Parameterization of %-sigiled variables is also supported:

my Num %foo1      = "0" => 0e0; # Str keys and Num values
my     %foo2{Int} =  0  => "x"; # Int keys and Any values
my Num %foo3{Int} =  0  => 0e0; # Int keys and Num values
Hash[Num,Int].new: 0, 0e0;      # Int keys and Num values

Now if you want to define a hash to preserve the objects you are using as keys as the exact objects you are providing to the hash to use as keys, then object hashes are what you are looking for.

my %intervals{Instant}; 
 my $first-instant = now; 
 %intervals{ $first-instant } = "Our first milestone."; 
 sleep 1; 
 my $second-instant = now; 
 %intervals{ $second-instant } = "Logging this Instant for spurious raisins."; 
 for %intervals.sort -> (:$key, :$value) { 
     state $last-instant //= $key; 
     say "We noted '$value' at $key, with an interval of {$key - $last-instant}"; 
     $last-instant = $key; 
 } 

This example uses an object hash that only accepts keys of type Instant to implement a rudimentary, yet type-safe, logging mechanism. We utilize a named state variable for keeping track of the previous Instant so that we can provide an interval.

The whole point of object hashes is to keep keys as objects-in-themselves. Currently object hashes utilize the WHICH method of an object, which returns a unique identifier for every mutable object. This is the keystone upon which the object identity operator (===) rests. Order and containers really matter here as the order of .keys is undefined and one anonymous list is never === to another.

my %intervals{Instant}; 
 my $first-instant = now; 
 %intervals{ $first-instant } = "Our first milestone."; 
 sleep 1; 
 my $second-instant = now; 
 %intervals{ $second-instant } = "Logging this Instant for spurious raisins."; 
 say ($first-instant, $second-instant) ~~ %intervals.keys;       # OUTPUT: «False␤» 
 say ($first-instant, $second-instant) ~~ %intervals.keys.sort;  # OUTPUT: «False␤» 
 say ($first-instant, $second-instant) === %intervals.keys.sort; # OUTPUT: «False␤» 
 say $first-instant === %intervals.keys.sort[0];                 # OUTPUT: «True␤» 

Since Instant defines its own comparison methods, in our example a sort according to cmp will always provide the earliest instant object as the first element in the List it returns.

If you would like to accept any object whatsoever in your hash, you can use Any!

my %h{Any};
%h{(now)} = "This is an Instant";
%h{(DateTime.now)} = "This is a DateTime, which is not an Instant";
%h{"completely different"} = "Monty Python references are neither DateTimes nor Instants";

There is a more concise syntax which uses binding.

my %h := :{ (now) => "Instant", (DateTime.now) => "DateTime" };

The binding is necessary because an object hash is about very solid, specific objects, which is something that binding is great at keeping track of but about which assignment doesn't concern itself much.

Since 6.d was released, Junction s can also be used as hash keys. The result will also be a Junction of the same type used as key.

my %hash = %( a => 1, b => 2, c=> 3);
say %hash{"a"|"c"};   # OUTPUT: «any(1, 3)␤»
say %hash{"b"^"c"};   # OUTPUT: «one(2, 3)␤»
say %hash{"a" & "c"}; # OUTPUT: «all(1, 3)␤»

If a Junction of any kind is used to define a key, it will have the same effect of defining elements of the Junction as separate keys:

my %hash = %( "a"|"b" => 1, c => 2 ); 
 say %hash{"b"|"c"};       # OUTPUT: «any(1, 2)␤» 

Constraint value types

Place a type object in-between the declarator and the name to constrain the type of all values of a Hash.

my Int %h;
put %h<Goku>   = 900;

try {
    %h<Vegeta> = "string";
    CATCH { when X::TypeCheck::Binding { .message.put } }
}

# OUTPUT:
# 9001
# Type check failed in assignment to %h; expected Int but got Str ("string")

You can do the same by a more readable syntax.

my %h of Int; # the same as my Int %h

If you want to constraint the type of all keys of a Hash, add {Type} following the name of variable.

my %h{Int};

Even put these two constraints together.

my %h{Int} of Int;
put %h{21} = 42;

try {
    %h{0} = "String";
    CATCH { when X::TypeCheck::Binding { .message.put } }
}

try {
    %h<string> = 42;
    CATCH { when X::TypeCheck::Binding { .message.put } }
}

try {
    %h<string> = "String";
    CATCH { when X::TypeCheck::Binding { .message.put } }
}

# OUTPUT:
# 42
# Type check failed in binding to parameter 'assignval'; expected Int but got Str ("String")
# Type check failed in binding to parameter 'key'; expected Int but got Str ("string")
# Type check failed in binding to parameter 'key'; expected Int but got Str ("string")

Looping over hash keys and values

A common idiom for processing the elements in a hash is to loop over the keys and values, for instance,

my %vowels = 'a' => 1, 'e' => 2, 'i' => 3, 'o' => 4, 'u' => 5;
for %vowels.kv -> $vowel, $index {
  "$vowel: $index".say;
}

gives output similar to this:

a: 1 
 e: 2 
 o: 4 
 u: 5 
 i: 3 

where we have used the kv method to extract the keys and their respective values from the hash, so that we can pass these values into the loop.

Note that the order of the keys and values printed cannot be relied upon; the elements of a hash are not always stored the same way in memory for different runs of the same program. In fact, since version 2018.05, the order is guaranteed to be different in every invocation. Sometimes one wishes to process the elements sorted on, e.g., the keys of the hash. If one wishes to print the list of vowels in alphabetical order then one would write

my %vowels = 'a' => 1, 'e' => 2, 'i' => 3, 'o' => 4, 'u' => 5;
for %vowels.sort(*.key)>>.kv -> ($vowel, $index) {
  "$vowel: $index".say;
}

which prints

a: 1 
 e: 2 
 i: 3 
 o: 4 
 u: 5 

in alphabetical order as desired. To achieve this result, we sorted the hash of vowels by key (%vowels.sort(*.key)) which we then ask for its keys and values by applying the .kv method to each element via the unary >> hyperoperator resulting in a List of key/value lists. To extract the key/value the variables thus need to be wrapped in parentheses.

An alternative solution is to flatten the resulting list. Then the key/value pairs can be accessed in the same way as with plain .kv:

my %vowels = 'a' => 1, 'e' => 2, 'i' => 3, 'o' => 4, 'u' => 5;
for %vowels.sort(*.key)>>.kv.flat -> $vowel, $index {
  "$vowel: $index".say;
}

You can also loop over a Hash using destructuring.

In place editing of values

There may be times when you would like to modify the values of a hash while iterating over them.

my %answers = illuminatus => 23, hitchhikers => 42;
# OUTPUT: «hitchhikers => 42, illuminatus => 23»
for %answers.values -> $v { $v += 10 }; # Fails
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::AdHoc: Cannot assign to a readonly variable or a value␤»

This is traditionally accomplished by sending both the key and the value as follows.

my %answers = illuminatus => 23, hitchhikers => 42;
for %answers.kv -> $k,$v { %answers{$k} = $v + 10 };

However, it is possible to leverage the signature of the block in order to specify that you would like read-write access to the values.

my %answers = illuminatus => 23, hitchhikers => 42;
for %answers.values -> $v is rw { $v += 10 };

It is not possible directly to do in-place editing of hash keys, even in the case of object hashes; however, a key can be deleted and a new key/value pair added to achieve the same results. For example, given this hash:

my %h = a => 1, b => 2; 
 for %h.keys.sort -> $k { 
     # use sort to ease output comparisons 
     print "$k => {%h{$k}}; "; 
 } 
 say ''; # OUTPUT: «a => 1; b => 2;»␤ 

replace key 'b' with 'bb' but retain 'b's value as the new key's value:

for %h.keys -> $k { 
     if $k eq 'b' { 
         my $v = %h{$k}; 
         %h{$k}:delete; 
         %h<bb> = $v; 
     } 
 } 
 for %h.keys.sort -> $k { 
     print "$k => {%h{$k}}; "; 
 } 
 say ''; # OUTPUT: «a => 1; bb => 2;»␤ 

52 Input/Output the definitive guide

Correctly use Perl 6 IO

The basics

The vast majority of common IO work is done by the IO::Path type. If you want to read from or write to a file in some form or shape, this is the class you want. It abstracts away the details of filehandles (or "file descriptors") and so you mostly don't even have to think about them.

Behind the scenes, IO::Path works with IO::Handle, a class which you can use directly if you need a bit more control than what IO::Path provides. When working with other processes, e.g. via Proc or Proc::Async types, you'll also be dealing with a subclass of IO::Handle: the IO::Pipe.

Lastly, you have the IO::CatHandle, as well as IO::Spec and its subclasses, that you'll rarely, if ever, use directly. These classes give you advanced features, such as operating on multiple files as one handle, or low-level path manipulations.

Along with all these classes, Perl 6 provides several subroutines that let you indirectly work with these classes. These come in handy if you like functional programming style or in Perl 6 one liners.

While IO::Socket and its subclasses also have to do with Input and Output, this guide does not cover them.

Navigating paths

What's an IO::Path anyway?

To represent paths as either files or directories, use IO::Path type. The simplest way to obtain an object of that type is to coerce a Str by calling the .IO method on it:

say 'my-file.txt'.IO; # OUTPUT: «"my-file.txt".IO␤»

It may seem like something is missing here—there is no volume or absolute path involved—but that information is actually present in the object. You can see it by using .perl method:

say 'my-file.txt'.IO.perl;
# OUTPUT: «IO::Path.new("my-file.txt", :SPEC(IO::Spec::Unix), :CWD("/home/camelia"))␤»

The two extra attributes—SPEC and CWD—specify what type of operating system semantics the path should use as well as the "current working directory" for the path, i.e. if it's a relative path, then it's relative to that directory.

This means that regardless of how you made one, an IO::Path object technically always refers to an absolute path. This is why its .absolute and .relative methods return Str objects and they are the correct way to stringify a path.

However, don't be in a rush to stringify anything. Pass paths around as IO::Path objects. All the routines that operate on paths can handle them, so there's no need to convert them.

Working with files

Writing into files

Writing new content

Let's make some files and write and read data from them! The spurt and slurp routines write and read the data in one chunk respectively. Unless you're working with very large files that are difficult to store entirely in memory all at the same time, these two routines are for you.

"my-file.txt".IO.spurt: "I ♥ Perl!"; 

The code above creates a file named my-file.txt in the current directory and then writes text I ♥ Perl! into it. If Perl 6 is your first language, celebrate your accomplishment! Try to open the file you created with a text editor to verify what you wrote with your program. If you already know some other language, you may be wondering if this guide missed anything like handling encoding or error conditions.

However, that is all the code you need. The string will be encoded in utf-8 encoding by default and the errors are handled via the Failure mechanism: these are exceptions you can handle using regular conditionals. In this case, we're letting all potential Failures get sunk after the call and so any Exceptions they contain will be thrown.

Appending content

If you wanted to add more content to the file we created in the previous section, you could note the spurt documentation mentions :append as one of its argument options. However, for finer control, let's get ourselves an IO::Handle to work with:

my $fh = 'my-file.txt'.IO.open: :a; 
 $fh.print: "I count: "; 
 $fh.print: "$_ " for ^10; 
 $fh.close; 

The .open method call opens our IO::Path and returns an IO::Handle. We passed :a as argument, to indicate we want to open the file for writing in append mode.

In the next two lines of code, we use the usual .print method on that IO::Handle to print a line with 11 pieces of text (the 'I count: ' string and 10 numbers). Note that, once again, Failure mechanism takes care of all the error checking for us. If the .open fails, it returns a Failure, which will throw when we attempt to call method the .print on it.

Finally, we close the IO::Handle by calling the .close method on it. It is important that you do it, especially in large programs or ones that deal with a lot of files, as many systems have limits to how many files a program can have open at the same time. If you don't close your handles, eventually you'll reach that limit and the .open call will fail. Note that unlike some other languages, Perl 6 does not use reference counting, so the filehandles are NOT closed when the scope they're defined in is left. They will be closed only when they're garbage collected and failing to close the handles may cause your program to reach the file limit before the open handles get a chance to get garbage collected.

Reading from files

Using IO::Path

We've seen in previous sections that writing stuff to files is a single-line of code in Perl 6. Reading from them, is similarly easy:

say 'my-file.txt'.IO.slurp;        # OUTPUT: «I ♥ Perl!␤» 
 say 'my-file.txt'.IO.slurp: :bin;  # OUTPUT: «Buf[uint8]:0x<49 20 e2 99 a5 20 50 65 72 6c 21>␤» 

The .slurp method reads entire contents of the file and returns them as a single Str object, or as a Buf object, if binary mode was requested, by specifying :bin named argument.

Since slurping loads the entire file into memory, it's not ideal for working with huge files.

The IO::Path type offers two other handy methods: .words and .lines that lazily read the file in smaller chunks and return Seq objects that (by default) don't keep already-consumed values around.

Here's an example that finds lines in a text file that mention Perl and prints them out. Despite the file itself being too large to fit into available RAM, the program will not have any issues running, as the contents are processed in small chunks:

.say for '500-PetaByte-File.txt'.IO.lines.grep: *.contains: 'Perl'; 

Here's another example that prints the first 100 words from a file, without loading it entirely:

.say for '500-PetaByte-File.txt'.IO.words: 100 

Note that we did this by passing a limit argument to .words instead of, say, using a list indexing operation. The reason for that is there's still a filehandle in use under the hood, and until you fully consume the returned Seq, the handle will remain open. If nothing references the Seq, eventually the handle will get closed, during a garbage collection run, but in large programs that work with a lot of files, it's best to ensure all the handles get closed right away. So, you should always ensure the Seq from IO::Path's .words and .lines methods is fully reified; and the limit argument is there to help you with that.

Using IO::Handle

Of course, you can read from files using the IO::Handle type, which gives you a lot finer control over what you're doing:

given 'some-file.txt'.IO.open { 
     say .readchars: 8;  # OUTPUT: «I ♥ Perl␤» 
     .seek: 1, SeekFromCurrent; 
     say .readchars: 15;  # OUTPUT: «I ♥ Programming␤» 
     .close 
 } 

The IO::Handle gives you .read, .readchars, .get, .getc, .words, .lines, .slurp, .comb, .split, and .Supply methods to read data from it. Plenty of options; and the catch is you need to close the handle when you're done with it.

Unlike some languages, the handle won't get automatically closed when the scope it's defined in is left. Instead, it'll remain open until it's garbage collected. To make the closing business easier, some of the methods let you specify a :close argument, you can also use the will leave trait, or the does auto-close trait provided by the Trait::IO module.

The wrong way to do things

This section describes how NOT to do Perl 6 IO.

Leave $*SPEC alone

You may have heard of $*SPEC and seen some code or books show its usage for splitting and joining path fragments. Some of the routine names it provides may even look familiar to what you've used in other languages.

However, unless you're writing your own IO framework, you almost never need to use $*SPEC directly. $*SPEC provides low-level stuff and its use will not only make your code tough to read, you'll likely introduce security issues (e.g. null characters)!

The IO::Path type is the workhorse of Perl 6 world. It caters to all the path manipulation needs as well as provides shortcut routines that let you avoid dealing with filehandles. Use that instead of the $*SPEC stuff.

Tip: you can join path parts with / and feed them to IO::Path's routines; they'll still do The Right Thing™ with them, regardless of the operating system.

# WRONG!! TOO MUCH WORK! 
 my $fh = open $*SPEC.catpath: '', 'foo/bar', $file; 
 my $data = $fh.slurp; 
 $fh.close; 
# RIGHT! Use IO::Path to do all the dirty work 
 my $data = 'foo/bar'.IO.add($file).slurp; 

However, it's fine to use it for things not otherwise provided by IO::Path. For example, the .devnull method:

{ 
     temp $*OUT = open :w, $*SPEC.devnull; 
     say "In space no one can hear you scream!"; 
 } 
 say "Hello"; 

Stringifying IO::Path

Don't use the .Str method to stringify IO::Path objects, unless you just want to display them somewhere for information purposes or something. The .Str method returns whatever basic path string the IO::Path was instantiated with. It doesn't consider the value of the $.CWD attribute. For example, this code is broken:

my $path = 'foo'.IO; 
 chdir 'bar'; 
 # WRONG!! .Str DOES NOT USE $.CWD! 
 run <tar -cvvf archive.tar>, $path.Str; 

The chdir call changed the value of the current directory, but the $path we created is relative to the directory before that change.

However, the IO::Path object does know what directory it's relative to. We just need to use .absolute or .relative to stringify the object. Both routines return a Str object; they only differ in whether the result is an absolute or relative path. So, we can fix our code like this:

my $path = 'foo'.IO; 
 chdir 'bar'; 
 # RIGHT!! .absolute does consider the value of $.CWD! 
 run <tar -cvvf archive.tar>, $path.absolute; 
 # Also good: 
 run <tar -cvvf archive.tar>, $path.relative; 

Be mindful of $*CWD

While usually out of view, every IO::Path object, by default, uses the current value of $*CWD to set its $.CWD attribute. This means there are two things to pay attention to.

temp the $*CWD

This code is a mistake:

# WRONG!! 
 my $*CWD = "foo".IO; 

The my $*CWD made $*CWD undefined. The .IO coercer then goes ahead and sets the $.CWD attribute of the path it's creating to the stringified version of the undefined $*CWD; an empty string.

The correct way to perform this operation is use temp instead of my. It'll localize the effect of changes to $*CWD, just like my would, but it won't make it undefined, so the .IO coercer will still get the correct old value:

temp $*CWD = "foo".IO; 

Better yet, if you want to perform some code in a localized $*CWD, use the indir routine for that purpose.

53 Lists, sequences, and arrays

Positional data constructs

Lists have been a central part of computing since before there were computers, during which time many devils have taken up residence in their details. They were actually one of the hardest parts of Perl 6 to design, but through persistence and patience, Perl 6 has arrived with an elegant system for handling them.

Literal lists

Literal List s are created with commas and semicolons, not with parentheses, so:

1, 2;                # This is two-element list
our $list = (1, 2);  # This is also a List, in parentheses
$list = (1; 2);      # same List (see below)
$list = (1);         # This is not a List, just a 1 in parentheses
$list = (1,);        # This is a one-element List

There is one exception, empty lists are created with just a pair of parentheses:

();          # This is an empty List 
(,);         # This is a syntax error 

Note that hanging commas are just fine as long as the beginning and end of a list are clear, so feel free to use them for easy code editing.

Parentheses can be used to mark the beginning and end of a List, so:

(1, 2), (1, 2); # This is a list of two lists.

Lists of Lists can also be created by combining comma and semicolon. This is also called multi-dimensional syntax, because it is most often used to index multidimensional arrays.

say so (1,2; 3,4) eqv ((1,2), (3,4));
# OUTPUT: «True␤»
say so (1,2; 3,4;) eqv ((1,2), (3,4));
# OUTPUT: «True␤»
say so ("foo";) eqv ("foo") eqv (("foo")); # not a list
# OUTPUT: «True␤»

Unlike a comma, a hanging semicolon does not create a multidimensional list in a literal. However, be aware that this behavior changes in most argument lists, where the exact behavior depends on the function... But will usually be:

say('foo';);   # a list with one element and the empty list
# OUTPUT: «(foo)()␤»
say(('foo';)); # no list, just the string "foo"
# OUTPUT: «foo␤»

Because the semicolon doubles as a statement terminator it will end a literal list when used at the top level, instead creating a statement list. If you want to create a statement list inside parenthesis, use a sigil before the parenthesis:

say so (42) eqv $(my $a = 42; $a;);
# OUTPUT: «True␤»
say so (42,42) eqv (my $a = 42; $a;);
# OUTPUT: «True␤»

Individual elements can be pulled out of a list using a subscript. The first element of a list is at index number zero:

say (1, 2)[0];  # says 1 
 say (1, 2)[1];  # says 2 
 say (1, 2)[2];  # says Nil 
say (1, 2)[-1]; # Error 
say ((<a b>,<c d>),(<e f>,<g h>))[1;0;1]; # says "f" 

The @ sigil

Variables in Perl 6 whose names bear the @ sigil are expected to contain some sort of list-like object. Of course, other variables may also contain these objects, but @-sigiled variables always do, and are expected to act the part.

By default, when you assign a List to an @-sigiled variable, you create an Array. Those are described below. If instead you want to refer directly to a List object using an @-sigiled variable, you can use binding with := instead.

my @a := 1, 2, 3;

One of the ways @-sigiled variables act like lists is by always supporting positional subscripting. Anything bound to a @-sigiled value must support the Positional role which guarantees that this is going to fail:

my @a := 1; # Type check failed in binding; expected Positional but got Int

Reset a list container

To remove all elements from a Positional container assign Empty, the empty list () or a Slip of the empty list to the container.

my @a = 1, 2, 3;
@a = ();
@a = Empty;
@a = |();

Iteration

All lists may be iterated, which means taking each element from the list in order and stopping after the last element:

for 1, 2, 3 { .say }  # OUTPUT: «1␤2␤3␤»

Single Argument Rule

It is the rule by which the set of parameters passed to an iterator such as for is treated as a single argument, instead of several arguments; that is some-iterator( a, b, c, ...) will always be treated as some-iterator( list-or-array(a, b, c)) and never as (some-iterator(a))(b)..., that is, iterative application of the iterator to the first argument, then the result to the next argument, and so on. In this example

my @list = [ (1, 2, 3), 
              (1, 2, ), 
              [<a b c>, <d e f>], 
              [[1]] ]; 
 
 for @list -> @element { 
   say "{@element} → {@element.^name}"; 
     for @element -> $sub-element { 
       say $sub-element; 
     } 
 } 
 # OUTPUT 
 #1 2 3 → List 
 #1 
 #2 
 #3 
 #1 2 → List 
 #1 
 #2 
 #a b c d e f → Array 
 #(a b c) 
 #(d e f) 
 #1 → Array 
 #1 

Since what for receives is a single argument, it will be treated as a list of elements to iterate over. The rule of thumb is that if there's a comma, anything preceding it is an element and the list thus created becomes the single element. That happens in the case of the two arrays separated by a comma which are the third in the Array we are iterating. In general, quoting the article linked above, the single argument rule ... makes for behavior as the programmer would expect.

Testing for elements

To test for elements in a List or Array, you can use the "is element of" Set operator.

my @a = <foo bar buzz>;
say 'bar' (elem) @a;    # OUTPUT: «True␤»
say 'bar' ∈ @a;         # same, using unicode version of operator

This is the equivalent of:

'bar' (elem) @a.Set;    # convert the array to a Set first 

except that, if possible, it won't actually do the conversion.

It basically compares the value with each element in the array using the === infix operator. If you want to use another way to compare values, you probably should use first.

Sequences

Not all lists are born full of elements. Some only create as many elements as they are asked for. These are called sequences, which are of type Seq. As it so happens, loops return Seqs.

(loop { 42.say })[2]  # OUTPUT: «42␤42␤42␤»

So, it is fine to have infinite lists in Perl 6, just so long as you never ask them for all their elements. In some cases, you may want to avoid asking them how long they are too – Perl 6 will try to return Inf if it knows a sequence is infinite, but it cannot always know.

These lists can be built using the ... operator, which builds lazy lists using a variety of generating expressions.

Although the Seq class does provide some positional subscripting, it does not provide the full interface of Positional, so an @-sigiled variable may not be bound to a Seq, and trying to do so will yield an error.

my @s := <a b c>.Seq; CATCH { default { say .^name, ' ', .Str } }
# OUTPUT «X::TypeCheck::Binding Type check failed in binding; expected Positional but got Seq ($(("a", "b","c").Seq))␤»

This is because the Seq does not keep values around after you have used them. This is useful behavior if you have a very long sequence, as you may want to throw values away after using them, so that your program does not fill up memory. For example, when processing a file of a million lines:

for 'filename'.IO.lines -> $line { 
     do-something-with($line); 
 } 

You can be confident that the entire content of the file will not stay around in memory, unless you are explicitly storing the lines somewhere.

On the other hand, you may want to keep old values around in some cases. It is possible to hide a Seq inside a List, which will still be lazy, but will remember old values. This is done by calling the .list method. Since this List fully supports Positional, you may bind it directly to an @-sigiled variable.

my @s := (loop { 42.say }).list;
@s[2]; # says 42 three times
@s[1]; # does not say anything
@s[4]; # says 42 two more times

You may also use the .cache method instead of .list, depending on how you want the references handled. See the page on Seq for details.

Using .iterator

All lists mix in the Iterator role, and as such have an .iterator method they can use for a finer control over a list. We can use it like this, for instance:

my @multiples-of-five = 0,5,10 … 500; 
 my $odd-iterator = @multiples-of-five.iterator; 
 my $odd; 
 repeat { 
     $odd-iterator.skip-one; 
     $odd = $odd-iterator.pull-one; 
     say "→ $odd"; 
 } until $odd.Str eq IterationEnd.Str; 

Instead of using the iterator implicitly as we do in for loops, we explicitly assign it to the $odd-iterator variable to work over the odd elements of the sequence only. That way, we can skip even elements using .skip-one. We do have to test explicitly for termination, which we do in the until expression. When there's nothing left to iterate, $odd will have the value IterationEnd. Please check the documentation on Iterator s for the methods and functions that are available.

Slips

Sometimes you want to insert the elements of a list into another list. This can be done with a special type of list called a Slip.

say (1, (2, 3), 4) eqv (1, 2, 3, 4);         # OUTPUT: «False␤»
say (1, Slip.new(2, 3), 4) eqv (1, 2, 3, 4); # OUTPUT: «True␤»
say (1, slip(2, 3), 4) eqv (1, 2, 3, 4);     # OUTPUT: «True␤»

Another way to make a Slip is with the | prefix operator. Note that this has a tighter precedence than the comma, so it only affects a single value, but unlike the above options, it will break Scalars.

say (1, |(2, 3), 4) eqv (1, 2, 3, 4);        # OUTPUT: «True␤»
say (1, |$(2, 3), 4) eqv (1, 2, 3, 4);       # OUTPUT: «True␤»
say (1, slip($(2, 3)), 4) eqv (1, 2, 3, 4);  # OUTPUT: «False␤»

Lazy lists

Lists, Seqs, Arrays and any other class that implements the Iterator role can be lazy, which means that their values are computed on demand and stored for later use. One of the ways to create a lazy object is to use gather/take or the sequence operator. You can also write a class that implements the role Iterator and returns True on a call to is-lazy. Please note that some methods like elems cannot be called on a lazy List and will result in a thrown Exception.

# This array is lazy and its elements will not be available 
 # until explicitly requested. 
 
 my @lazy-array = lazy 1, 11, 121 ... 10**100; 
 say @lazy-array.is-lazy;     # OUTPUT: «True␤» 
 say @lazy-array[];           # OUTPUT: «[...]␤» 
 
 # Once all elements have been retrieved, the list 
 # is no longer considered lazy. 
 
 my @no-longer-lazy = eager @lazy-array;  # Forcing eager evaluation 
 say @no-longer-lazy.is-lazy;             # OUTPUT: «False␤» 
 say @no-longer-lazy[]; 
 # OUTPUT: (sequence starting with «[1 11 121» ending with a 300 digit number) 

In the example above, @lazy-array is an Array which, through construction, is made lazy. Calling is-lazy on it actually calls the method mixed in by the role Iterator, which, since it originates in a lazy list, is itself lazy.

A common use case for lazy Seqs is the processing of infinite sequences of numbers, whose values have not been computed yet and cannot be computed in their entirety. Specific values in the List will only be computed when they are needed.

my  $l := 1, 2, 4, 8 ... Inf; 
 say $l[0..16]; 
 #OUTPUT: «(1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768 65536)␤» 

You can easily assign lazy objects to other objects, conserving their laziness:

my  $l := 1, 2, 4, 8 ... Inf; # This is a lazy Seq.
my  @lazy-array = $l;
say @lazy-array[10..15]; # OUTPUT: «(1024 2048 4096 8192 16384 32768)␤»
say @lazy-array.is-lazy; # OUTPUT: «True␤»

Immutability

The lists we have talked about so far (List, Seq and Slip) are all immutable. This means you cannot remove elements from them, or re-bind existing elements:

(1, 2, 3)[0]:delete; # Error Can not remove elements from a List 
 (1, 2, 3)[0] := 0;   # Error Cannot use bind operator with this left-hand side 
 (1, 2, 3)[0] = 0;    # Error Cannot modify an immutable Int 

However, if any of the elements is wrapped in a Scalar you can still change the value which that Scalar points to:

my $a = 2;
(1, $a, 3)[1] = 42;
$a.say;            # OUTPUT: «42␤»

that is, it is only the list structure itself – how many elements there are and each element's identity – that is immutable. The immutability is not contagious past the identity of the element.

List contexts

So far we have mostly dealt with lists in neutral contexts. Lists are actually very context sensitive on a syntactical level.

List assignment context

When a list (or something that is going to be converted into a list) appears on the right-hand side of an assignment into a @-sigiled variable, it is "eagerly" evaluated. This means that a Seq will be iterated until it can produce no more elements, for instance. This is one of the places you do not want to put an infinite list, lest your program hang and, eventually, run out of memory:

my @divisors = (gather {
    for <2 3 5 7> {
        take $_ if 70 %% $_;
    }
});
say @divisors; # OUTPUT: «[2 5 7]␤»

The gather statement creates a lazy list, which is eagerly evaluated when assigned to @divisors.

Flattening "context"

When you have a list that contains sub-lists, but you only want one flat list, you may flatten the list to produce a sequence of values as if all parentheses were removed. This works no matter how many levels deep the parentheses are nested.

say (1, (2, (3, 4)), 5).flat eqv (1, 2, 3, 4, 5) # OUTPUT: «True␤»

This is not really a syntactical "context" as much as it is a process of iteration, but it has the appearance of a context.

Note that Scalar s around a list will make it immune to flattening:

for (1, (2, $(3, 4)), 5).flat { .say } # OUTPUT: «1␤2␤(3 4)␤5␤»

...but an @-sigiled variable will spill its elements.

my @l := 2, (3, 4);
for (1, @l, 5).flat { .say };      # OUTPUT: «1␤2␤3␤4␤5␤»
my @a = 2, (3, 4);                 # Arrays are special, see below
for (1, @a, 5).flat { .say };      # OUTPUT: «1␤2␤(3 4)␤5␤»

Argument list (Capture) context

When a list appears as arguments to a function or method call, special syntax rules are at play: the list is immediately converted into a Capture. A Capture itself has a List (.list) and a Hash (.hash). Any Pair literals whose keys are not quoted, or which are not parenthesized, never make it into .list. Instead, they are considered to be named arguments and squashed into .hash. See the page on Capture for the details of this processing.

Consider the following ways to make a new Array from a List. These ways place the List in an argument list context and because of that, the Array only contains 1 and 2 but not the Pair :c(3), which is ignored.

Array.new(1, 2, :c(3));
Array.new: 1, 2, :c(3);
new Array: 1, 2, :c(3);

In contrast, these ways do not place the List in argument list context, so all the elements, even the Pair :c(3), are placed in the Array.

Array.new((1, 2, :c(3)));
(1, 2, :c(3)).Array;
my @a = 1, 2, :c(3); Array.new(@a);
my @a = 1, 2, :c(3); Array.new: @a;
my @a = 1, 2, :c(3); new Array: @a;

In argument list context the | prefix operator applied to a Positional will always slip list elements as positional arguments to the Capture, while a | prefix operator applied to an Associative will slip pairs in as named parameters:

my @a := 2, "c" => 3;
Array.new(1, |@a, 4);    # Array contains 1, 2, :c(3), 4
my %a = "c" => 3;
Array.new(1, |%a, 4);    # Array contains 1, 4

Slice indexing context

From the perspective of the List inside a slice subscript, is only remarkable in that it is unremarkable: because adverbs to a slice are attached after the ], the inside of a slice is not an argument list, and no special processing of pair forms happens.

Most Positional types will enforce an integer coercion on each element of a slice index, so pairs appearing there will generate an error, anyway:

(1, 2, 3)[1, 2, :c(3)] # OUTPUT: «Method 'Int' not found for invocant of class 'Pair'␤» 

...however this is entirely up to the type – if it defines an order for pairs, it could consider :c(3) a valid index.

Indices inside a slice are usually not automatically flattened, but neither are sublists usually coerced to Int. Instead, the list structure is kept intact, causing a nested slice operation that replicates the structure in the result:

say ("a", "b", "c")[(1, 2), (0, 1)] eqv (("b", "c"), ("a", "b")) # OUTPUT: «True␤»

Slices can be taken also across several dimensions using semilists, which are lists of slices separated by semicolons:

my @sliceable = [[ ^10 ], ['a'..'h'], ['Ⅰ'..'Ⅺ']];
say @sliceable[ ^3; 4..6 ]; #OUTPUT: «(4 5 6 e f g Ⅴ Ⅵ Ⅶ)␤»

which is selecting the 4 to 6th element from the three first dimensions (^3).

Range as slice

A Range is a container for a lower and an upper boundary, either of which may be excluded. Generating a slice with a Range will include any index between the bounds, though an infinite Range will truncate non-existent elements. An infinite range with excluded upper boundary (e.g. 0..^Inf) is still infinite and will reach all elements.

my @a = 1..5;
say @a[0..2];     # OUTPUT: «(1 2 3)␤»
say @a[0..^2];    # OUTPUT: «(1 2)␤»
say @a[0..*];     # OUTPUT: «(1 2 3 4 5)␤»
say @a[0..^*];    # OUTPUT: «(1 2 3 4 5)␤»
say @a[0..Inf-1]; # OUTPUT: «(1 2 3 4 5)␤»

Note that when the upper boundary is a WhateverCode instead of just a Whatever, the range is not infinite but becomes a Callable producing Ranges. This is normal behavior of the .. operator. The subscript operator [] evaluates the WhateverCode providing the list's .elems as an argument and uses the resulting range to slice:

    say @a[0..*-1];   # OUTPUT: «(1 2 3 4 5)␤» 
     say @a[0..^*-1];  # OUTPUT: «(1 2 3 4)␤» 
     # Produces 0..^2.5 as the slice range 
     say @a[0..^*/2];  # OUTPUT: «(1 2 3)␤» 

Notice that 0..^* and 0..^*+0 behave consistently in subscripts despite one being an infinite range and the other a WhateverCode producing ranges, but 0..*+0 will give you an additional trailing Nil because, unlike the infinite range 0..*, it does not truncate.

Array constructor context

Inside an Array Literal, the list of initialization values is not in capture context and is just a normal list. It is, however, eagerly evaluated just as in assignment.

say so [ 1, 2, :c(3) ] eqv Array.new((1, 2, :c(3))); # OUTPUT: «True␤»
[while $++ < 2 { 42.say; 43 }].map: *.say;           # OUTPUT: «42␤42␤43␤43␤»
(while $++ < 2 { 42.say; 43 }).map: *.say;           # OUTPUT: «42␤43␤42␤43␤»

Which brings us to Arrays...

Arrays

Arrays differ from lists in three major ways: Their elements may be typed, they automatically itemize their elements, and they are mutable. Otherwise they are Lists and are accepted wherever lists are.

say Array ~~ List     # OUTPUT: «True␤»

A fourth, more subtle, way they differ is that when working with Arrays, it can sometimes be harder to maintain laziness or work with infinite sequences.

Typing

Arrays may be typed such that their slots perform a typecheck whenever they are assigned to. An Array that only allows Int values to be assigned is of type Array[Int] and one can create one with Array[Int].new. If you intend to use an @-sigiled variable only for this purpose, you may change its type by specifying the type of the elements when declaring it:

my Int @a = 1, 2, 3;              # An Array that contains only Ints 
 # the same as 
 my @a of Int = 1, 2, 3;           # An Array of Ints 
 my @b := Array[Int].new(1, 2, 3); # Same thing, but the variable is not typed 
 my @b := Array[Int](1, 2, 3);     # Rakudo shortcut for the same code 
 say @b eqv @a;                    # says True. 
 my @c = 1, 2, 3;                  # An Array that can contain anything 
 say @b eqv @c;                    # says False because types do not match 
 say @c eqv (1, 2, 3);             # says False because one is a List 
 say @b eq @c;                     # says True, because eq only checks values 
 say @b eq (1, 2, 3);              # says True, because eq only checks values 
 
 @a[0] = 42;                       # fine 
 @a[0] = "foo";                    # error: Type check failed in assignment 

In the above example we bound a typed Array object to a @-sigil variable for which no type had been specified. The other way around does not work – you may not bind an Array that has the wrong type to a typed @-sigiled variable:

my @a := Array[Int].new(1, 2, 3);     # fine 
 @a := Array[Str].new("a", "b");       # fine, can be re-bound 
 my Int @b := Array[Int].new(1, 2, 3); # fine 
 @b := Array.new(1, 2, 3);             # error: Type check failed in binding 

When working with typed arrays, it is important to remember that they are nominally typed. This means the declared type of an array is what matters. Given the following sub declaration:

sub mean(Int @a) {
    @a.sum / @a.elems
}

Calls that pass an Array[Int] will be successful:

my Int @b = 1, 3, 5; 
 say mean(@b);                       # @b is Array[Int] 
 say mean(Array[Int].new(1, 3, 5));  # Anonymous Array[Int] 
 say mean(my Int @ = 1, 3, 5);       # Another anonymous Array[Int] 

However, the following calls will all fail, due to passing an untyped array, even if the array just happens to contain Int values at the point it is passed:

my @c = 1, 3, 5; 
 say mean(@c);                       # Fails, passing untyped Array 
 say mean([1, 3, 5]);                # Same 
 say mean(Array.new(1, 3, 5));       # Same again 

Note that in any given compiler, there may be fancy, under-the-hood, ways to bypass the type check on arrays, so when handling untrusted input, it can be good practice to perform additional type checks, where it matters:

for @a -> Int $i { $_++.say }; 

However, as long as you stick to normal assignment operations inside a trusted area of code, this will not be a problem, and typecheck errors will happen promptly during assignment to the array, if they cannot be caught at compile time. None of the core functions provided in Perl 6 for operating on lists should ever produce a wonky typed Array.

Nonexistent elements (when indexed), or elements to which Nil has been assigned, will assume a default value. This default may be adjusted on a variable-by-variable basis with the is default trait. Note that an untyped @-sigiled variable has an element type of Mu, however its default value is an undefined Any:

my @a;
@a.of.perl.say;                 # OUTPUT: «Mu␤»
@a.default.perl.say;            # OUTPUT: «Any␤»
@a[0].say;                      # OUTPUT: «(Any)␤»
my Numeric @n is default(Real);
@n.of.perl.say;                 # OUTPUT: «Numeric␤»
@n.default.perl.say;            # OUTPUT: «Real␤»
@n[0].say;                      # OUTPUT: «(Real)␤»

Fixed size arrays

To limit the dimensions of an Array, provide the dimensions separated by , or ; in square brackets after the name of the array container in case there is more than one dimension; these are called shaped arrays too. The values of such a kind of Array will default to Any. The shape can be accessed at runtime via the shape method.

my @a[2,2];
say @a.perl;
# OUTPUT: «Array.new(:shape(2, 2), [Any, Any], [Any, Any])␤»
say @a.shape;         # OUTPUT: «(2 2)␤»
my @just-three[3] = <alpha beta kappa>;
say @just-three.perl;
# OUTPUT: «Array.new(:shape(3,), ["alpha", "beta", "kappa"])␤»

Shape will control the amount of elements that can be assigned by dimension:

my @just-two[2] = <alpha beta kappa>; 
 # Will throw exception: «Index 2 for dimension 1 out of range (must be 0..1)» 

Assignment to a fixed size Array will promote a List of Lists to an Array of Arrays (making then mutable in the process).

my @a[2;2] = (1,2; 3,4);
say @a.Array; # OUTPUT: «[1 2 3 4]␤»
@a[1;1] = 42;
say @a.perl;
# OUTPUT: «Array.new(:shape(2, 2), [1, 2], [3, 42])␤»

As the third statement shows, you can assign directly to an element in a shaped array too. Note: the second statement works only from version 2018.09.

Itemization

For most uses, Arrays consist of a number of slots each containing a Scalar of the correct type. Every such Scalar, in turn, contains a value of that type. Perl 6 will automatically type-check values and create Scalars to contain them when Arrays are initialized, assigned to, or constructed.

This is actually one of the trickiest parts of Perl 6 list handling to get a firm understanding of.

First, be aware that because itemization in Arrays is assumed, it essentially means that $(…)s are being put around everything that you assign to an array, if you do not put them there yourself. On the other side, Array.perl does not put $ to explicitly show scalars, unlike List.perl:

((1, 2), $(3, 4)).perl.say; # says "((1, 2), $(3, 4))"
[(1, 2), $(3, 4)].perl.say; # says "[(1, 2), (3, 4)]"
                            # ...but actually means: "[$(1, 2), $(3, 4)]"

It was decided all those extra dollar signs and parentheses were more of an eye sore than a benefit to the user. Basically, when you see a square bracket, remember the invisible dollar signs.

Second, remember that these invisible dollar signs also protect against flattening, so you cannot really flatten the elements inside of an Array with a normal call to flat or .flat.

((1, 2), $(3, 4)).flat.perl.say; # OUTPUT: «(1, 2, $(3, 4)).Seq␤»
[(1, 2), $(3, 4)].flat.perl.say; # OUTPUT: «($(1, 2), $(3, 4)).Seq␤»

Since the square brackets do not themselves protect against flattening, you can still spill the elements out of an Array into a surrounding list using flat.

(0, [(1, 2), $(3, 4)], 5).flat.perl.say; # OUTPUT: «(0, $(1, 2), $(3, 4), 5).Seq␤»

...the elements themselves, however, stay in one piece.

This can irk users of data you provide if you have deeply nested Arrays where they want flat data. Currently they have to deeply map the structure by hand to undo the nesting:

say gather [0, [(1, 2), [3, 4]], $(5, 6)].deepmap: *.take; # OUTPUT: «(1 2 3 4 5 6)␤»

... Future versions of Perl 6 might find a way to make this easier. However, not returning Arrays or itemized lists from functions, when non-itemized lists are sufficient, is something that one should consider as a courtesy to their users:

The fact that all elements of an array are itemized (in Scalar containers) is more a gentleman's agreement than a universally enforced rule, and it is less well enforced that typechecks in typed arrays. See the section below on binding to Array slots.

Literal arrays

Literal Arrays are constructed with a List inside square brackets. The List is eagerly iterated (at compile time if possible) and values in it are each type-checked and itemized. The square brackets themselves will spill elements into surrounding lists when flattened, but the elements themselves will not spill due to the itemization.

Mutability

Unlike lists, Arrays are mutable. Elements may deleted, added, or changed.

my @a = "a", "b", "c";
@a.say;                  # OUTPUT: «[a b c]␤»
@a.pop.say;              # OUTPUT: «c␤»
@a.say;                  # OUTPUT: «[a b]␤»
@a.push("d");
@a.say;                  # OUTPUT: «[a b d]␤»
@a[1, 3] = "c", "c";
@a.say;                  # OUTPUT: «[a c d c]␤»

Assigning

Assignment of a list to an Array is eager. The list will be entirely evaluated, and should not be infinite or the program may hang. Assignment to a slice of an Array is, likewise, eager, but only up to the requested number of elements, which may be finite:

my @a;
@a[0, 1, 2] = (loop { 42 });
@a.say;                     # OUTPUT: «[42 42 42]␤»

During assignment, each value will be typechecked to ensure it is a permitted type for the Array. Any Scalar will be stripped from each value and a new Scalar will be wrapped around it.

Binding

Individual Array slots may be bound the same way $-sigiled variables are:

my $b = "foo";
my @a = 1, 2, 3;
@a[2] := $b;
@a.say;          # OUTPUT: «[1 2 "foo"]␤»
$b = "bar";
@a.say;          # OUTPUT: «[1 2 "bar"]␤»

... But binding Array slots directly to values is strongly discouraged. If you do, expect surprises with built-in functions. The only time this would be done is if a mutable container that knows the difference between values and Scalar-wrapped values is needed, or for very large Arrays where a native-typed array cannot be used. Such a creature should never be passed back to unsuspecting users.

54 Meta-object protocol (MOP)

Introspection and the Perl 6 object system

Perl 6 is built on a meta object layer. That means that there are objects (the meta objects) that control how various object-oriented constructs (such as classes, roles, methods, attributes or enums) behave.

The meta object has a practical benefit to the user when a normal object's type is needed. For example:

my $arr = [1, 2]; 
 sub show-type($arr) { 
     my $type = $arr.^name; 
     say $type; 
 } 
 show-type $arr; # OUTPUT: «Array␤» 

To get a more in-depth understanding of the meta object for a class, here is an example repeated twice: once as normal declarations in Perl 6, and once expressed through the meta model:

class A {
    method x() { say 42 }
}

A.x();

corresponds to:

constant A := Metamodel::ClassHOW.new_type( name => 'A' );  # class A {
A.^add_method('x', my method x(A:) { say 42 });             #   method x()
A.^compose;                                                 # }

A.x();

(except that the declarative form is executed at compile time, and the latter form does not).

The meta object behind an object can be obtained with $obj.HOW, where HOW stands for Higher Order Workings (or, HOW the *%@$ does this work?).

Here, the calls with .^ are calls to the meta object, so A.^compose is a shortcut for A.HOW.compose(A). The invocant is passed in the parameter list as well, to make it possible to support prototype-style type systems, where there is just one meta object (and not one meta object per type, as standard Perl 6 does it).

As the example above demonstrates, all object oriented features are available to the user, not just to the compiler. In fact the compiler just uses such calls to meta objects.

Metamethods

These are introspective macros that resemble method calls.

Metamethods are generally named with ALLCAPS, and it is considered good style to avoid creating your own methods with ALLCAPS names. This will avoid conflicts with any metamethods that may appear in future versions of the language.

WHAT

The type object of the type. This is a pseudo-method that can be overloaded without producing error or warning, but will be ignored.

For example 42.WHAT returns the Int type object.

WHICH

The object's identity value. This can be used for hashing and identity comparison, and is how the === infix operator is implemented.

WHO

The package supporting the object.

WHERE

The memory address of the object. Note that this is not stable in implementations with moving/compacting garbage collectors. Use WHICH for a stable identity indicator.

HOW

Returns the metaclass object, as in "Higher Order Workings".

say (%).HOW.^name # OUTPUT: «Perl6::Metamodel::ClassHOW+{<anon>}␤»

HOW returns an object of type Perl6::Metamodel::ClassHOW in this case; objects of this type are used to build classes. The same operation on the & sigil will return Perl6::Metamodel::ParametricRoleGroupHOW. You will be calling this object whenever you use the ^ syntax to access meta methods. In fact, the code above is equivalent to say (&).HOW.HOW.name(&) which is much more unwieldy. Metamodel::ClassHOW is part of the Rakudo implementation, so use with caution.

WHY

The attached Pod value.

DEFINITE

The object has a valid concrete representation. This is a pseudo-method that can be overloaded without producing error or warning, but will be ignored.

Returns True for instances and False for type objects.

VAR

Returns the underlying Scalar object, if there is one.

The presence of a Scalar object indicates that the object is "itemized".

.say for (1, 2, 3);           # OUTPUT: «1␤2␤3␤», not itemized
.say for $(1, 2, 3);          # OUTPUT: «(1 2 3)␤», itemized
say (1, 2, 3).VAR ~~ Scalar;  # OUTPUT: «False␤»
say $(1, 2, 3).VAR ~~ Scalar; # OUTPUT: «True␤»

Structure of the meta object system

Note: this documentation largely reflects the meta object system as implemented by the Rakudo Perl 6 compiler, since the design documents are very light on details.

For each type declarator keyword, such as class, role, enum, module, package, grammar or subset, there is a separate meta class in the Metamodel:: namespace. (Rakudo implements them in the Perl6::Metamodel:: namespace, and then maps Perl6::Metamodel to Metamodel).

Many of the these meta classes share common functionality. For example roles, grammars and classes can all contain methods and attributes, as well as being able to do roles. This shared functionality is implemented in roles which are composed into the appropriate meta classes. For example role Metamodel::RoleContainer implements the functionality that a type can hold roles and Metamodel::ClassHOW, which is the meta class behind the class keyword, does this role.

Most meta classes have a compose method that you must call when you're done creating or modifying a meta object. It creates method caches, validates things and so on, and weird behavior ensues if you forget to call it, so don't :-).

Bootstrapping concerns

You might wonder how Metamodel::ClassHOW can be a class, when being a class is defined in terms of Metamodel::ClassHOW, or how the roles responsible for role handling can be roles. The answer is by magic.

Just kidding. Bootstrapping is implementation specific. Rakudo does it by using the object system of the language in which itself is implemented, which happens to be (nearly) a subset of Perl 6: NQP, Not Quite Perl. NQP has a primitive, class-like kind called knowhow, which is used to bootstrap its own classes and roles implementation. knowhow is built on primitives that the virtual machine under NQP provides.

Since the object model is bootstrapped in terms of lower-level types, introspection can sometimes return low-level types instead of the ones you expect, like an NQP-level routine instead of a normal Routine object, or a bootstrap-attribute instead of Attribute.

Composition time and static reasoning

In Perl 6, a type is constructed as it is parsed, so in the beginning, it must be mutable. However if all types were always mutable, all reasoning about them would get invalidated at any modification of a type. For example the list of parent types and thus the result of type checking can change during that time.

So to get the best of both worlds, there is a time when a type transitions from mutable to immutable. This is called composition, and for syntactically declared types, it happens when the type declaration is fully parsed (so usually when the closing curly brace is parsed).

If you create types through the meta-object system directly, you must call .^compose on them before they become fully functional.

Most meta classes also use composition time to calculate some properties like the method resolution order, publish a method cache, and other house-keeping tasks. Meddling with types after they have been composed is sometimes possible, but usually a recipe for disaster. Don't do it.

Power and responsibility

The meta object protocol offers much power that regular Perl 6 code intentionally limits, such as calling private methods on classes that don't trust you, peeking into private attributes, and other things that usually simply aren't done.

Regular Perl 6 code has many safety checks in place; not so the meta model. It is close to the underlying virtual machine, and violating the contracts with the VM can lead to all sorts of strange behaviors that, in normal code, would obviously be bugs.

So be extra careful and thoughtful when writing meta types.

Power, convenience and pitfalls

The meta object protocol is designed to be powerful enough to implement the Perl 6 object system. This power occasionally comes at the cost of convenience.

For example, when you write my $x = 42 and then proceed to call methods on $x, most of these methods end up acting on the integer 42, not on the scalar container in which it is stored. This is a piece of convenience found in ordinary Perl 6. Many parts of the meta object protocol cannot afford to offer the convenience of automatically ignoring scalar containers, because they are used to implement those scalar containers as well. So if you write my $t = MyType; ... ; $t.^compose you are composing the Scalar that the $-sigiled variable implies, not MyType.

The consequence is that you need to have a rather detailed understanding of the subtleties of Perl 6 in order to avoid pitfalls when working with the MOP, and can't expect the same "do what I mean" convenience that ordinary Perl 6 code offers.

55 Native calling interface

Call into dynamic libraries that follow the C calling convention

Getting started

The simplest imaginable use of NativeCall would look something like this:

use NativeCall;
sub some_argless_function() is native('something') { * }
some_argless_function();

The first line imports various traits and types. The next line looks like a relatively ordinary Perl 6 sub declaration—with a twist. We use the "native" trait in order to specify that the sub is actually defined in a native library. The platform-specific extension (e.g., .so or .dll), as well as any customary prefixes (e.g., 'lib') will be added for you.

The first time you call "some_argless_function", the "libsomething" will be loaded and the "some_argless_function" will be located in it. A call will then be made. Subsequent calls will be faster, since the symbol handle is retained.

Of course, most functions take arguments or return values—but everything else that you can do is just adding to this simple pattern of declaring a Perl 6 sub, naming it after the symbol you want to call and marking it with the "native" trait.

You will also need to declare and use native types. Please check the native types page for more information.

Changing names

Sometimes you want the name of your Perl subroutine to be different from the name used in the library you're loading. Maybe the name is long or has different casing or is otherwise cumbersome within the context of the module you are trying to create.

NativeCall provides a symbol trait for you to specify the name of the native routine in your library that may be different from your Perl subroutine name.

unit module Foo; 
 use NativeCall; 
 our sub init() is native('foo') is symbol('FOO_INIT') { * } 

Inside of libfoo there is a routine called FOO_INIT but, since we're creating a module called Foo and we'd rather call the routine as Foo::init, we use the symbol trait to specify the name of the symbol in libfoo and call the subroutine whatever we want ("init" in this case).

Passing and returning values

Normal Perl 6 signatures and the returns trait are used in order to convey the type of arguments a native function expects and what it returns. Here is an example.

use NativeCall;
sub add(int32, int32) returns int32 is native("calculator") { * }

Here, we have declared that the function takes two 32-bit integers and returns a 32-bit integer. You can find the other types that you may pass in the native types page. Note that the lack of a returns trait is used to indicate void return type. Do not use the void type anywhere except in the Pointer parameterization.

For strings, there is an additional encoded trait to give some extra hints on how to do the marshaling.

use NativeCall;
sub message_box(Str is encoded('utf8')) is native('gui') { * }

To specify how to marshal string return types, just apply this trait to the routine itself.

use NativeCall;
sub input_box() returns Str is encoded('utf8') is native('gui') { * }

Note that a NULL string pointer can be passed by passing the Str type object; a NULL return will also be represented by the type object.

If the C function requires the lifetime of a string to exceed the function call, the argument must be manually encoded and passed as CArray[uint8]:

use NativeCall;
# C prototype is void set_foo(const char *)
sub set_foo(CArray[uint8]) is native('foo') { * }
# C prototype is void use_foo(void)
sub use_foo() is native('foo') { * } # will use pointer stored by set_foo()

my $string = "FOO";
# The lifetime of this variable must be equal to the required lifetime of
# the data passed to the C function.
my $array = CArray[uint8].new($string.encode.list);

set_foo($array);
# ...
use_foo();
# It's fine if $array goes out of scope starting from here.

Specifying the native representation

When working with native functions, sometimes you need to specify what kind of native data structure is going to be used. is repr is the term employed for that.

use NativeCall; 
 
 class timespec is repr('CStruct') { 
     has uint32 $.tv_sec; 
     has long $.tv_nanosecs; 
 } 
 
 sub clock_gettime(uint32 $clock-id, timespec $tspec --> uint32) is native { * }; 
 
 my timespec $this-time .=new; 
 
 my $result = clock_gettime( 0, $this-time); 
 
 say "$result, $this-time"; # OUTPUT: «0, timespec<65385480>␤» 

The original function we are calling, clock_gettime, uses a pointer to the timespec struct as second argument. We declare it as a class here, but specify its representation as is repr('CStruct'), to indicate it corresponds to a C data structure. When we create an object of that class, we are creating exactly the kind of pointer clock_gettime expects. This way, data can be transferred seamlessly to and from the native interface.

Basic use of pointers

When the signature of your native function needs a pointer to some native type (int32, uint32, etc.) all you need to do is declare the argument is rw :

use NativeCall;
# C prototype is void my_version(int *major, int *minor)
sub my_version(int32 is rw, int32 is rw) is native('foo') { * }
my_version(my int32 $major, my int32 $minor); # Pass a pointer to

Sometimes you need to get a pointer (for example, a library handle) back from a C library. You don't care about what it points to - you just need to keep hold of it. The Pointer type provides for this.

use NativeCall;
sub Foo_init() returns Pointer is native("foo") { * }
sub Foo_free(Pointer) is native("foo") { * }

This works out OK, but you may fancy working with a type named something better than Pointer. It turns out that any class with the representation "CPointer" can serve this role. This means you can expose libraries that work on handles by writing a class like this:

use NativeCall; 
 
 class FooHandle is repr('CPointer') { 
     # Here are the actual NativeCall functions. 
     sub Foo_init() returns FooHandle is native("foo") { * } 
     sub Foo_free(FooHandle) is native("foo") { * } 
     sub Foo_query(FooHandle, Str) returns int8 is native("foo") { * } 
     sub Foo_close(FooHandle) returns int8 is native("foo") { * } 
 
     # Here are the methods we use to expose it to the outside world. 
     method new { 
         Foo_init(); 
     } 
 
     method query(Str $stmt) { 
         Foo_query(self, $stmt); 
     } 
 
     method close { 
         Foo_close(self); 
     } 
 
     # Free data when the object is garbage collected. 
     submethod DESTROY { 
         Foo_free(self); 
     } 
 } 

Note that the CPointer representation can do nothing more than hold a C pointer. This means that your class cannot have extra attributes. However, for simple libraries this may be a neat way to expose an object oriented interface to it.

Of course, you can always have an empty class:

class DoorHandle is repr('CPointer') { }

And just use the class as you would use Pointer, but with potential for better type safety and more readable code.

Once again, type objects are used to represent NULL pointers.

Function pointers

C libraries can expose pointers to C functions as return values of functions and as members of Structures like, e.g., structs and unions.

Example of invoking a function pointer "$fptr" returned by a function "f", using a signature defining the desired function parameters and return value:

sub f() returns Pointer is native('mylib') { * } 
 
 my $fptr    = f(); 
 my &newfunc = nativecast(:(Str, size_t --> int32), $fptr); 
 
 say newfunc("test", 4); 

Arrays

NativeCall has some support for arrays. It is constrained to work with machine-size integers, doubles and strings, sized numeric types, arrays of pointers, arrays of structs, and arrays of arrays.

Perl 6 arrays, which support amongst other things laziness, are laid out in memory in a radically different way to C arrays. Therefore, the NativeCall library offers a much more primitive CArray type, which you must use if working with C arrays.

Here is an example of passing a C array.

sub RenderBarChart(Str, int32, CArray[Str], CArray[num64]) is native("chart") { * } 
 my @titles := CArray[Str].new; 
 @titles[0]  = 'Me'; 
 @titles[1]  = 'You'; 
 @titles[2]  = 'Hagrid'; 
 my @values := CArray[num64].new; 
 @values[0]  = 59.5e0; 
 @values[1]  = 61.2e0; 
 @values[2]  = 180.7e0; 
 RenderBarChart('Weights (kg)', 3, @titles, @values); 

Note that binding was used to @titles, not assignment! If you assign, you are putting the values into a Perl 6 array, and it will not work out. If this all freaks you out, forget you ever knew anything about the @ sigil and just use $ all the way when using NativeCall.

use NativeCall;
my $titles = CArray[Str].new;
$titles[0] = 'Me';
$titles[1] = 'You';
$titles[2] = 'Hagrid';

Getting return values for arrays works out just the same.

Some library APIs may take an array as a buffer that will be populated by the C function and, for instance, return the actual number of items populated:

use NativeCall;
sub get_n_ints(CArray[int32], int32) returns int32 is native('ints') { * }

In these cases it is important that the CArray has at least the number of elements that are going to be populated before passing it to the native subroutine, otherwise the C function may stomp all over Perl's memory leading to possibly unpredictable behavior:

my $number_of_ints = 10; 
 my $ints = CArray[int32].allocate($number_of_ints); # instantiates an array with 10 elements 
 my $n = get_n_ints($ints, $number_of_ints); 

Note: allocate was introduced in Rakudo 2018.05. Before that, you had to use this mechanism to extend an array to a number of elements:

my $ints = CArray[int32].new; 
 my $number_of_ints = 10; 
 $ints[$number_of_ints - 1] = 0; # extend the array to 10 items 

The memory management of arrays is important to understand. When you create an array yourself, then you can add elements to it as you wish and it will be expanded for you as required. However, this may result in it being moved in memory (assignments to existing elements will never cause this, however). This means you'd best know what you're doing if you twiddle with an array after passing it to a C library.

By contrast, when a C library returns an array to you, then the memory can not be managed by NativeCall, and it doesn't know where the array ends. Presumably, something in the library API tells you this (for example, you know that when you see a null element, you should read no further). Note that NativeCall can offer you no protection whatsoever here - do the wrong thing, and you will get a segfault or cause memory corruption. This isn't a shortcoming of NativeCall, it's the way the big bad native world works. Scared? Here, have a hug. Good luck!

CArray methods

Besides the usual methods available on every Perl 6 instance, CArray provides the following methods that can be used to interact with the it from the Perl 6 point of view:

As an example, consider the following simple piece of code:

use NativeCall; 
 
 my $native-array = CArray[int32].new( 1, 2, 3, 4, 5 ); 
 say 'Number of elements: ' ~ $native-array.elems; 
 
 # walk the array 
 for $native-array.list -> $elem { 
     say "Current element is: $elem"; 
 } 
 
 # get every element by its index-based position 
 for 0..$native-array.elems - 1 -> $position { 
     say "Element at position $position is " 
           ~ $native-array.AT-POS( $position ); 
 } 
 

that produces the following output

Number of elements: 5 
 Current element is: 1 
 Current element is: 2 
 Current element is: 3 
 Current element is: 4 
 Current element is: 5 
 Element at position 0 is 1 
 Element at position 1 is 2 
 Element at position 2 is 3 
 Element at position 3 is 4 
 Element at position 4 is 5 

Structs

Thanks to representation polymorphism, it's possible to declare a normal looking Perl 6 class that, under the hood, stores its attributes in the same way a C compiler would lay them out in a similar struct definition. All it takes is a quick use of the "repr" trait:

class Point is repr('CStruct') {
    has num64 $.x;
    has num64 $.y;
}

The attributes can only be of the types that NativeCall knows how to marshal into struct fields. Currently, structs can contain machine-sized integers, doubles, strings, and other NativeCall objects (CArrays, and those using the CPointer and CStruct reprs). Other than that, you can do the usual set of things you would with a class; you could even have some of the attributes come from roles or have them inherited from another class. Of course, methods are completely fine too. Go wild!

CStruct objects are passed to native functions by reference and native functions must also return CStruct objects by reference. The memory management rules for these references are very much like the rules for arrays, though simpler since a struct is never resized. When you create a struct, the memory is managed for you and when the variable(s) pointing to the instance of a CStruct go away, the memory will be freed when the GC gets to it. When a CStruct-based type is used as the return type of a native function, the memory is not managed for you by the GC.

NativeCall currently doesn't put object members in containers, so assigning new values to them (with =) doesn't work. Instead, you have to bind new values to the private members:

class MyStruct is repr('CStruct') { 
     has CArray[num64] $!arr; 
     has Str $!str; 
     has Point $!point; # Point is a user-defined class 
 
     submethod TWEAK { 
         my $arr := CArray[num64].new; 
         $arr[0] = 0.9e0; 
         $arr[1] = 0.2e0; 
         $!arr := $arr; 
         $!str := 'Perl 6 is fun'; 
         $!point := Point.new; 
     } 
 } 

As you may have predicted by now, a NULL pointer is represented by the type object of the struct type.

CUnions

Likewise, it is possible to declare a Perl 6 class that stores its attributes the same way a C compiler would lay them out in a similar union definition; using the CUnion representation:

use NativeCall; 
 
 class MyUnion is repr('CUnion') { 
     has int32 $.flags32; 
     has int64 $.flags64; 
 } 
 
 say nativesizeof(MyUnion.new);  # OUTPUT: «8␤» 
                                 # ie. max(sizeof(MyUnion.flags32), sizeof(MyUnion.flags64)) 

Embedding CStructs and CUnions

CStructs and CUnions can be in turn referenced by—or embedded into—a surrounding CStruct and CUnion. To say the former we use has as usual, and to do the latter we use the HAS declarator instead:

class MyStruct is repr('CStruct') { 
     has Point $.point;  # referenced 
     has int32 $.flags; 
 } 
 
 say nativesizeof(MyStruct.new);  # OUTPUT: «16␤» 
                                  # ie. sizeof(struct Point *) + sizeof(int32_t) 
 
 class MyStruct2 is repr('CStruct') { 
     HAS Point $.point;  # embedded 
     has int32 $.flags; 
 } 
 
 say nativesizeof(MyStruct2.new);  # OUTPUT: «24␤» 
                                   # ie. sizeof(struct Point) + sizeof(int32_t) 

Notes on memory management

When allocating a struct for use as a struct, make sure that you allocate your own memory in your C functions. If you're passing a struct into a C function which needs a Str/char* allocated ahead of time, be sure to assign a container for a variable of type Str prior to passing your struct into the function.

In your Perl 6 code...

class AStringAndAnInt is repr("CStruct") { 
   has Str $.a_string; 
   has int32 $.an_int32; 
 
   sub init_struct(AStringAndAnInt is rw, Str, int32) is native('simple-struct') { * } 
 
   submethod BUILD(:$a_string, :$an_int) { 
     init_struct(self, $a_string, $an_int); 
   } 
 } 
 

In this code we first set up our members, $.a_string and $.an_int32. After that we declare our init_struct() function for the init() method to wrap around; this function is then called from BUILD to effectively assign the values before returning the created object.

In your C code...

typedef struct a_string_and_an_int32_t_ { 
   char *a_string; 
   int32_t an_int32; 
 } a_string_and_an_int32_t; 
 

Here's the structure. Notice how we've got a char * there.

void init_struct(a_string_and_an_int32_t *target, char *str, int32_t int32) { 
   target->an_int32 = int32; 
   target->a_string = strdup(str); 
 
   return; 
 } 
 

In this function we initialize the C structure by assigning an integer by value, and passing the string by reference. The function allocates memory that it points <char *a_string> to within the structure as it copies the string. (Note you will also have to manage deallocation of the memory as well to avoid memory leaks.)

# A long time ago in a galaxy far, far away... 
 my $foo = AStringAndAnInt.new(a_string => "str", an_int => 123); 
 say "foo is {$foo.a_string} and {$foo.an_int32}"; 
 # OUTPUT: «foo is str and 123␤» 

Typed pointers

You can type your Pointer by passing the type as a parameter. It works with the native type but also with CArray and CStruct defined types. NativeCall will not implicitly allocate the memory for it even when calling new on them. It's mostly useful in the case of a C routine returning a pointer, or if it's a pointer embedded in a CStruct.

use NativeCall; 
 sub strdup(Str $s --> Pointer[Str]) is native {*} 
 my Pointer[Str] $p = strdup("Success!"); 
 say $p.deref; 

You have to call .deref on Pointers to access the embedded type. In the example above, declaring the type of the pointer avoids typecasting error when dereferenced. Please note that the original strdup returns a pointer to char; we are using Pointer<Str>.

my Pointer[int32] $p; #For a pointer on int32; 
 my Pointer[MyCstruct] $p2 = some_c_routine(); 
 my MyCstruct $mc = $p2.deref; 
 say $mc.field1; 

It's quite common for a native function to return a pointer to an array of elements. Typed pointers can be dereferenced as an array to obtain individual elements.

my $n = 5; 
 # returns a pointer to an array of length $n 
 my Pointer[Point] $plot = some_other_c_routine($n); 
 # display the 5 elements in the array 
 for 1 .. $n -> $i { 
     my $x = $plot[$i - 1].x; 
     my $y = $plot[$i - 1].y; 
     say "$i: ($x, $y)"; 
 } 

Pointers can also be updated to reference successive elements in the array:

my Pointer[Point] $elem = $plot; 
 # show differences between successive points 
 for 1 ..^ $n { 
     my Point $lo = $elem.deref; 
     ++$elem; # equivalent to $elem = $elem.add(1); 
     my Point $hi = (++$elem).deref; 
     my $dx = $hi.x = $lo.x; 
     my $dy = $hi.y = $lo.y; 
     say "$_: delta ($dx, $dy)"; 
 } 

Void pointers can also be used by declaring them Pointer[void]. Please consult the native types documentation for more information on the subject.

Strings

Explicit memory management

Let's say there is some C code that caches strings passed, like so:

#include <stdlib.h> 
 
 static char *__VERSION; 
 
 char * 
 get_version() 
 { 
     return __VERSION; 
 } 
 
 char * 
 set_version(char *version) 
 { 
     if (__VERSION != NULL) free(__VERSION); 
     __VERSION = version; 
     return __VERSION; 
 } 

If you were to write bindings for get_version and set_version, they would initially look like this, but will not work as intended:

sub get_version(--> Str)     is native('./version') { * } 
 sub set_version(Str --> Str) is native('./version') { * } 
 
 say set_version('1.0.0'); # 1.0.0 
 say get_version;          # Differs on each run 
 say set_version('1.0.1'); # Double free; segfaults 

This code segfaults on the second set_version call because it tries to free the string passed on the first call after the garbage collector had already done so. If the garbage collector shouldn't free a string passed to a native function, use explicitly-manage with it:

say set_version(explicitly-manage('1.0.0')); # 1.0.0 
 say get_version;                             # 1.0.0 
 say set_version(explicitly-manage('1.0.1')); # 1.0.1 
 say get_version;                             # 1.0.1 

Bear in mind all memory management for explicitly managed strings must be handled by the C library itself or through the NativeCall API to prevent memory leaks.

Buffers and blobs

Blobs and Bufs are the Perl 6 way of storing binary data. We can use them for interchange of data with native functions and data structures, although not directly. We will have to use nativecast.

my $blob = Blob.new(0x22, 0x33); 
 my $src = nativecast(Pointer, $blob); 

This $src can then be used as an argument for any native function that takes a Pointer. The opposite, putting values pointed to by a Pointer into a Buf or using it to initialize a Blob is not directly supported. You might want to use NativeHelpers::Blob to do this kind of operations.

my $esponja = blob-from-pointer( $inter, :2elems, :type(Blob[int8])); 
 say $esponja; 

Function arguments

NativeCall also supports native functions that take functions as arguments. One example of this is using function pointers as callbacks in an event-driven system. When binding these functions via NativeCall, one needs only provide the equivalent signature as a constraint on the code parameter. In the case of NativeCall, however, as of Rakudo 2019.07, a space between the function argument and the signature, and the colon of a normal Signature literal is omitted, as in:

use NativeCall;
# void SetCallback(int (*callback)(const char *))
my sub SetCallback(&callback (Str --> int32)) is native('mylib') { * }

Note: the native code is responsible for memory management of values passed to Perl 6 callbacks this way. In other words, NativeCall will not free() strings passed to callbacks.

Library paths and names

The native trait accepts the library name, the full path, or a subroutine returning either of the two. When using the library name, the name is assumed to be prepended with "lib" and appended with ".so" (or just appended with ".dll" on Windows), and will be searched for in the paths in the LD_LIBRARY_PATH (PATH on Windows) environment variable.

use NativeCall; 
 constant LIBMYSQL = 'mysqlclient'; 
 constant LIBFOO = '/usr/lib/libfoo.so.1'; 
 sub LIBBAR { 
     my $path = qx/pkg-config --libs libbar/.chomp; 
     $path ~~ s/\/[[\w+]+ % \/]/\0\/bar/; 
     $path 
 } 
 # and later 
 
 sub mysql_affected_rows returns int32 is native(LIBMYSQL) {*}; 
 sub bar is native(LIBFOO) {*} 
 sub baz is native(LIBBAR) {*} 

You can also put an incomplete path like './foo' and NativeCall will automatically put the right extension according to the platform specification. If you wish to suppress this expansion, simply pass the string as the body of a block.

sub bar is native({ './lib/Non Standard Naming Scheme' }) {*} 

BE CAREFUL: the native trait and constant are evaluated at compile time. Don't write a constant that depends on a dynamic variable like:

# WRONG:
constant LIBMYSQL = %*ENV<P6LIB_MYSQLCLIENT> || 'mysqlclient';

This will keep the value given at compile time. A module will be precompiled and LIBMYSQL will keep the value it acquires when the module gets precompiled.

ABI/API version

If you write native('foo') NativeCall will search libfoo.so under Unix like system (libfoo.dynlib on OS X, foo.dll on win32). In most modern system it will require you or the user of your module to install the development package because it's recommended to always provide an API/ABI version to a shared library, so libfoo.so ends often being a symbolic link provided only by a development package.

To avoid that, the native trait allows you to specify the API/ABI version. It can be a full version or just a part of it. (Try to stick to Major version, some BSD code does not care for Minor.)

use NativeCall;
sub foo1 is native('foo', v1) {*} # Will try to load libfoo.so.1
sub foo2 is native('foo', v1.2.3) {*} # Will try to load libfoo.so.1.2.3

my List $lib = ('foo', 'v1');
sub foo3 is native($lib) {*}

Routine

The native trait also accepts a Callable as argument, allowing you to provide your own way to handle the way it will find the library file to load.

use NativeCall;
sub foo is native(sub {'libfoo.so.42'}) {*}

It will only be called at the first invocation of the sub.

Calling into the standard library

If you want to call a C function that's already loaded, either from the standard library or from your own program, you can omit the value, so is native.

For example on a UNIX-like operating system, you could use the following code to print the home directory of the current user:

use NativeCall;
my class PwStruct is repr('CStruct') {
    has Str $.pw_name;
    has Str $.pw_passwd;
    has uint32 $.pw_uid;
    has uint32 $.pw_gid;
    has Str $.pw_gecos;
    has Str $.pw_dir;
    has Str $.pw_shell;
}
sub getuid()              returns uint32   is native { * };
sub getpwuid(uint32 $uid) returns PwStruct is native { * };

say getpwuid(getuid()).pw_dir;

Though of course $*HOME is a much easier way :-)

Exported variables

Variables exported by a library – also named "global" or "extern" variables – can be accessed using cglobal. For example:

my $var := cglobal('libc.so.6', 'errno', int32) 

This code binds to $var a new Proxy object that redirects all its accesses to the integer variable named "errno" as exported by the "libc.so.6" library.

C++ support

NativeCall offers support to use classes and methods from C++ as shown in https://github.com/rakudo/rakudo/blob/master/t/04-nativecall/13-cpp-mangling.t (and its associated C++ file). Note that at the moment it's not as tested and developed as C support.

Helper functions

The NativeCall library exports several subroutines to help you work with data from native libraries.

sub nativecast

sub nativecast($target-type, $source) is export(:DEFAULT)

This will cast the Pointer $source to an object of $target-type. The source pointer will typically have been obtained from a call to a native subroutine that returns a pointer or as a member of a struct, this may be specified as void * in the C library definition for instance, but you may also cast from a pointer to a less specific type to a more specific one.

As a special case, if a Signature is supplied as $target-type then a subroutine will be returned which will call the native function pointed to by $source in the same way as a subroutine declared with the native trait. This is described in Function Pointers.

sub cglobal

sub cglobal($libname, $symbol, $target-type) is export is rw

This returns a Proxy object that provides access to the extern named $symbol that is exposed by the specified library. The library can be specified in the same ways that they can be to the native trait.

sub nativesizeof

sub nativesizeof($obj) is export(:DEFAULT)

This returns the size in bytes of the supplied object, it can be thought of as being equivalent to sizeof in C. The object can be a builtin native type such as int64 or num64, a CArray or a class with the repr CStruct, CUnion or CPointer.

sub explicitly-manage

sub explicitly-manage($str) is export(:DEFAULT)

This returns a CStr object for the given Str. If the string returned is passed to a NativeCall subroutine, it will not be freed by the runtime's garbage collector.

Examples

Some specific examples, and instructions to use examples above in particular platforms.

PostgreSQL

The PostgreSQL examples in DBIish make use of the NativeCall library and is native to use the native _putenv function call in Windows.

MySQL

NOTE: Please bear in mind that, under the hood, Debian has substituted MySQL with MariaDB since the Stretch version, so if you want to install MySQL, use MySQL APT repository instead of the default repository.

To use the MySQL example in DBIish, you'll need to install MySQL server locally; on Debian-esque systems it can be installed with something like:

wget https://dev.mysql.com/get/mysql-apt-config_0.8.10-1_all.deb 
 sudo dpkg -i mysql-apt-config_0.8.10-1_all.deb # Don't forget to select 5.6.x 
 sudo apt-get update 
 sudo apt-get install mysql-community-server -y 
 sudo apt-get install libmysqlclient18 -y 

Prepare your system along these lines before trying out the examples:

$ mysql -u root -p 
 SET PASSWORD = PASSWORD('sa'); 
 DROP DATABASE test; 
 CREATE DATABASE test; 

Microsoft Windows

Here is an example of a Windows API call:

use NativeCall; 
 
 sub MessageBoxA(int32, Str, Str, int32) 
     returns int32 
     is native('user32') 
     { * } 
 
 MessageBoxA(0, "We have NativeCall", "ohai", 64); 

Short tutorial on calling a C function

This is an example for calling a standard function and using the returned information in a Perl 6 program.

getaddrinfo is a POSIX standard function for obtaining network information about a network node, e.g., google.com. It is an interesting function to look at because it illustrates a number of the elements of NativeCall.

The Linux manual provides the following information about the C callable function:

int getaddrinfo(const char *node, const char *service, 
        const struct addrinfo *hints, 
        struct addrinfo **res); 

The function returns a response code 0 = error, 1 = success. The data are extracted from a linked list of addrinfo elements, with the first element pointed to by res.

From the table of NativeCall Types we know that an int is int32. We also know that a char * is one of the forms C for a C Str, which maps simply to Str. But addrinfo is a structure, which means we will need to write our own Type class. However, the function declaration is straightforward:

sub getaddrinfo( Str $node, Str $service, Addrinfo $hints, Pointer $res is rw ) 
     returns int32 
     is native 
     { * } 

Note that $res is to be written by the function, so it must be labeled as rw. Since the library is standard POSIX, the library name can be the Type definition or null.

We now have to handle structure Addrinfo. The Linux Manual provides this information:

struct addrinfo { 
                int              ai_flags; 
                int              ai_family; 
                int              ai_socktype; 
                int              ai_protocol; 
                socklen_t        ai_addrlen; 
                struct sockaddr *ai_addr; 
                char            *ai_canonname; 
                struct addrinfo *ai_next; 
            }; 

The int, char* parts are straightforward. Some research indicates that socklen_t can be architecture dependent, but is an unsigned integer of at least 32 bits. So socklen_t can be mapped to the uint32 type.

The complication is sockaddr which differs depending on whether ai_socktype is undefined, INET, or INET6 (a standard v4 IP address or a v6 address).

So we create a Perl 6 class to map to the C struct addrinfo; while we're at it, we also create another class for SockAddr which is needed for it.

class SockAddr is repr('CStruct') { 
     has int32    $.sa_family; 
     has Str      $.sa_data; 
 } 
 
 class Addrinfo is repr('CStruct') { 
     has int32     $.ai_flags; 
     has int32     $.ai_family; 
     has int32     $.ai_socktype; 
     has int32     $.ai_protocol; 
     has int32     $.ai_addrlen; 
     has SockAddr  $.ai_addr       is rw; 
     has Str       $.ai_cannonname is rw; 
     has Addrinfo  $.ai_next       is rw; 
 
 } 

The is rw on the last three attributes reflects that these were defined in C to be pointers.

The important thing here for mapping to a C Struct is the structure of the state part of the class, that is the attributes. However, a class can have methods and NativeCall does not 'touch' them for mapping to C. This means that we can add extra methods to the class to unpack the attributes in a more readable manner, e.g.,

method flags { 
     do for AddrInfo-Flags.enums { .key if $!ai_flags +& .value } 
 } 

By defining an appropriate enum, flags will return a string of keys rather than a bit packed integer.

The most useful information in the sockaddr structure is the address of node, which depends on the family of the Socket. So we can add method address to the Perl 6 class that interprets the address depending on the family.

In order to get a human readable IP address, there is the C function inet_ntop which returns a char * given a buffer with the addrinfo.

Putting all these together, leads to the following program:

#!/usr/bin/env perl6 
 
 use v6; 
 use NativeCall; 
 
 constant \INET_ADDRSTRLEN = 16; 
 constant \INET6_ADDRSTRLEN = 46; 
 
 enum AddrInfo-Family ( 
     AF_UNSPEC                   => 0; 
     AF_INET                     => 2; 
     AF_INET6                    => 10; 
 ); 
 
 enum AddrInfo-Socktype ( 
     SOCK_STREAM                 => 1; 
     SOCK_DGRAM                  => 2; 
     SOCK_RAW                    => 3; 
     SOCK_RDM                    => 4; 
     SOCK_SEQPACKET              => 5; 
     SOCK_DCCP                   => 6; 
     SOCK_PACKET                 => 10; 
 ); 
 
 enum AddrInfo-Flags ( 
     AI_PASSIVE                  => 0x0001; 
     AI_CANONNAME                => 0x0002; 
     AI_NUMERICHOST              => 0x0004; 
     AI_V4MAPPED                 => 0x0008; 
     AI_ALL                      => 0x0010; 
     AI_ADDRCONFIG               => 0x0020; 
     AI_IDN                      => 0x0040; 
     AI_CANONIDN                 => 0x0080; 
     AI_IDN_ALLOW_UNASSIGNED     => 0x0100; 
     AI_IDN_USE_STD3_ASCII_RULES => 0x0200; 
     AI_NUMERICSERV              => 0x0400; 
 ); 
 
 sub inet_ntop(int32, Pointer, Blob, int32 --> Str) 
     is native {} 
 
 class SockAddr is repr('CStruct') { 
     has uint16 $.sa_family; 
 } 
 
 class SockAddr-in is repr('CStruct') { 
     has int16 $.sin_family; 
     has uint16 $.sin_port; 
     has uint32 $.sin_addr; 
 
     method address { 
         my $buf = buf8.allocate(INET_ADDRSTRLEN); 
         inet_ntop(AF_INET, Pointer.new(nativecast(Pointer,self)+4), 
             $buf, INET_ADDRSTRLEN) 
     } 
 } 
 
 class SockAddr-in6 is repr('CStruct') { 
     has uint16 $.sin6_family; 
     has uint16 $.sin6_port; 
     has uint32 $.sin6_flowinfo; 
     has uint64 $.sin6_addr0; 
     has uint64 $.sin6_addr1; 
     has uint32 $.sin6_scope_id; 
 
     method address { 
         my $buf = buf8.allocate(INET6_ADDRSTRLEN); 
         inet_ntop(AF_INET6, Pointer.new(nativecast(Pointer,self)+8), 
             $buf, INET6_ADDRSTRLEN) 
     } 
 } 
 
 class Addrinfo is repr('CStruct') { 
     has int32 $.ai_flags; 
     has int32 $.ai_family; 
     has int32 $.ai_socktype; 
     has int32 $.ai_protocol; 
     has uint32 $.ai_addrNativeCalllen; 
     has SockAddr $.ai_addr is rw; 
     has Str $.ai_cannonname is rw; 
     has Addrinfo $.ai_next is rw; 
 
     method flags { 
         do for AddrInfo-Flags.enums { .key if $!ai_flags +& .value } 
     } 
 
     method family { 
         AddrInfo-Family($!ai_family) 
     } 
 
     method socktype { 
         AddrInfo-Socktype($!ai_socktype) 
     } 
 
     method address { 
         given $.family { 
             when AF_INET { 
                 nativecast(SockAddr-in, $!ai_addr).address 
             } 
             when AF_INET6 { 
                 nativecast(SockAddr-in6, $!ai_addr).address 
             } 
         } 
     } 
 } 
 
 sub getaddrinfo(Str $node, Str $service, Addrinfo $hints, 
                 Pointer $res is rw --> int32) 
     is native {}; 
 
 sub freeaddrinfo(Pointer) 
     is native {} 
 
 sub MAIN() { 
     my Addrinfo $hint .= new(:ai_flags(AI_CANONNAME)); 
     my Pointer $res .= new; 
     my $rv = getaddrinfo("google.com", Str, $hint, $res); 
     say "return val: $rv"; 
     if ( ! $rv ) { 
         my $addr = nativecast(Addrinfo, $res); 
         while $addr { 
             with $addr { 
                 say "Name: ", $_ with .ai_cannonname; 
                 say .family, ' ', .socktype; 
                 say .address; 
                 $addr = .ai_next; 
             } 
         } 
     } 
     freeaddrinfo($res); 
 } 

This produces the following output:

return val: 0 
 Name: google.com 
 AF_INET SOCK_STREAM 
 216.58.219.206 
 AF_INET SOCK_DGRAM 
 216.58.219.206 
 AF_INET SOCK_RAW 
 216.58.219.206 
 AF_INET6 SOCK_STREAM 
 2607:f8b0:4006:800::200e 
 AF_INET6 SOCK_DGRAM 
 2607:f8b0:4006:800::200e 
 AF_INET6 SOCK_RAW 
 2607:f8b0:4006:800::200e 

56 Newline handling in Perl 6

How the different newline characters are handled, and how to change the behavior

Different operating systems use different characters, or combinations of them, to represent the transition to a new line. Every language has its own set of rules to handle this. Perl 6 has the following ones:

You can change the default behavior for a particular handle by setting the :nl-out attribute when you create that handle.

my $crlf-out = open(IO::Special.new('<STDOUT>'), :nl-out("\\\n\r"));
$*OUT.say: 1;     #OUTPUT: «1␤»
$crlf-out.say: 1; #OUTPUT: «1\␤␍»

In this example, where we are replicating standard output to a new handle by using IO::Special, we are appending a \ to the end of the string, followed by a newline and a carriage return ; everything we print to that handle will get those characters at the end of the line, as shown.

In regular expressions, \n is defined in terms of the Unicode definition of logical newline. It will match . and also \v, as well as any class that includes whitespace.

57 Numerics

Numeric types available in Perl 6

Int

The Int type offers arbitrary-size integer numbers. They can get as big as your computer memory allows, although some implementations choose to throw a numeric overflow error when asked to produce integers of truly staggering size:

say 10**600**600 
 # OUTPUT: «Numeric overflow␤» 

Unlike some languages, division performed using / operator when both operands are of Int type, would produce a fractional number, without any rounding performed.

say 4/5; # OUTPUT: «0.8␤» 

The type produced by this division is either a Rat or a Num type. The Rat is produced if, after reduction, the fraction's denominator is smaller than 64 bits, otherwise a Num type is produced.

The div and narrow routines can be helpful if you wish to end up with an Int result, whenever possible. The div operator performs integer division, discarding the remainder, while narrow fits the number into the narrowest type it'll fit:

say 5 div 2; # OUTPUT: «2␤» 
 
 # Result `2` is narrow enough to be an Int: 
 say (4/2).narrow; # OUTPUT: «2␤» 
 say (4/2).narrow.^name; # OUTPUT: «Int␤» 
 
 # But 2.5 has fractional part, so it ends up being a Rat type: 
 say (5/2).narrow.^name; # OUTPUT: «Rat␤» 
 say (5/2).narrow;       # OUTPUT: «2.5␤» 
 
 # Denominator is too big for a Rat, so a Num is produced: 
 say 1 / 10⁹⁹; # OUTPUT: «1e-99␤» 

Perl 6 has a FatRat type that offers arbitrary precision fractions. How come a limited-precision Num is produced instead of a FatRat type in the last example above? The reason is: performance. Most operations are fine with a little bit of precision lost and so do not require the use of a more expensive FatRat type. You'll need to instantiate one yourself if you wish to have the extra precision.

Num

The Num type offers double-precision floating-point decimal numbers, sometimes called "doubles" in other languages.

A Num literal is written with the exponent separated using the letter e. Keep in mind that the letter e is required even if the exponent is zero, as otherwise you'll get a Rat rational literal instead:

say 42e0.^name; # OUTPUT: «Num␤» 
 say 42.0.^name; # OUTPUT: «Rat␤» 

Case-sensitive words Inf and NaN represent the special values infinity and not-a-number respectively. The U+221E INFINITY () character can be used instead of Inf:

Perl 6 follows the IEEE 754-2008 Standard for Floating-Point Arithmetic as much as possible, with more conformance planned to be implemented in later language versions. The language guarantees the closest representable number is chosen for any given Num literal and does offer support for negative zero and denormals (also known as "subnormals").

Keep in mind that output routines like say or put do not try very hard to distinguish between how Numeric types are output and may choose to display a Num as an Int or a Rat number. For a more definitive string to output, use the perl method:

say  1e0;      # OUTPUT: «1␤» 
 say .5e0;      # OUTPUT: «0.5␤» 
 say  1e0.perl; # OUTPUT: «1e0␤» 
 say .5e0.perl; # OUTPUT: «0.5e0␤» 

Complex

The Complex type numerics of the complex plane. The Complex objects consist of two Num objects representing the real and imaginary portions of the complex number.

To create a Complex, you can use the postfix i operator on any other non-complex number, optionally setting the real part with addition. To use the i operator on NaN or Inf literals, separate it from them with a backslash.

say 42i;      # OUTPUT: «0+42i␤» 
 say 73+42i;   # OUTPUT: «73+42i␤» 
 say 73+Inf\i; # OUTPUT: «73+Inf\i␤» 

Keep in mind the above syntax is just an addition expression and precedence rules apply. It also cannot be used in places that forbid expressions, such as literals in routine parameters.

# Precedence of `*` is higher than that of `+` 
 say 2 * 73+10i; # OUTPUT: «146+10i␤» 

To avoid these issues, you can choose to use the Complex literal syntax instead, which involves surrounding the real and imaginary parts with angle brackets, without any spaces:

say 2 * <73+10i>; # OUTPUT: «146+20i␤» 
 
 multi how-is-it (<2+4i>) { say "that's my favorite number!" } 
 multi how-is-it (|)      { say "meh"                        } 
 how-is-it 2+4i;  # OUTPUT: «that's my favorite number!␤» 
 how-is-it 3+2i;  # OUTPUT: «meh␤» 

Rational

The types that do the Rational role offer high-precision and arbitrary-precision decimal numbers. Since the higher the precision the larger the performance penalty, the Rational types come in two flavors: Rat and FatRat. The Rat is the most often-used variant that degrades into a Num in most cases, when it can no longer hold all of the requested precision. The FatRat is the arbitrary-precision variant that keeps growing to provide all of the requested precision.

Rat

The most common of Rational types. It supports rationals with denominators as large as 64 bits (after reduction of the fraction to the lowest denominator). Rat objects with larger denominators can be created directly, however, when Rats with such denominators are the result of mathematical operations, they degrade to a Num object.

The Rat literals use syntax similar to Num literals in many other languages, using the dot to indicate the number is a decimal:

say .1 + .2 == .3; # OUTPUT: «True␤» 

If you try to execute a statement similar to the above in many common languages, you'll get False as the answer, due to imprecision of floating point math. To get the same result in Perl 6, you'd have to use Num literals instead:

say .1e0 + .2e0 == .3e0; # OUTPUT: «False␤» 

You can also use / division operator with Int or Rat objects to produce a Rat:

say 3/4;     # OUTPUT: «0.75␤» 
 say 3/4.2;   # OUTPUT: «0.714286␤» 
 say 1.1/4.2; # OUTPUT: «0.261905␤» 

Keep in mind the above syntax is just a division expression and precedence rules apply. It also cannot be used in places that forbid expressions, such as literals in routine parameters.

# Precedence of power operators is higher than division 
 say 3/2²; # OUTPUT: «0.75␤» 

To avoid these issues, you can choose to use the Rational literal syntax instead, which involves surrounding the numerator and denominator with angle brackets, without any spaces:

say <3/2>²; # OUTPUT: «2.25␤» 
 
 multi how-is-it (<3/2>) { say "that's my favorite number!" } 
 multi how-is-it (|)     { say "meh"                        } 
 how-is-it 3/2;  # OUTPUT: «that's my favorite number!␤» 
 how-is-it 1/3;  # OUTPUT: «meh␤» 

Lastly, any Unicode character with property No that represents a fractional number can be used as a Rat literal:

say ½ + ⅓ + ⅝ + ⅙; # OUTPUT: «1.625␤» 

Degradation to Num

If a mathematical operation that produces a Rat answer would produce a Rat with denominator larger than 64 bits, that operation would instead return a Num object. When constructing a Rat (i.e. when it is not a result of some mathematical expression), however, a larger denominator can be used:

my $a = 1 / (2⁶⁴ - 1);
say $a;                   # OUTPUT: «0.000000000000000000054␤»
say $a.^name;             # OUTPUT: «Rat␤»
say $a.nude;              # OUTPUT: «(1 18446744073709551615)␤»

my $b = 1 / 2⁶⁴;
say $b;                   # OUTPUT: «5.421010862427522e-20␤»
say $b.^name;             # OUTPUT: «Num␤»

my $c = Rat.new(1, 2⁶⁴);
say $c;                   # OUTPUT: «0.000000000000000000054␤»
say $c.^name;             # OUTPUT: «Rat␤»
say $c.nude;              # OUTPUT: «(1 18446744073709551616)␤»
say $c.Num;               # OUTPUT: «5.421010862427522e-20␤»

FatRat

The last Rational type—FatRat—keeps all of the precision you ask of it, storing the numerator and denominator as two Int objects. A FatRat is more infectious than a Rat, so many math operations with a FatRat will produce another FatRat, preserving all of the available precision. Where a Rat degrades to a Num, math with a FatRat keeps chugging along:

say ((42 + Rat.new(1,2))/999999999999999999).^name;         # OUTPUT: «Rat␤» 
 say ((42 + Rat.new(1,2))/9999999999999999999).^name;        # OUTPUT: «Num␤» 
 say ((42 + FatRat.new(1,2))/999999999999999999).^name;      # OUTPUT: «FatRat␤» 
 say ((42 + FatRat.new(1,2))/99999999999999999999999).^name; # OUTPUT: «FatRat␤» 

There's no special operator or syntax available for construction of FatRat objects. Simply use FatRat.new method, giving numerator as first positional argument and denominator as the second.

If your program requires a significant amount of FatRat creation, you could create your own custom operator:

sub infix:<🙼> { FatRat.new: $^a, $^b } 
 say (1🙼3).perl; # OUTPUT: «FatRat.new(1, 3)␤» 

Printing rationals

Keep in mind that output routines like say or put do not try very hard to distinguish between how Numeric types are output and may choose to display a Num as an Int or a Rat number. For a more definitive string to output, use the perl method:

say 1.0;        # OUTPUT: «1␤» 
 say ⅓;          # OUTPUT: «0.333333␤» 
 say 1.0.perl;   # OUTPUT: «1.0␤» 
 say ⅓.perl;     # OUTPUT: «<1/3>␤» 

For even more information, you may choose to see the Rational object in the nude, displaying its numerator and denominator:

say ⅓;          # OUTPUT: «0.333333␤» 
 say 4/2;        # OUTPUT: «2␤» 
 say ⅓.perl;     # OUTPUT: «<1/3>␤» 
 say <4/2>.nude; # OUTPUT: «(2 1)␤» 

Division by zero

In many languages division by zero is an immediate exception. In Perl 6, what happens depends on what you're dividing and how you use the result.

Perl 6 follows IEEE 754-2008 Standard for Floating-Point Arithmetic, but for historical reasons 6.c and 6.d language versions do not comply fully. Num division by zero produces a Failure, while Complex division by zero produces NaN components, regardless of what the numerator is.

As of 6.e language, both Num and Complex division by zero will produce a -Inf, +Inf, or NaN depending on whether the numerator was negative, positive, or zero, respectively (for Complex the real and imaginary components are Num and are considered separately).

Division of Int numerics produces a Rat object (or a Num, if after reduction the denominator is larger than 64-bits, which isn't the case when you're dividing by zero). This means such division never produces an Exception or a Failure. The result is a Zero-Denominator Rational, which can be explosive.

Zero-denominator rationals

A Zero-Denominator Rational is a numeric that does role Rational, which among core numerics would be Rat and FatRat objects, which has denominator of zero. The numerator of such Rationals is normalized to -1, 0, or 1 depending on whether the original numerator is negative, zero or positive, respectively.

Operations that can be performed without requiring actual division to occur are non-explosive. For example, you can separately examine numerator and denominator in the nude or perform mathematical operations without any exceptions or failures popping up.

Converting zero-denominator rationals to Num follows the IEEE conventions, and the result is a -Inf, Inf, or NaN, depending on whether the numerator is negative, positive, or zero, respectively. The same is true going the other way: converting ±Inf/NaN to one of the Rational types will produce a zero-denominator rational with an appropriate numerator:

say  <1/0>.Num;   # OUTPUT: «Inf␤» 
 say <-1/0>.Num;   # OUTPUT: «-Inf␤» 
 say  <0/0>.Num;   # OUTPUT: «NaN␤» 
 say Inf.Rat.nude; # OUTPUT: «(1 0)␤» 

All other operations that require non-IEEE division of the numerator and denominator to occur will result in X::Numeric::DivideByZero exception to be thrown. The most common of such operations would likely be trying to print or stringify a zero-denominator rational:

say 0/0; 
 # OUTPUT: 
 # Attempt to divide by zero using div 
 #  in block <unit> at -e line 1 

Allomorphs

Allomorphs are subclasses of two types that can behave as either of them. For example, the allomorph IntStr is the subclass of Int and Str types and will be accepted by any type constraint that requires an Int or Str object.

Allomorphs can be created using angle brackets, either used standalone or as part of a hash key lookup; directly using method .new and are also provided by some constructs such as parameters of sub MAIN.

say <42>.^name;                 # OUTPUT: «IntStr␤» 
 say <42e0>.^name;               # OUTPUT: «NumStr␤» 
 say < 42+42i>.^name;            # OUTPUT: «ComplexStr␤» 
 say < 1/2>.^name;               # OUTPUT: «RatStr␤» 
 say <0.5>.^name;                # OUTPUT: «RatStr␤» 
 
 @*ARGS = "42"; 
 sub MAIN($x) { say $x.^name }   # OUTPUT: «IntStr␤» 
 
 say IntStr.new(42, "42").^name; # OUTPUT: «IntStr␤» 

A couple of constructs above have a space after the opening angle bracket. That space isn't accidental. Numerics that are often written using an operator, such as 1/2 (Rat, division operator) and 1+2i (Complex, addition) can be written as a literal that doesn't involve the use of an operator: angle brackets without any spaces between the angle brackets and the characters inside. By adding spaces within the angle brackets, we tell the compiler that not only we want a Rat or Complex literal, but we also want it to be an allomorph: the RatStr or ComplexStr, in this case.

If the numeric literal doesn't use any operators, then writing it inside the angle brackets, even without including any spaces within, would produce the allomorph. (Logic: if you didn't want the allomorph, you wouldn't use the angle brackets. The same isn't true for operator-using numbers as some constructs, such as signature literals, do not let you use operators, so you can't just omit angle brackets for such numeric literals).

Available allomorphs

The core language offers the following allomorphs:

Type Allomorph of Example
IntStr Int and Str <42>
NumStr Num and Str <42e0>
ComplexStr Complex and Str < 1+2i>
RatStr Rat and Str <1.5>

Note: there is no FatRatStr type.

Coercion of allomorphs

Keep in mind that allomorphs are simply subclasses of the two (or three) types they represent. Just as a variable or parameter type-constrained to Foo can accept any subclass of Foo, so will a variable or parameter type-constrained to Int will accept an IntStr allomorph:

sub foo(Int $x) { say $x.^name } 
 foo <42>;                          # OUTPUT: «IntStr␤» 
 my Num $y = <42e0>; 
 say $y.^name;                      # OUTPUT: «NumStr␤» 

This, of course, also applies to parameter coercers:

sub foo(Int(Cool) $x) { say $x.^name } 
 foo <42>;  # OUTPUT: «IntStr␤» 

The given allomorph is already an object of type Int, so it does not get converted to a "plain" Int in this case.

Of course, the power of allomorphs would be severely diminished if there were no way to "collapse" them to one of their components. Thus, if you explicitly call a method with the name of the type to coerce to, you'll get just that component. The same applies to any proxy methods, such as calling method .Numeric instead of .Int or using the prefix:<~> operator instead of .Str method call.

my $al := IntStr.new: 42, "forty two"; 
 say $al.Str;  # OUTPUT: «forty two␤» 
 say +$al;     # OUTPUT: «42␤» 
 
 say <1/99999999999999999999>.Rat.^name;    # OUTPUT: «Rat␤» 
 say <1/99999999999999999999>.FatRat.^name; # OUTPUT: «FatRat␤» 

A handy way to coerce a whole list of allomorphs is by applying the hyper operator to the appropriate prefix:

say map *.^name,   <42 50e0 100>;  # OUTPUT: «(IntStr NumStr IntStr)␤» 
 say map *.^name, +«<42 50e0 100>;  # OUTPUT: «(Int Num Int)␤» 
 say map *.^name, ~«<42 50e0 100>;  # OUTPUT: «(Str Str Str)␤» 

Object identity

The above discussion on coercing allomorphs becomes more important when we consider object identity. Some constructs utilize it to ascertain whether two objects are "the same". And while to humans an allomorphic 42 and regular 42 might appear "the same", to those constructs, they're entirely different objects:

# "42" shows up twice in the result: 42 and <42> are different objects: 
 say unique 1, 1, 1, 42, <42>; # OUTPUT: «(1 42 42)␤» 
 # Use a different operator to `unique` with: 
 say unique :with(&[==]), 1, 1, 1, 42, <42>; # OUTPUT: «(1 42)␤» 
 # Or coerce the input instead (faster than using a different `unique` operator): 
 say unique :as(*.Int), 1, 1, 1, 42, <42>; # OUTPUT: «(1 42)␤» 
 say unique +«(1, 1, 1, 42, <42>);         # OUTPUT: «(1 42)␤» 
 
 # Parameterized Hash with `Any` keys does not stringify them; our key is of type `Int`: 
 my %h{Any} = 42 => "foo"; 
 # But we use the allomorphic key of type `IntStr`, which is not in the Hash: 
 say %h<42>:exists;           # OUTPUT: «False␤» 
 # Must use curly braces to avoid the allomorph: 
 say %h{42}:exists;           # OUTPUT: «True␤» 
 
 # We are using a set operator to look up an `Int` object in a list of `IntStr` objects: 
 say 42 ∈ <42 100 200>; # OUTPUT: «False␤» 
 # Convert it to an allomorph: 
 say <42> ∈ <42 100 200>; # OUTPUT: «True␤» 
 # Or convert the items in the list to plain `Int` objects: 
 say 42 ∈ +«<42 100 200>; # OUTPUT: «True␤» 

Be mindful of these object identity differences and coerce your allomorphs as needed.

Native numerics

As the name suggests, native numerics offer access to native numerics—i.e. those offered directly by your hardware. This in turn offers two features: overflow/underflow and better performance.

NOTE: at the time of this writing (2018.05), certain implementations (such as Rakudo) offer somewhat spotty details on native types, such as whether int64 is available and is of 64-bit size on 32-bit machines, and how to detect when your program is running on such hardware.

Available native numerics

Native type Base numeric Size
int integer 64-bits
int8 integer 8-bits
int16 integer 16-bits
int32 integer 32-bits
int64 integer 64-bits
uint unsigned integer 64-bits
uint8 unsigned integer 8-bits
uint16 unsigned integer 16-bits
uint32 unsigned integer 32-bits
uint64 unsigned integer 64-bits
num floating point 64-bits
num32 floating point 32-bits
num64 floating point 64-bits
atomicint integer sized to offer CPU-provided atomic operations. (typically 64 bits on 64-bit platforms and 32 bits on 32-bit ones)

Creating native numerics

To create a natively-typed variable or parameter, simply use the name of one of the available numerics as the type constraint:

my int32 $x = 42; 
 sub foo(num $y) {} 
 class { has int8 $.z } 

At times, you may wish to coerce some value to a native type without creating any usable variables. There are no .int or similar coercion methods (method calls are latebound, so they're not well-suited for this purpose). Instead, simply use an anonymous variable:

some-native-taking-sub (my int $ = $y), (my int32 $ = $z) 

Overflow/Underflow

Trying to assign a value that does not fit into a particular native type, produces an exception. This includes attempting to give too large an argument to a native parameter:

my int $x = 2¹⁰⁰; 
 # OUTPUT: 
 # Cannot unbox 101 bit wide bigint into native integer 
 #  in block <unit> at -e line 1 
 
 sub f(int $x) { $x }; say f 2⁶⁴ 
 # OUTPUT: 
 # Cannot unbox 65 bit wide bigint into native integer 
 #   in sub f at -e line 1 
 #   in block <unit> at -e line 1 

However, modifying an already-existing value in such a way that it becomes too big/small, produces overflow/underflow behavior:

my int $x = 2⁶³-1; 
 say $x;             # OUTPUT: «9223372036854775807␤» 
 say ++$x;           # OUTPUT: «-9223372036854775808␤» 
 
 my uint8 $x; 
 say $x;             # OUTPUT: «0␤» 
 say $x -= 100;      # OUTPUT: «156␤» 

Creating objects that utilize native types does not involve direct assignment by the programmer; that is why these constructs offer overflow/underflow behavior instead of throwing exceptions.

say Buf.new(1000, 2000, 3000).List; # OUTPUT: «(232 208 184)␤» 
 say my uint8 @a = 1000, 2000, 3000; # OUTPUT: «232 208 184␤» 

Auto-boxing

While they can be referred to as "native types", native numerics are not actually classes that have any sort of methods available. However, you can call any of the methods available on non-native versions of these numerics. What's going on?

my int8 $x = -42; 
 say $x.abs; # OUTPUT: «42␤» 

This behavior is known as "auto-boxing". The compiler automatically "boxes" the native type into a full-featured higher-level type with all the methods. In other words, the int8 above was automatically converted to an Int and it's the Int class that then provided the abs method that was called.

This detail is significant when you're using native types for performance gains. If the code you're using results in a lot of auto-boxing being performed you might get worse performance with native types than you would with non-natives:

my $a = -42; 
 my int $a-native = -42; 
 { for ^1000_000 { $a.abs        }; say now - ENTER now } # OUTPUT: «0.38180862␤» 
 { for ^1000_000 { $a-native.abs }; say now - ENTER now } # OUTPUT: «0.938720␤» 

As you can see above, the native variant is more than twice slower. The reason is the method call requires the native type to be boxed, while no such thing is needed in the non-native variant, hence the performance loss.

In this particular case, we can simply switch to a subroutine form of abs, which can work with native types without boxing them. In other cases, you may need to seek out other solutions to avoid excessive autoboxing, including switching to non-native types for a portion of the code.

my $a = -42; 
 my int $a-native = -42; 
 { for ^1000_000 { abs $a        }; say now - ENTER now } # OUTPUT: «0.38229177␤» 
 { for ^1000_000 { abs $a-native }; say now - ENTER now } # OUTPUT: «0.3088305␤» 

Default values

Since there are no classes behind native types, there are no type objects you'd normally get with variables that haven't been initialized. Thus, native types are automatically initialized to zero. In 6.c language, native floating point types (num, num32, and num64) were initialized to value NaN; in 6.d language the default is 0e0.

Native dispatch

It is possible to have native candidates alongside non-native candidates to, for example, offer faster algorithms with native candidates when sizes are predictable, but to fallback to slower non-native alternatives otherwise. The following are the rules concerning multi-dispatch involving native candidates.

First, the size of the native type does not play a role in dispatch and an int8 is considered to be the same as int16 or int:

multi foo(int   $x) { say "int" } 
 multi foo(int32 $x) { say "int32" } 
 foo my int $x = 42; 
 # OUTPUT: 
 # Ambiguous call to 'foo(Int)'; these signatures all match: 
 # :(int $x) 
 # :(int32 $x) 

Second, if a routine is an only—i.e. it is not a multi—that takes a non-native type but a native one was given during the call, or vice-versa, then the argument will be auto-boxed or auto-unboxed to make the call possible. If the given argument is too large to fit into the native parameter, an exception will be thrown:

-> int {}( 42 );            # OK; auto-unboxing 
 -> int {}( 2¹⁰⁰ );          # Too large; exception 
 -> Int {}( 2¹⁰⁰ );          # OK; non-native parameter 
 -> Int {}( my int $ = 42 ); # OK; auto-boxing 

When it comes to multi routines, native arguments will always be auto-boxed if no native candidates are available to take them:

multi foo (Int $x) { $x } 
 say foo my int $ = 42; # OUTPUT: «42␤» 

The same luxury is not afforded when going the other way. If only a native candidate is available, a non-native argument will not be auto-unboxed and instead an exception indicating no candidates matched will be thrown (the reason for this asymmetry is a native type can always be boxed, but a non-native may be too large to fit into a native):

multi f(int $x) { $x } 
 my $x = 2; 
 say f $x; 
 # OUTPUT: 
 # Cannot resolve caller f(Int); none of these signatures match: 
 #     (int $x) 
 #   in block <unit> at -e line 1 

However, this rule is waived if a call is being made where one of the arguments is a native type and another one is a numeric literal:

multi f(int, int) {} 
 f 42, my int $x; # Successful call 

This way you do not have to constantly write, for example, $n +> 2 as $n +> (my int $ = 2). The compiler knows the literal is small enough to fit to a native type and converts it to a native.

Atomic operations

The language offers some operations that are guaranteed to be performed atomically, i.e. safe to be executed by multiple threads without the need for locking with no risk of data races.

For such operations, the atomicint native type is required. This type is similar to a plain native int, except it is sized such that CPU-provided atomic operations can be performed upon it. On a 32-bit CPU it will typically be 32 bits in size, and on an a 64-bit CPU it will typically be 64 bits in size.

# !!WRONG!! Might be non-atomic on some systems 
 my int $x; 
 await ^100 .map: { start $x⚛++ }; 
 say $x; # OUTPUT: «98␤» 
 
 # RIGHT! The use of `atomicint` type guarantees operation is atomic 
 my atomicint $x; 
 await ^100 .map: { start $x⚛++ }; 
 say $x; # OUTPUT: «100␤» 

The similarity to int is present in multi dispatch as well: an atomicint, plain int, and the sized int variants are all considered to be the same by the dispatcher and cannot be differentiated through multi-dispatch.

Numeric infectiousness

Numeric "infectiousness" dictates the resultant type when two numerics of different types are involved in some mathematical operations. A type is said to be more infectious than the other type if the result is of that type rather than the type of the other operand. For example, Num type is more infectious than an Int, thus we can expect 42e0 + 42 to produce a Num as the result.

The infectiousness is as follows, with the most infectious type listed first:

say (2 + 2e0).^name; # Int + Num => OUTPUT: «Num␤» 
 say (½ + ½).^name; # Rat + Rat => OUTPUT: «Rat␤» 
 say (FatRat.new(1,2) + ½).^name; # FatRat + Rat => OUTPUT: «FatRat␤» 

The allomorphs have the same infectiousness as their numeric component. Native types get autoboxed and have the same infectiousness as their boxed variant.

58 Object orientation

Object orientation in Perl 6

Perl 6 provides strong support for Object Oriented Programming (OOP). Although Perl 6 allows programmers to program in multiple paradigms, Object Oriented Programming is at the heart of the language.

Perl 6 comes with a wealth of predefined types, which can be classified in two categories: regular and native types. Everything that you can store in a variable is either a native value or an object. That includes literals, types (type objects), code and containers.

Native types are used for low-level types (like uint64). Even if native types do not have the same capabilities as objects, if you call methods on them, they are automatically boxed into normal objects.

Everything that is not a native value is an object. Objects do allow for both inheritance and encapsulation.

Using objects

To call a method on an object, add a dot, followed by the method name:

say "abc".uc; 
 # OUTPUT: «ABC␤» 

This calls the uc method on "abc", which is an object of type Str. To supply arguments to the method, add arguments inside parentheses after the method.

my $formatted-text = "Fourscore and seven years ago...".indent(8); 
 say $formatted-text; 
 # OUTPUT: «        Fourscore and seven years ago...␤» 

$formatted-text now contains the above text, but indented 8 spaces.

Multiple arguments are separated by commas:

my @words = "Abe", "Lincoln"; 
 @words.push("said", $formatted-text.comb(/\w+/)); 
 say @words; 
 # OUTPUT: «[Abe Lincoln said (Fourscore and seven years ago)]␤» 

Similarly, multiple arguments can be specified by placing a colon after the method and separating the argument list with a comma:

say @words.join('--').subst: 'years', 'DAYS'; 
 # OUTPUT: «Abe--Lincoln--said--Fourscore and seven DAYS ago␤» 

Since you have to put a : after the method if you want to pass arguments without parentheses, a method call without a colon or parentheses is unambiguously a method call without an argument list:

say 4.log:   ; # OUTPUT: «1.38629436111989␤» ( natural logarithm of 4 )
say 4.log: +2; # OUTPUT: «2␤» ( base-2 logarithm of 4 )
say 4.log  +2; # OUTPUT: «3.38629436111989␤» ( natural logarithm of 4, plus 2 )

Many operations that don't look like method calls (for example, smartmatching or interpolating an object into a string) might result in method calls under the hood.

Methods can return mutable containers, in which case you can assign to the return value of a method call. This is how read-writable attributes to objects are used:

$*IN.nl-in = "\r\n"; 

Here, we call method nl-in on the $*IN object, without arguments, and assign to the container it returned with the = operator.

All objects support methods from class Mu, which is the type hierarchy root. All objects derive from Mu.

Type objects

Types themselves are objects and you can get the type object by writing its name:

my $int-type-obj = Int; 

You can request the type object of anything by calling the WHAT method, which is actually a macro in method form:

my $int-type-obj = 1.WHAT; 

Type objects (other than Mu) can be compared for equality with the === identity operator:

sub f(Int $x) { 
     if $x.WHAT === Int { 
         say 'you passed an Int'; 
     } 
     else { 
         say 'you passed a subtype of Int'; 
     } 
 } 

Although, in most cases, the .isa method will suffice:

sub f($x) { 
     if $x.isa(Int) { 
         ... 
     } 
     ... 
 } 

Subtype checking is done by smartmatching:

if $type ~~ Real { 
     say '$type contains Real or a subtype thereof'; 
 } 

Classes

Classes are declared using the class keyword, typically followed by a name.

class Journey { } 

This declaration results in a type object being created and installed in the current package and current lexical scope under the name Journey. You can also declare classes lexically:

my class Journey { } 

This restricts their visibility to the current lexical scope, which can be useful if the class is an implementation detail nested inside a module or another class.

Attributes

Attributes are variables that exist per instance of a class; when instantiated to a value, the association between the variable and its value is called a property. They are where the state of an object is stored. In Perl 6, all attributes are private, which means they can be accessed directly only by the class instance itself. They are typically declared using the has declarator and the ! twigil.

class Journey { 
     has $!origin; 
     has $!destination; 
     has @!travelers; 
     has $!notes; 
 } 

While there is no such thing as a public (or even protected) attribute, there is a way to have accessor methods generated automatically: replace the ! twigil with the . twigil (the . should remind you of a method call).

class Journey { 
     has $.origin; 
     has $.destination; 
     has @!travelers; 
     has $.notes; 
 } 

This defaults to providing a read-only accessor. In order to allow changes to the attribute, add the is rw trait:

class Journey { 
     has $.origin; 
     has $.destination; 
     has @!travelers; 
     has $.notes is rw; 
 } 

Now, after a Journey object is created, its .origin, .destination, and .notes will all be accessible from outside the class, but only .notes can be modified.

If an object is instantiated without certain attributes, such as origin or destination, we may not get the desired result. To prevent this, provide default values or make sure that an attribute is set on object creation by marking an attribute with an is required trait.

class Journey { 
     # error if origin is not provided 
     has $.origin is required; 
     # set the destination to Orlando as default (unless that is the origin!) 
     has $.destination = self.origin eq 'Orlando' ?? 'Kampala' !! 'Orlando'; 
     has @!travelers; 
     has $.notes is rw; 
 } 

Since classes inherit a default constructor from Mu and we have requested that some accessor methods are generated for us, our class is already somewhat functional.

# Create a new instance of the class. 
 my $vacation = Journey.new( 
     origin      => 'Sweden', 
     destination => 'Switzerland', 
     notes       => 'Pack hiking gear!' 
 ); 
 
 # Use an accessor; this outputs Sweden. 
 say $vacation.origin; 
 
 # Use an rw accessor to change the value. 
 $vacation.notes = 'Pack hiking gear and sunglasses!'; 

Note that, although the default constructor can initialize read-only attributes, it will only set attributes that have an accessor method. That is, even if you pass travelers => ["Alex", "Betty"] to the default constructor, the attribute @!travelers is not initialized.

Methods

Methods are declared with the method keyword inside a class body.

class Journey { 
     has $.origin; 
     has $.destination; 
     has @!travelers; 
     has $.notes is rw; 
 
     method add-traveler($name) { 
         if $name ne any(@!travelers) { 
             push @!travelers, $name; 
         } 
         else { 
             warn "$name is already going on the journey!"; 
         } 
     } 
 
     method describe() { 
         "From $!origin to $!destination" 
     } 
 } 

A method can have a signature, just like a subroutine. Attributes can be used in methods and can always be used with the ! twigil, even if they are declared with the . twigil. This is because the . twigil declares a ! twigil and generates an accessor method.

Looking at the code above, there is a subtle but important difference between using $!origin and $.origin in the method describe. $!origin is an inexpensive and obvious lookup of the attribute. $.origin is a method call and thus may be overridden in a subclass. Only use $.origin if you want to allow overriding.

Unlike subroutines, additional named arguments will not produce compile time or runtime errors. That allows chaining of methods via Re-dispatching.

You may write your own accessors to override any or all of the autogenerated ones.

my $ⲧ = " " xx 4; # A tab-like thing 
 class Journey { 
     has $.origin; 
     has $.destination; 
     has @.travelers; 
     has Str $.notes is rw; 
 
     multi method notes() { "$!notes\n" }; 
     multi method notes( Str $note ) { $!notes ~= "$note\n$ⲧ" }; 
 
     method Str { "⤷ $!origin\n$ⲧ" ~ self.notes() ~ "$!destination ⤶\n" }; 
 } 
 
 my $trip = Journey.new( :origin<Here>, :destination<There>, 
                         travelers => <þor Freya> ); 
 
 $trip.notes("First steps"); 
 notes $trip: "Almost there"; 
 print $trip; 
 
 # OUTPUT: 
 #⤷ Here 
 #       First steps 
 #       Almost there 
 # 
 #There ⤶ 

The declared multi method notes overrides the auto-generated methods implicit in the declaration of $.notes, using a different signature for reading and writing.

Please note that in notes $trip: "Almost there" we are using indirect invocant syntax, which puts first the method name, then the object, and then, separated by a colon, the arguments: method invocant: arguments. We can use this syntax whenever it feels more natural than the classical period-and-parentheses one. It works exactly in the same way.

Method names can be resolved at runtime with the ."" operator.

class A { has $.b }; 
 my $name = 'b'; 
 A.new."$name"().say; 
 # OUTPUT: «(Any)␤» 

The syntax used to update $.notes changed in this section with respect to the previous #Attributes section. Instead of an assignment:

$vacation.notes = 'Pack hiking gear and sunglasses!'; 

we now do a method call:

$trip.notes("First steps"); 

Overriding the default auto-generated accessor means it is no longer available to provide a mutable container on return for an assignment. A method call is the preferred approach to adding computation and logic to the update of an attribute. Many modern languages can update an attribute by overloading assignment with a “setter” method. While Perl 6 can overload the assignment operator for this purpose with a Proxy object, overloading assignment to set attributes with complex logic is currently discouraged as weaker object oriented design.

Class and instance methods

A method's signature can have an explicit invocant as its first parameter followed by a colon, which allows for the method to refer to the object it was called on.

class Foo { 
     method greet($me: $person) { 
         say "Hi, I am $me.^name(), nice to meet you, $person"; 
     } 
 } 
 Foo.new.greet("Bob");    # OUTPUT: «Hi, I am Foo, nice to meet you, Bob␤» 

Providing an invocant in the method signature also allows for defining the method as either as a class method, or as an object method, through the use of type constraints. The ::?CLASS variable can be used to provide the class name at compile time, combined with either :U (for class methods) or :D (for instance methods).

class Pizza { 
     has $!radius = 42; 
     has @.ingredients; 
 
     # class method: construct from a list of ingredients 
     method from-ingredients(::?CLASS:U $pizza: @ingredients) { 
         $pizza.new( ingredients => @ingredients ); 
     } 
 
     # instance method 
     method get-radius(::?CLASS:D:) { $!radius } 
 } 
 my $p = Pizza.from-ingredients: <cheese pepperoni vegetables>; 
 say $p.ingredients;     # OUTPUT: «[cheese pepperoni vegetables]␤» 
 say $p.get-radius;      # OUTPUT: «42␤» 
 say Pizza.get-radius;   # This will fail. 
 CATCH { default { put .^name ~ ":\n" ~ .Str } }; 
 # OUTPUT: «X::Parameter::InvalidConcreteness:␤ 
 #          Invocant of method 'get-radius' must be 
 #          an object instance of type 'Pizza', 
 #          not a type object of type 'Pizza'. 
 #          Did you forget a '.new'?» 

A method can be both a class and object method by using the multi declarator:

class C { 
     multi method f(::?CLASS:U:) { say "class method"  } 
     multi method f(::?CLASS:D:) { say "object method" } 
 } 
 C.f;       # OUTPUT: «class method␤» 
 C.new.f;   # OUTPUT: «object method␤» 

self

Inside a method, the term self is available and bound to the invocant object. self can be used to call further methods on the invocant, including constructors:

class Box { 
   has $.data; 
 
   method make-new-box-from() { 
       self.new: data => $!data; 
   } 
 } 

self can be used in class or instance methods as well, though beware of trying to invoke one type of method from the other:

class C { 
     method g()            { 42     } 
     method f(::?CLASS:U:) { self.g } 
     method d(::?CLASS:D:) { self.f } 
 } 
 C.f;        # OUTPUT: «42␤» 
 C.new.d;    # This will fail. 
 CATCH { default { put .^name ~ ":\n" ~ .Str } }; 
 # OUTPUT: «X::Parameter::InvalidConcreteness:␤ 
 #          Invocant of method 'f' must be a type object of type 'C', 
 #          not an object instance of type 'C'.  Did you forget a 'multi'?» 

self can also be used with attributes, as long as they have an accessor. self.a will call the accessor for an attribute declared as has $.a. However, there is a difference between self.a and $.a, since the latter will itemize; $.a will be equivalent to self.a.item or $(self.a).

class A { 
     has $.x = (1, 2, 3); 
     method b() { .say for self.x; .say for $.x } 
 }; 
 A.new.b; # OUTPUT: «1␤2␤3␤(1 2 3)␤» 

The colon-syntax for method arguments is only supported for method calls using self, not the shortcut.

Note that if the relevant methods bless, CREATE of Mu are not overloaded, self will point to the type object in those methods.

On the other hand, the submethods BUILD and TWEAK are called on instances, in different stages of initialization. Submethods of the same name from subclasses have not yet run, so you should not rely on potentially virtual method calls inside these methods.

Private methods

Methods with an exclamation mark ! before the method name are not callable from anywhere outside the defining class; such methods are private in the sense that they are not visible from outside the class that declares them. Private methods are invoked with an exclamation mark instead of a dot:

class FunMath { 
     has $.value is required; 
     method !do-subtraction( $num ) { 
         if $num ~~ Str { 
             return $!value + (-1 * $num.chars); 
         } 
         return $!value + (-1 * $num); 
     } 
     method minus( $minuend: $subtrahend ) { 
         # invoking the private method on the explicit invocant 
         $minuend!do-subtraction($subtrahend); 
     } 
 } 
 my $five = FunMath.new(value => 5); 
 say $five.minus(6);         # OUTPUT: «-1␤» 
 
 say $five.do-subtraction(6); 
 CATCH { default { put .^name ~ ":\n" ~ .Str } } 
 # OUTPUT: «X::Method::NotFound: 
 # No such method 'do-subtraction' for invocant of type 
 # 'FunMath'. Did you mean '!do-subtraction'?␤» 

Private methods are not inherited by subclasses.

Submethods

Submethods are public methods that will not be inherited by subclasses. The name stems from the fact that they are semantically similar to subroutines.

Submethods are useful for object construction and destruction tasks, as well as for tasks that are so specific to a certain type that subtypes would certainly have to override them.

For example, the default method new calls submethod BUILD on each class in an inheritance chain:

class Point2D { 
     has $.x; 
     has $.y; 
 
     submethod BUILD(:$!x, :$!y) { 
         say "Initializing Point2D"; 
     } 
 } 
 
 class InvertiblePoint2D is Point2D { 
     submethod BUILD() { 
         say "Initializing InvertiblePoint2D"; 
     } 
     method invert { 
         self.new(x => - $.x, y => - $.y); 
     } 
 } 
 
 say InvertiblePoint2D.new(x => 1, y => 2); 
 # OUTPUT: «Initializing Point2D␤» 
 # OUTPUT: «Initializing InvertiblePoint2D␤» 
 # OUTPUT: «InvertiblePoint2D.new(x => 1, y => 2)␤» 

See also: Object construction.

Inheritance

Classes can have parent classes.

class Child is Parent1 is Parent2 { } 

If a method is called on the child class, and the child class does not provide that method, the method of that name in one of the parent classes is invoked instead, if it exists. The order in which parent classes are consulted is called the method resolution order (MRO). Perl 6 uses the C3 method resolution order. You can ask a type for its MRO through a call to its meta class:

say List.^mro;      # ((List) (Cool) (Any) (Mu)) 

If a class does not specify a parent class, Any is assumed by default. All classes directly or indirectly derive from Mu, the root of the type hierarchy.

All calls to public methods are "virtual" in the C++ sense, which means that the actual type of an object determines which method to call, not the declared type:

class Parent { 
     method frob { 
         say "the parent class frobs" 
     } 
 } 
 
 class Child is Parent { 
     method frob { 
         say "the child's somewhat more fancy frob is called" 
     } 
 } 
 
 my Parent $test; 
 $test = Child.new; 
 $test.frob;          # calls the frob method of Child rather than Parent 
 # OUTPUT: «the child's somewhat more fancy frob is called␤» 

Object construction

Objects are generally created through method calls, either on the type object or on another object of the same type.

Class Mu provides a constructor method called new, which takes named arguments and uses them to initialize public attributes.

class Point { 
     has $.x; 
     has $.y; 
 } 
 my $p = Point.new( x => 5, y => 2); 
 #             ^^^ inherited from class Mu 
 say "x: ", $p.x; 
 say "y: ", $p.y; 
 # OUTPUT: «x: 5␤» 
 # OUTPUT: «y: 2␤» 

Mu.new calls method bless on its invocant, passing all the named arguments. bless creates the new object, and then walks all subclasses in reverse method resolution order (i.e. from Mu to most derived classes) and in each class checks for the existence of a method named BUILD. If the method exists, the method is called with all the named arguments from the new method. If not, the public attributes from this class are initialized from named arguments of the same name. In either case, if neither BUILD nor the default mechanism has initialized the attribute, default values are applied. This means that BUILD may change an attribute, but it does not have access to the contents of the attribute declared as its default; these are available only during TWEAK (see below), which can 'see' the contents of an attribute initialized in the declaration of the class.

After the BUILD methods have been called, methods named TWEAK are called, if they exist, again with all the named arguments that were passed to new. See an example of its use below.

Due to the default behavior of BUILD and TWEAK submethods, named arguments to the constructor new derived from Mu can correspond directly to public attributes of any of the classes in the method resolution order, or to any named parameter of any BUILD or TWEAK submethod.

This object construction scheme has several implications for customized constructors. First, custom BUILD methods should always be submethods, otherwise they break attribute initialization in subclasses. Second, BUILD submethods can be used to run custom code at object construction time. They can also be used for creating aliases for attribute initialization:

class EncodedBuffer { 
     has $.enc; 
     has $.data; 
 
     submethod BUILD(:encoding(:$enc), :$data) { 
         $!enc  :=  $enc; 
         $!data := $data; 
     } 
 } 
 my $b1 = EncodedBuffer.new( encoding => 'UTF-8', data => [64, 65] ); 
 my $b2 = EncodedBuffer.new( enc      => 'UTF-8', data => [64, 65] ); 
 #  both enc and encoding are allowed now 

Since passing arguments to a routine binds the arguments to the parameters, a separate binding step is unnecessary if the attribute is used as a parameter. Hence the example above could also have been written as:

submethod BUILD(:encoding(:$!enc), :$!data) { 
     # nothing to do here anymore, the signature binding 
     # does all the work for us. 
 } 

However, be careful when using this auto-binding of attributes when the attribute may have special type requirements, such as an :$!id that must be a positive integer. Remember, default values will be assigned unless you specifically take care of this attribute, and that default value will be Any, which would cause a type error.

The third implication is that if you want a constructor that accepts positional arguments, you must write your own new method:

class Point { 
     has $.x; 
     has $.y; 
     method new($x, $y) { 
         self.bless(:$x, :$y); 
     } 
 } 

However this is considered poor practice, because it makes correct initialization of objects from subclasses harder.

Another thing to note is that the name new is not special in Perl 6. It is merely a common convention, one that is followed quite thoroughly in most Perl 6 classes. You can call bless from any method at all, or use CREATE to fiddle around with low-level workings.

The TWEAK submethod allows you to check things or modify attributes after object construction:

class RectangleWithCachedArea { 
     has ($.x1, $.x2, $.y1, $.y2); 
     has $.area; 
     submethod TWEAK() { 
         $!area = abs( ($!x2 - $!x1) * ( $!y2 - $!y1) ); 
     } 
 } 
 
 say RectangleWithCachedArea.new( x2 => 5, x1 => 1, y2 => 1, y1 => 0).area; 
 # OUTPUT: «4␤» 

Object cloning

The cloning is done using the clone method available on all objects, which shallow-clones both public and private attributes. New values for public attributes can be supplied as named arguments.

class Foo { 
     has $.foo = 42; 
     has $.bar = 100; 
 } 
 
 my $o1 = Foo.new; 
 my $o2 = $o1.clone: :bar(5000); 
 say $o1; # Foo.new(foo => 42, bar => 100) 
 say $o2; # Foo.new(foo => 42, bar => 5000) 

See document for clone for details on how non-scalar attributes get cloned, as well as examples of implementing your own custom clone methods.

Roles

Roles are a collection of attributes and methods; however, unlike classes, roles are meant for describing only parts of an object's behavior; this is why, in general, roles are intended to be mixed in classes and objects. In general, classes are meant for managing objects and roles are meant for managing behavior and code reuse within objects.

Roles use the keyword role preceding the name of the role that is declared. Roles are mixed in using the does keyword preceding the name of the role that is mixed in.

constant ⲧ = " " xx 4; #Just a ⲧab 
 role Notable { 
     has Str $.notes is rw; 
 
     multi method notes() { "$!notes\n" }; 
     multi method notes( Str $note ) { $!notes ~= "$note\n" ~ ⲧ }; 
 
 } 
 
 class Journey does Notable { 
     has $.origin; 
     has $.destination; 
     has @.travelers; 
 
     method Str { "⤷ $!origin\n" ~ ⲧ ~ self.notes() ~ "$!destination ⤶\n" }; 
 } 
 
 my $trip = Journey.new( :origin<Here>, :destination<There>, 
                         travelers => <þor Freya> ); 
 
 $trip.notes("First steps"); 
 notes $trip: "Almost there"; 
 print $trip; 
 # OUTPUT: 
 #⤷ Here 
 #       First steps 
 #       Almost there 
 # 
 #There ⤶ 

Roles are immutable as soon as the compiler parses the closing curly brace of the role declaration.

Applying roles

Role application differs significantly from class inheritance. When a role is applied to a class, the methods of that role are copied into the class. If multiple roles are applied to the same class, conflicts (e.g. attributes or non-multi methods of the same name) cause a compile-time error, which can be solved by providing a method of the same name in the class.

This is much safer than multiple inheritance, where conflicts are never detected by the compiler, but are instead resolved to the superclass that appears earlier in the method resolution order, which might not be what the programmer wanted.

For example, if you've discovered an efficient method to ride cows, and are trying to market it as a new form of popular transportation, you might have a class Bull, for all the bulls you keep around the house, and a class Automobile, for things that you can drive.

class Bull { 
     has Bool $.castrated = False; 
     method steer { 
         # Turn your bull into a steer 
         $!castrated = True; 
         return self; 
     } 
 } 
 class Automobile { 
     has $.direction; 
     method steer($!direction) { } 
 } 
 class Taurus is Bull is Automobile { } 
 
 my $t = Taurus.new; 
 say $t.steer; 
 # OUTPUT: «Taurus.new(castrated => Bool::True, direction => Any)␤» 

With this setup, your poor customers will find themselves unable to turn their Taurus and you won't be able to make more of your product! In this case, it may have been better to use roles:

role Bull-Like { 
     has Bool $.castrated = False; 
     method steer { 
         # Turn your bull into a steer 
         $!castrated = True; 
         return self; 
     } 
 } 
 role Steerable { 
     has Real $.direction; 
     method steer(Real $d = 0) { 
         $!direction += $d; 
     } 
 } 
 class Taurus does Bull-Like does Steerable { } 

This code will die with something like:

===SORRY!=== 
 Method 'steer' must be resolved by class Taurus because it exists in 
 multiple roles (Steerable, Bull-Like) 

This check will save you a lot of headaches:

class Taurus does Bull-Like does Steerable { 
     method steer($direction?) { 
         self.Steerable::steer($direction) 
     } 
 } 

When a role is applied to a second role, the actual application is delayed until the second role is applied to a class, at which point both roles are applied to the class. Thus

role R1 { 
     # methods here 
 } 
 role R2 does R1 { 
     # methods here 
 } 
 class C does R2 { } 

produces the same class C as

role R1 { 
     # methods here 
 } 
 role R2 { 
     # methods here 
 } 
 class C does R1 does R2 { } 

Stubs

When a role contains a stubbed method, a non-stubbed version of a method of the same name must be supplied at the time the role is applied to a class. This allows you to create roles that act as abstract interfaces.

role AbstractSerializable { 
     method serialize() { ... }        # literal ... here marks the 
                                       # method as a stub 
 } 
 
 # the following is a compile time error, for example 
 #        Method 'serialize' must be implemented by Point because 
 #        it's required by a role 
 
 class APoint does AbstractSerializable { 
     has $.x; 
     has $.y; 
 } 
 
 # this works: 
 class SPoint does AbstractSerializable { 
     has $.x; 
     has $.y; 
     method serialize() { "p($.x, $.y)" } 
 } 

The implementation of the stubbed method may also be provided by another role.

Inheritance

Roles cannot inherit from classes, but they may carry classes, causing any class which does that role to inherit from the carried classes. So if you write:

role A is Exception { } 
 class X::Ouch does A { } 
 X::Ouch.^parents.say # OUTPUT: «((Exception))␤» 

then X::Ouch will inherit directly from Exception, as we can see above by listing its parents.

As they do not use what can properly be called inheritance, roles are not part of the class hierarchy. Roles are listed with the .^roles meta-method instead, which uses transitive as flag for including all levels or just the first one. Despite this, a class or instance may still be tested with smartmatches or type constraints to see if it does a role.

role F { } 
 class G does F { } 
 G.^roles.say;                    # OUTPUT: «((F))␤» 
 role Ur {} 
 role Ar does Ur {} 
 class Whim does Ar {}; Whim.^roles(:!transitive).say;   # OUTPUT: «((Ar))␤» 
 say G ~~ F;                      # OUTPUT: «True␤» 
 multi a (F $a) { "F".say } 
 multi a ($a)   { "not F".say } 
 a(G);                            # OUTPUT: «F␤» 

Pecking order

A method defined directly in a class will always override definitions from applied roles or from inherited classes. If no such definition exists, methods from roles override methods inherited from classes. This happens both when said class was brought in by a role, and also when said class was inherited directly.

role M { 
   method f { say "I am in role M" } 
 } 
 
 class A { 
   method f { say "I am in class A" } 
 } 
 
 class B is A does M { 
   method f { say "I am in class B" } 
 } 
 
 class C is A does M { } 
 
 B.new.f; # OUTPUT «I am in class B␤» 
 C.new.f; # OUTPUT «I am in role M␤» 

Note that each candidate for a multi-method is its own method. In this case, the above only applies if two such candidates have the same signature. Otherwise, there is no conflict, and the candidate is just added to the multi-method.

Automatic role punning

Any attempt to directly instantiate a role or use it as a type object will automatically create a class with the same name as the role, making it possible to transparently use a role as if it were a class.

role Point { 
     has $.x; 
     has $.y; 
     method abs { sqrt($.x * $.x + $.y * $.y) } 
     method dimensions { 2 } 
 } 
 say Point.new(x => 6, y => 8).abs; # OUTPUT «10␤» 
 say Point.dimensions;              # OUTPUT «2␤» 

We call this automatic creation of classes punning, and the generated class a pun.

Punning is not caused by most meta-programming constructs, however, as those are sometimes used to work directly with roles.

Parameterized roles

Roles can be parameterized, by giving them a signature in square brackets:

role BinaryTree[::Type] { 
     has BinaryTree[Type] $.left; 
     has BinaryTree[Type] $.right; 
     has Type $.node; 
 
     method visit-preorder(&cb) { 
         cb $.node; 
         for $.left, $.right -> $branch { 
             $branch.visit-preorder(&cb) if defined $branch; 
         } 
     } 
     method visit-postorder(&cb) { 
         for $.left, $.right -> $branch { 
             $branch.visit-postorder(&cb) if defined $branch; 
         } 
         cb $.node; 
     } 
     method new-from-list(::?CLASS:U: *@el) { 
         my $middle-index = @el.elems div 2; 
         my @left         = @el[0 .. $middle-index - 1]; 
         my $middle       = @el[$middle-index]; 
         my @right        = @el[$middle-index + 1 .. *]; 
         self.new( 
             node    => $middle, 
             left    => @left  ?? self.new-from-list(@left)  !! self, 
             right   => @right ?? self.new-from-list(@right) !! self, 
         ); 
     } 
 } 
 
 my $t = BinaryTree[Int].new-from-list(4, 5, 6); 
 $t.visit-preorder(&say);    # OUTPUT: «5␤4␤6␤» 
 $t.visit-postorder(&say);   # OUTPUT: «4␤6␤5␤» 

Here the signature consists only of a type capture, but any signature will do:

enum Severity <debug info warn error critical>; 
 
 role Logging[$filehandle = $*ERR] { 
     method log(Severity $sev, $message) { 
         $filehandle.print("[{uc $sev}] $message\n"); 
     } 
 } 
 
 Logging[$*OUT].log(debug, 'here we go'); # OUTPUT: «[DEBUG] here we go␤» 

You can have multiple roles of the same name, but with different signatures; the normal rules of multi dispatch apply for choosing multi candidates.

Mixins of roles

Roles can be mixed into objects. A role's given attributes and methods will be added to the methods and attributes the object already has. Multiple mixins and anonymous roles are supported.

role R { method Str() {'hidden!'} }; 
 my $i = 2 but R; 
 sub f(\bound){ put bound }; 
 f($i); # OUTPUT: «hidden!␤» 
 my @positional := <a b> but R; 
 say @positional.^name; # OUTPUT: «List+{R}␤» 

Note that the object got the role mixed in, not the object's class or the container. Thus, @-sigiled containers will require binding to make the role stick as is shown in the example with @positional. Some operators will return a new value, which effectively strips the mixin from the result. That is why it might be more clear to mix in the role in the declaration of the variable using does:

role R {}; 
 my @positional does R = <a b>; 
 say @positional.^name; # OUTPUT: «Array+{R}␤» 

The operator infix:<but> is narrower than the list constructor. When providing a list of roles to mix in, always use parentheses.

role R1 { method m {} } 
 role R2 { method n {} } 
 my $a = 1 but R1,R2; # R2 is in sink context, issues a WARNING 
 say $a.^name; 
 # OUTPUT: «Int+{R1}␤» 
 my $all-roles = 1 but (R1,R2); 
 say $all-roles.^name; # OUTPUT: «Int+{R1,R2}␤» 

Mixins can be used at any point in your object's life.

# A counter for Table of Contents 
 role TOC-Counter { 
     has Int @!counters is default(0); 
     method Str() { @!counters.join: '.' } 
     method inc($level) { 
         @!counters[$level - 1]++; 
         @!counters.splice($level); 
         self 
     } 
 } 
 
 my Num $toc-counter = NaN;     # don't do math with Not A Number 
 say $toc-counter;              # OUTPUT: «NaN␤» 
 $toc-counter does TOC-Counter; # now we mix the role in 
 $toc-counter.inc(1).inc(2).inc(2).inc(1).inc(2).inc(2).inc(3).inc(3); 
 put $toc-counter / 1;          # OUTPUT: «NaN␤» (because that's numerical context) 
 put $toc-counter;              # OUTPUT: «2.2.2␤» (put will call TOC-Counter::Str) 

Roles can be anonymous.

my %seen of Int is default(0 but role :: { method Str() {'NULL'} }); 
 say %seen<not-there>;          # OUTPUT: «NULL␤» 
 say %seen<not-there>.defined;  # OUTPUT: «True␤» (0 may be False but is well defined) 
 say Int.new(%seen<not-there>); # OUTPUT: «0␤» 

Meta-object programming and introspection

Perl 6 has a meta object system, which means that the behavior of objects, classes, roles, grammars, enums, etc. are themselves controlled by other objects; those objects are called meta objects. Meta objects are, like ordinary objects, instances of classes, in this case we call them meta classes.

For each object or class you can get the meta object by calling .HOW on it. Note that although this looks like a method call, it works more like a macro.

So, what can you do with the meta object? For one you can check if two objects have the same meta class by comparing them for equality:

say 1.HOW ===   2.HOW;      # OUTPUT: «True␤» 
 say 1.HOW === Int.HOW;      # OUTPUT: «True␤» 
 say 1.HOW === Num.HOW;      # OUTPUT: «False␤» 

Perl 6 uses the word HOW (Higher Order Workings) to refer to the meta object system. Thus it should be no surprise that in Rakudo, the class name of the meta class that controls class behavior is called Perl6::Metamodel::ClassHOW. For each class there is one instance of Perl6::Metamodel::ClassHOW.

But of course the meta model does much more for you. For example, it allows you to introspect objects and classes. The calling convention for methods on meta objects is to call the method on the meta object and pass in the object of interest as first argument to the object. So to get the name of the class of an object, you could write:

my $object = 1; 
 my $metaobject = 1.HOW; 
 say $metaobject.name($object);      # OUTPUT: «Int␤» 
 
 # or shorter: 
 say 1.HOW.name(1);                  # OUTPUT: «Int␤» 

(The motivation is that Perl 6 also wants to allow a more prototype-based object system, where it's not necessary to create a new meta object for every type).

There's a shortcut to keep from using the same object twice:

say 1.^name;                        # OUTPUT: «Int␤» 
 # same as 
 say 1.HOW.name(1);                  # OUTPUT: «Int␤» 

See Metamodel::ClassHOW for documentation on the meta class of class and also the general documentation on the meta object protocol.

59 Operators

Common Perl 6 infixes, prefixes, postfixes, and more!

See creating operators on how to define new operators.

Operator precedence

In an expression like 1 + 2 * 3, the 2 * 3 is evaluated first because the infix * has tighter precedence than the +.

The following table summarizes the precedence levels in Perl 6, from tightest to loosest:

A Level Examples
N Terms 42 3.14 "eek" qq["foo"] $x :!verbose @$array rand time now ∅
L Method postfix .meth .+ .? .* .() .[] .{} .<> .«» .:: .= .^ .:
N Autoincrement ++ --
R Exponentiation **
L Symbolic unary ! + - ~ ? | || +^ ~^ ?^ ^
L Dotty infix .= .
L Multiplicative * × / ÷ % %% +& +< +> ~& ~< ~> ?& div mod gcd lcm
L Additive + - − +| +^ ~| ~^ ?| ?^
L Replication x xx
X Concatenation ~ o ∘
X Junctive and & (&) (.) ∩ ⊍
X Junctive or | ^ (|) (^) (+) (-) ∪ ⊖ ⊎ ∖
L Named unary temp let
N Structural infix but does <=> leg unicmp cmp coll .. ..^ ^.. ^..^
C Chaining infix != ≠ == < <= ≤ > >= ≥ eq ne lt le gt ge ~~ === eqv !eqv =~= ≅ (elem) (cont) (<) (>) (<=) (>=) (<+) (>+) ∈ ∉ ∋ ∌ ⊂ ⊄ ⊃ ⊅ ⊆ ⊈ ⊇ ⊉ ≼ ≽
X Tight and &&
X Tight or || ^^ // min max
R Conditional ?? !! ff ff^ ^ff ^ff^ fff fff^ ^fff ^fff^
R Item assignment = => += -= **= xx=
L Loose unary so not
X Comma operator , :
X List infix Z minmax X X~ X* Xeqv ... … ...^ …^
R List prefix print push say die map substr ... [+] [*] any Z=
X Loose and and andthen notandthen
X Loose or or xor orelse
X Sequencer <==, ==>, <<==, ==>>
N Terminator ; {...}, unless, extra ), ], }

Using two ! symbols below generically to represent any pair of operators that have the same precedence, the associativities specified above for binary operators are interpreted as follows:

A Assoc Meaning of $a ! $b ! $c
L left ($a ! $b) ! $c
R right $a ! ($b ! $c)
N non ILLEGAL
C chain ($a ! $b) and ($b ! $c)
X list infix:<!>($a; $b; $c)

For unary operators this is interpreted as:

A Assoc Meaning of !$a!
L left (!$a)!
R right !($a!)
N non ILLEGAL

In the operator descriptions below, a default associativity of left is assumed.

Operator classification

Operators can occur in several positions relative to a term:

+term prefix
term1 + term2 infix
term++ postfix
(term) circumfix
term1[term2] postcircumfix
.+(term) method

Each operator (except method operators) is also available as a subroutine. The name of the routine is formed from the operator category, followed by a colon, then a list quote construct with the symbol(s) that make up the operator:

infix:<+>(1, 2);                # same as 1 + 2
circumfix:«[ ]»(<a b c>);       # same as [<a b c>]

As a special case, a listop (list operator) can stand either as a term or as a prefix. Subroutine calls are the most common listops. Other cases include meta-reduced infix operators ([+] 1, 2, 3) and the #prefix ... etc. stub operators.

Defining custom operators is covered in Defining operators functions.

Metaoperators

Metaoperators can be parameterized with other operators or subroutines in the same way as functions can take functions as parameters. To use a subroutine as a parameter, prefix its name with a &. Perl 6 will generate the actual combined operator in the background, allowing the mechanism to be applied to user defined operators. To disambiguate chained metaoperators, enclose the inner operator in square brackets. There are quite a few metaoperators with different semantics as explained, next.

Substitution operators

Each substitution operator comes into two main forms: a lowercase one (e.g., s///) that performs in-place (i.e., destructive behavior; and an uppercase form (e.g., S///) that provides a non-destructive behavior.

s/// in-place substitution

my $str = 'old string';
$str ~~ s/o .+ d/new/;
say $str; # OUTPUT: «new string␤»

s/// operates on the $_ topical variable, changing it in place. It uses the given Regex to find portions to replace and changes them to the provided replacement string. Sets $/ to the Match object or, if multiple matches were made, a List of Match objects. Returns $/.

It's common to use this operator with the ~~ smartmatch operator, as it aliases left-hand side to $_, which s/// uses.

Regex captures can be referenced in the replacement part; it takes the same adverbs as the .subst method, which go between the s and the opening /, separated with optional whitespace:

my $str = 'foo muCKed into the lEn';

# replace second 'o' with 'x'
$str ~~ s:2nd/o/x/;

# replace 'M' or 'L' followed by non-whitespace stuff with 'd'
# and lower-cased version of that stuff:
$str ~~ s :g :i/<[ML]> (\S+)/d{lc $0}/;

say $str; # OUTPUT: «fox ducked into the den␤»

You can also use a different delimiter:

my $str = 'foober';
$str ~~ s!foo!fox!;
$str ~~ s{b(.)r} = " d$0n";
say $str; # OUTPUT: «fox den␤»

Non-paired characters can simply replace the original slashes. Paired characters, like curly braces, are used only on the match portion, with the substitution given by assignment (of anything: a string, a routine call, etc.).

S/// non-destructive substitution

say S/o .+ d/new/ with 'old string';      # OUTPUT: «new string␤»
S:g/« (.)/$0.uc()/.say for <foo bar ber>; # OUTPUT: «Foo␤Bar␤Ber␤»

S/// uses the same semantics as the s/// operator, except it leaves the original string intact and returns the resultant string instead of $/ ($/ still being set to the same values as with s///).

Note: since the result is obtained as a return value, using this operator with the ~~ smartmatch operator is a mistake and will issue a warning. To execute the substitution on a variable that isn't the $_ this operator uses, alias it to $_ with given, with, or any other way. Alternatively, use the .subst method.

tr/// in-place transliteration

my $str = 'old string';
$str ~~ tr/dol/wne/;
say $str; # OUTPUT: «new string␤»

tr/// operates on the $_ topical variable and changes it in place. It behaves similar to Str.trans called with a single Pair argument, where key is the matching part (characters dol in the example above) and value is the replacement part (characters wne in the example above). Accepts the same adverbs as Str.trans. Returns the StrDistance object that measures the distance between original value and the resultant string.

my $str = 'old string';
$str ~~ tr:c:d/dol st//;
say $str; # OUTPUT: «ring␤»

TR/// non-destructive transliteration

with 'old string' {
    say TR/dol/wne/; # OUTPUT: «new string␤»
}

TR/// behaves the same as the tr/// operator, except that it leaves the $_ value untouched and instead returns the resultant string.

say TR:d/dol // with 'old string'; # OUTPUT: «string␤»

Assignment operators

Infix operators can be combined with the assignment operator to modify a value and apply the result to a container in one go. Containers will be autovivified if possible. Some examples:

my $a = 32;
$a += 10;     # 42
$a -= 2;      # 40

$a = 3;
$a min= 5;    # still 3
$a min= 2;    # 2

my $s = 'a';
$s ~= 'b';    # 'ab'

This behavior is automatically extended to include custom-defined infix operators.

sub infix:<space-concat> ($a, $b) { $a ~ " " ~ $b };
my $a = 'word1';
$a space-concat= 'word2';     # RESULT: «'word1 word2'»

Although not strictly operators, methods can be used in the same fashion.

my Real $a = 1/2;
$a = 3.14;
$a .= round;      # RESULT: «3»

Negated relational operators

The result of a relational operator returning Bool can be negated by prefixing with !. To avoid visual confusion with the !! operator, you may not modify any operator already beginning with !.

There are shortcuts for !== and !eq, namely != and ne.

my $a = True;
say so $a != True;    # OUTPUT: «False␤»
my $i = 10;

my $release = Date.new(:2015year, :12month, :24day);
my $today = Date.today;
say so $release !before $today;     # OUTPUT: «False␤»

Reversed operators

Any infix operator may be called with its two arguments reversed by prefixing with R. Associativity of operands is reversed as well.

say 4 R/ 12;               # OUTPUT: «3␤»
say [R/] 2, 4, 16;         # OUTPUT: «2␤»
say [RZ~] <1 2 3>,<4 5 6>  # OUTPUT: «(41 52 63)␤»

Hyper operators

Hyper operators include « and », with their ASCII variants << and >>. They apply a given operator enclosed (or preceded or followed, in the case of unary operators) by « and/or » to one or two lists, returning the resulting list, with the pointy part of « or » aimed at the shorter list. Single elements are turned to a list, so they can be used too. If one of the lists is shorter than the other, the operator will cycle over the shorter list until all elements of the longer list are processed.

say (1, 2, 3) »*» 2;          # OUTPUT: «(2 4 6)␤»
say (1, 2, 3, 4) »~» <a b>;   # OUTPUT: «(1a 2b 3a 4b)␤»
say (1, 2, 3) »+« (4, 5, 6);  # OUTPUT: «(5 7 9)␤»
say (&sin, &cos, &sqrt)».(0.5);
# OUTPUT: «(0.479425538604203 0.877582561890373 0.707106781186548)␤»

The last example illustrates how postcircumfix operators (in this case .()) can also be hypered.

my @a = <1 2 3>;
my @b = <4 5 6>;
say (@a,@b)»[1]; # OUTPUT: «(2 5)␤»

In this case, it's the postcircumfix[] which is being hypered.

Assignment metaoperators can be hyped.

my @a = 1, 2, 3;
say @a »+=» 1;    # OUTPUT: «[2 3 4]␤»
my ($a, $b, $c);
(($a, $b), $c) «=» ((1, 2), 3);
say "$a, $c";       #  OUTPUT: «1, 3␤»

Hyper forms of unary operators have the pointy bit aimed at the operator and the blunt end at the list to be operated on.

my @wisdom = True, False, True;
say !« @wisdom;     # OUTPUT: «[False True False]␤»

my @a = 1, 2, 3;
@a»++;              # OUTPUT: «(2, 3, 4)␤»

Hyper operators are defined recursively on nested arrays.

say -« [[1, 2], 3]; # OUTPUT: «[[-1 -2] -3]␤»

Also, methods can be called in an out of order, concurrent fashion. The resulting list will be in order. Note that all hyper operators are candidates for parallelism and will cause tears if the methods have side effects. The optimizer has full reign over hyper operators, which is the reason that they cannot be defined by the user.

class CarefulClass { method take-care {} }
my CarefulClass @objs;
my @results = @objs».take-care();

my @slops;        # May Contain Nuts
@slops».?this-method-may-not-exist();

Hyper operators can work with hashes. The pointy direction indicates if missing keys are to be ignored in the resulting hash. The enclosed operator operates on all values that have keys in both hashes.

%foo «+» %bar; intersection of keys
%foo »+« %bar; union of keys
%outer »+» %inner; only keys of %inner that exist in %outer will occur in the result
my %outer = 1, 2, 3 Z=> <a b c>;
my %inner = 1, 2 Z=> <x z>;
say %outer «~» %inner;          # OUTPUT: «{"1" => "ax", "2" => "bz"}␤»

Hyper operators can take user-defined operators as their operator argument.

sub pretty-file-size (Int $size --> Str) {
    # rounding version of infix:</>(Int, Int)
    sub infix:<r/>(Int \i1, Int \i2) {
        round(i1 / i2, 0.1)
    }

    # we build a vector of fractions of $size and zip that with the fitting prefix
    for $size «[r/]« (2**60, 2**50, 2**40, 2**30, 2**20, 2**10)
              Z      <EB     PB     TB     GB     MB     KB> -> [\v,\suffix] {
        # starting with the biggest suffix,
        # we take the first that is 0.5 of that suffix or bigger
        return v ~ ' ' ~ suffix if v > 0.4
    }
    # this be smaller or equal then 0.4 KB
    return $size.Str;
}

for 60, 50, 40, 30, 20, 10 -> $test {
    my &a = { (2 ** $test) * (1/4, 1/2, 1, 10, 100).pick * (1..10).pick };
    print pretty-file-size(a.Int) xx 2, ' ';
}

# OUTPUT: «10 EB 4 EB 2 PB 5 PB 0.5 PB 4 TB 300 GB 4.5 GB 50 MB 200 MB 9 KB 0.6 MB␤»

Whether hyperoperators descend into child lists depends on the nodality of the inner operator of a chain. For the hyper method call operator (».), the nodality of the target method is significant.

say (<a b>, <c d e>)».elems;        # OUTPUT: «(2 3)␤»
say (<a b>, <c d e>)».&{ .elems };  # OUTPUT: «((1 1) (1 1 1))␤»

You can chain hyper operators to destructure a List of Lists.

my $neighbors = ((-1, 0), (0, -1), (0, 1), (1, 0));
my $p = (2, 3);
say $neighbors »>>+<<» ($p, *);   # OUTPUT: «((1 3) (2 2) (2 4) (3 3))␤»

Reduction metaoperators

The reduction metaoperator, [ ], reduces a list with the given infix operator. It gives the same result as the reduce routine - see there for details.

# These two are equivalent:
say [+] 1, 2, 3;                # OUTPUT: «6␤»
say reduce &infix:<+>, 1, 2, 3; # OUTPUT: «6␤»

No whitespace is allowed between the square brackets and the operator. To wrap a function instead of an operator, provide an additional layer of square brackets:

sub plus { $^a + $^b };
say [[&plus]] 1, 2, 3;          # OUTPUT: «6␤»

The argument list is iterated without flattening. This means that you can pass a nested list to the reducing form of a list infix operator:

say [X~] (1, 2), <a b>;         # OUTPUT: «(1a 1b 2a 2b)␤»

which is equivalent to 1, 2 X~ <a b>.

By default, only the final result of the reduction is returned. Prefix the wrapped operator with a \, to return a lazy list of all intermediate values instead. This is called a "triangular reduce". If the non-meta part contains a \ already, quote it with [] (e.g. [\[\x]]).

my @n = [\~] 1..*;
say @n[^5];         # OUTPUT: «(1 12 123 1234 12345)␤»

Cross operators

The cross metaoperator, X, will apply a given infix operator in order of cross product to all lists, such that the rightmost operator varies most quickly.

1..3 X~ <a b> # RESULT: «<1a, 1b, 2a, 2b, 3a, 3b>␤»

Zip metaoperator

The zip metaoperator (which is not the same thing as Z) will apply a given infix operator to pairs taken one left, one right, from its arguments. The resulting list is returned.

my @l = <a b c> Z~ 1, 2, 3;     # RESULT: «[a1 b2 c3]␤»

If one of the operands runs out of elements prematurely, the zip operator will stop. An infinite list can be used to repeat elements. A list with a final element of * will repeat its 2nd last element indefinitely.

my @l = <a b c d> Z~ ':' xx *;  # RESULT: «<a: b: c: d:>»
   @l = <a b c d> Z~ 1, 2, *;   # RESULT: «<a1 b2 c2 d2>»

If an infix operator is not given, the , (comma operator) will be used by default:

my @l = 1 Z 2;  # RESULT: «[(1 2)]»

Sequential operators

The sequential metaoperator, S, will suppress any concurrency or reordering done by the optimizer. Most simple infix operators are supported.

say so 1 S& 2 S& 3;  # OUTPUT: «True␤»

Nesting of metaoperators

To avoid ambiguity when chaining metaoperators, use square brackets to help the compiler understand you.

my @a = 1, 2, 3;
my @b = 5, 6, 7;
@a X[+=] @b;
say @a;         # OUTPUT: «[19 20 21]␤»

Term precedence

term < >

The quote-words construct breaks up the contents on whitespace and returns a List of the words. If a word looks like a number literal or a Pair literal, it's converted to the appropriate number.

say <a b c>[1];   # OUTPUT: «b␤»

term ( )

The grouping operator.

An empty group () creates an empty list. Parentheses around non-empty expressions simply structure the expression, but do not have additional semantics.

In an argument list, putting parenthesis around an argument prevents it from being interpreted as a named argument.

multi sub p(:$a!) { say 'named'      }
multi sub p($a)   { say 'positional' }
p a => 1;           # OUTPUT: «named␤»
p (a => 1);         # OUTPUT: «positional␤»

term { }

Block or Hash constructor.

If the content is empty, or contains a single list that starts with a Pair literal or %-sigiled variable, and the $_ variable or placeholder parameters are not used, the constructor returns a Hash. Otherwise it constructs a Block.

To force construction of a Block, follow the opening brace with a semicolon. To always ensure you end up with a Hash, you can use %( ) coercer or hash routine instead:

{}.^name.say;        # OUTPUT: «Hash␤»
{;}.^name.say;       # OUTPUT: «Block␤»

{:$_}.^name.say;     # OUTPUT: «Block␤»
%(:$_).^name.say;    # OUTPUT: «Hash␤»
hash(:$_).^name.say; # OUTPUT: «Hash␤»

circumfix [ ]

The Array constructor returns an itemized Array that does not flatten in list context. Check this:

say .perl for [3,2,[1,0]]; # OUTPUT: «3␤2␤$[1, 0]␤»

This array is itemized, in the sense that every element constitutes an item, as shown by the $ preceding the last element of the array, the (list) item contextualizer.

Terms

Terms have their own extended documentation.

Method postfix precedence

postcircumfix [ ]

sub postcircumfix:<[ ]>(@container, **@index,
                        :$k, :$v, :$kv, :$p, :$exists, :$delete)

Universal interface for positional access to zero or more elements of a @container, a.k.a. "array indexing operator".

my @alphabet = 'a' .. 'z';
say @alphabet[0];                   # OUTPUT: «a␤»
say @alphabet[1];                   # OUTPUT: «b␤»
say @alphabet[*-1];                 # OUTPUT: «z␤»
say @alphabet[100]:exists;          # OUTPUT: «False␤»
say @alphabet[15, 4, 17, 11].join;  # OUTPUT: «perl␤»
say @alphabet[23 .. *].perl;        # OUTPUT: «("x", "y", "z")␤»

@alphabet[1, 2] = "B", "C";
say @alphabet[0..3].perl            # OUTPUT: «("a", "B", "C", "d")␤»

See Subscripts, for a more detailed explanation of this operator's behavior and for how to implement support for it in custom types.

postcircumfix { }

sub postcircumfix:<{ }>(%container, **@key,
                        :$k, :$v, :$kv, :$p, :$exists, :$delete)

Universal interface for associative access to zero or more elements of a %container, a.k.a. "hash indexing operator".

my %color = kiwi => "green", banana => "yellow", cherry => "red";
say %color{"banana"};                 # OUTPUT: «yellow␤»
say %color{"cherry", "kiwi"}.perl;    # OUTPUT: «("red", "green")␤»
say %color{"strawberry"}:exists;      # OUTPUT: «False␤»

%color{"banana", "lime"} = "yellowish", "green";
%color{"cherry"}:delete;
say %color;             # OUTPUT: «banana => yellowish, kiwi => green, lime => green␤»

See postcircumfix < > and postcircumfix « » for convenient shortcuts, and Subscripts for a more detailed explanation of this operator's behavior and how to implement support for it in custom types.

postcircumfix <>

Decontainerization operator, which extracts the value from a container and makes it independent of the container type.

use JSON::Tiny; 
 
 my $config = from-json('{ "files": 3, "path": "/home/perl6/perl6.pod6" }'); 
 say $config.perl;      # OUTPUT: «${:files(3), :path("/home/perl6/perl6.pod6")}» 
 my %config-hash = $config<>; 
 say %config-hash.perl; # OUTPUT: «{:files(3), :path("/home/perl6/perl6.pod6")}» 

It's a Hash in both cases, and it can be used like that; however, in the first case it was in item context, and in the second case it has been extracted to its proper context.

postcircumfix < >

Shortcut for postcircumfix { } that quotes its argument using the same rules as the quote-words operator of the same name.

my %color = kiwi => "green", banana => "yellow", cherry => "red";
say %color<banana>;               # OUTPUT: «yellow␤»
say %color<cherry kiwi>.perl;     # OUTPUT: «("red", "green")␤»
say %color<strawberry>:exists;    # OUTPUT: «False␤»

Technically, not a real operator; it's syntactic sugar that's turned into the { } postcircumfix operator at compile-time.

postcircumfix « »

Shortcut for postcircumfix { } that quotes its argument using the same rules as the interpolating quote-words operator of the same name.

my %color = kiwi => "green", banana => "yellow", cherry => "red";
my $fruit = "kiwi";
say %color«cherry "$fruit"».perl;   # OUTPUT: «("red", "green")␤»

Technically, not a real operator; it's syntactic sugar that's turned into the { } postcircumfix operator at compile-time.

postcircumfix ( )

The call operator treats the invocant as a Callable and invokes it, using the expression between the parentheses as arguments.

Note that an identifier followed by a pair of parentheses is always parsed as a subroutine call.

If you want your objects to respond to the call operator, implement a method CALL-ME.

methodop .

The operator for calling one method, $invocant.method.

Technically, not a real operator; it's syntax special-cased in the compiler.

methodop .&

The operator to call a subroutine (with at least one positional argument), such as a method. The invocant will be bound to the first positional argument.

Technically, not a real operator; it's syntax special-cased in the compiler.

my sub f($invocant){ "The arg has a value of $invocant" }
42.&f;
# OUTPUT: «The arg has a value of 42␤»

42.&(-> $invocant { "The arg has a value of $invocant" });
# OUTPUT: «The arg has a value of 42␤»

methodop .=

A mutating method call. $invocant.=method desugars to $invocant = $invocant.method, similar to = .

Technically, not a real operator; it's syntax special-cased in the compiler.

methodop .^

A meta-method call. $invocant.^method calls method on $invocant's metaclass. It desugars to $invocant.HOW.method($invocant, ...). See the meta-object protocol documentation for more information.

Technically, not a real operator; it's syntax special-cased in the compiler.

methodop .?

Safe call operator. $invocant.?method calls method method on $invocant if it has a method of such name. Otherwise it returns Nil.

Technically, not a real operator; it's syntax special-cased in the compiler.

methodop .+

$foo.+meth walks the MRO and calls all the methods called meth and submethods called meth if the type is the same as type of $foo. Those methods might be multis, in which case the matching candidate would be called.

After that, a List of the results are returned. If no such method was found, it throws a X::Method::NotFound exception.

class A {
  method foo { say "from A"; }
}
class B is A {
  multi method foo { say "from B"; }
  multi method foo(Str) { say "from B (Str)"; }
}
class C is B is A {
  multi method foo { say "from C"; }
  multi method foo(Str) { say "from C (Str)"; }
}

say C.+foo; # OUTPUT: «from C␤from B␤from A␤(True True True)␤»

methodop .*

$foo.*meth walks the MRO and calls all the methods called meth and submethods called meth if the type is the same as type of $foo. Those methods might be multis, in which case the matching candidate would be called.

After that, a List of the results are returned. If no such method was found, an empty List is returned.

Technically, postfix .+ calls .* at first. Read postfix .+ section to see examples.

methodop ». / methodop >>.

This is the hyper method call operator. Will call a method on all elements of a List out of order and return the list of return values in order.

my @a = <a b c>; 
 my @b = @a».ord;                  # OUTPUT: «[97, 98, 99]␤» 
 # The first parameter of a method is the invocant. 
 sub foo(Str:D $c){ $c.ord * 2 }; 
 # So we can pretend to have a method call with a sub that got a good 
 # first positional argument. 
 say @a».&foo; 
 # Blocks have an implicit positional arguments that lands in $_. The latter can 
 # be omitted for method calls. 
 say @a».&{ .ord}; 

Hyper method calls may appear to be the same as doing a map call, however along with being a hint to the compiler that it can parallelize the call, the behavior is also affected by nodality of the method being invoked, depending on which either nodemap or deepmap semantics are used to perform the call.

The nodality is checked by looking up whether the Callable provides nodal method. If the hyper is applied to a method, that Callable is that method name, looked up on List type; if the hyper is applied to a routine (e.g. ».&foo), that routine functions as that Callable. If the Callable is determined to provide nodal method, nodemap semantics are used to perform the hyper call, otherwise duckmap semantics are used.

Take care to avoid a common mistake of expecting side-effects to occur in order. The following say is not guaranteed to produce the output in order:

@a».say;  # WRONG! Could produce a␤b␤c␤ or c␤b␤a␤ or any other order 

methodop .postfix / .postcircumfix

In most cases, a dot may be placed before a postfix or postcircumfix:

my @a;
@a[1, 2, 3];
@a.[1, 2, 3]; # Same

This can be useful for visual clarity or brevity. For example, if an object's attribute is a function, putting a pair of parentheses after the attribute name will become part of the method call. So, either two pairs of parentheses must be used or a dot has to come before the parentheses to separate it from the method call.

class Operation {
    has $.symbol;
    has &.function;
}
my $addition = Operation.new(:symbol<+>, :function{ $^a + $^b });
say $addition.function()(1, 2);   # OUTPUT: «3␤»
# OR
say $addition.function.(1, 2);    # OUTPUT: «3␤»

If the postfix is an identifier, however, it will be interpreted as a normal method call.

1.i # No such method 'i' for invocant of type 'Int' 

Technically, not a real operator; it's syntax special-cased in the compiler.

methodop .:<prefix>

An operator in prefix form can still be called like a method, that is, using the . methodop notation, by preceding it by a colon. For example:

my $a = 1;
say ++$a;       # OUTPUT: «2␤»
say $a.:<++>;   # OUTPUT: «3␤»

Technically, not a real operator; it's syntax special-cased in the compiler, that is why it's classified as a methodop.

methodop .::

A class-qualified method call, used to call a method as defined in a parent class or role, even after it has been redefined in the child class.

class Bar {
    method baz { 42 }
}
class Foo is Bar {
    method baz { "nope" }
}
say Foo.Bar::baz;       # OUTPUT: «42␤»

postfix ,=

Creates an object that concatenates, in a class-dependent way, the contents of the variable on the left hand side and the expression on the right hand side:

my %a = :11a, :22b;
%a ,= :33x;
say %a # OUTPUT: «{a => 11, b => 22, x => 33}␤»

Autoincrement precedence

prefix ++

multi sub prefix:<++>($x is rw) is assoc<non>

This is the . Increments its argument by one and returns the updated value.

my $x = 3;
say ++$x;   # OUTPUT: «4␤»
say $x;     # OUTPUT: «4␤»

It works by calling the succ method (for successor) on its argument, which gives custom types the freedom to implement their own increment semantics.

prefix --

multi sub prefix:<-->($x is rw) is assoc<non>

Decrements its argument by one and returns the updated value.

my $x = 3;
say --$x;   # OUTPUT: «2␤»
say $x;     # OUTPUT: «2␤»

It works by calling the pred method (for predecessor) on its argument, which gives custom types the freedom to implement their own decrement semantics.

postfix ++

multi sub postfix:<++>($x is rw) is assoc<non>

Increments its argument by one and returns the original value.

my $x = 3;
say $x++;   # OUTPUT: «3␤»
say $x;     # OUTPUT: «4␤»

It works by calling the succ method (for successor) on its argument, which gives custom types the freedom to implement their own increment semantics.

Note that this does not necessarily return its argument; e.g., for undefined values, it returns 0:

my $x;
say $x++;   # OUTPUT: «0␤»
say $x;     # OUTPUT: «1␤»

Increment on Str will increment the number part of a string and assign the resulting string to the container. A is rw-container is required.

my $filename = "somefile-001.txt";
say $filename++ for 1..3;
# OUTPUT: «somefile-001.txt␤somefile-002.txt␤somefile-003.txt␤»

postfix --

multi sub postfix:<-->($x is rw) is assoc<non>

Decrements its argument by one and returns the original value.

my $x = 3;
say $x--;   # OUTPUT: «3␤»
say $x;     # OUTPUT: «2␤»

It works by calling the pred method (for predecessor) on its argument, which gives custom types the freedom to implement their own decrement semantics.

Note that this does not necessarily return its argument;e.g., for undefined values, it returns 0:

my $x;
say $x--;   # OUTPUT: «0␤»
say $x;     # OUTPUT: «-1␤»

Decrement on Str will decrement the number part of a string and assign the resulting string to the container. A is rw-container is required. Crossing 0 is prohibited and throws X::AdHoc.

my $filename = "somefile-003.txt";
say $filename-- for 1..3;
# OUTPUT: «somefile-003.txt␤somefile-002.txt␤somefile-001.txt␤»

Exponentiation precedence

infix **

multi sub infix:<**>(Any, Any --> Numeric:D) is assoc<right>

The exponentiation operator coerces both arguments to Numeric and calculates the left-hand-side raised to the power of the right-hand side.

If the right-hand side is a non-negative integer and the left-hand side is an arbitrary precision type (Int, FatRat), then the calculation is carried out without loss of precision.

Unicode superscripts will behave in exactly the same way.

sub squared( Int $num ) { $num² };
say squared($_) for ^5; OUTPUT: «0␤1␤4␤9␤16␤»

It also works for sequences of several Unicode superscript numbers:

sub twenty-second-power( Int $num ) { $num²² };
say twenty-second-power($_) for ^5; # OUTPUT: «0␤1␤4194304␤31381059609␤17592186044416␤»

Symbolic unary precedence

prefix ?

multi sub prefix:<?>(Mu --> Bool:D)

Boolean context operator.

Coerces the argument to Bool by calling the Bool method on it. Note that this collapses Junctions.

prefix !

multi sub prefix:<!>(Mu --> Bool:D)

Negated boolean context operator.

Coerces the argument to Bool by calling the Bool method on it, and returns the negation of the result. Note that this collapses Junctions.

prefix +

multi sub prefix:<+>(Any --> Numeric:D)

Numeric context operator.

Coerces the argument to Numeric by calling the Numeric method on it.

prefix -

multi sub prefix:<->(Any --> Numeric:D)

Negative numeric context operator.

Coerces the argument to Numeric by calling the Numeric method on it, and then negates the result.

prefix ~

multi sub prefix:<~>(Any --> Str:D)

String context operator.

Coerces the argument to Str by calling the Str method on it.

prefix |

Flattens objects of type Capture, Pair, List, Map and Hash into an argument list.

sub slurpee( |args ){
    say args.perl
};
slurpee( <a b c d>, { e => 3 }, 'e' => 'f' => 33 )
# OUTPUT: «\(("a", "b", "c", "d"), {:e(3)}, :e(:f(33)))␤»

Please see the Signature page, specially the section on Captures for more information on the subject.

Outside of argument lists, it returns a Slip, which makes it flatten into the outer list. Inside argument list Positional s are turned into positional arguments and Associative s are turned into named arguments.

prefix +^

multi sub prefix:<+^>(Any --> Int:D)

Integer bitwise negation operator: Coerces the argument to Int and does a bitwise negation on the result, assuming two's complement.

prefix ~^

Coerces the argument to a non-variable-encoding string buffer type (e.g. buf8, buf16, buf32) and then flips each bit in that buffer.

Please note that this has not yet been implemented.

prefix ?^

multi sub prefix:<?^>(Mu --> Bool:D)

Boolean bitwise negation operator: Coerces the argument to Bool and then does a bit flip, which makes it the same as prefix:<!> .

prefix ^

multi sub prefix:<^>(Any --> Range:D)

upto operator.

Coerces the argument to Numeric, and generates a range from 0 up to (but excluding) the argument.

say ^5;         # OUTPUT: «0..^5␤»
for ^5 { }      # 5 iterations

Dotty infix precedence

These operators are like their Method Postfix counterparts, but require surrounding whitespace (before and/or after) to distinguish them.

infix .=

Calls the right-side method on the value in the left-side container, replacing the resulting value in the left-side container.

In most cases, this behaves identically to the postfix mutator, but the precedence is lower:

my $a = -5; 
 say ++$a.=abs; 
 # OUTPUT: «6␤» 
say ++$a .= abs; 
 # OUTPUT: «Cannot modify an immutable Int␤ 
 #           in block <unit> at <tmp> line 1␤␤» 

infix .

Calls the following method (whose name must be alphabetic) on the left-side invocant.

Note that the infix form of the operator has a slightly lower precedence than postfix .meth.

say -5.abs;      # like: -(5.abs)
# OUTPUT: «-5␤»
say -5 . abs;    # like: (-5) . abs
# OUTPUT: «5␤»
say -5 .abs;     # following whitespace is optional
# OUTPUT: «5␤»

Multiplicative precedence

infix *

multi sub infix:<*>(Any, Any --> Numeric:D)

Multiplication operator.

Coerces both arguments to Numeric and multiplies them. The result is of the wider type. See Numeric for details.

infix /

multi sub infix:</>(Any, Any --> Numeric:D)

Division operator.

Coerces both argument to Numeric and divides the left through the right number. Division of Int values returns Rat, otherwise the "wider type" rule described in Numeric holds.

infix div

multi sub infix:<div>(Int:D, Int:D --> Int:D)

Integer division operator. Rounds down.

infix %

multi sub infix:<%>($x, $y --> Numeric:D)

Modulo operator. Coerces to Numeric first.

Generally the following identity holds:

my ($x, $y) = 1,2;
$x % $y == $x - floor($x / $y) * $y

infix %%

multi sub infix:<%%>($a, $b --> Bool:D)

Divisibility operator. Returns True if $a % $b == 0.

infix mod

multi sub infix:<mod>(Int:D $a, Int:D $b --> Int:D)

Integer modulo operator. Returns the remainder of an integer modulo operation.

infix +&

multi sub infix:<+&>($a, $b --> Int:D)

Numeric bitwise AND operator. Coerces both arguments to Int and does a bitwise AND operation assuming two's complement.

infix +<

multi sub infix:<< +< >>($a, $b --> Int:D)

Integer bit shift to the left.

infix +>

multi sub infix:<< +> >>($a, $b --> Int:D)

Integer bit shift to the right.

infix ~&

Coerces each argument to a non-variable-encoding string buffer type (e.g. buf8, buf16, buf32) and then performs a numeric bitwise AND on corresponding integers of the two buffers, padding the shorter buffer with zeroes.

infix ~<

Coerces the left argument to a non-variable-encoding string buffer type (e.g. buf8, buf16, buf32) and then performs a numeric bitwise left shift on the bits of the buffer.

Please note that this has not yet been implemented.

infix ~>

Coerces the left argument to a non-variable-encoding string buffer type (e.g. buf8, buf16, buf32) and then performs a numeric bitwise right shift on the bits of the buffer.

Please note that this has not yet been implemented.

infix gcd

multi sub infix:<gcd>($a, $b --> Int:D)

Coerces both arguments to Int and returns the greatest common divisor. If one of its arguments is 0, the other is returned (when both arguments are 0, the operator returns 0).

infix lcm

multi sub infix:<lcm>($a, $b --> Int:D)

Coerces both arguments to Int and returns the least common multiple; that is, the smallest integer that is evenly divisible by both arguments.

Additive precedence

infix +

multi sub infix:<+>($a, $b --> Numeric:D)

Addition operator.

Coerces both arguments to Numeric and adds them.

infix -

multi sub infix:<->($a, $b --> Numeric:D)

Subtraction operator.

Coerces both arguments to Numeric and subtracts the second from the first.

infix +|

multi sub infix:<+|>($a, $b --> Int:D)

Integer bitwise OR operator: Coerces both arguments to Int and does a bitwise OR (inclusive OR) operation.

infix +^

multi sub infix:<+^>($a, $b --> Int:D)

Integer bitwise XOR operator: Coerces both arguments to Int and does a bitwise XOR (exclusive OR) operation.

infix ~|

Coerces each argument to a non-variable-encoding string buffer type (e.g. buf8, buf16, buf32) and then performs a numeric bitwise OR on corresponding integers of the two buffers, padding the shorter buffer with zeroes.

infix ~^

Coerces each argument to a non-variable-encoding string buffer type (e.g. buf8, buf16, buf32) and then performs a numeric bitwise XOR on corresponding integers of the two buffers, padding the shorter buffer with zeroes.

infix ?^

multi sub infix:<?^>(Mu $x = Bool::False)
multi sub infix:<?^>(Mu \a, Mu \b)

Boolean bitwise XOR operator: Coerces the argument(s) to Bool and performs logical XOR on them: it will return True if and only if just one of the argument is true. It returns identity on a single argument.

infix ?|

multi sub infix:<?|>($a, $b --> Bool:D)

Boolean logical OR operator.

Coerces both arguments to Bool and does a logical OR (inclusive OR) operation.

Replication precedence

infix x

sub infix:<x>($a, $b --> Str:D)

String repetition operator.

Repeats the string $a $b times, if necessary coercing $a to Str and $b Int. Returns an empty string if $b <= 0 . An exception X::Numeric::CannotConvert will be thrown if $b is -Inf or NaN.

say 'ab' x 3;           # OUTPUT: «ababab␤»
say 42 x 3;             # OUTPUT: «424242␤»

my $a = 'a'.IO;
my $b = 3.5;
say $a x $b;            # OUTPUT: «aaa␤»

List repetition operator

infix xx

Defined as:

multi sub infix:<xx>()
multi sub infix:<xx>(Mu \x)
multi sub infix:<xx>(&x, Num:D() $n)
multi sub infix:<xx>(&x, Whatever)
multi sub infix:<xx>(&x, Bool:D $b)
multi sub infix:<xx>(&x, Int:D $n)
multi sub infix:<xx>(Mu \x, Num:D() $n)
multi sub infix:<xx>(Mu \x, Whatever)
multi sub infix:<xx>(Mu \x, Bool:D $b)
multi sub infix:<xx>(Mu \x, Int:D $n)

In general, it returns a Sequence of $a repeated and evaluated $b times ($b is coerced to Int). If $b <= 0 , the empty list is returned. It will return an error with no operand, and return the operand itself with a single operand. An exception X::Numeric::CannotConvert will be thrown if $b is -Inf or NaN.

The left-hand side is evaluated for each repetition, so

say [1, 2] xx 5;
# OUTPUT: «([1 2] [1 2] [1 2] [1 2] [1 2])␤»

returns five distinct arrays (but with the same content each time), and

rand xx 3

returns three pseudo random numbers that are determined independently.

The right-hand side can be *, in which case a lazy, infinite list is returned. If it's a Bool, a Seq with a single element is returned if it's True.

Concatenation

Same as the rest of the infix operators, these can be combined with metaoperators such as assignment, for instance.

infix ~

multi sub infix:<~>(Any,   Any)
multi sub infix:<~>(Str:D, Str:D)
multi sub infix:<~>(Buf:D, Buf:D)

This is the string concatenation operator, which coerces both arguments to Str and concatenates them. If both arguments are Buf, a combined buffer is returned.

say 'ab' ~ 'c';     # OUTPUT: «abc␤»

infix

multi sub infix:<∘>()
multi sub infix:<∘>(&f)
multi sub infix:<∘>(&f, &g --> Block:D)

The function composition operator infix:<∘> or infix:<o> combines two functions, so that the left function is called with the return value of the right function. If the .count of the left function is greater than 1, the return value of the right function will be slipped into the left function.

Both .count and .arity of the right-hand side will be maintained.

sub f($p){ say 'f'; $p / 2 }
sub g($p){ say 'g'; $p * 2 }

my &composed = &f ∘ &g;
say composed 2; # OUTPUT: «g␤f␤2␤»
# equivalent to:
say 2.&g.&f;
# or to:
say f g 2;
sub f($a, $b, $c) { [~] $c, $b, $a } 
 sub g($str){ $str.comb } 
 my &composed = &f ∘ &g; 
 say composed 'abc'; # OUTPUT: «cba␤» 
 # equivalent to: 
 say f |g 'abc'; 

The single-arg candidate returns the given argument as is. The zero-arg candidate returns an identity routine that simply returns its argument.

my &composed = [∘] &uc;
say composed 'foo'; # OUTPUT: «FOO␤»

my &composed = [∘];
say composed 'foo'; # OUTPUT: «foo␤»

Junctive AND (all) precedence

infix &

multi sub infix:<&>($a, $b --> Junction:D) is assoc<list>

All junction operator.

Creates an all Junction from its arguments. See Junction for more details.

infix (&), infix

multi sub infix:<(&)>(**@p)
multi sub infix:<∩>(**@p)

Intersection operator.

Returns the intersection of all of its arguments. This creates a new Set that contains only the elements common to all of the arguments if none of the arguments are a Bag, BagHash, Mix or MixHash.

say <a b c> (&) <b c d>; # OUTPUT: «set(b c)␤» 
 <a b c d> ∩ <b c d e> ∩ <c d e f>; # OUTPUT: «set(c d)␤» 

If any of the arguments are Baggy or Mixy>, the result is a new Bag (or Mix) containing the common elements, each weighted by the largest common weight (which is the minimum of the weights of that element over all arguments).

say <a a b c a> (&) bag(<a a b c c>); # OUTPUT: «Bag(a(2), b, c)␤» 

is equivalent to (&), at codepoint U+2229 (INTERSECTION).

infix (.), infix

multi sub infix:<(.)>(**@p)
multi sub infix:<⊍>(**@p)

Baggy multiplication operator.

Returns the Baggy multiplication of its arguments, i.e., a Bag that contains each element of the arguments with the weights of the element across the arguments multiplied together to get the new weight. Returns a Mix if any of the arguments is a Mixy.

say <a b c> (.) <a b c d>; # OUTPUT: «Bag(a, b, c)␤» 
                            # Since 1 * 0 == 0, in the case of 'd' 
 say <a a b c a d> ⊍ bag(<a a b c c>); # OUTPUT: «Bag(a(6), b, c(2))␤» 

is equivalent to (.), at codepoint U+228D (MULTISET MULTIPLICATION).

Junctive OR (any) precedence

infix |

multi sub infix:<|>($a, $b --> Junction:D) is assoc<list>

Creates an any Junction from its arguments.

my $three-letters = /<[a b c]>/ | /<[i j k]>/ | /<[x y z]>/;
say $three-letters.perl; # OUTPUT: «any(/<[a b c]>/, /<[i j k]>/, /<[x y z]>/)␤»
say 'b' ~~ $three-letters; # OUTPUT: «True␤»

This first creates an any Junction of three regular expressions (every one of them matching any of 3 letters), and then uses smartmatching to check whether the letter b matches any of them, resulting in a positive match. See also Junction for more details.

infix (|), infix

multi sub infix:<(|)>(**@p)
multi sub infix:<∪>(**@p)

Union operator.

Returns the union of all of its arguments. This creates a new Set that contains all the elements its arguments contain if none of the arguments are a Bag, BagHash, Mix or MixHash.

say <a b d> ∪ bag(<a a b c>); # OUTPUT: «Bag(a(2), b, c, d)␤» 

If any of the arguments are Baggy or Mixy>, the result is a new Bag (or Mix) containing all the elements, each weighted by the highest weight that appeared for that element.

say <a b d> ∪ bag(<a a b c>); # OUTPUT: «Bag(a(2), b, c, d)␤» 

is equivalent to (|), at codepoint U+222A (UNION).

infix (+), infix

multi sub infix:<(+)>(**@p)
multi sub infix:<⊎>(**@p)

Baggy addition operator.

Returns the Baggy addition of its arguments. This creates a new Bag from each element of the arguments with the weights of the element added together to get the new weight, if none of the arguments are a Mix or MixHash.

say <a a b c a d> (+) <a a b c c>; # OUTPUT: «Bag(a(5), b(2), c(3), d)␤» 

If any of the arguments is a Mixy, the result is a new Mix.

say <a b c> (+) (a => 2.5, b => 3.14).Mix; # OUTPUT: «Mix(a(3.5), b(4.14), c)␤» 

is equivalent to (+), at codepoint U+228E (MULTISET UNION).

infix (-), infix

multi sub infix:<(-)>(**@p)
multi sub infix:<∖>(**@p)

Set difference operator.

Returns the set difference of all its arguments. This creates a new Set that contains all the elements the first argument has but the rest of the arguments don't, i.e., of all the elements of the first argument, minus the elements from the other arguments. But only if none of the arguments are a Bag, BagHash, Mix or MixHash.

say <a a b c a d> (-) <a a b c c>; # OUTPUT: «set(d)␤» 
 say <a b c d e> (-) <a b c> (-) <a b d>; # OUTPUT: «set(e)␤» 

If any of the arguments are Baggy or Mixy>, the result is a new Bag (or Mix) containing all the elements remaining after the first argument with its weight subtracted by the weight of that element in each of the other arguments.

say <a a b c a d> (-) bag(<a b c c>); # OUTPUT: «Bag(a(2), d)␤» 
 say <a a b c a d>  ∖  mix(<a b c c>); # OUTPUT: «Mix(a(2), c(-1), d)␤» 

is equivalent to (-), at codepoint U+2216 (SET MINUS).

infix ^

multi sub infix:<^>($a, $b --> Junction:D) is assoc<list>

One junction operator.

Creates a one Junction from its arguments. See Junction for more details.

infix (^), infix

multi sub infix:<(^)>($a, $b)
multi sub infix:<⊖>($a,$b)

multi sub infix:<(^)>(**@p)
multi sub infix:<⊖>(**@p)

Symmetric set difference operator.

Returns the symmetric set difference of all its arguments. This creates a new Set made up of all the elements that $a has but $b doesn't and all the elements $b has but $a doesn't if none of the arguments are a Bag, BagHash, Mix or MixHash. Equivalent to ($a ∖ $b) ∪ ($b ∖ $a).

say <a b> (^) <b c>; # OUTPUT: «set(a c)␤» 

If any of the arguments are Baggy or Mixy>, the result is a new Bag (or Mix).

say <a b> ⊖ bag(<b c>); # OUTPUT: «Bag(a, c)␤» 

is equivalent to (^), at codepoint U+2296 (CIRCLED MINUS).

Named unary precedence

prefix temp

sub prefix:<temp>(Mu $a is rw)

"temporizes" the variable passed as the argument. The variable begins with the same value as it had in the outer scope, but can be assigned new values in this scope. Upon exiting the scope, the variable will be restored to its original value.

my $a = "three";
say $a; # OUTPUT: «three␤»
{
    temp $a;
    say $a; # OUTPUT: «three␤»
    $a = "four";
    say $a; # OUTPUT: «four␤»
}
say $a; # OUTPUT: «three␤»

You can also assign immediately as part of the call to temp:

temp $a = "five"; 

Be warned the temp effects get removed once the block is left. If you were to access the value from, say, within a Promise after the temp was undone, you'd get the original value, not the temp one:

my $v = "original"; 
 { 
     temp $v = "new one"; 
     start { 
         say "[PROMISE] Value before block is left: `$v`"; 
         sleep 1; 
         say "[PROMISE] Block was left while we slept; value is now `$v`"; 
     } 
     sleep ½; 
     say "About to leave the block; value is `$v`"; 
 } 
 say "Left the block; value is now `$v`"; 
 sleep 2; 
 
 # OUTPUT: 
 # [PROMISE] Value before block is left: `new one` 
 # About to leave the block; value is `new one` 
 # Left the block; value is now `original` 
 # [PROMISE] Block was left while we slept; value is now `original` 

prefix let

sub prefix:<let>(Mu $a is rw)

Refers to a variable in an outer scope whose value will be restored if the block exits unsuccessfully, implying that the block returned a defined object.

my $name = "Jane Doe"; 
 
 { 
     let $name = prompt("Say your name "); 
     die if !$name; 
     CATCH { 
         default { say "No name entered" } 
     } 
     say "We have $name"; 
 } 
 
 say "We got $name"; 

This code provides a default name for $name. If the user exits from the prompt or simply does not provide a valid input for $name; let will restore the default value provided at the top. If user input is valid, it will keep that.

this is duplicated in variables.pod

Nonchaining binary precedence

infix does

sub infix:<does>(Mu $obj, Mu $role) is assoc<non>

Mixes $role into $obj at runtime. Requires $obj to be mutable.

Similar to but operator, the $role can instead be an instantiated object, in which case, the operator will create a role for you automatically. The role will contain a single method named the same as $obj.^name and that returns $obj:

my $o = class { method Str { "original" } }.new;
put $o;            # OUTPUT: «original␤»
$o does "modded";
put $o;            # OUTPUT: «modded␤»

If methods of the same name are present already, the last mixed in role takes precedence.

infix but

multi sub infix:<but>(Mu $obj1, Mu   $role) is assoc<non>
multi sub infix:<but>(Mu $obj1, Mu:D $obj2) is assoc<non>

Creates a copy of $obj with $role mixed in. Since $obj is not modified, but can be used to created immutable values with mixins.

Instead of a role, you can provide an instantiated object. In this case, the operator will create a role for you automatically. The role will contain a single method named the same as $obj.^name and that returns $obj:

my $forty-two = 42 but 'forty two'; 
 say $forty-two+33;    # OUTPUT: «75␤» 
 say $forty-two.^name; # OUTPUT: «Int+{<anon|1>}␤» 
 say $forty-two.Str;   # OUTPUT: «forty two␤» 

Calling ^name shows that the variable is an Int with an anonymous object mixed in. However, that object is of type Str, so the variable, through the mixin, is endowed with a method with that name, which is what we use in the last sentence.

We can also mixin classes, even created on the fly.

my $s = 12 but class Warbles { method hi { 'hello' } }.new; 
 say $s.Warbles.hi;    # OUTPUT: «hello␤» 
 say $s + 42;          # OUTPUT: «54␤» 

To access the mixed-in class, as above, we use the class name as is shown in the second sentence. If methods of the same name are present already, the last mixed in role takes precedence. A list of methods can be provided in parentheses separated by comma. In this case conflicts will be reported at runtime.

infix cmp

multi sub infix:<cmp>(Any,       Any)
multi sub infix:<cmp>(Real:D,    Real:D)
multi sub infix:<cmp>(Str:D,     Str:D)
multi sub infix:<cmp>(Version:D, Version:D)

Generic, "smart" three-way comparator.

Compares strings with string semantics, numbers with number semantics, Pair objects first by key and then by value etc.

if $a eqv $b, then $a cmp $b always returns Order::Same.

say (a => 3) cmp (a => 4);   # OUTPUT: «Less␤»
say 4        cmp 4.0;        # OUTPUT: «Same␤»
say 'b'      cmp 'a';        # OUTPUT: «More␤»

infix coll

Defined as:

multi sub infix:<coll>(Str:D \a, Str:D \b --> Order:D)
multi sub infix:<coll>(Cool:D \a, Cool:D \b --> Order:D)
multi sub infix:<coll>(Pair:D \a, Pair:D \b --> Order:D)

coll is a sorting operator that takes pairs of Strs, Cools or Pairs and returns an Order that uses the $*COLLATION order. The default behavior disregards diacritic marks and capitalization, for instance.

say "b" cmp "à";  # OUTPUT: «Less␤»
say "b" coll "à"; # OUTPUT: «More␤»

In the first case, lexicographic or codepoint order is taken into account. In the second, which uses coll, the diacritic is not considered and sorting happens according to intuitive order.

NOTE: These are not yet implemented in the JVM.

infix unicmp

Defined as:

multi sub infix:<unicmp>(Str:D \a, Str:D \b --> Order:D)
multi sub infix:<unicmp>(Pair:D \a, Pair:D \b --> Order:D)
multi sub infix:<coll>(Pair:D \a, Pair:D \b --> Order:D)

Unlike the cmp operator which sorts according to codepoint, unicmp and coll sort according to how most users would expect, that is, disregarding aspects of the particular character like capitalization.

say 'a' unicmp 'Z'; # Less
say 'a' coll 'Z';   # Less
say 'a' cmp 'Z';    # More

The main difference between coll and unicmp is that the behavior of the former can be changed by the $*COLLATION dynamic variable.

NOTE: These are not yet implemented in the JVM.

infix leg

multi sub infix:<leg>(Any,   Any)
multi sub infix:<leg>(Str:D, Str:D)

String three-way comparator. Short for less, equal or greater?.

Coerces both arguments to Str and then does a lexicographic comparison.

say 'a' leg 'b';       # OUTPUT: «Less␤»
say 'a' leg 'a';       # OUTPUT: «Same␤»
say 'b' leg 'a';       # OUTPUT: «More␤»

infix <=>

multi sub infix:«<=>»($a, $b --> Order:D) is assoc<non>

Numeric three-way comparator.

Coerces both arguments to Real and then does a numeric comparison.

infix ..

multi sub infix:<..>($a, $b --> Range:D) is assoc<non>

Range operator

Constructs a Range from the arguments.

infix ..^

multi sub infix:<..^>($a, $b --> Range:D) is assoc<non>

Right-open range operator.

Constructs a Range from the arguments, excluding the end point.

infix ^..

multi sub infix:<^..>($a, $b --> Range:D) is assoc<non>

Left-open range operator.

Constructs a Range from the arguments, excluding the start point.

infix ^..^

multi sub infix:<^..^>($a, $b --> Range:D) is assoc<non>

Open range operator

Constructs a Range from the arguments, excluding both start and end point.

Chaining binary precedence

infix ==

multi sub infix:<==>(Any, Any)
multi sub infix:<==>(Int:D, Int:D)
multi sub infix:<==>(Num:D, Num:D)
multi sub infix:<==>(Rational:D, Rational:D)
multi sub infix:<==>(Real:D, Real:D)
multi sub infix:<==>(Complex:D, Complex:D)
multi sub infix:<==>(Numeric:D, Numeric:D)

Numeric equality operator.

Coerces both arguments to Numeric (if necessary); returns True if they are equal.

infix !=

sub infix:<!=>(Mu, Mu --> Bool:D)

Numeric inequality operator.

Coerces both arguments to Numeric (if necessary); returns True if they are distinct.

Is an alias to !==.

infix

Numeric inequality operator.

Equivalent to !=, at codepoint U+2260 (NOT EQUAL TO).

infix <

multi sub infix:«<»(Int:D, Int:D)
multi sub infix:«<»(Num:D, Num:D)
multi sub infix:«<»(Real:D, Real:D)

Numeric less than operator.

Coerces both arguments to Real (if necessary); returns True if the first argument is smaller than the second.

infix <=

multi sub infix:«<=»(Int:D, Int:D)
multi sub infix:«<=»(Num:D, Num:D)
multi sub infix:«<=»(Real:D, Real:D)

Numeric less than or equal to operator.

Coerces both arguments to Real (if necessary); returns True if the first argument is smaller than or equal to the second.

infix

Numeric less than or equal to operator.

Equivalent to <=, at codepoint U+2264 (LESS-THAN OR EQUAL TO).

infix >

multi sub infix:«>»(Int:D, Int:D)
multi sub infix:«>»(Num:D, Num:D)
multi sub infix:«>»(Real:D, Real:D)

Numeric greater than operator.

Coerces both arguments to Real (if necessary); returns True if the first argument is larger than the second.

infix >=

multi sub infix:«>=»(Int:D, Int:D)
multi sub infix:«>=»(Num:D, Num:D)
multi sub infix:«>=»(Real:D, Real:D)

Numeric greater than or equal to operator.

Coerces both arguments to Real (if necessary); returns True if the first argument is larger than or equal to the second.

infix

Numeric greater than or equal to operator.

Equivalent to >=, at codepoint U+2265 (GREATER-THAN OR EQUAL TO).

infix eq

multi sub infix:<eq>(Any,   Any)
multi sub infix:<eq>(Str:D, Str:D)

String equality operator.

Coerces both arguments to Str (if necessary); returns True if both are equal.

Mnemonic: equal

infix ne

multi sub infix:<ne>(Mu,    Mu)
multi sub infix:<ne>(Str:D, Str:D)

String inequality operator.

Coerces both arguments to Str (if necessary); returns False if both are equal.

Mnemonic: not equal

infix gt

multi sub infix:<gt>(Mu,    Mu)
multi sub infix:<gt>(Str:D, Str:D)

String greater than operator.

Coerces both arguments to Str (if necessary); returns True if the first is larger than the second, as determined by lexicographic comparison.

Mnemonic: greater than

infix ge

multi sub infix:<ge>(Mu,    Mu)
multi sub infix:<ge>(Str:D, Str:D)

String greater than or equal to operator.

Coerces both arguments to Str (if necessary); returns True if the first is equal to or larger than the second, as determined by lexicographic comparison.

Mnemonic: greater or equal

infix lt

multi sub infix:<lt>(Mu,    Mu)
multi sub infix:<lt>(Str:D, Str:D)

String less than operator.

Coerces both arguments to Str (if necessary); returns True if the first is smaller than the second, as determined by lexicographic comparison.

Mnemonic: less than

infix le

multi sub infix:<le>(Mu,    Mu)
multi sub infix:<le>(Str:D, Str:D)

String less than or equal to operator.

Coerces both arguments to Str (if necessary); returns True if the first is equal to or smaller than the second, as determined by lexicographic comparison.

Mnemonic: less or equal

infix before

multi sub infix:<before>(Any,       Any)
multi sub infix:<before>(Real:D,    Real:D)
multi sub infix:<before>(Str:D,     Str:D)
multi sub infix:<before>(Version:D, Version:D)

Generic ordering, uses the same semantics as cmp. Returns True if the first argument is smaller than the second.

infix after

multi sub infix:<after>(Any,       Any)
multi sub infix:<after>(Real:D,    Real:D)
multi sub infix:<after>(Str:D,     Str:D)
multi sub infix:<after>(Version:D, Version:D)

Generic ordering, uses the same semantics as cmp. Returns True if the first argument is larger than the second.

infix eqv

sub infix:<eqv>(Any, Any)

Equivalence operator. Returns True if the two arguments are structurally the same, i.e. from the same type and (recursively) contain equivalent values.

say [1, 2, 3] eqv [1, 2, 3];    # OUTPUT: «True␤»
say Any eqv Any;                # OUTPUT: «True␤»
say 1 eqv 2;                    # OUTPUT: «False␤»
say 1 eqv 1.0;                  # OUTPUT: «False␤»

Lazy Iterables cannot be compared, as they're assumed to be infinite. However, the operator will do its best and return False if the two lazy Iterables are of different types or if only one Iterable is lazy.

say (1…∞) eqv (1…∞).List; # Both lazy, but different types;   OUTPUT: «False␤»
say (1…∞) eqv (1…3);      # Same types, but only one is lazy; OUTPUT: «False␤»
(try say (1…∞) eqv (1…∞)) # Both lazy and of the same type. Cannot compare; throws.
    orelse say $!.^name;  # OUTPUT: «X::Cannot::Lazy␤»

The default eqv operator even works with arbitrary objects. E.g., eqv will consider two instances of the same object as being structurally equivalent:

my class A {
    has $.a;
}
say A.new(a => 5) eqv A.new(a => 5);  # OUTPUT: «True␤»

Although the above example works as intended, the eqv code might fall back to a slower code path in order to do its job. One way to avoid this is to implement an appropriate infix eqv operator:

my class A {
    has $.a;
}
multi infix:<eqv>(A $l, A $r) { $l.a eqv $r.a }
say A.new(a => 5) eqv A.new(a => 5);            # OUTPUT: «True␤»

Note that eqv does not work recursively on every kind of container type, e.g. Set:

my class A {
    has $.a;
}
say Set(A.new(a => 5)) eqv Set(A.new(a => 5));  # OUTPUT: «False␤»

Even though the contents of the two sets are eqv, the sets are not. The reason is that eqv delegates the equality check to the Set object which relies on element-wise === comparison. Turning the class A into a value type by giving it a WHICH method produces the expected behavior:

my class A {
    has $.a;
    method WHICH {
        ValueObjAt.new: "A|$!a.WHICH()"
    }
}
say Set(A.new(a => 5)) eqv Set(A.new(a => 5));  # OUTPUT: «True␤»

infix ===

sub infix:<===>(Any, Any)

Value identity operator. Returns True if both arguments are the same object, disregarding any containerization.

my class A { };
my $a = A.new;
say $a === $a;              # OUTPUT: «True␤»
say A.new === A.new;        # OUTPUT: «False␤»
say A === A;                # OUTPUT: «True␤»

For value types, === behaves like eqv:

say 'a' === 'a';            # OUTPUT: «True␤»
say 'a' === 'b';            # OUTPUT: «False␤»

my $b = 'a';
say $b === 'a';             # OUTPUT: «True␤»

# different types
say 1 === 1.0;              # OUTPUT: «False␤»

=== uses the WHICH method to obtain the object identity.

If you want to create a class that should act as a value type, then that class must create an instance method WHICH, that should return a ValueObjAt object that won't change for the lifetime of the object.

infix =:=

multi sub infix:<=:=>(Mu \a, Mu \b)

Container identity operator. Returns True if both arguments are bound to the same container. If it returns True, it generally means that modifying one will also modify the other.

my ($a, $b) = (1, 3);
say $a =:= $b;      # OUTPUT: «False␤»
$b = 2;
say $a;             # OUTPUT: «1␤»
$b := $a;
say $a =:= $b;      # OUTPUT: «True␤»
$a = 5;
say $b;             # OUTPUT: «5␤»

infix ~~

The smartmatch operator aliases the left-hand side to $_, then evaluates the right-hand side and calls .ACCEPTS($_) on it. The semantics are left to the type of the right-hand side operand.

Here is a partial list of some of the built-in smartmatching functionality. For full details, see ACCEPTS documentation for the type on the right-hand side of the operator.

Right-hand side Comparison semantics
Mu:U type check
Str string equality
Numeric numeric equality
Regex regex match
Callable boolean result of invocation
Set/Bag equal element values
Any:D object identity

infix =~=

multi sub infix:<=~=>(Any, Any)
multi sub infix:<=~=>(Int:D, Int:D)
multi sub infix:<=~=>(Num:D, Num:D)
multi sub infix:<=~=>(Rational:D, Rational:D)
multi sub infix:<=~=>(Real:D, Real:D)
multi sub infix:<=~=>(Complex:D, Complex:D)
multi sub infix:<=~=>(Numeric:D, Numeric:D)

The approximately-equal operator , whose ASCII variant is =~=, calculates the relative difference between the left-hand and right-hand sides and returns True if the difference is less than $*TOLERANCE (which defaults to 1e-15). However, if either side is zero then it checks that the absolute difference between the sides is less than $*TOLERANCE. Note that this operator is not arithmetically symmetrical (doesn't do ± Δ):

my $x = 1;
say ($x + $*TOLERANCE) =~= $x;   # OUTPUT: «False␤»
say ($x - $*TOLERANCE) =~= $x;   # OUTPUT: «True␤»

The tolerance is supposed to be modifiable via an adverb:

my ($x, $y) = 42, 42.1; 
 say $x =~= $y :tolerance(.1); 

However, this is not yet implemented. The same effect can be achieved by assigning to $*TOLERANCE.

{
    my $*TOLERANCE = .1;
    say 11 =~= 10;        # OUTPUT: «True␤»
}

Note that setting $*TOLERANCE = 0 will cause all comparisons to fail.

{
    my $*TOLERANCE = 0;
    say 1 =~= 1;          # OUTPUT: «False␤»
}

infix (elem), infix ∈»

multi sub infix:<(elem)>($a,$b --> Bool:D)
multi sub infix:<∈>($a,$b --> Bool:D)

Membership operator.

Returns True if $a is an element of $b.

say 2 (elem) (1, 2, 3); # OUTPUT: «True␤» 
 say 4 ∈ (1, 2, 3); # OUTPUT: «False␤» 

is equivalent to (elem), at codepoint U+2208 (ELEMENT OF).

infix

multi sub infix:<∉>($a,$b --> Bool:D)

Non-membership operator.

Returns True if $a is not an element of $b. Equivalent to !(elem).

say 4 ∉ (1, 2, 3); # OUTPUT: «True␤» 
 say 2 !(elem) (1, 2, 3); # OUTPUT: «False␤» 

is codepoint U+2209 (NOT AN ELEMENT OF).

infix (cont), infix ∋»

multi sub infix:<(cont)>($a,$b --> Bool:D)
multi sub infix:<∋>($a,$b --> Bool:D)

Membership operator.

Returns True if $a is an element of $b.

say (1,2,3) (cont) 2; # OUTPUT: «True␤» 
 say (1, 2, 3) ∋ 4; # OUTPUT: «False␤» 

is equivalent to (cont), at codepoint U+220B (CONTAINS AS MEMBER).

infix

multi sub infix:<∌>($a,$b --> Bool:D)

Non-membership operator.

Returns True if $a is not an element of $b. Equivalent to !(cont).

say (1,2,3) ∌ 4; # OUTPUT: «True␤» 
 say (1,2,3) !(cont) 2; # OUTPUT: «False␤» 

is codepoint U+220C (DOES NOT CONTAIN AS MEMBER).

infix (<), infix

multi sub infix:<< (<) >>($a,$b --> Bool:D)
multi sub infix:<⊂>($a,$b --> Bool:D)

Subset of operator.

Returns True if $a is a strict subset of $b, i.e., that all the elements of $a are elements of $b but $a is a smaller set than $b.

say (1,2,3) (<) (2,3,1); # OUTPUT: «False␤» 
 say (2,3) (<) (2,3,1); # OUTPUT: «True␤» 
 say 4 ⊂ (1,2,3); # OUTPUT: «False␤» 

is equivalent to (<), at codepoint U+2282 (SUBSET OF).

infix

multi sub infix:<⊄>($a,$b --> Bool:D)

Not a subset of operator.

Returns True if $a is not a strict subset of $b. Equivalent to !(<).

say (1,2,3) ⊄ (2,3,1); # OUTPUT: «True␤» 
 say (2,3) ⊄ (2,3,1); # OUTPUT: «False␤» 
 say 4 !(<) (1,2,3); # OUTPUT: «True␤» 

is codepoint U+2284 (NOT A SUBSET OF).

infix (<=), infix

multi sub infix:<< (<=) >>($a,$b --> Bool:D)
multi sub infix:<⊆>($a,$b --> Bool:D)

Subset of or equal to operator.

Returns True if $a is a subset of $b, i.e., that all the elements of $a are elements of $b but $a is a smaller or equal sized set than $b.

say (1,2,3) (<=) (2,3,1); # OUTPUT: «True␤» 
 say (2,3) (<=) (2,3,1); # OUTPUT: «True␤» 
 say 4 ⊆ (1,2,3); # OUTPUT: «False␤» 

is equivalent to (<=), at codepoint U+2286 (SUBSET OF OR EQUAL TO).

infix

multi sub infix:<⊈>($a,$b --> Bool:D)

Not a subset of nor equal to operator.

Returns True if $a is not a subset of $b. Equivalent to !(<=).

say (1,2,3) ⊄ (2,3,1); # OUTPUT: «True␤» 
 say (2,3) ⊄ (2,3,1); # OUTPUT: «False␤» 
 say 4 !(<=) (1,2,3); # OUTPUT: «True␤» 

is codepoint U+2288 (NEITHER A SUBSET OF NOR EQUAL TO).

infix (>), infix

multi sub infix:<< (>) >>($a,$b --> Bool:D)
multi sub infix:<⊃>($a,$b --> Bool:D)

Superset of operator.

Returns True if $a is a strict superset of $b, i.e., that all the elements of $b are elements of $a but $a is a larger set than $b.

say (1,2,3) (>) (2,3,1); # OUTPUT: «False␤» 
 say (1,2,3) (>) (2,3); # OUTPUT: «True␤» 
 say 4 ⊃ (1,2,3); # OUTPUT: «False␤» 

is equivalent to (>), at codepoint U+2283 (SUPERSET OF).

infix

multi sub infix:<⊅>($a,$b --> Bool:D)

Not a superset of operator.

Returns True if $a is not a strict superset of $b. Equivalent to !(>).

say (1,2,3) ⊅ (2,3,1); # OUTPUT: «True␤» 
 say (1,2,3) ⊅ (2,3); # OUTPUT: «False␤» 
 say 4 !(>) (1,2,3); # OUTPUT: «True␤» 

is codepoint U+2285 (NOT A SUPERSET OF).

infix (>=), infix

multi sub infix:<< (>=) >>($a,$b --> Bool:D)
multi sub infix:<⊇>($a,$b --> Bool:D)

Superset of or equal to operator.

Returns True if $a is a superset of $b, i.e., that all the elements of $b are elements of $a but $a is a larger or equal sized set than $b.

say (1,2,3) (>=) (2,3,1); # OUTPUT: «True␤» 
 say (1,2,3) (>=) (2,3); # OUTPUT: «True␤» 
 say 4 ⊇ (1,2,3); # OUTPUT: «False␤» 

is equivalent to (>=), at codepoint U+2287 (SUPERSET OF OR EQUAL TO).

infix

multi sub infix:<⊉>($a,$b --> Bool:D)

Not a superset of nor equal to operator.

Returns True if $a is not a superset of $b. Equivalent to !(>=).

say (1,2,3) ⊉ (2,3,1); # OUTPUT: «False␤» 
 say (1,2,3) ⊉ (2,3); # OUTPUT: «False␤» 
 say 4 !(>=) (1,2,3); # OUTPUT: «True␤» 

is codepoint U+2289 (NEITHER A SUPERSET OF OR EQUAL TO).

Tight AND precedence

infix &&

Returns the first argument that evaluates to False in boolean context, otherwise returns the last argument.

Note that this short-circuits, i.e. if one of the arguments evaluates to a false value, the arguments to the right are never evaluated.

sub a { 1 }
sub b { 0 }
sub c { die "never called" };
say a() && b() && c();      # OUTPUT: «0␤»

Tight OR precedence

infix ||

Returns the first argument that evaluates to True in boolean context, otherwise returns the last argument.

Note that this short-circuits; i.e., if one of the arguments evaluates to a true value, the remaining arguments are not evaluated.

sub a { 0 }
sub b { 1 }
sub c { die "never called" };
say a() || b() || c();      # OUTPUT: «1␤»

infix ^^

Short-circuit exclusive-or. Returns the true argument if there is one (and only one). Returns the last argument if all arguments are false. Returns Nil when more than one argument is true.

This operator short-circuits in the sense that it does not evaluate any arguments after a 2nd true result.

say 0 ^^ 42;                             # OUTPUT: «42␤»
say '' ^^ 0;                             # OUTPUT: «0␤»
say 0 ^^ 42 ^^ 1 ^^ die "never called";  # OUTPUT: «Nil␤»

Note that the semantics of this operator may not be what you assume: infix ^^ flips to the first true value it finds and then flips to Nil forever after the second, no matter how many more true values there are. (In other words, it has "find the one true value" semantics, not "boolean parity" semantics.)

infix //

The defined-or operator or infix // returns the first defined operand, or else the last operand. Short-circuits.

say Any // 0 // 42;         # OUTPUT: «0␤»

infix min

Returns the smallest of the arguments, as determined by cmp semantics.

my $foo = 42;
$foo min= 0   # read as: $foo decreases to 0

infix max

Returns the largest of the arguments, as determined by cmp semantics.

my $foo = -42;
$foo max= 0   # read as: $foo increases to 0

infix minmax

Returns the Range starting from the lowest to the highest of the values, as determined by the cmp semantics. For instance:

# numeric comparison 
 10 minmax 3;     # 3..10 
 
 # string comparison 
 '10' minmax '3'; # "10".."3" 
 'z' minmax 'k';  # "k".."z" 

If the lowest and highest values coincide, the operator returns a Range made by the same value:

1 minmax 1;  # 1..1 

When applied to Lists, the operator evaluates the lowest and highest values among all available values:

(10,20,30) minmax (0,11,22,33);       # 0..33 
 ('a','b','z') minmax ('c','d','w');   # "a".."z" 

Similarly, when applied to Hashes, it performs a cmp way comparison:

my %winner = points => 30, misses => 10; 
 my %loser = points => 20, misses => 10; 
 %winner cmp %loser;      # More 
 %winner minmax %loser; 
 # ${:misses(10), :points(20)}..${:misses(10), :points(30)} 

Conditional operator precedence

infix ?? !!

Also called ternary or conditional operator, $condition ?? $true !! $false evaluates $condition and returns the expression right behind ??, in this case $true if it is True, otherwise evaluates and returns the expression behind !!, $false in this case.

infix ff

sub infix:<ff>(Mu $a, Mu $b)

Also called the flipflop operator, compares both arguments to $_ (that is, $_ ~~ $a and $_ ~~ $b). Evaluates to False until the left-hand smartmatch is True, at which point it evaluates to True until the right-hand smartmatch is True.

In effect, the left-hand argument is the "start" condition and the right-hand is the "stop" condition. This construct is typically used to pick up only a certain section of lines. For example:

my $excerpt = q:to/END/; 
 Here's some unimportant text. 
 =begin code 
     This code block is what we're after. 
     We'll use 'ff' to get it. 
 =end code 
 More unimportant text. 
 END 
 
 my @codelines = gather for $excerpt.lines { 
     take $_ if  "=begin code" ff "=end code" 
 } 
 # this will print four lines, starting with "=begin code" and ending with 
 # "=end code" 
 say @codelines.join("\n"); 

After matching the start condition, the operator will then match the same $_ to the stop condition and act accordingly if successful. In this example, only the first element is printed:

for <AB C D B E F> {
    say $_ if /A/ ff /B/;  # OUTPUT: «AB␤»
}

If you only want to test against a start condition and have no stop condition, * can be used as such.

for <A B C D E> {
    say $_ if /C/ ff *;    # OUTPUT: «C␤D␤E␤»
}

For the sed-like version, which does not try $_ on the stop condition after succeeding on the start condition, see fff.

This operator cannot be overloaded, as it's handled specially by the compiler.

infix ^ff

sub infix:<^ff>(Mu $a, Mu $b)

Works like ff, except it does not return True for items matching the start condition (including items also matching the stop condition).

A comparison:

my @list = <A B C>;
say $_ if /A/ ff /C/ for @list;    # OUTPUT: «A␤B␤C␤»
say $_ if /A/ ^ff /C/ for @list;   # OUTPUT: «B␤C␤»

The sed-like version can be found in ^fff.

This operator cannot be overloaded, as it's handled specially by the compiler.

infix ff^

sub infix:<ff^>(Mu $a, Mu $b)

Works like ff, except it does not return True for items matching the stop condition (including items that first matched the start condition).

my @list = <A B C>;
say $_ if /A/ ff /C/ for @list;    # OUTPUT: «A␤B␤C␤»
say $_ if /A/ ff^ /C/ for @list;   # OUTPUT: «A␤B␤»

The sed-like version can be found in fff^.

This operator cannot be overloaded, as it's handled specially by the compiler.

infix ^ff^

sub infix:<^ff^>(Mu $a, Mu $b)

Works like ff, except it does not return True for items matching either the stop or start condition (or both).

my @list = <A B C>;
say $_ if /A/ ff /C/ for @list;    # OUTPUT: «A␤B␤C␤»
say $_ if /A/ ^ff^ /C/ for @list;  # OUTPUT: «B␤»

The sed-like version can be found in ^fff^.

This operator cannot be overloaded, as it's handled specially by the compiler.

infix fff

sub infix:<fff>(Mu $a, Mu $b)

Performs a sed-like flipflop operation, wherein it returns False until the left argument smartmatches against $_, then returns True until the right argument smartmatches against $_.

Works similarly to ff, except that it only tries one argument per invocation. That is, if $_ smartmatches the left argument, fff will not then try to match that same $_ against the right argument.

for <AB C D B E F> {
    say $_ if /A/ fff /B/;         # OUTPUT: «AB␤C␤D␤B␤»
}

The non-sed-like flipflop (which after successfully matching the left argument against $_ will try that same $_ against the right argument and act accordingly). See ff.

This operator cannot be overloaded, as it's handled specially by the compiler.

infix ^fff

sub infix:<^fff>(Mu $a, Mu $b)

Like fff, except it does not return true for matches to the left argument.

my @list = <A B C>;
say $_ if /A/ fff /C/ for @list;   # OUTPUT: «A␤B␤C␤»
say $_ if /A/ ^fff /C/ for @list;  # OUTPUT: «B␤C␤»

For the non-sed version, see ^ff.

This operator cannot be overloaded, as it's handled specially by the compiler.

infix fff^

sub infix:<fff^>(Mu $a, Mu $b)

Like fff, except it does not return true for matches to the right argument.

my @list = <A B C>;
say $_ if /A/ fff /C/ for @list;   # OUTPUT: «A␤B␤C␤»
say $_ if /A/ fff^ /C/ for @list;  # OUTPUT: «A␤B␤»

For the non-sed version, see ff^.

This operator cannot be overloaded, as it's handled specially by the compiler.

infix ^fff^

sub infix:<^fff^>(Mu $a, Mu $b)

Like fff, except it does not return true for matches to either the left or right argument.

my @list = <A B C>;
say $_ if /A/ fff /C/ for @list;   # OUTPUT: «A␤B␤C␤»
say $_ if /A/ ^fff^ /C/ for @list; # OUTPUT: «B␤»

For the non-sed version, see ^ff^.

This operator cannot be overloaded, as it's handled specially by the compiler.

Item assignment precedence

infix =

    sub infix:<=>(Mu $a is rw, Mu $b) 

Called the item assignment operator, it Places the value of the right-hand side into the container on the left-hand side. Its exact semantics are left to the container type on the left-hand side.

(Note that item assignment and list assignment have different precedence levels, and the syntax of the left-hand side decides whether an equal sign = is parsed as item assignment or list assignment operator).

infix =>

sub infix:«=>»($key, Mu $value --> Pair:D)

Pair constructor.

Constructs a Pair object with the left-hand side as the key and the right-hand side as the value.

Note that the => operator is syntactically special-cased, in that it allows unquoted identifier on the left-hand side.

my $p = a => 1;
say $p.key;         # OUTPUT: «a␤»
say $p.value;       # OUTPUT: «1␤»

A Pair within an argument list with an unquoted identifier on the left is interpreted as a named argument.

See the Terms language documentation for more ways to create Pair objects.

Loose unary precedence

prefix not

multi sub prefix:<not>(Mu $x --> Bool:D)

Evaluates its argument in boolean context (and thus collapses Junctions), and negates the result. Please note that not is easy to misuse. See traps.

prefix so

multi sub prefix:<so>(Mu $x --> Bool:D)

Evaluates its argument in boolean context (and thus collapses Junctions), and returns the result.

Comma operator precedence

infix ,

sub infix:<,>(*@a --> List:D) is assoc<list>

Constructs a higher-order Cool from its arguments.

my @list = :god('Þor'), ['is',"mighty"];
say @list;      # OUTPUT: «[god => Þor [is mighty]]␤»
my %hash = :god('Þor'), :is("mighty");
say %hash.perl; # OUTPUT: «{:god("Þor"), :is("mighty")}␤»
my %a = :11a, :22b;
say %(%a, :33x);  # OUTPUT: «{a => 11, b => 22, x => 33}␤»

In the first case it returns a List, in the second case, since the arguments are Pairs, it builds a Hash.

It can also be used for constructing variables from other variables, collating elements of different types, in this case a Hash and a Pair:

my %features = %hash, :wields("hammer"); 
 say %features;  # OUTPUT: «{god => Þor, is => mighty, wields => hammer}␤» 

The comma is also used syntactically as the separator of arguments in calls.

infix :

Used as an argument separator just like infix , and marks the argument to its left as the invocant. That turns what would otherwise be a function call into a method call.

substr('abc': 1);       # same as 'abc'.substr(1)

Infix : is only allowed after the first argument of a non-method call. In other positions, it's a syntax error.

List infix precedence

infix Z

sub infix:<Z>(**@lists --> Seq:D) is assoc<chain>

The Zip operator interleaves the lists passed to Z like a zipper, taking index-corresponding elements from each operand. The returned Seq contains nested lists, each with a value from every operand in the chain. If one of the operands runs out of elements prematurely, the zip operator will stop.

say (1, 2 Z <a b c> Z <+ ->).perl; 
 # OUTPUT: «((1, "a", "+"), (2, "b", "-")).Seq␤» 
 for <a b c> Z <1 2 3 4> -> [$l, $r] { 
     say "$l:$r" 
 } 
 # OUTPUT: «a:1␤b:2␤c:3␤» 

The Z operator also exists as a metaoperator, in which case the inner lists are replaced by the value from applying the operator to the list:

say 100, 200 Z+ 42, 23;             # OUTPUT: «(142 223)␤»
say 1..3 Z~ <a b c> Z~ 'x' xx 3;    # OUTPUT: «(1ax 2bx 3cx)␤»

infix X

Defined as:

multi sub infix:<X>(+lol, :&with! --> Seq:D)
multi sub infix:<X>(+lol --> Seq:D)

Creates a cross product from all the lists, ordered so that the rightmost elements vary most rapidly, and returns a Seq:

1..3 X <a b c> X 9
# produces ((1 a 9) (1 b 9) (1 c 9)
#           (2 a 9) (2 b 9) (2 c 9)
#           (3 a 9) (3 b 9) (3 c 9))

The X operator also exists as a metaoperator, in which case the inner lists are replaced by the value from applying the operator to the list:

1..3 X~ <a b c> X~ 9
# produces (1a9 1b9 1c9 2a9 2b9 2c9 3a9 3b9 3c9)

infix ...

multi sub infix:<...>(**@) is assoc<list>
multi sub infix:<...^>(**@) is assoc<list>

The sequence operator, which can be written either as ... or as (with variants ...^ and …^) will produce (possibly lazy) generic sequences on demand.

The left-hand side will always include the initial elements; it may include a generator too (after the first element or elements). The right-hand side will have an endpoint, which can be Inf or * for "infinite" lists (that is, lazy lists whose elements are only produced on demand), an expression which will end the sequence when True, or other elements such as Junctions.

The sequence operator invokes the generator with as many arguments as necessary. The arguments are taken from the initial elements and the already generated elements. The default generator is *.succ or *.pred, depending on how the end points compare:

say 1 ... 4;        # OUTPUT: «(1 2 3 4)␤»
say 4 ... 1;        # OUTPUT: «(4 3 2 1)␤»
say 'a' ... 'e';    # OUTPUT: «(a b c d e)␤»
say 'e' ... 'a';    # OUTPUT: «(e d c b a)␤»

An endpoint of * (Whatever), Inf or generates on demand an infinite sequence, with a default generator of *.succ

say (1 ... *)[^5];  # OUTPUT: «(1 2 3 4 5)␤»

Custom generators need to be the last element of the list before the '...' operator. This one takes two arguments, and generates the eight first Fibonacci numbers

say (1, 1, -> $a, $b { $a + $b } ... *)[^8]; # OUTPUT: «(1 1 2 3 5 8 13 21)␤» 
 # same but shorter 
 say (1, 1, * + * ... *)[^8];                 # OUTPUT: «(1 1 2 3 5 8 13 21)␤» 

Of course the generator can also take only one argument.

say 5, { $_ * 2 } ... 40;                # OUTPUT: «5 10 20 40␤»

There must be at least as many initial elements as arguments to the generator.

Without a generator and with more than one initial element and all initial elements numeric, the sequence operator tries to deduce the generator. It knows about arithmetic and geometric sequences.

say 2, 4, 6 ... 12;     # OUTPUT: «(2 4 6 8 10 12)␤»
say 1, 2, 4 ... 32;     # OUTPUT: «(1 2 4 8 16 32)␤»

If the endpoint is not *, it's smartmatched against each generated element and the sequence is terminated when the smartmatch succeeded. For the ... operator, the final element is included, for the ...^ operator it's excluded.

This allows you to write

say 1, 1, * + * ...^ *>= 100;

to generate all Fibonacci numbers up to but excluding 100.

The ... operators consider the initial values as "generated elements" as well, so they are also checked against the endpoint:

my $end = 4;
say 1, 2, 4, 8, 16 ... $end;
# OUTPUT: «(1 2 4)␤»

List prefix precedence

infix =

In this context, it acts as the list assignment operator. Its exact semantics are left to the container type on the left-hand side. See Array and Hash for common cases.

The distinction between item assignment and list assignment is determined by the parser depending on the syntax of the left-hand side.

infix :=

Binding operator. Whereas $x = $y puts the value in $y into $x, $x := $y makes $x and $y the same thing.

my $a = 42;
my $b = $a;
$b++;
say $a;

This will output 42, because $a and $b both contained the number 42, but the containers were different.

my $a = 42;
my $b := $a;
$b++;
say $a;

This will output 43, since $b and $a both represented the same object.

If type constrains on variables or containers are present a type check will be performed at runtime. On failure X::TypeCheck::BindingType will be thrown.

Please note that := is a compile time operator. As such it can not be referred to at runtime and thus can't be used as an argument to metaoperators.

infix ::=

Read-only binding operator, not yet implemented in Rakudo. See infix :=.

listop ...

Called the yada, yada, yada operator or stub operator, if it's the only statement in a routine or type, it marks that routine or type as a stub (which is significant in the context of pre-declaring types and composing roles).

If the ... statement is executed, it calls fail, with the default message Stub code executed.

listop !!!

If it's the only statement in a routine or type, it marks that routine or type as a stub (which is significant in the context of pre-declaring types and composing roles).

If the !!! statement is executed, it calls die, with the default message Stub code executed.

listop ???

If it's the only statement in a routine or type, it marks that routine or type as a stub (which is significant in the context of pre-declaring types and composing roles).

If the ??? statement is executed, it calls warn, with the default message Stub code executed.

Reduction operators

Any infix operator (except for non-associating operators) can be surrounded by square brackets in term position to create a list operator that reduces using that operation.

say [+] 1, 2, 3;      # 1 + 2 + 3 = 6
my @a = (5, 6);
say [*] @a;           # 5 * 6 = 30

Reduction operators have the same associativity as the operators they are based on.

say [-] 4, 3, 2;      # 4-3-2 = (4-3)-2 = -1
say [**] 4, 3, 2;     # 4**3**2 = 4**(3**2) = 262144

Loose AND precedence

infix and

Same as infix &&, except with looser precedence.

Short-circuits so that it returns the first operand that evaluates to False, otherwise returns the last operand. Note that and is easy to misuse, see traps.

infix andthen

The andthen operator returns Empty upon encountering the first undefined argument, otherwise the last argument. Last argument is returned as-is, without being checked for definedness at all. Short-circuits. The result of the left side is bound to $_ for the right side, or passed as arguments if the right side is a Callable, whose count must be 0 or 1.

A handy use of this operator is to alias a routine's return value to $_ and to do additional manipulation with it, such as printing or returning it to caller. Since the andthen operator short-circuits, statements on the right-hand side won't get executed, unless left-hand side is defined (tip: Failures are never defined, so you can handle them with this operator).

sub load-data {
    rand  > .5 or return; # simulated load data failure; return Nil
    (rand > .3 ?? 'error' !! 'good data') xx 10 # our loaded data
}
load-data.first: /good/ andthen say "$_ is good";
# OUTPUT: «(good data is good)␤»

load-data() andthen .return; # return loaded data, if it's defined
die "Failed to load data!!";

The above example will print good data is good only if the subroutine returned any items that match /good/ and will die unless loading data returned a defined value. The aliasing behavior lets us pipe the values across the operator.

The andthen operator is a close relative of with statement modifier, and some compilers compile with to andthen, meaning these two lines have equivalent behavior:

.say with 42;
42 andthen .say;

infix notandthen

The notandthen operator returns Empty upon encountering the first defined argument, otherwise the last argument. Last argument is returned as-is, without being checked for definedness at all. Short-circuits. The result of the left side is bound to $_ for the right side, or passed as arguments if the right side is a Callable, whose count must be 0 or 1.

At first glance, notandthen might appear to be the same thing as the orelse operator. The difference is subtle: notandthen returns Empty when it encounters a defined item (that isn't the last item), whereas orelse returns that item. In other words, notandthen is a means to act when items aren't defined, whereas orelse is a means to obtain the first defined item:

sub all-sensors-down     { [notandthen] |@_, True             } 
 sub first-working-sensor { [orelse]     |@_, 'default sensor' } 
 
 all-sensors-down Nil, Nil, Nil 
   and say 'OMG! All sensors are down!'; # OUTPUT:«OMG! All sensors are down!␤» 
 say first-working-sensor Nil, Nil, Nil; # OUTPUT:«default sensor␤» 
 
 all-sensors-down Nil, 42, Nil 
   and say 'OMG! All sensors are down!'; # No output 
 say first-working-sensor Nil, 42, Nil;  # OUTPUT:«42␤» 

The notandthen operator is a close relative of without statement modifier, and some compilers compile without to notandthen, meaning these two lines have equivalent behavior:

sub good-things { fail } 
 
 'boo'.say without good-things; 
 good-things() notandthen 'boo'.say; 

Loose OR precedence

infix or

Same as infix ||, except with looser precedence.

Returns the first argument that evaluates to True in boolean context, or otherwise the last argument, it short-circuits. Please note that or is easy to misuse. See traps.

infix orelse

The orelse operator is similar to infix //, except with looser precedence and $_ aliasing.

Returns the first defined argument, or else the last argument. Last argument is returned as-is, without being checked for definedness at all. Short-circuits. The result of the left side is bound to $_ for the right side, or passed as an argument if the right side is a Callable, whose count must be 0 or 1.

This operator is useful for handling Failures returned by routines since the expected value is usually defined and Failure never is:

sub meows { ++$ < 4 ?? fail 'out of meows!' !! '🐱' }

sub meows-processor1 { meows() orelse .return } # return handled Failure
sub meows-processor2 { meows() orelse fail $_ } # return re-armed Failure
sub meows-processor3 {
    # Use non-Failure output, or else print a message that stuff's wrong
    meows() andthen .say orelse ‘something's wrong’.say;
}

say "{.^name}, {.handled}"  # OUTPUT: «Failure, True␤»
    given meows-processor1;
say "{.^name}, {.handled}"  # OUTPUT: «Failure, False␤»
    given meows-processor2;
meows-processor3;           # OUTPUT: «something's wrong␤»
meows-processor3;           # OUTPUT: «🐱␤»

infix xor

Same as infix ^^, except with looser precedence.

Returns the operand that evaluates to True in boolean context, if and only if the other operand evaluates to False in boolean context. If both operands evaluate to False, returns the last argument. If both operands evaluate to True, returns Nil.

When chaining, returns the operand that evaluates to True, if and only if there is one such operand. If more than one operand is true, it short-circuits after evaluating the second and returns Nil. If all operands are false, returns the last one.

Sequencer precedence

infix ==>

This feed operator takes the result from the left and passes it to the next (right) routine as the last parameter.

my @array = (1, 2, 3, 4, 5);
@array ==> sum() ==> say();   # OUTPUT: «15␤»

This simple example, above, is the equivalent of writing:

my @array = (1, 2, 3, 4, 5);
say(sum(@array));             # OUTPUT: «15␤»

Or if using methods:

my @array = (1, 2, 3, 4, 5);
@array.sum.say;               # OUTPUT: «15␤»

The precedence is very loose so you will need to use parentheses to assign the result or you can even just use another feed operator! In the case of routines/methods that take a single argument or where the first argument is a block, it's often required that you call with parentheses (though this is not required for the very last routine/method).

This "traditional" structure, read bottom-to-top, with the last two lines creating the data structure that is going to be processed

my @fractions = <TWO THREE FOUR FIVE SEVEN> »~» " " X~ <FIFTHS SIXTHS EIGHTHS>;
my @result = map { .uniparse },                    # (3) Converts to unicode
    grep { .uniparse },                            # (2) Checks if it parses
    map( {"VULGAR FRACTION " ~ $^þ }, @fractions); # (1) Adds string to input

# @result is [⅖ ⅗ ⅜ ⅘ ⅚ ⅝ ⅞]

Now we use the feed operator (left-to-right) with parentheses, read top-to-bottom

my @result = (
    <TWO THREE FOUR FIVE SEVEN> »~» " " X~ <FIFTHS SIXTHS EIGHTHS> # (1) Input
    ==> map( {"VULGAR FRACTION " ~ $^þ } )                         # (2) Converts to Unicode name
    ==> grep({ .uniparse })                                        # (3) Filters only real names
    ==> map( { .uniparse} );                                       # (4) Converts to unicode
);

For illustration, method chaining equivalent, read top-to-bottom, using the same sequence as above

my @result = ( <TWO THREE FOUR FIVE SEVEN> »~» " " X~ <FIFTHS SIXTHS EIGHTHS>)
    .map( {"VULGAR FRACTION " ~ $^þ } )
    .grep({ .uniparse })
    .map({ .uniparse });

Although in this particular case the result is the same, the feed operator ==> more clearly shows intent with arrow pointing in the direction of the data flow. To assign without the need of parentheses use another feed operator

my @result;
<people of earth>
    ==> map({ .tc })
    ==> grep /<[PE]>/
    ==> sort()
    ==> @result;

It can be useful to capture a partial result, however, unlike the leftward feed operator, it does require parentheses or a semicolon

my @result;
<people of earth>
    ==> map({ .tc })
    ==> my @caps; @caps   # also could wrap in parentheses instead
    ==> grep /<[PE]>/
    ==> sort()
    ==> @result;

The feed operator lets you construct method-chaining-like patterns out of routines and the results of methods on unrelated data. In method-chaining, you are restricted to the methods available on the data or the result of previous method call. With feed operators, that restriction is gone. The resulting code could also be seen to be more readable than a series of method calls broken over multiple lines.

Note: In the future, this operator will see some change as it gains the ability to run list operations in parallel. It will enforce that the left operand is enclosable as a closure (that can be cloned and run in a subthread).

infix <==

This leftward feed operator takes the result from the right and passes it to the previous (left) routine as the last parameter. This elucidates the right-to-left dataflow for a series of list manipulating functions.

# Traditional structure, read bottom-to-top
my @result =
    sort                   # (4) Sort, result is <Earth People>
    grep { /<[PE]>/ },     # (3) Look for P or E
    map { .tc },           # (2) Capitalize the words
    <people of earth>;     # (1) Start with the input

# Feed (right-to-left) with parentheses, read bottom-to-top
my @result = (
    sort()                 # (4) Sort, result is <Earth People>
    <== grep({ /<[PE]>/ }) # (3) Look for P or E
    <== map({ .tc })       # (2) Capitalize the words
    <== <people of earth>  # (1) Start with the input
);

# To assign without parentheses, use another feed operator
my @result
    <== sort()              # (4) Sort, result is <Earth People>
    <== grep({ /<[PE]>/ })  # (3) Look for P or E
    <== map({ .tc })        # (2) Capitalize the words
    <== <people of earth>;  # (1) Start with the input

# It can be useful to capture a partial result
my @result
    <== sort()
    <== grep({ /<[PE]>/ })
    <== my @caps            # unlike ==>, there's no need for additional statement
    <== map({ .tc })
    <== <people of earth>;

Unlike the rightward feed operator, the result is not closely mappable to method-chaining. However, compared to the traditional structure above where each argument is separated by a line, the resulting code is more demonstrative than commas. The leftward feed operator also allows you to "break into" the statement and capture an intermediary result which can be extremely useful for debugging or to take that result and create another variation on the final result.

Note: In the future, this operator will see some change as it gains the ability to run list operations in parallel. It will enforce that the right operand is enclosable as a closure (that can be cloned and run in a subthread).

Identity

In general, infix operators can be applied to a single or no element without yielding an error, generally in the context of a reduce operation.

say [-] ()  # OUTPUT: «0␤»

The design documents specify that this should return an identity value, and that an identity value must be specified for every operator. In general, the identity element returned should be intuitive. However, here is a table that specifies how it is defined for operator classes in Perl 6, which corresponds to the table in the above definition in the types and operators defined by the language:

Operator class Identity value
Equality Bool::True
Arithmetic + 0
Arithmetic * 1
Comparison True
Bitwise 0
Stringy ''
Sets Empty set or equivalent
Or-like Bool False
And-like Bool True

For instance, union of an empty list will return an empty set:

say [∪];  # OUTPUT: «set()␤»

This only applies to operators where empty or 0 is always a valid operand. For instance, applying it to division will yield an exception.

say [%] ();  # OUTPUT: «(exit code 1) No zero-arg meaning for infix:<%>␤ 

60 Packages

Organizing and referencing namespaced program elements

TODO * Take a lot of stuff from S02 for this * Document 'import'

Packages are nested namespaces of named program elements. Modules, classes, grammars, and others are types of packages. Like files in a directory, you can generally refer to named elements with their short-name if they are local, or with the longer name that includes the namespace to disambiguate as long as their scope allows that.

Names

A package name is anything that is a legal part of a variable name (not counting the sigil). This includes:

class Foo { 
     sub zape () { say "zipi" } 
     class Bar { 
         method baz () { return 'Þor is mighty' } 
         our &zape = { "zipi" }; 
         our $quux = 42; 
     } 
 } 
 
 my $foo;                # simple identifiers 
 say Foo::Bar.baz;       # calling a method; OUTPUT: «Þor is mighty␤» 
 say Foo::Bar::zape;     # compound identifiers separated by ::; OUTPUT: «zipi␤» 
 my $bar = 'Bar'; 
 say $Foo::($bar)::quux; # compound identifiers with interpolations; OUTPUT: «42␤» 
 $42;                    # numeric names 
 $!;                     # certain punctuation variables 

:: is used to separate nested package names.

Packages do not really have an identity; they can be simply part of a module or class name, for instance. They are more similar to namespaces than to modules; with a module of the same name capturing the identity of a package if it exists.

package Foo:ver<0> {}; 
 module Foo:ver<1> {}; 
 say Foo.^ver; # OUTPUT: «1␤» 

The syntax allows the declared package to use a version, but as a matter of fact, it's dismissed; only modules and classes have an identity that might include auth and ver.

Package-qualified names

Ordinary package-qualified names look like this: $Foo::Bar::quux, which would be the $quux variable in package Foo::Bar; Foo::Bar::zape would represent the &zape variable in the same package.

Sometimes it's clearer to keep the sigil with the variable name, so an alternate way to write this is:

Foo::Bar::<$quux>

This does not work with the Foo«&zape» variable, since subs, by default, have lexical scope. The name is resolved at compile time because the variable name is a constant. We can access the rest of the variables in Bar (as shown in the example above) since classes, by default, have package scope.

If the name part before :: is null, it means the package is unspecified and must be searched for. Generally this means that an initial :: following the main sigil is a no-op on names that are known at compile time, though ::() can also be used to introduce an interpolation. Also, in the absence of another sigil, :: can serve as its own sigil indicating intentional use of a not-yet-declared package name.

Pseudo-packages

The following pseudo-package names are reserved at the front of a name:

MY Symbols in the current lexical scope (aka $?SCOPE)
OUR Symbols in the current package (aka $?PACKAGE)
CORE Outermost lexical scope, definition of standard Perl
GLOBAL Interpreter-wide package symbols, really UNIT::GLOBAL
PROCESS Process-related globals (superglobals). The last place dynamic variable lookup will look.
COMPILING Lexical symbols in the scope being compiled

The following relative names are also reserved but may be used anywhere in a name:

CALLER Dynamic symbols in the immediate caller's lexical scope
CALLERS Dynamic symbols in any caller's lexical scope
DYNAMIC Dynamic symbols in my or any caller's lexical scope
OUTER Symbols in the next outer lexical scope
OUTERS Symbols in any outer lexical scope
LEXICAL Dynamic symbols in my or any outer's lexical scope
UNIT Symbols in the outermost lexical scope of compilation unit
SETTING Lexical symbols in the unit's DSL (usually CORE)
PARENT Symbols in this package's parent package (or lexical scope)
CLIENT The nearest CALLER that comes from a different package

The file's scope is known as UNIT, but there are one or more lexical scopes outside of that corresponding to the linguistic setting (often known as the prelude in other cultures). Hence, the SETTING scope is equivalent to UNIT::OUTERS. For a standard Perl 6 program SETTING is the same as CORE, but various startup options (such as -n or -p) can put you into a domain specific language, in which case CORE remains the scope of the standard language, while SETTING represents the scope defining the DSL that functions as the setting of the current file. When used as a search term in the middle of a name, SETTING includes all its outer scopes up to CORE. To get only the setting's outermost scope, use UNIT::OUTER instead.

Looking up names

Interpolating into names

You may interpolate a string into a package or variable name using ::($expr) where you'd ordinarily put a package or variable name. The string is allowed to contain additional instances of ::, which will be interpreted as package nesting. You may only interpolate entire names, since the construct starts with ::, and either ends immediately or is continued with another :: outside the parentheses. Most symbolic references are done with this notation:

my $foo = "Foo"; 
 my $bar = "Bar"; 
 my $foobar = "Foo::Bar"; 
 $::($bar)              # lexically-scoped $Bar 
 $::("MY::$bar")        # lexically-scoped $Bar 
 $::("OUR::$bar")       # package-scoped $Bar 
 $::("GLOBAL::$bar")    # global $Bar 
 $::("PROCESS::$bar")   # process $Bar 
 $::("PARENT::$bar")    # current package's parent's $Bar 
 $::($foobar)           # $Foo::Bar 
 @::($foobar)::baz      # @Foo::Bar::baz 
 @::($foo)::Bar::baz    # @Bar::Bar::baz 
 @::($foobar)baz        # ILLEGAL at compile time (no operator baz) 
 @::($foo)::($bar)::baz # @Foo::Bar::baz 

An initial :: doesn't imply global; here as part of the interpolation syntax it doesn't even imply package. After the interpolation of the ::() component, the indirect name is looked up exactly as if it had been there in the original source code, with priority given first to leading pseudo-package names, then to names in the lexical scope (searching scopes outwards, ending at CORE). The current package is searched last.

Use the MY pseudopackage to limit the lookup to the current lexical scope, and OUR to limit the scopes to the current package scope.

In the same vein, class and method names can be interpolated too:

role with-method {
    method a-method { return 'in-a-method of ' ~ $?CLASS.^name  };
}

class a-class does with-method {
    method another-method { return 'in-another-method' };
}

class b-class does with-method {};

my $what-class = 'a-class';

say ::($what-class).a-method; # OUTPUT: «in-a-method of a-class␤»
$what-class = 'b-class';
say ::($what-class).a-method; # OUTPUT: «in-a-method of b-class␤»

my $what-method = 'a-method';
say a-class."$what-method"(); # OUTPUT: «in-a-method of a-class␤»
$what-method = 'another-method';
say a-class."$what-method"(); # OUTPUT: «in-another-method␤»

Direct lookup

To do direct lookup in a package's symbol table without scanning, treat the package name as a hash:

Foo::Bar::{'&baz'}  # same as &Foo::Bar::baz 
 PROCESS::<$IN>      # same as $*IN 
 Foo::<::Bar><::Baz> # same as Foo::Bar::Baz 

Unlike ::() symbolic references, this does not parse the argument for ::, nor does it initiate a namespace scan from that initial point. In addition, for constant subscripts, it is guaranteed to resolve the symbol at compile time.

The null pseudo-package is the same search list as an ordinary name search. That is, the following are all identical in meaning:

$foo 
 ::{'$foo'} 
 ::<$foo> 

Each of them scans the lexical scopes outward, and then the current package scope (though the package scope is then disallowed when "strict" is in effect).

Package lookup

Subscript the package object itself as a hash object, the key of which is the variable name, including any sigil. The package object can be derived from a type name by use of the :: postfix:

MyType::<$foo> 

Class member lookup

Methods—including auto-generated methods, such as public attributes' accessors—are stored in the class meta object and can be looked up through by the lookup method.

Str.^lookup('chars') 

Globals

Interpreter globals live in the GLOBAL package. The user's program starts in the GLOBAL package, so "our" declarations in the mainline code go into that package by default. Process-wide variables live in the PROCESS package. Most predefined globals such as $*UID and $*PID are actually process globals.

61 Performance

Measuring and improving runtime or compile-time performance

This page is about computer performance in the context of Perl 6.

First, profile your code

Make sure you're not wasting time on the wrong code: start by identifying your "critical 3%" by profiling your code's performance. The rest of this document shows you how to do that.

Time with now - INIT now

Expressions of the form now - INIT now, where INIT is a phase in the running of a Perl 6 program, provide a great idiom for timing code snippets.

Use the m: your code goes here #perl6 channel evalbot to write lines like:

m: say now - INIT now 
 rakudo-moar abc1234: OUTPUT«0.0018558␤» 

The now to the left of INIT runs 0.0018558 seconds later than the now to the right of the INIT because the latter occurs during the INIT phase.

Profile locally

When using the MoarVM backend, the Rakudo compiler's --profile command line option writes the profile data to an HTML file.

This file will open to the "Overview" section, which gives some overall data about how the program ran, e.g., total runtime, time spent doing garbage collection. One important piece of information you'll get here is percentage of the total call frames (i.e., blocks) that were interpreted (slowest, in red), speshed (faster, in orange), and jitted (fastest, in green).

The next section, "Routines", is probably where you'll spend the most time. It has a sortable and filterable table of routine (or block) name+file+line, the number of times it ran, the inclusive time (time spent in that routine + time spent in all routines called from it), exclusive time (just the time spent in that routine), and whether it was interpreted, speshed, or jitted (same color code as the "Overview" page). Sorting by exclusive time is a good way to know where to start optimizing. Routines with a filename that starts like SETTING::src/core/ or gen/moar/ are from the compiler, a good way to just see the stuff from your own code is to put the filename of the script you profiled in the "Name" search box.

The "Call Graph" section gives a flame graph representation of much of the same information as the "Routines" section.

The "Allocations" section gives you information about the amount of different types that were allocated, as well as which routines did the allocating.

The "GC" section gives you detailed information about all the garbage collections that occurred.

The "OSR / Deopt" section gives you information about On Stack Replacements (OSRs), which is when routines are "upgraded" from interpreted to speshed or jitted. Deopts are the opposite, when speshed or jitted code has to be "downgraded" to being interpreted.

If the profile data is too big, it could take a long time for a browser to open the file. In that case, output to a file with a .json extension using the --profile=filename option, then open the file with the Qt viewer.

To deal with even larger profiles, output to a file with a .sql extension. This will write the profile data as a series of SQL statements, suitable for opening in SQLite.

# create a profile 
 perl6 --profile=demo.sql -e 'say (^20).combinations(3).elems' 
 
 # create a SQLite database 
 sqlite3 demo.sqlite 
 
 # load the profile data 
 sqlite> .read demo.sql 
 
 # the query below is equivalent to the default view of the "Routines" tab in the HTML profile 
 sqlite> select 
       case when r.name = "" then "<anon>" else r.name end as name, 
       r.file, 
       r.line, 
       sum(entries) as entries, 
       sum(case when rec_depth = 0 then inclusive_time else 0 end) as inclusive_time, 
       sum(exclusive_time) as exclusive_time 
     from 
       calls c, 
       routines r 
     where 
       c.id = r.id 
     group by 
       c.id 
     order by 
       inclusive_time desc 
     limit 30; 

The in-progress, next-gen profiler is moarperf, which can accept .sql or SQLite files and has a bunch of new functionality compared to the original profiler. However, it has more dependencies than the relatively stand-alone original profiler, so you'll have to install some modules before using it.

To learn how to interpret the profile info, use the prof-m: your code goes here evalbot (explained above) and ask questions on the IRC channel.

Profile compiling

If you want to profile the time and memory it takes to compile your code, use Rakudo's --profile-compile or --profile-stage options.

Create or view benchmarks

Use perl6-bench.

If you run perl6-bench for multiple compilers (typically, versions of Perl 5, Perl 6, or NQP), results for each are visually overlaid on the same graphs, to provide for quick and easy comparison.

Share problems

Once you've used the above techniques to identify the code to improve, you can then begin to address (and share) the problem with others:

Solve problems

This bears repeating: make sure you're not wasting time on the wrong code. Start by identifying the "critical 3%" of your code.

Line by line

A quick, fun, productive way to try improve code line-by-line is to collaborate with others using the #perl6 evalbot camelia.

Routine by routine

With multi-dispatch, you can drop in new variants of routines "alongside" existing ones:

# existing code generically matches a two arg foo call:
multi sub foo(Any $a, Any $b) { ... }

# new variant takes over for a foo("quux", 42) call:
multi sub foo("quux", Int $b) { ... }

The call overhead of having multiple foo definitions is generally insignificant (though see discussion of where below), so if your new definition handles its particular case more efficiently than the previously existing set of definitions, then you probably just made your code that much more efficient for that case.

Speed up type-checks and call resolution

Most where clauses – and thus most subsets – force dynamic (runtime) type checking and call resolution for any call it might match. This is slower, or at least later, than compile-time.

Method calls are generally resolved as late as possible (dynamically at runtime), whereas sub calls are generally resolved statically at compile-time.

Choose better algorithms

One of the most reliable techniques for making large performance improvements, regardless of language or compiler, is to pick a more appropriate algorithm.

A classic example is Boyer-Moore. To match a small string in a large string, one obvious way to do it is to compare the first character of the two strings and then, if they match, compare the second characters, or, if they don't match, compare the first character of the small string with the second character in the large string, and so on. In contrast, the Boyer-Moore algorithm starts by comparing the *last* character of the small string with the correspondingly positioned character in the large string. For most strings, the Boyer-Moore algorithm is close to N times faster algorithmically, where N is the length of the small string.

The next couple sections discuss two broad categories for algorithmic improvement that are especially easy to accomplish in Perl 6. For more on this general topic, read the wikipedia page on algorithmic efficiency, especially the 'See also' section near the end.

Change sequential/blocking code to parallel/non-blocking

This is another very important class of algorithmic improvement.

See the slides for Parallelism, Concurrency, and Asynchrony in Perl 6 and/or the matching video.

Use existing high performance code

There are plenty of high performance C libraries that you can use within Perl 6 and NativeCall makes it easy to create wrappers for them. There's experimental support for C++ libraries, too.

If you want to use Perl 5 modules in Perl 6, mix in Perl 6 types and the Meta-Object Protocol.

More generally, Perl 6 is designed to smoothly interoperate with other languages and there are a number of modules aimed at facilitating the use of libs from other langs.

Make the Rakudo compiler generate faster code

To date, the focus for the compiler has been correctness, not how fast it generates code or how fast or lean the code it generates runs. But that's expected to change, eventually... You can talk to compiler devs on the freenode IRC channels #perl6 and #moarvm about what to expect. Better still, you can contribute yourself:

Still need more ideas?

Some known current Rakudo performance weaknesses not yet covered in this page include the use of gather/take, junctions, regexes, and string handling in general.

If you think some topic needs more coverage on this page, please submit a PR or tell someone your idea. Thanks. :)

Not getting the results you need/want?

If you've tried everything on this page to no avail, please consider discussing things with a compiler dev on #perl6, so we can learn from your use-case and what you've found out about it so far.

Once a dev knows of your plight, allow enough time for an informed response (a few days or weeks, depending on the exact nature of your problem and potential solutions).

If that hasn't worked out, please consider filing an issue about your experience at our user experience repo before moving on.

Thanks. :)

62 Perl 6 native types

Using the types the compiler and hardware make available to you

Perl 6 offers a set of native types with a fixed, and known, representation in memory. This page shows which ones exist and how they can be used. Please check also the page on native numerics for more information on them.

Types with native representation

Some simple types in Perl 6 have a native representation, indicating that they will use the C language representation provided by the compiler, operating system and machine. These are the four native types available:

int Equivalent to Int (with limited range)
uint Equivalent to Int (with limited range) with the unsigned trait
num Equivalent to Num
str Equivalent to Str

However, these types do not necessarily have the size that is required by the NativeCall interface (e.g., Perl 6's int can be 8 bytes but C's int is only 4 bytes); the types below will have to be used instead of the types int or num listed above.

In general, these variables will behave in the same way as regular scalar variables, in a behavior that is called auto-boxing; however, there are some differences, since what you are actually declaring is how they will be represented, not their actual type. The first one is that their type will be actually their equivalent type, not their native type.

my int $intillo = 3;
say $intillo.^name; # OUTPUT: «Int␤»

This obviously means that they will smartmatch their equivalent (auto-boxed) type, not their native type:

my str $strillo = "tres";
say $strillo ~~ str; # OUTPUT: «False␤»
say $strillo ~~ Str; # OUTPUT: «True␤»

And also that they will always have a default value, unlike their non-native counterparts:

say (my Str $); # OUTPUT: «(Str)␤»
say (my str $); # OUTPUT: «␤»
say (my num $); # OUTPUT: «0␤»

Note: In v6.c, the default value for num would have been a NaN.

This is due to the fact that Natives don't know their types because they're just values, without any meta-data. In multi-dispatch, you can have a native candidate, but you cannot differentiate different sizes of the same native type. That is, you can have an Int and int candidates, but there would be an ambiguity between, for instance int, atomicint or int64 candidates.

They cannot be bound either. Trying to do my num $numillo := 3.5 will raise the exception Cannot bind to natively typed variable '$variable-name'; use assignment instead.

Native types can also be composite.

my int @intillos = ^10_000_000;
say [+] @intillos; # OUTPUT: «49999995000000␤»

In this case, nativeness extends to the composite type, which will be array

my num @many-pi  = ^8 »*» π ; say @many-pi.^name;  # OUTPUT: «array[num]␤»

Native arrays are Iterable, but they are not a subclass of List. However, they behave similarly to Arrays; for instance, they can be shaped:

my str @letter-pairs[10] = 'a'..'j' Z~ 'A'..'J'; 
 say @letter-pairs.perl; 
 # OUTPUT: «array[str].new(:shape(10,), ["aA", "bB", "cC", "dD", "eE", "fF", "gG", "hH", "iI", "jJ"])␤» 

Types with native representation and size

What has been mentioned about types with native representation also applies here; they will be auto-boxed to Perl 6 types and will not be boundable. However, these types, which are listed in the table below, have the characteristic of being usable in NativeCall functions.

int8 (int8_t in C)
int16 (int16_t in C)
int32 (int32_t in C)
int64 (int64_t in C)
byte, uint8 (uint8_t in C)
uint16 (uint16_t in C)
uint32 (uint32_t in C)
uint64 (uint64_t in C)
num32 (float in C)
num64 (double in C)

These types have a fixed size representation which is independent of the platform, and thus can be used safely for those native calls. Nothing prevents us from using them in any other environment, if we so wish. In the same way as the types above, this size will have to be taken into account when assigning values to variables of this type:

my byte $intillo = 257;
say $intillo; # OUTPUT: «1␤»

Since byte is able to hold only 8 bits, it will wrap over and assign the result of the original value modulo 256, which is what is shown.

The main difference between types with declared native size and those without is the use of is nativesize in their declaration. For instance, int8 is declared in this way:

my native int8 is repr('P6int') is Int is nativesize(8) { }

Indicating that it will use, besides an integer representation (P6int), a native size of only 8 bits. This trait, however, is not intended to be used in your programs since it is not part of the Perl 6 specification.

The void type

The native void type corresponds to the C void type. Although, being a valid type, you can use it in expressions:

use NativeCall;
my void $nothing;
say $nothing.perl; # OUTPUT: «NativeCall::Types::void␤»

In practice, it is an Uninstantiable type that can rarely be used by itself, and in fact it is explicitly forbidden in return types. However, it is generally found in typed pointers representing the equivalent to the void * pointer in C.

sub malloc( int32 $size --> Pointer[void] ) is native { * }; 
 my Pointer[void] $for-malloc = malloc( 32 ); 
 say $for-malloc.perl; 

You can also nativecast Blobs to this kind of pointer in case you need to work with them in native functions that use the type

use NativeCall; 
 my Pointer[void] $native = nativecast(Pointer[void], Blob.new(0x22, 0x33)); 

However, outside that, the functionality it offers is quite limited, since pointers to void cannot be dereferenced:

use NativeCall; 
 my Pointer[void] $native = nativecast(Pointer[void], Buf.new(0x22, 0x33)); 
 say $native.deref; # ERROR OUTPUT: «Internal error: unhandled target type␤» 

Atomic types

In this context, atomic refers to safe operation under threading. Perl 6 provides a type, atomicint, and some operations which, together, guarantee this. Please check the atomic operations section on the Numerics page for more information on this.

Rakudo specific native types

The types described in this section are Rakudo specific, so they are not guaranteed to be in other implementations or remain the same in future versions.

long (long in C)
longlong (longlong in C)
ulong (long and unsigned in C)
ulonglong (longlong and unsigned in C)
size_t (size_t and unsigned in C)
ssize_t (size_t in C)
bool (bool in C)

You can use them in the same way they would be used in native C:

use NativeCall; 
 
 my $just-an-array = CArray[int32].new( 1, 2, 3, 4, 5 ); 
 
 loop ( my size_t $i = 0; $i < $just-an-array.elems; $i++ ) { 
     say $just-an-array[$i]; 
 } 

Which would print the five elements of the array, as it should be expected.

63 Phasers

Program execution phases and corresponding phaser blocks

The lifetime (execution timeline) of a program is broken up into phases. A phaser is a block of code called during a specific execution phase.

Phasers

A phaser block is just a trait of the closure containing it, and is automatically called at the appropriate moment. These auto-called blocks are known as phasers, since they generally mark the transition from one phase of computing to another. For instance, a CHECK block is called at the end of compiling a compilation unit. Other kinds of phasers can be installed as well; these are automatically called at various times as appropriate, and some of them respond to various control exceptions and exit values. For instance, some phasers might be called if the exit from a block is successful or not, with success in this case defined by returning with a defined value or list without any Failure or exception in the process.

Here is a summary:

  BEGIN {...} #  * at compile time, as soon as possible, only ever runs once 
   CHECK {...} #  * at compile time, as late as possible, only ever runs once 
    INIT {...} #  * at runtime, as soon as possible, only ever runs once 
     END {...} #  at runtime, as late as possible, only ever runs once 
     DOC [BEGIN|CHECK|INIT] {...} # only in documentation mode 
 
   ENTER {...} #  * at every block entry time, repeats on loop blocks. 
   LEAVE {...} #  at every block exit time (even stack unwinds from exceptions) 
    KEEP {...} #  at every successful block exit, part of LEAVE queue 
    UNDO {...} #  at every unsuccessful block exit, part of LEAVE queue 
 
   FIRST {...} #  at loop initialization time, before any ENTER 
    NEXT {...} #  at loop continuation time, before any LEAVE 
    LAST {...} #  at loop termination time, after any LEAVE 
 
     PRE {...} #  assert precondition at every block entry, before ENTER 
    POST {...} #  assert postcondition at every block exit, after LEAVE 
 
   CATCH {...} #  catch exceptions, before LEAVE 
 CONTROL {...} #  catch control exceptions, before LEAVE 
 
    LAST {...} #  supply tapped by whenever-block is done, runs very last 
    QUIT {...} #  catch async exceptions within a whenever-block, runs very last 
 
 COMPOSE {...} #  when a role is composed into a class (Not yet implemented) 
   CLOSE {...} #  appears in a supply block, called when the supply is closed 

Phasers marked with a * have a runtime value, and if evaluated earlier than their surrounding expression, they simply save their result for use in the expression later when the rest of the expression is evaluated:

my $compiletime = BEGIN { now };
our $random = ENTER { rand };

As with other statement prefixes, these value-producing constructs may be placed in front of either a block or a statement:

my $compiletime = BEGIN now;
our $random = ENTER rand;

Most of these phasers will take either a block or a function reference. The statement form can be particularly useful to expose a lexically scoped declaration to the surrounding lexical scope without "trapping" it inside a block.

These declare the same variables with the same scope as the preceding example, but run the statements as a whole at the indicated time:

BEGIN my $compiletime = now;
ENTER our $random = rand;

(Note, however, that the value of a variable calculated at compile time may not persist under runtime cloning of any surrounding closure.)

Most of the non-value-producing phasers may also be so used:

END say my $accumulator;

Note, however, that

END say my $accumulator = 0;

sets the variable to 0 at END time, since that is when the "my" declaration is actually executed. Only argumentless phasers may use the statement form. This means that CATCH and CONTROL always require a block, since they take an argument that sets $_ to the current topic, so that the innards are able to behave as a switch statement. (If bare statements were allowed, the temporary binding of $_ would leak out past the end of the CATCH or CONTROL, with unpredictable and quite possibly dire consequences. Exception handlers are supposed to reduce uncertainty, not increase it.)

Some of these phasers also have corresponding traits that can be set on variables; they use will followed by the name of the phaser in lowercase. These have the advantage of passing the variable in question into the closure as its topic:

our $h will enter { .rememberit() } will undo { .forgetit() };

Only phasers that can occur multiple times within a block are eligible for this per-variable form; this excludes CATCH and others like CLOSE or QUIT.

The topic of the block outside a phaser is still available as OUTER::<$_> . Whether the return value is modifiable may be a policy of the phaser in question. In particular, the return value should not be modified within a POST phaser, but a LEAVE phaser could be more liberal.

Any phaser defined in the lexical scope of a method is a closure that closes over self as well as normal lexicals. (Or equivalently, an implementation may simply turn all such phasers into submethods whose primed invocant is the current object.)

When multiple phasers are scheduled to run at the same moment, the general tiebreaking principle is that initializing phasers execute in order declared, while finalizing phasers execute in the opposite order, because setup and teardown usually want to happen in the opposite order from each other.

Execution order

Compilation begins

      BEGIN {...} #  at compile time, As soon as possible, only ever runs once 
       CHECK {...} #  at compile time, As late as possible, only ever runs once 
     COMPOSE {...} #  when a role is composed into a class (Not yet implemented) 

Execution begins

       INIT {...} #  at runtime, as soon as possible, only ever runs once 

Before block execution begins

        PRE {...} #  assert precondition at every block entry, before ENTER 

Loop execution begins

      FIRST {...} #  at loop initialization time, before any ENTER 

Block execution begins

      ENTER {...} #  at every block entry time, repeats on loop blocks. 

Exception maybe happens

      CATCH {...} #  catch exceptions, before LEAVE 
     CONTROL {...} #  catch control exceptions, before LEAVE 

End of loop, either continuing or finished

       NEXT {...} #  at loop continuation time, before any LEAVE 
        LAST {...} #  at loop termination time, after any LEAVE 

End of block

      LEAVE {...} #  when blocks exits, even stack unwinds from exceptions 
        KEEP {...} #  at every successful block exit, part of LEAVE queue 
        UNDO {...} #  at every unsuccessful block exit, part of LEAVE queue 

Postcondition for block

       POST {...} #  assert postcondition at every block exit, after LEAVE 

Async whenever-block is complete

       LAST {...} #  if ended normally with done, runs once after block 
        QUIT {...} #  catch async exceptions 

Program terminating

        END {...} #  at runtime, ALAP, only ever runs once 

Program execution phasers

BEGIN

Runs at compile time, as soon as the code in the phaser has compiled, only runs once.

The return value is available for use in later phases:

say "About to print 3 things";
for ^3 {
    say ^10 .pick ~ '-' ~ BEGIN { say  "Generating BEGIN value"; ^10 .pick }
}
# OUTPUT:
# Generating BEGIN value
# About to print 3 things
# 3-3
# 4-3
# 6-3

The ^10 .pick in the phaser is generated only once and is then re-used by the loop during runtime. Note how the say in the BEGIN block is executed before the say that is above the loop.

CHECK

Runs at compile time, as late as possible, only runs once.

Can have a return value that is provided even in later phases.

Code that is generated at runtime can still fire off CHECK and INIT phasers, though of course those phasers can't do things that would require travel back in time. You need a wormhole for that.

INIT

Runs after compilation during main execution, as soon as possible, only runs once. It can have a return value that is provided even in later phases.

When phasers are in different modules, the INIT and END phasers are treated as if declared at use time in the using module. (It is erroneous to depend on this order if the module is used more than once, however, since the phasers are only installed the first time they're noticed.)

Code that is generated at runtime can still fire off CHECK and INIT phasers, though of course those phasers can't do things that would require travel back in time. You need a wormhole for that.

An INIT only runs once for all copies of a cloned closure.

END

Runs after compilation during main execution, as late as possible, only runs once.

When phasers are in different modules, the INIT and END phasers are treated as if declared at use time in the using module. (It is erroneous to depend on this order if the module is used more than once, however, since the phasers are only installed the first time they're noticed.)

Block phasers

Execution in the context of a block has its own phases.

Block-leaving phasers wait until the call stack is actually unwound to run. Unwinding happens only after some exception handler decides to handle the exception that way. That is, just because an exception is thrown past a stack frame does not mean we have officially left the block yet, since the exception might be resumable. In any case, exception handlers are specified to run within the dynamic scope of the failing code, whether or not the exception is resumable. The stack is unwound and the phasers are called only if an exception is not resumed.

These can occur multiple times within the block. So they aren't really traits, exactly--they add themselves onto a list stored in the actual trait. If you examine the ENTER trait of a block, you'll find that it's really a list of phasers rather than a single phaser.

All of these phaser blocks can see any previously declared lexical variables, even if those variables have not been elaborated yet when the closure is invoked (in which case the variables evaluate to an undefined value.)

ENTER

Runs at every block entry time, repeats on loop blocks.

Can have a return value that is provided even in later phases.

An exception thrown from an ENTER phaser will abort the ENTER queue, but one thrown from a LEAVE phaser will not.

LEAVE

Runs at every block exit time (even stack unwinds from exceptions), except when the program exits abruptly (e.g. with exit).

LEAVE phasers for a given block are necessarily evaluated after any CATCH and CONTROL phasers. This includes the LEAVE variants, KEEP and UNDO. POST phasers are evaluated after everything else, to guarantee that even LEAVE phasers can't violate postconditions.

An exception thrown from an ENTER phaser will abort the ENTER queue, but one thrown from a LEAVE phaser will not.

If a POST fails or any kind of LEAVE block throws an exception while the stack is unwinding, the unwinding continues and collects exceptions to be handled. When the unwinding is completed all new exceptions are thrown from that point.

sub answer() {
    LEAVE say „I say after the return value.“;

    42 # this is the return value
}

Note: be mindful of LEAVE phasers directly in blocks of routines, as they will get executed even when an attempt to call the routine with wrong arguments is made:

sub foo (Int) {
    say "Hello!";
    LEAVE say "oh noes!"
}
try foo rand; # OUTPUT: «oh noes!␤»

Although the subroutine's body did not get run, because the sub expects an Int and rand returned a Num, its block was entered and left (when param binding failed), and so the LEAVE phaser was run.

KEEP

Runs at every successful block exit, as part of the LEAVE queue (shares the same order of execution).

UNDO

Runs at every unsuccessful block exit, as part of the LEAVE queue (shares the same order of execution).

PRE

Asserts a precondition at every block entry. Runs before the ENTER phase.

PRE phasers fire off before any ENTER or FIRST.

The exceptions thrown by failing PRE and POST phasers cannot be caught by a CATCH in the same block, which implies that POST phaser are not run if a PRE phaser fails.

POST

Asserts a postcondition at every block entry. Runs after the LEAVE phase.

For phasers such as KEEP and POST that are run when exiting a scope normally, the return value (if any) from that scope is available as the current topic within the phaser.

The POST block can be defined in one of two ways. Either the corresponding POST is defined as a separate phaser, in which case PRE and POST share no lexical scope. Alternately, any PRE phaser may define its corresponding POST as an embedded phaser block that closes over the lexical scope of the PRE.

If a POST fails or any kind of LEAVE block throws an exception while the stack is unwinding, the unwinding continues and collects exceptions to be handled. When the unwinding is completed all new exceptions are thrown from that point.

The exceptions thrown by failing PRE and POST phasers cannot be caught by a CATCH in the same block, which implies that POST phaser are not run if a PRE phaser fails.

Loop phasers

FIRST, NEXT, and LAST are meaningful only within the lexical scope of a loop, and may occur only at the top level of such a loop block.

FIRST

Runs at loop initialization, before ENTER.

NEXT

Runs when loop is continued (either through next or because you got to the bottom of the loop and are looping back around), before LEAVE.

A NEXT executes only if the end of the loop block is reached normally, or an explicit next is executed. In distinction to LEAVE phasers, a NEXT phaser is not executed if the loop block is exited via any exception other than the control exception thrown by next. In particular, a last bypasses evaluation of NEXT phasers.

LAST

Runs when a loop is finished because the condition is met, or when it exits using last or return; it is executed after LEAVE.

Exception handling phasers

CATCH

Runs when an exception is raised by the current block, before the LEAVE phase.

CONTROL

Runs when a control exception is raised by the current block, before the LEAVE phase. It is raised by return, fail, redo, next, last, done, emit, take, warn, proceed and succeed.

say elems gather {
    CONTROL {
        when CX::Warn { say "WARNING!!! $_"; .resume }
        when CX::Take { say "Don't take my stuff"; .resume }
        when CX::Done { say "Done"; .resume }
    }
    warn 'people take stuff here';
    take 'keys';
    done;
}
# OUTPUT:
# WARNING!!! people take stuff here
# Don't take my stuff
# Done
# 0

Object phasers

COMPOSE (Not yet implemented)

Runs when a role is composed into a class.

Asynchronous phasers

LAST

Runs when a Supply finishes with a call to done or when a supply block exits normally. It runs completely after the whenever block it is placed within finishes.

This phaser reuses the name LAST, but works differently from the LAST loop phaser. This phaser is similar to setting the done routine while tapping a supply with tap.

QUIT

Runs when a Supply terminates early with an exception. It runs after the whenever block it is placed within finishes.

This phaser is similar to setting the quit routine while tapping a Supply with tap.

CLOSE

Appears in a supply block. Called when the supply is closed.

DOC phasers

DOC

The phasers BEGIN, CHECK and INIT are run only in documentation mode when prefixed with the DOC keyword. The compiler is in documentation when run with --doc.

DOC INIT { say 'init'  }  # prints 'init' at initialization time when in documentation mode.

64 Pragmas

Special modules that define certain aspects of the behavior of the code

In Perl 6, pragmas are directive used to either identify a specific version of Perl 6 to be used or to modify the compiler's normal behavior in some way. The use keyword enables a pragma (similar to how you can use a module). To disable a pragma, use the no keyword:

use v6.c;   # use 6.c language version 
 no worries; # don't issue compile time warnings 

Following is a list of pragmas with a short description of each pragma's purpose or a link to more details about its use. (Note: Pragmas marked "[NYI]" are not yet implemented, and those marked "[TBD]" are to be defined later.)

v6.x

This pragma states the version of the compiler that is going to be used, and turns on its features if they are optional.

use v6;   # Load latest supported version (non-PREVIEW). 
           # Also, useful for producing better errors when accidentally 
           # executing the program with `perl` instead of `perl6` 
use v6.c;         # Use the "Christmas" version of Perl 6 
use v6.d;         # Use the "Diwali" version of Perl 6 

From 2018.11, which implemented 6.d, this pragma does not do anything.

use v6.d.PREVIEW; # On 6.d-capable compilers, enables 6.d features, 
                   # otherwise enables the available experimental 
                   # preview features for 6.d language 

Since these pragmas turn on the compiler version, they should be the first statement in the file (preceding comments and Pod are fine).

MONKEY-GUTS

This pragma is not currently part of any Perl 6 specification, but is present in Rakudo as a synonym to use nqp (see below).

MONKEY-SEE-NO-EVAL

EVAL

MONKEY-TYPING

augment

MONKEY

use MONKEY;

Turns on all available MONKEY pragmas, currently the three above; thus, it would be equivalent to

use MONKEY-TYPING;
use MONKEY-SEE-NO-EVAL;
use MONKEY-GUTS;

dynamic-scope, pragma

dynamic-scope

Applies the is dynamic trait to variables in the pragma's lexical scope. The effect can be restricted to a subset of variables by listing their names as arguments. By default applies to all variables.

# Apply  is dynamic  only to $x, but not to $y 
 use dynamic-scope <$x>; 
 
 sub poke { 
     say $CALLER::x; 
     say $CALLER::y; 
 } 
 
 my $x = 23; 
 my $y = 34; 
 poke; 
 
 # OUTPUT: 
 # 23 
 # Cannot access '$y' through CALLER, because it is not declared as dynamic 

This pragma is not currently part of any Perl 6 specification and was added in Rakudo 2019.03.

experimental

Allows use of experimental features

fatal

A lexical pragma that makes Failures returned from routines fatal. For example, prefix + on a Str coerces it to Numeric, but will return a Failure if the string contains non-numeric characters. Saving that Failure in a variable prevents it from being sunk, and so the first code block below reaches the say $x.^name; line and prints Failure in output.

In the second block, the use fatal pragma is enabled, so the say line is never reached because the Exception contained in the Failure returned from prefix + gets thrown and the CATCH block gets run, printing the Caught... line. Note that both blocks are the same program and use fatal only affects the lexical block it was used in:

{
    my $x = +"a";
    say $x.^name;
    CATCH { default { say "Caught {.^name}" } }
} # OUTPUT: «Failure␤»

{
    use fatal;
    my $x = +"a";
    say $x.^name;
    CATCH { default { say "Caught {.^name}" } }
} # OUTPUT: «Caught X::Str::Numeric␤»

Inside try blocks, the fatal pragma is enabled by default, and you can disable it with no fatal:

try {
    my $x = +"a";
    say $x.^name;
    CATCH { default { say "Caught {.^name}" } }
} # OUTPUT: «Caught X::Str::Numeric␤»

try {
    no fatal;
    my $x = +"a";
    say $x.^name;
    CATCH { default { say "Caught {.^name}" } }
} # OUTPUT: «Failure␤»

internals

[NYI]

invocant

[NYI]

isms

[2018.09 and later]

Allow for some other language constructs that were deemed to be a trap that warranted a warning and/or an error in normal Perl 6 programming. Currently, Perl5 and C++ are allowed.

sub abs() { say "foo" } 
 abs; 
 # Unsupported use of bare "abs"; in Perl 6 please use .abs if you meant 
 # to call it as a method on $_, or use an explicit invocant or argument, 
 # or use &abs to refer to the function as a noun 

In this case, providing an abs sub that doesn't take any arguments, did not make the compilation error go away.

use isms <Perl5>;
sub abs() { say "foo" }
abs;   # foo

With this, the compiler will allow the offending Perl 5 construct, allowing the code to actually be executed.

If you do not specify any language, all known language constructs are allowed.

use isms;   # allow for Perl5 and C++ isms

lib

This pragma adds subdirectories to the library search path so that the interpreter can find the modules.

use lib <lib /opt/lib /usr/local/lib>; 

This will search the directories passed in a list. Please check the modules documentation for more examples.

newline

Set the value of the $?NL constant in the scope it is called. Possible values are :lf (which is the default, indicating Line Feed), :crlf (indicating Carriage Return, Line Feed) and :cr (indicating Carriage Return).

nqp

Use at your own risk.

This is a Rakudo-specific pragma. With it, Rakudo provides access to the nqp opcodes in a top level namespace:

use nqp;
nqp::say("hello world");

This uses the underlying nqp say opcode instead of the Perl 6 routine. This pragma may make your code rely on a particular version of nqp, and since that code is not part of the Perl 6 specification, it's not guaranteed to be stable. You may find a large number of usages in the Rakudo core, which are used to make the core functionality as fast as possible. Future optimizations in the code generation of Rakudo may obsolete these usages.

parameters

[NYI]

precompilation

The default allows precompilation of source code, specifically if used in a module. If for whatever reason you do not want the code (of your module) to be precompiled, you can use no precompilation. This will prevent the entire compilation unit (usually a file) from being precompiled.

soft

Re-dispatching, inlining

strict

strict is the default behavior, and requires that you declare variables before using them. You can relax this restriction with no.

no strict; $x = 42; # OK 

trace

When use trace is activated, any line of code executing will be written to STDERR. You can use no trace to switch off the feature, so this only happens for certain sections of code.

v6

Writing Tests

variables

Defined Variables Pragma

worries

Lexically controls whether compile-time warnings generated by the compiler get shown. Enabled by default.

$ perl6 -e 'say :foo<>.Pair' 
 Potential difficulties: 
   Pair with <> really means an empty list, not null string; use :foo('') to represent the null string, 
     or :foo() to represent the empty list more accurately 
   at -e:1 
   ------> say :foo<>⏏.Pair 
 foo => Nil 
 
 $ perl6 -e 'no worries; say :foo<>.Pair' 
 foo => Nil 

65 Quoting constructs

Writing strings, word lists, and regexes in Perl 6

The Q lang

Strings are usually represented in Perl 6 code using some form of quoting construct. The most minimalistic of these is Q, usable via the shortcut 「…」, or via Q followed by any pair of delimiters surrounding your text. Most of the time, though, the most you'll need is '…' or "…", described in more detail in the following sections.

Literal strings: Q

Q[ A literal string ] 
  More plainly.  
 Q ^ Almost any non-word character can be a delimiter! ^ 
 Q 「「 Delimiters can be repeated/nested if they are adjacent. 」」 

Delimiters can be nested, but in the plain Q form, backslash escapes aren't allowed. In other words, basic Q strings are as literal as possible.

Some delimiters are not allowed immediately after Q, q, or qq. Any characters that are allowed in identifiers are not allowed to be used, since in such a case, the quoting construct together with such characters are interpreted as an identifier. In addition, ( ) is not allowed because that is interpreted as a function call. If you still wish to use those characters as delimiters, separate them from Q, q, or qq with a space. Please note that some natural languages use a left delimiting quote on the right side of a string. Q will not support those as it relies on unicode properties to tell left and right delimiters apart.

Q' this will not work! ' 
 Q( this won't work either! ) 

The examples above will produce an error. However, this will work

Q ( this is fine, because of space after Q ) 
 Q ' and so is this ' 
 Q<Make sure you  < match >  opening and closing delimiters> 
 Q{This is still a closing curly brace →  \ } 

These examples produce:

this is fine, because of space after Q 
 and so is this 
 Make sure you <match> opening and closing delimiters 
 This is still a closing curly brace → \ 

The behavior of quoting constructs can be modified with adverbs, as explained in detail in later sections.

Short Long Meaning
:x :exec Execute as command and return results
:w :words Split result on words (no quote protection)
:ww :quotewords Split result on words (with quote protection)
:q :single Interpolate \\, \qq[...] and escaping the delimiter with \
:qq :double Interpolate with :s, :a, :h, :f, :c, :b
:s :scalar Interpolate $ vars
:a :array Interpolate @ vars
:h :hash Interpolate % vars
:f :function Interpolate & calls
:c :closure Interpolate {...} expressions
:b :backslash Enable backslash escapes (\n, \qq, \$foo, etc)
:to :heredoc Parse result as heredoc terminator
:v :val Convert to allomorph if possible

Escaping: q

'Very plain'; 
 q[This back\slash stays]; 
 q[This back\\slash stays]; # Identical output 
 q{This is not a closing curly brace → \}, but this is → }; 
 Q :q $There are no backslashes here, only lots of \$\$\$>!$; 
 '(Just kidding. There\'s no money in that string)'; 
 'No $interpolation {here}!'; 
 Q:q!Just a literal "\n" here!; 

The q form allows for escaping characters that would otherwise end the string using a backslash. The backslash itself can be escaped, too, as in the third example above. The usual form is '…' or q followed by a delimiter, but it's also available as an adverb on Q, as in the fifth and last example above.

These examples produce:

Very plain 
 This back\slash stays 
 This back\slash stays 
 This is not a closing curly brace → } but this is → 
 There are no backslashes here, only lots of $$$! 
 (Just kidding. There's no money in that string) 
 No $interpolation {here}! 
 Just a literal "\n" here 

The \qq[...] escape sequence enables qq interpolation for a portion of the string. Using this escape sequence is handy when you have HTML markup in your strings, to avoid interpretation of angle brackets as hash keys:

my $var = 'foo';
say '<code>$var</code> is <var>\qq[$var.uc()]</var>';
# OUTPUT: «<code>$var</code> is <var>FOO</var>␤»

Interpolation: qq

my $color = 'blue'; 
 say   " My favorite color is  $color ! " 
My favorite color is blue! 

The qq form – usually written using double quotes – allows for interpolation of backslash sequences and variables, i.e., variables can be written within the string so that the content of the variable is inserted into the string. It is also possible to escape variables within a qq-quoted string:

say  " The  \ $color variable contains the value '$color' " ; 
The $color variable contains the value 'blue' 

Another feature of qq is the ability to interpolate Perl 6 code from within the string, using curly braces:

my ($x, $y, $z) = 4, 3.5, 3; 
 say "This room is  $x  m by  $y  m by  $z  m."; 
 say "Therefore its volume should be  { $x * $y * $z }  m³!"; 
This room is 4 m by 3.5 m by 3 m. 
 Therefore its volume should be 42 m³! 

By default, only variables with the $ sigil are interpolated normally. This way, when you write "documentation@perl6.org", you aren't interpolating the @perl6 variable. If that's what you want to do, append a [] to the variable name:

my @neighbors = "Felix", "Danielle", "Lucinda"; 
 say "@neighbors []  and I try our best to coexist peacefully." 
Felix Danielle Lucinda and I try our best to coexist peacefully. 

Often a method call is more appropriate. These are allowed within qq quotes as long as they have parentheses after the call. Thus the following code will work:

say "@neighbors . join (', ')  and I try our best to coexist peacefully." 
Felix, Danielle, Lucinda and I try our best to coexist peacefully. 

However, "@example.com" produces @example.com.

To call a subroutine, use the &-sigil.

say "abc&uc("def")ghi";
# OUTPUT: «abcDEFghi␤»

Postcircumfix operators and therefore subscripts are interpolated as well.

my %h = :1st; say "abc%h<st>ghi";
# OUTPUT: «abc1ghi␤»

To enter unicode sequences, use \x or \x[] with the hex-code of the character or a list of characters.

my $s = "I \x2665 Perl 6!";
say $s;
# OUTPUT: «I ♥ Perl 6!␤»

$s = "I really \x[2661,2665,2764,1f495] Perl 6!";
say $s;
# OUTPUT: «I really ♡♥❤💕 Perl 6!␤»

You can also use unicode names , named sequences and name aliases with \c[].

my $s = "Camelia \c[BROKEN HEART] my \c[HEAVY BLACK HEART]!";
say $s;
# OUTPUT: «Camelia 💔 my ❤!␤»

Interpolation of undefined values will raise a control exception that can be caught in the current block with CONTROL.

sub niler {Nil}; 
 my Str $a = niler; 
 say("$a.html", "sometext"); 
 say "alive"; # this line is dead code 
 CONTROL { .die }; 

Word quoting: qw

qw| ! @ # $ % ^ & * \| < >  |  eqv '! @ # $ % ^ & * | < >'.words.list; 
 q:w {  [ ] \{ \}  }  eqv ('[', ']', '{', '}'); 
 Q:w |  [ ] { }  |  eqv ('[', ']', '{', '}'); 

The :w form, usually written as qw, splits the string into "words". In this context, words are defined as sequences of non-whitespace characters separated by whitespace. The q:w and qw forms inherit the interpolation and escape semantics of the q and single quote string delimiters, whereas Qw and Q:w inherit the non-escaping semantics of the Q quoter.

This form is used in preference to using many quotation marks and commas for lists of strings. For example, where you could write:

my @directions = 'left', 'right,', 'up', 'down';

It's easier to write and to read this:

my @directions = qw|left right up down|;

Word quoting: < >

say  < a b c >   eqv  ('a', 'b', 'c');   # OUTPUT: «True␤» 
 say  < a b 42 >   eqv  ('a', 'b', '42'); # OUTPUT: «False␤», the 42 became an IntStr allomorph 
 say < 42 > ~~ Int; # OUTPUT: «True␤» 
 say < 42 > ~~ Str; # OUTPUT: «True␤» 

The angle brackets quoting is like qw, but with extra feature that lets you construct allomorphs or literals of certain numbers:

say <42 4/2 1e6 1+1i abc>.perl;
# OUTPUT: «(IntStr.new(42, "42"), RatStr.new(2.0, "4/2"), NumStr.new(1000000e0, "1e6"), ComplexStr.new(<1+1i>, "1+1i"), "abc")␤»

To construct a Rat or Complex literal, use angle brackets around the number, without any extra spaces:

say <42/10>.^name;   # OUTPUT: «Rat␤»
say <1+42i>.^name;   # OUTPUT: «Complex␤»
say < 42/10 >.^name; # OUTPUT: «RatStr␤»
say < 1+42i >.^name; # OUTPUT: «ComplexStr␤»

Compared to 42/10 and 1+42i, there's no division (or addition) operation involved. This is useful for literals in routine signatures, for example:

sub close-enough-π (<355/113>) { 
     say "Your π is close enough!" 
 } 
 close-enough-π 710/226; # OUTPUT: «Your π is close enough!␤» 
# WRONG: can't do this, since it's a division operation 
 sub compilation-failure (355/113) {} 

Word quoting with quote protection: qww

The qw form of word quoting will treat quote characters literally, leaving them in the resulting words:

say qw{"a b" c}.perl; # OUTPUT: «("\"a", "b\"", "c")␤»

Thus, if you wish to preserve quoted sub-strings as single items in the resulting words you need to use the qww variant:

say qww{"a b" c}.perl; # OUTPUT: «("a b", "c")␤»

Word quoting with interpolation: qqw

The qw form of word quoting doesn't interpolate variables:

my $a = 42; say qw{$a b c};  # OUTPUT: «$a b c␤»

Thus, if you wish for variables to be interpolated within the quoted string, you need to use the qqw variant:

my $a = 42;
my @list = qqw{$a b c};
say @list;                # OUTPUT: «[42 b c]␤»

Note that variable interpolation happens before word splitting:

my $a = "a b";
my @list = qqw{$a c};
.say for @list; # OUTPUT: «a␤b␤c␤»

Word quoting with interpolation and quote protection: qqww

The qqw form of word quoting will treat quote characters literally, leaving them in the resulting words:

my $a = 42; say qqw{"$a b" c}.perl;  # OUTPUT: «("\"42", "b\"", "c")␤»

Thus, if you wish to preserve quoted sub-strings as single items in the resulting words you need to use the qqww variant:

my $a = 42; say qqww{"$a b" c}.perl; # OUTPUT: «("42 b", "c")␤»

Quote protection happens before interpolation, and interpolation happens before word splitting, so quotes coming from inside interpolated variables are just literal quote characters:

my $a = "1 2";
say qqww{"$a" $a}.perl; # OUTPUT: «("1 2", "1", "2")␤»
my $b = "1 \"2 3\"";
say qqww{"$b" $b}.perl; # OUTPUT: «("1 \"2 3\"", "1", "\"2", "3\"")␤»

Word quoting with interpolation and quote protection: « »

This style of quoting is like qqww, but with the added benefit of constructing allomorphs (making it functionally equivalent to qq:ww:v). The ASCII equivalent to « » are double angle brackets << >>.

# Allomorph Construction
my $a = 42; say «  $a b c    ».perl;  # OUTPUT: «(IntStr.new(42, "42"), "b", "c")␤»
my $a = 42; say << $a b c   >>.perl;  # OUTPUT: «(IntStr.new(42, "42"), "b", "c")␤»

# Quote Protection
my $a = 42; say «  "$a b" c  ».perl;  # OUTPUT: «("42 b", "c")␤»
my $a = 42; say << "$a b" c >>.perl;  # OUTPUT: «("42 b", "c")␤»

Shell quoting: qx

To run a string as an external program, not only is it possible to pass the string to the shell or run functions but one can also perform shell quoting. There are some subtleties to consider, however. qx quotes don't interpolate variables. Thus

my $world = "there";
say qx{echo "hello $world"}

prints simply hello. Nevertheless, if you have declared an environment variable before calling perl6, this will be available within qx, for instance

WORLD="there" perl6 
 > say qx{echo "hello $WORLD"} 

will now print hello there.

The result of calling qx is returned, so this information can be assigned to a variable for later use:

my $output = qx{echo "hello!"};
say $output;    # OUTPUT: «hello!␤»

See also shell, run and Proc::Async for other ways to execute external commands.

Shell quoting with interpolation: qqx

If one wishes to use the content of a Perl 6 variable within an external command, then the qqx shell quoting construct should be used:

my $world = "there";
say qqx{echo "hello $world"};  # OUTPUT: «hello there␤»

Again, the output of the external command can be kept in a variable:

my $word = "cool";
my $option = "-i";
my $file = "/usr/share/dict/words";
my $output = qqx{grep $option $word $file};
# runs the command: grep -i cool /usr/share/dict/words
say $output;      # OUTPUT: «Cooley␤Cooley's␤Coolidge␤Coolidge's␤cool␤...»

See also run and Proc::Async for better ways to execute external commands.

Heredocs: :to

A convenient way to write multi-line string literals are heredocs, which let you choose the delimiter yourself:

say q:to/END/; 
 Here is 
 some multi-line 
 string 
 END 

The contents of the heredoc always begin on the next line, so you can (and should) finish the line.

my $escaped = my-escaping-function(q:to/TERMINATOR/, language => 'html'); 
 Here are the contents of the heredoc. 
 Potentially multiple lines. 
 TERMINATOR 

If the terminator is indented, that amount of indention is removed from the string literals. Therefore this heredoc

say q:to/END/; 
     Here is 
     some multi line 
         string 
     END 

produces this output:

Here is 
 some multi line 
     string 
 
 

Heredocs include the newline from before the terminator.

To allow interpolation of variables use the qq form, but you will then have to escape meta characters {\ as well as $ if it is not the sigil for a defined variable. For example:

my $f = 'db.7.3.8';
my $s = qq:to/END/;
option \{
    file "$f";
};
END
say $s;

would produce:

option { 
     file "db.7.3.8"; 
 }; 

You can begin multiple Heredocs in the same line.

my ($first, $second) = qq:to/END1/, qq:to/END2/; 
   FIRST 
   MULTILINE 
   STRING 
   END1 
    SECOND 
    MULTILINE 
    STRING 
    END2 

Unquoting

Literal strings permit interpolation of embedded quoting constructs by using the escape sequences such as these:

my $animal="quaggas";
say 'These animals look like \qq[$animal]'; # OUTPUT: «These animals look like quaggas␤»
say 'These animals are \qqw[$animal or zebras]'; # OUTPUT: «These animals are quaggas or zebras␤»

In this example, \qq will do double-quoting interpolation, and \qqw word quoting with interpolation. Escaping any other quoting construct as above will act in the same way, allowing interpolation in literal strings.

Regexes

For information about quoting as applied in regexes, see the regular expression documentation.

66 Regexes

Pattern matching against strings

A regular expression is a sequence of characters that defines a certain text pattern, typically one that one wishes to find in some large body of text.

In theoretical computer science and formal language theory, regular expressions are used to describe so-called regular languages. Since their inception in the 1950's, practical implementations of regular expressions, for instance in the text search and replace functions of text editors, have outgrown their strict scientific definition. In acknowledgement of this, and in an attempt to disambiguate, a regular expression in Perl 6 is normally referred to as a regex (from: regular expression), a term that is also in common use in other programming languages.

In Perl 6, regexes are written in a domain-specific language, i.e. a sublanguage or slang. This page describes this language, and explains how regexes can be used to search for text patterns in strings in a process called pattern matching.

Lexical conventions

Fundamentally, Perl 6 regexes are very much like subroutines: both are code objects, and just as you can have anonymous subs and named subs, you can have anonymous and named regexes.

A regex, whether anonymous or named, is represented by a Regex object. Yet, the syntax for constructing anonymous and named Regex objects differs. We will therefore discuss them in turn.

Anonymous regex definition syntax

An anonymous regex may be constructed in one of the following ways:

rx/pattern/;          # an anonymous Regex object; 'rx' stands for 'regex'
/pattern/;            # an anonymous Regex object; shorthand for 'rx/.../'

regex { pattern };    # keyword-declared anonymous regex; this form is
                      # intended for defining named regexes and is discussed
                      # in that context in the next section

The rx/ / form has two advantages over the bare shorthand form / /.

Firstly, it enables the use of delimiters other than the slash, which may be used to improve the readability of the regex definition:

rx{ '/tmp/'.* };      # the use of curly braces as delimiters makes this first
rx/ '/tmp/'.* /;      # definition somewhat easier on the eyes than the second

Although the choice is vast, not every character may be chosen as an alternative regex delimiter:

Secondly, the rx form enables the use of regex adverbs, which may be placed between rx and the opening delimiter to modify the definition of the entire regex:

rx:r:s/pattern/;            # :r (:ratchet) and :s (:sigspace) adverbs, defining
                            # a racheting regex in which whitespace is significant

Although anonymous regexes are not, as such, named, they may effectively be given a name by putting them inside a named variable, after which they can be referenced, both outside of an embedding regex and from within an embedding regex by means of interpolation:

my $regex = / R \w+ /;
say "Zen Buddists like Raku too" ~~ $regex; # OUTPUT: 「Raku」

my $regex = /pottery/;
"Japanese pottery rocks!" ~~ / <$regex> /;  # Interpolation of $regex into /.../
say $/;                                     # OUTPUT: 「pottery」

Named regex definition syntax

A named regex may be constructed using the regex declarator as follows:

regex R { pattern };        # a named Regex object, named 'R'

Unlike with the rx form, you cannot chose your preferred delimiter: curly braces are mandatory. In this regard it should be noted that the definition of a named regex using the regex form is syntactically similar to the definition of a subroutine:

my sub   S { /pattern/ };   # definition of Sub object (returning a Regex)
my regex R {  pattern  };   # definition of Regex object

which emphasizes the fact that a Regex object represents code rather than data:

&S ~~ Code;                 # OUTPUT: True 
 
 &R ~~ Code;                 # OUTPUT: True 
 &R ~~ Method;               # OUTPUT: True (A Regex is really a Method!) 

Also unlike with the rx form for defining an anonymous regex, the definition of a named regex using the regex keyword does not allow for adverbs to be inserted before the opening delimiter. Instead, adverbs that are to modify the entire regex pattern may be included first thing within the curly braces:

regex R { :i pattern };     # :i (:ignorecase), renders pattern case insensitive

Alternatively, by way of shorthand, it is also possible (and recommended) to use the rule and token variants of the regex declarator for defining a Regex when the :ratchet and :sigspace adverbs are of interest:

regex R { :r pattern };     # apply :r (:ratchet) to entire pattern 

and, alternatively

token R { pattern };        # same thing: 'token' implies ':r' 

Or

regex R { :r :s pattern };  # apply :r (:ratchet) and :s (:sigspace) to pattern 

with this alternative:

rule  R { pattern };        # same thing: 'rule' implies ':r:s' 

Named regexes may be used as building blocks for other regexes, as they are methods that may called from within other regexes using the <regex-name> syntax. When they are used this way, they are often referred to as subrules; see for more details on their use here. Grammars are the natural habitat of subrules, but many common predefined character classes are also implemented as named regexes.

Regex readability: whitespace and comments

Whitespace in regexes is ignored unless the :sigspace adverb is used to make whitespace syntactically significant.

In addition to whitespace, comments may be used inside of regexes to improve their comprehensibility just as in code in general. This is true for both single line comments and multi line/embedded comments:

my $regex =  rx/ \d ** 4            #`(match the year YYYY)
                 '-'
                 \d ** 2            # ...the month MM
                 '-'
                 \d ** 2 /;         # ...and the day DD

say '2015-12-25'.match($regex);     # OUTPUT: «「2015-12-25」␤»

Match syntax

There are a variety of ways to match a string against a regex. Irrespective of the syntax chosen, a successful match results in a Match object. In case the match is unsuccessful, the result is Nil. In either case, the result of the match operation is available via the special match variable $/.

The most common ways to match a string against an anonymous regex /pattern/ or against a named regex R include the following:

Literals and metacharacters

A regex describes a pattern to be matched in terms of literals and metacharacters. Alphanumeric characters and the underscore _ constitute the literals: these characters match themselves and nothing else. Other characters act as metacharacters and may, as such, have a special meaning, either by themselves (such as the dot ., which serves as a wildcard) or together with other characters in larger metasyntactic constructs (such as <?before ...>, which defines a lookahead assertion).

In its simplest form a regex comprises only literals:

/Cześć/;           # "Hello" in Polish
/こんばんは/;        # "Good afternoon" in Japanese
/Καλησπέρα/;       # "Good evening" in Greek

If you want a regex to literally match one or more characters that normally act as metacharacters, those characters must either be escaped using a backslash, or be quoted using single or double quotes.

The backslash serves as a switch. It switches a single metacharacter into a literal, and vice versa:

/ \# /;             # matches the hash metacharacter literally
/ \w /;             # turns literal 'w' into a character class (see below)
/Hallelujah\!/;     # matches string 'Hallelujah!' incl. exclamation mark

Even if a metacharacter does not (yet) have a special meaning in Perl 6, escaping (or quoting) it is required to ensure that the regex compiles and matches the character literally. This allows the clear distinction between literals and metacharacters to be maintained. So, for instance, to match a comma this will work:

/ \, /;             # matches a literal comma ','

while this will fail:

/ ,  /;             # !! error: an as-yet meaningless/unrecognized metacharacter 
                     # does not automatically match literally 

While an escaping backslash exerts its effect on the next individual character, both a single metacharacter and a sequence of metacharacters may be turned into literally matching strings by quoting them in single or double quotes:

/ "abc" /;          # quoting literals does not make them more literal
/ "Hallelujah!" /;  # yet, this form is generally preferred over /Hallelujah\!/

/ "two words" /;    # quoting a space renders it significant, so this matches
                    # the string 'two words' including the intermediate space

/ '#!:@' /;         # this regex matches the string of metacharacters '#!:@'

Quoting does not simply turn every metacharacter into a literal, however. This is because quotes allow for backslash-escapes and interpolation. Specifically: in single quotes, the backslash may be used to escape single quotes and the backslash itself; double quotes additionally enable the interpolation of variables, and of code blocks of the form {...}. Hence all of this works:

/ '\\\'' /;          # matches a backslash followed by a single quote: \'

my $x = 'Hi';
/ "$x there!" /;     # matches the string 'Hi there!'

/ "1 + 1 = {1+1}" /; # matches the string '1 + 1 = 2'

while these examples illustrate mistakes that you will want to avoid:

/ '\' /;             # !! error: this is NOT the way to literally match a 
                      # backslash because now it escapes the second quote 
 
 /"Price tag $0.50"/; # !! error: "$0" is interpreted as the first positional 
                      # capture (which is Nil), not as '$0' 

Strings are searched left to right, so it is enough if only part of the string matches the regex:

if 'Life, the Universe and Everything' ~~ / and / {
    say ~$/;            # OUTPUT: «and␤»
    say $/.prematch;    # OUTPUT: «Life, the Universe ␤»
    say $/.postmatch;   # OUTPUT: « Everything␤»
    say $/.from;        # OUTPUT: «19␤»
    say $/.to;          # OUTPUT: «22␤»
};

Match results are always stored in the $/ variable and are also returned from the match. They are both of type Match if the match was successful; otherwise both are of type Nil.

Wildcards

An unescaped dot . in a regex matches any single character.

So, these all match:

'perl' ~~ /per./;       # matches the whole string
'perl' ~~ / per . /;    # the same; whitespace is ignored
'perl' ~~ / pe.l /;     # the . matches the r
'speller' ~~ / pe.l/;   # the . matches the first l

while this doesn't match:

'perl' ~~ /. per /;

because there's no character to match before per in the target string.

Notably . also matches a logical newline \n:

my $text = qq:to/END/
  Although I am a
  multi-line text,
  I can be matched
  with /.*/.
  END
  ;

say $text ~~ / .* /;
# OUTPUT «「Although I am a␤multi-line text,␤I can be matched␤with /.*/.␤」»

Character classes

Backslashed character classes

There are predefined character classes of the form \w. Its negation is written with an upper-case letter, \W.

\n and \N

\n matches a logical newline. \N matches a single character that's not a logical newline.

The definition of what constitutes a logical newline follows the Unicode definition of a line boundary and includes in particular all of: a line feed (LF) \U+000A, a vertical tab (VT) \U+000B, a form feed (FF) \U+000C, a carriage return (CR) \U+000D, and the Microsoft Windows style newline sequence CRLF.

The interpretation of \n in regexes is independent of the value of the variable $?NL controlled by the newline pragma.

\t and \T

\t matches a single tab/tabulation character, U+0009. \T matches a single character that is not a tab.

Note that exotic tabs like the U+000B VERTICAL TABULATION character are not included here.

\h and \H

\h matches a single horizontal whitespace character. \H matches a single character that is not a horizontal whitespace character.

Examples of horizontal whitespace characters are

U+0020 SPACE 
 U+00A0 NO-BREAK SPACE 
 U+0009 CHARACTER TABULATION 
 U+2001 EM QUAD 

Vertical whitespace such as newline characters are explicitly excluded; those can be matched with \v; \s matches any kind of whitespace.

\v and \V

\v matches a single vertical whitespace character. \V matches a single character that is not vertical whitespace.

Examples of vertical whitespace characters:

U+000A LINE FEED 
 U+000B VERTICAL TABULATION 
 U+000C FORM FEED 
 U+000D CARRIAGE RETURN 
 U+0085 NEXT LINE 
 U+2028 LINE SEPARATOR 
 U+2029 PARAGRAPH SEPARATOR 

Use \s to match any kind of whitespace, not just vertical whitespace.

\s and \S

\s matches a single whitespace character. \S matches a single character that is not whitespace.

say $/.prematch if 'Match the first word.' ~~ / \s+ /;
# OUTPUT: «Match␤»

\d and \D

\d matches a single digit (Unicode property N) and \D matches a single character that is not a digit.

'ab42' ~~ /\d/ and say ~$/;     # OUTPUT: «4␤»
'ab42' ~~ /\D/ and say ~$/;     # OUTPUT: «a␤»

Note that not only the Arabic digits (commonly used in the Latin alphabet) match \d, but also digits from other scripts.

Examples of digits are:

U+0035 5 DIGIT FIVE 
 U+0BEB ௫ TAMIL DIGIT FIVE 
 U+0E53 ๓ THAI DIGIT THREE 
 U+17E5 ៥ KHMER DIGIT FIVE 

\w and \W

\w matches a single word character, i.e. a letter (Unicode category L), a digit or an underscore. \W matches a single character that is not a word character.

Examples of word characters:

0041 A LATIN CAPITAL LETTER A 
 0031 1 DIGIT ONE 
 03B4 δ GREEK SMALL LETTER DELTA 
 03F3 ϳ GREEK LETTER YOT 
 0409 Љ CYRILLIC CAPITAL LETTER LJE 

Predefined character classes

Class Shorthand Description
<alpha> Alphabetic characters plus underscore (_)
<digit> \d Decimal digits
<xdigit> Hexadecimal digit [0-9A-Fa-f]
<alnum> \w <alpha> plus <digit>
<punct> Punctuation and Symbols (only Punct beyond ASCII)
<graph> <alnum> plus <punct>
<space> \s Whitespace
<cntrl> Control characters
<print> <graph> plus <space>, but no <cntrl>
<blank> \h Horizontal whitespace
<lower> <:Ll> Lowercase characters
<upper> <:Lu> Uppercase characters
<same> Matches between two identical characters
<wb> Word boundary
<ws> Whitespace. This is actually a default rule.
<ww> Within word
<ident> Identifier. Also a default rule.

The predefined character classes in the leftmost column are all of the form <name>, a hint to the fact that they are implemented as built-in named regexes. As such they are subject to the usual capturing semantics. This means that if a character class is called with the syntax <name> (i.e. as indicated in the leftmost column), it will not only match, but also capture, installing a correspondingly named 'named capture' in the resulting Match object. In case just a match and no capture is desired, the capture may be suppressed through the use of call syntax that includes a leading dot: <.name>.

Note that the character classes <same>, <wb> and <ww> are so-called zero-width assertions, which do not really match any character.

Unicode properties

The character classes mentioned so far are mostly for convenience; another approach is to use Unicode character properties. These come in the form <:property>, where property can be a short or long Unicode General Category name. These use pair syntax.

To match against a Unicode property you can use either smartmatch or uniprop:

"a".uniprop('Script');                 # OUTPUT: «Latin␤»
"a" ~~ / <:Script<Latin>> /;           # OUTPUT: «「a」␤»
"a".uniprop('Block');                  # OUTPUT: «Basic Latin␤»
"a" ~~ / <:Block('Basic Latin')> /;    # OUTPUT: «「a」␤»

These are the Unicode general categories used for matching:

Short Long
L Letter
LC Cased_Letter
Lu Uppercase_Letter
Ll Lowercase_Letter
Lt Titlecase_Letter
Lm Modifier_Letter
Lo Other_Letter
M Mark
Mn Nonspacing_Mark
Mc Spacing_Mark
Me Enclosing_Mark
N Number
Nd Decimal_Number or digit
Nl Letter_Number
No Other_Number
P Punctuation or punct
Pc Connector_Punctuation
Pd Dash_Punctuation
Ps Open_Punctuation
Pe Close_Punctuation
Pi Initial_Punctuation
Pf Final_Punctuation
Po Other_Punctuation
S Symbol
Sm Math_Symbol
Sc Currency_Symbol
Sk Modifier_Symbol
So Other_Symbol
Z Separator
Zs Space_Separator
Zl Line_Separator
Zp Paragraph_Separator
C Other
Cc Control or cntrl
Cf Format
Cs Surrogate
Co Private_Use
Cn Unassigned

For example, <:Lu> matches a single, upper-case letter.

Its negation is this: <:!property>. So, <:!Lu> matches a single character that is not an upper-case letter.

Categories can be used together, with an infix operator:

Operator Meaning
+ set union
- set difference

To match either a lower-case letter or a number, write <:Ll+:N> or <:Ll+:Number> or <+ :Lowercase_Letter + :Number>.

It's also possible to group categories and sets of categories with parentheses; for example:

say $0 if 'perl6' ~~ /\w+(<:Ll+:N>)/ # OUTPUT: «「6」␤»

Enumerated character classes and ranges

Sometimes the pre-existing wildcards and character classes are not enough. Fortunately, defining your own is fairly simple. Within <[ ]>, you can put any number of single characters and ranges of characters (expressed with two dots between the end points), with or without whitespace.

"abacabadabacaba" ~~ / <[ a .. c 1 2 3 ]>* /;
# Unicode hex codepoint range
"ÀÁÂÃÄÅÆ" ~~ / <[ \x[00C0] .. \x[00C6] ]>* /;
# Unicode named codepoint range
"αβγ" ~~ /<[\c[GREEK SMALL LETTER ALPHA]..\c[GREEK SMALL LETTER GAMMA]]>*/;

Within the < > you can use + and - to add or remove multiple range definitions and even mix in some of the Unicode categories above. You can also write the backslashed forms for character classes between the [ ].

/ <[\d] - [13579]> /;
# starts with \d and removes odd ASCII digits, but not quite the same as
/ <[02468]> /;
# because the first one also contains "weird" unicodey digits

You can include Unicode properties in the list as well:

/<:Zs + [\x9] - [\xA0]>/
# Any character with "Zs" property, or a tab, but not a "no-break space"

You can use \ to escape characters that would have some meaning in the regular expression:

say "[ hey ]" ~~ /<-[ \] \[ \s ]>+/; # OUTPUT: «「hey」␤»

To negate a character class, put a - after the opening angle bracket:

say 'no quotes' ~~ /  <-[ " ]> + /;  # <-["]> matches any character except "

A common pattern for parsing quote-delimited strings involves negated character classes:

say '"in quotes"' ~~ / '"' <-[ " ]> * '"'/;

This regex first matches a quote, then any characters that aren't quotes, and then a quote again. The meaning of * and + in the examples above are explained in the next section on quantifiers.

Just as you can use the - for both set difference and negation of a single value, you can also explicitly put a + in front:

/ <+[123]> /  # same as <[123]>

Quantifiers

A quantifier makes the preceding atom match a variable number of times. For example, a+ matches one or more a characters.

Quantifiers bind tighter than concatenation, so ab+ matches one a followed by one or more bs. This is different for quotes, so 'ab'+ matches the strings ab, abab, ababab etc.

One or more: +

The + quantifier makes the preceding atom match one or more times, with no upper limit.

For example, to match strings of the form key=value, you can write a regex like this:

/ \w+ '=' \w+ /

Zero or more: *

The * quantifier makes the preceding atom match zero or more times, with no upper limit.

For example, to allow optional whitespace between a and b you can write:

/ a \s* b /

Zero or one: ?

The ? quantifier makes the preceding atom match zero or once.

For example, to match dog or dogs, you can write:

/ dogs? /

General quantifier: ** min..max

To quantify an atom an arbitrary number of times, use the ** quantifier, which takes a single Int or a Range on the right-hand side that specifies the number of times to match. If a Range is specified, the end-points specify the minimum and maximum number of times to match.

say 'abcdefg' ~~ /\w ** 4/;      # OUTPUT: «「abcd」␤» 
 say 'a'       ~~ /\w **  2..5/;  # OUTPUT: «Nil␤» 
 say 'abc'     ~~ /\w **  2..5/;  # OUTPUT: «「abc」␤» 
 say 'abcdefg' ~~ /\w **  2..5/;  # OUTPUT: «「abcde」␤» 
 say 'abcdefg' ~~ /\w ** 2^..^5/; # OUTPUT: «「abcd」␤» 
 say 'abcdefg' ~~ /\w ** ^3/;     # OUTPUT: «「ab」␤» 
 say 'abcdefg' ~~ /\w ** 1..*/;   # OUTPUT: «「abcdefg」␤» 

Only basic literal syntax for the right-hand side of the quantifier is supported, to avoid ambiguities with other regex constructs. If you need to use a more complex expression, for example, a Range made from variables, enclose the Range in curly braces:

my $start = 3; 
 say 'abcdefg' ~~ /\w ** {$start .. $start+2}/; # OUTPUT: «「abcde」␤» 
 say 'abcdefg' ~~ /\w ** {π.Int}/;              # OUTPUT: «「abc」␤» 

Negative values are treated like zero:

say 'abcdefg' ~~ /\w ** {-Inf}/;     # OUTPUT: «「」␤» 
 say 'abcdefg' ~~ /\w ** {-42}/;      # OUTPUT: «「」␤» 
 say 'abcdefg' ~~ /\w ** {-10..-42}/; # OUTPUT: «「」␤» 
 say 'abcdefg' ~~ /\w ** {-42..-10}/; # OUTPUT: «「」␤» 

If then, the resultant value is Inf or NaN or the resultant Range is empty, non-Numeric, contains NaN end-points, or has minimum effective end-point as Inf, the X::Syntax::Regex::QuantifierValue exception will be thrown:

(try say 'abcdefg' ~~ /\w ** {42..10}/  ) 
     orelse say ($!.^name, $!.empty-range); 
     # OUTPUT: «(X::Syntax::Regex::QuantifierValue True)␤» 
 (try say 'abcdefg' ~~ /\w ** {Inf..Inf}/) 
     orelse say ($!.^name, $!.inf); 
     # OUTPUT: «(X::Syntax::Regex::QuantifierValue True)␤» 
 (try say 'abcdefg' ~~ /\w ** {NaN..42}/ ) 
     orelse say ($!.^name, $!.non-numeric-range); 
     # OUTPUT: «(X::Syntax::Regex::QuantifierValue True)␤» 
 (try say 'abcdefg' ~~ /\w ** {"a".."c"}/) 
     orelse say ($!.^name, $!.non-numeric-range); 
     # OUTPUT: «(X::Syntax::Regex::QuantifierValue True)␤» 
 (try say 'abcdefg' ~~ /\w ** {Inf}/) 
     orelse say ($!.^name, $!.inf); 
     # OUTPUT: «(X::Syntax::Regex::QuantifierValue True)␤» 
 (try say 'abcdefg' ~~ /\w ** {NaN}/) 
     orelse say ($!.^name, $!.non-numeric); 
     # OUTPUT: «(X::Syntax::Regex::QuantifierValue True)␤» 

Modified quantifier: % , %%

To more easily match things like comma separated values, you can tack on a % modifier to any of the above quantifiers to specify a separator that must occur between each of the matches. For example, a+ % ',' will match a or a,a or a,a,a, etc. To also match trailing delimiters ( a, or a,a, ), you can use %% instead of %.

The quantifier interacts with % and controls the number of overall repetitions that can match successfully, so a* % ',' also matches the empty string. If you want match words delimited by commas, you might need to nest an ordinary and a modified quantifier:

say so 'abc,def' ~~ / ^ [\w+] ** 1 % ',' $ /;  # Output: «False» 
 say so 'abc,def' ~~ / ^ [\w+] ** 2 % ',' $ /;  # Output: «True» 

Preventing backtracking: :

One way to prevent backtracking is through the use of the ratchet adverb as described below. Another more fine-grained way of preventing backtracking in regexes is attaching a : modifier to a quantifier:

my $str = "ACG GCT ACT An interesting chain"; 
 say $str ~~ /<[ACGT\s]>+ \s+ (<[A..Z a..z \s]>+)/; 
 # OUTPUT: «「ACG GCT ACT An interesting chain」␤ 0 => 「An interesting chain」␤» 
 say $str ~~ /<[ACGT\s]>+: \s+ (<[A..Z a..z \s]>+)/; 
 # OUTPUT: «Nil␤» 

In the second case, the A in An had already been "absorbed" by the pattern, preventing the matching of the second part of the pattern, after \s+. Generally we will want the opposite: prevent backtracking to match precisely what we are looking for.

In most cases, you will want to prevent backtracking for efficiency reasons, for instance here:

say $str ~~ m:g/[(<[ACGT]> **: 3) \s*]+ \s+ (<[A..Z a..z \s]>+)/; 
 # OUTPUT: 
 # (「ACG GCT ACT An interesting chain」 
 # 0 => 「ACG」 
 # 0 => 「GCT」 
 # 0 => 「ACT」 
 # 1 => 「An interesting chain」) 

Although in this case, eliminating the : from behind ** would make it behave exactly in the same way. The best use is to create tokens that will not be backtracked:

$_ = "ACG GCT ACT IDAQT";
say  m:g/[(\w+:) \s*]+ (\w+) $$/;
# OUTPUT:
# (「ACG GCT ACT IDAQT」
# 0 => 「ACG」
# 0 => 「GCT」
# 0 => 「ACT」
# 1 => 「IDAQT」)

Without the : following \w+, the ID part captured would have been simply T, since the pattern would go ahead and match everything, leaving a single letter to match the \w+ expression at the end of the line.

Greedy versus frugal quantifiers: ?

By default, quantifiers request a greedy match:

'abababa' ~~ /a .* a/ && say ~$/;   # OUTPUT: «abababa␤» 

You can attach a ? modifier to the quantifier to enable frugal matching:

'abababa' ~~ /a .*? a/ && say ~$/;   # OUTPUT: «aba␤» 

You can also enable frugal matching for general quantifiers:

say '/foo/o/bar/' ~~ /\/.**?{1..10}\//;  # OUTPUT: «「/foo/」␤»
say '/foo/o/bar/' ~~ /\/.**!{1..10}\//;  # OUTPUT: «「/foo/o/bar/」␤»

Greedy matching can be explicitly requested with the ! modifier.

Alternation: ||

To match one of several possible alternatives, separate them by ||; the first matching alternative wins.

For example, ini files have the following form:

[section] 
 key = value 

Hence, if you parse a single line of an ini file, it can be either a section or a key-value pair and the regex would be (to a first approximation):

/ '[' \w+ ']' || \S+ \s* '=' \s* \S* /

That is, either a word surrounded by square brackets, or a string of non-whitespace characters, followed by zero or more spaces, followed by the equals sign =, followed again by optional whitespace, followed by another string of non-whitespace characters.

An empty string as the first branch is ignored, to allow you to format branches consistently. You could have written the previous example as

/
|| '[' \w+ ']'
|| \S+ \s* '=' \s* \S*
/

Even in non-backtracking contexts, the alternation operator || tries all the branches in order until the first one matches.

Longest alternation: |

In short, in regex branches separated by |, the longest token match wins, independent of the textual ordering in the regex. However, what | really does is more than that. It does not decide which branch wins after finishing the whole match, but follows the longest-token matching (LTM) strategy.

Briefly, what | does is this:

say "abc" ~~ /ab | a.* /;                 # Output: ⌜abc⌟
say "abc" ~~ /ab | a {} .* /;             # Output: ⌜ab⌟
say "if else" ~~ / if | if <.ws> else /;  # Output: 「if」
say "if else" ~~ / if | if \s+   else /;  # Output: 「if else」

As is shown above, a.* is a declarative prefix, while a {} .* terminates at {}, then its declarative prefix is a. Note that non-declarative atoms terminate declarative prefix. This is quite important if you want to apply | in a rule, which automatically enables :s, and <.ws> accidentally terminates declarative prefix.

say "abc" ~~ /a. | ab { print "win" } /;  # Output: win「ab」

When two alternatives match at the same length, the tie is broken by specificity. That is, ab, as an exact match, counts as closer than a., which uses character classes.

say "abc" ~~ /a\w| a. { print "lose" } /; # Output: ⌜ab⌟

If the tie breaker above doesn't work, then the textually earlier alternative takes precedence.

For more details, see the LTM strategy.

Quoted lists are LTM matches

Using a quoted list in a regex is equivalent to specifying the longest-match alternation of the list's elements. So, the following match:

say 'food' ~~ /< f fo foo food >/;      # OUTPUT: «「food」␤»

is equivalent to:

say 'food' ~~ / f | fo | foo | food /;  # OUTPUT: «「food」␤»

Note that the space after the first < is significant here: <food> calls the named rule food while < food > and < food> specify quoted lists with a single element, 'food'.

If the first branch is an empty string, it is ignored. This allows you to format your regexes consistently:

/
| f
| fo
| foo
| food
/

Arrays can also be interpolated into a regex to achieve the same effect:

my @increasingly-edible = <f fo foo food>;
say 'food' ~~ /@increasingly-edible/;   # OUTPUT: «「food」␤»

This is documented further under Regex Interpolation, below.

Conjunction: &&

Matches successfully if all &&-delimited segments match the same substring of the target string. The segments are evaluated left to right.

This can be useful for augmenting an existing regex. For example if you have a regex quoted that matches a quoted string, then / <quoted> && <-[x]>* / matches a quoted string that does not contain the character x.

Note that you cannot easily obtain the same behavior with a lookahead, that is, a regex doesn't consume characters, because a lookahead doesn't stop looking when the quoted string stops matching.

say 'abc' ~~ / <?before a> && . /;    # OUTPUT: «Nil␤» 
 say 'abc' ~~ / <?before a> . && . /;  # OUTPUT: «「a」␤» 
 say 'abc' ~~ / <?before a> . /;       # OUTPUT: «「a」␤» 
 say 'abc' ~~ / <?before a> .. /;      # OUTPUT: «「ab」␤» 

Just like with ||, empty first branches are ignored.

Conjunction: &

Much like && in a regex, it matches successfully if all segments separated by & match the same part of the target string.

& (unlike &&) is considered declarative, and notionally all the segments can be evaluated in parallel, or in any order the compiler chooses.

Just like with || and &, empty first branches are ignored.

Anchors

Regexes search an entire string for matches. Sometimes this is not what you want. Anchors match only at certain positions in the string, thereby anchoring the regex match to that position.

Start of string and end of string

The ^ anchor only matches at the start of the string:

say so 'properly' ~~ /  perl/;    # OUTPUT: «True␤»
say so 'properly' ~~ /^ perl/;    # OUTPUT: «False␤»
say so 'perly'    ~~ /^ perl/;    # OUTPUT: «True␤»
say so 'perl'     ~~ /^ perl/;    # OUTPUT: «True␤»

The $ anchor only matches at the end of the string:

say so 'use perl' ~~ /  perl  /;   # OUTPUT: «True␤»
say so 'use perl' ~~ /  perl $/;   # OUTPUT: «True␤»
say so 'perly'    ~~ /  perl $/;   # OUTPUT: «False␤»

You can combine both anchors:

say so 'use perl' ~~ /^ perl $/;   # OUTPUT: «False␤»
say so 'perl'     ~~ /^ perl $/;   # OUTPUT: «True␤»

Keep in mind that ^ matches the start of a string, not the start of a line. Likewise, $ matches the end of a string, not the end of a line.

The following is a multi-line string:

my $str = chomp q:to/EOS/;
   Keep it secret
   and keep it safe
   EOS

# 'safe' is at the end of the string
say so $str ~~ /safe   $/;   # OUTPUT: «True␤»

# 'secret' is at the end of a line, not the string
say so $str ~~ /secret $/;   # OUTPUT: «False␤»

# 'Keep' is at the start of the string
say so $str ~~ /^Keep   /;   # OUTPUT: «True␤»

# 'and' is at the start of a line -- not the string
say so $str ~~ /^and    /;   # OUTPUT: «False␤»

Start of line and end of line

The ^^ anchor matches at the start of a logical line. That is, either at the start of the string, or after a newline character. However, it does not match at the end of the string, even if it ends with a newline character.

The $$ anchor matches at the end of a logical line. That is, before a newline character, or at the end of the string when the last character is not a newline character.

To understand the following example, it's important to know that the q:to/EOS/...EOS heredoc syntax removes leading indention to the same level as the EOS marker, so that the first, second and last lines have no leading space and the third and fourth lines have two leading spaces each.

my $str = q:to/EOS/;
    There was a young man of Japan
    Whose limericks never would scan.
      When asked why this was,
      He replied "It's because I always try to fit
    as many syllables into the last line as ever I possibly can."
    EOS

# 'There' is at the start of string
say so $str ~~ /^^ There/;        # OUTPUT: «True␤»

# 'limericks' is not at the start of a line
say so $str ~~ /^^ limericks/;    # OUTPUT: «False␤»

# 'as' is at start of the last line
say so $str ~~ /^^ as/;            # OUTPUT: «True␤»

# there are blanks between start of line and the "When"
say so $str ~~ /^^ When/;         # OUTPUT: «False␤»

# 'Japan' is at end of first line
say so $str ~~ / Japan $$/;       # OUTPUT: «True␤»

# there's a . between "scan" and the end of line
say so $str ~~ / scan $$/;        # OUTPUT: «False␤»

# matched at the last line
say so $str ~~ / '."' $$/;        # OUTPUT: «True␤»

Word boundary

To match any word boundary, use <|w> or <?wb>. This is similar to \b in other languages. To match the opposite, any character that is not bounding a word, use <!|w> or <!wb>. This is similar to \B in other languages.

These are both zero-width regex elements.

say "two-words" ~~ / two<|w>\-<|w>words /;    # OUTPUT: «「two-words」␤»
say "twowords" ~~ / two<!|w><!|w>words /;     # OUTPUT: «「twowords」»

Left and right word boundary

<< matches a left word boundary. It matches positions where there is a non-word character at the left, or the start of the string, and a word character to the right.

>> matches a right word boundary. It matches positions where there is a word character at the left and a non-word character at the right, or the end of the string.

These are both zero-width regex elements.

my $str = 'The quick brown fox';
say so ' ' ~~ /\W/;               # OUTPUT: «True␤»
say so $str ~~ /br/;              # OUTPUT: «True␤»
say so $str ~~ /<< br/;           # OUTPUT: «True␤»
say so $str ~~ /br >>/;           # OUTPUT: «False␤»
say so $str ~~ /own/;             # OUTPUT: «True␤»
say so $str ~~ /<< own/;          # OUTPUT: «False␤»
say so $str ~~ /own >>/;          # OUTPUT: «True␤»
say so $str ~~ /<< The/;          # OUTPUT: «True␤»
say so $str ~~ /fox >>/;          # OUTPUT: «True␤»

You can also use the variants « and » :

my $str = 'The quick brown fox';
say so $str ~~ /« own/;          # OUTPUT: «False␤»
say so $str ~~ /own »/;          # OUTPUT: «True␤»

To see the difference between <|w> and «, »:

say "stuff here!!!".subst(:g, />>/, '|');   # OUTPUT: «stuff| here|!!!␤»
say "stuff here!!!".subst(:g, /<</, '|');   # OUTPUT: «|stuff |here!!!␤»
say "stuff here!!!".subst(:g, /<|w>/, '|'); # OUTPUT: «|stuff| |here|!!!␤»

Summary of anchors

Anchors are zero-width regex elements. Hence they do not use up a character of the input string, that is, they do not advance the current position at which the regex engine tries to match. A good mental model is that they match between two characters of an input string, or before the first, or after the last character of an input string.

Anchor Description Examples
^ Start of string "⏏two\nlines"
^^ Start of line "⏏two\n⏏lines"
$ End of string "two\nlines⏏"
$$ End of line "two⏏\nlines⏏"
<< or « Left word boundary "⏏two ⏏words"
>> or » Right word boundary "two⏏ words⏏"
<?wb> Any word boundary "⏏two⏏ ⏏words⏏~!"
<!wb> Not a word boundary "t⏏w⏏o w⏏o⏏r⏏d⏏s~⏏!"
<?ww> Within word "t⏏w⏏o w⏏o⏏r⏏d⏏s~!"
<!ww> Not within word "⏏two⏏ ⏏words⏏~⏏!⏏"

Zero-width assertions

Zero-Width assertions can help you implement your own anchor: it turns another regex into an anchor, making them consume no characters of the input string. There are two variants: lookahead and lookbehind assertions.

Technically, anchors are also zero-width assertions, and they can look both ahead and behind.

Lookaround assertions

Lookaround assertions work both ways. They match, but they don't consume a character.

my regex key {^^ <![#-]> \d+ } 
 say "333" ~~ &key;                  # OUTPUT: «「333」␤» 
 say '333$' ~~ m/ \d+ <?[$]>/;       # OUTPUT: «「333」␤» 
 say '$333' ~~ m/^^ <?[$]> . \d+ /;  # OUTPUT: «「$333」␤» 

They can be positive or negative: ![] is negative, while ?[] is positive; the square brackets will include the characters or backslashed character classes that are going to be matched.

You can use predefined character classes and Unicode properties directly preceded by the semicolon:

say '333' ~~ m/^^ <?alnum> \d+ /;          # OUTPUT: «「333」␤» 
 say '333' ~~ m/^^ <?:Nd> \d+ /;            # OUTPUT: «「333」␤» 
 say '333' ~~ m/^^ <!:L> \d+ /;             # OUTPUT: «「333」␤» 
 say '333' ~~ m/^^ \d+ <!:Script<Tamil>> /; # OUTPUT: «「33」␤» 

In the first two cases, the character class matches, but does not consume, the first digit, which is then consumed by the expression; in the third, the negative lookaround assertion behaves in the same way. In the fourth statement the last digit is matched but not consumed, thus the match includes only the first two digits.

Lookahead assertions

To check that a pattern appears before another pattern, use a lookahead assertion via the before assertion. This has the form:

<?before pattern>

Thus, to search for the string foo which is immediately followed by the string bar, use the following regexp:

/ foo <?before bar> /

For example:

say "foobar" ~~ / foo <?before bar> /;  # OUTPUT: «foo␤»

However, if you want to search for a pattern which is not immediately followed by some pattern, then you need to use a negative lookahead assertion, this has the form:

<!before pattern>

In the following example, all occurrences of foo which is not before bar would match with

say "foobaz" ~~ / foo <!before bar> /;  # OUTPUT: «foo␤»

Lookahead assertions can be used also with other patterns, like characters ranges, interpolated variables, subscripts and so on. In such cases it does suffice to use a ?, or a ! for the negate form. For instance, the following lines all produce the very same result:

say 'abcdefg' ~~ rx{ abc <?before def> };        # OUTPUT: 「abc」
say 'abcdefg' ~~ rx{ abc <?[ d..f ]> };          # OUTPUT: 「abc」
my @ending_letters = <d e f>;
say 'abcdefg' ~~ rx{ abc <?@ending_letters> };   # OUTPUT: 「abc」

A practical use of lookahead assertions is in substitutions, where you only want to substitute regex matches that are in a certain context. For example, you might want to substitute only numbers that are followed by a unit (like kg), but not other numbers:

my @units = <kg m km mm s h>;
$_ = "Please buy 2 packs of sugar, 1 kg each";
s:g[\d+ <?before \s* @units>] = 5 * $/;
say $_;         # OUTPUT: Please buy 2 packs of sugar, 5 kg each

Since the lookahead is not part of the match object, the unit is not substituted.

Lookbehind assertions

To check that a pattern appears after another pattern, use a lookbehind assertion via the after assertion. This has the form:

<?after pattern>

Therefore, to search for the string bar immediately preceded by the string foo, use the following regexp:

/ <?after foo> bar /

For example:

say "foobar" ~~ / <?after foo> bar /;   # OUTPUT: «bar␤»

However, if you want to search for a pattern which is not immediately preceded by some pattern, then you need to use a negative lookbehind assertion, this has the form:

<!after pattern>

Hence all occurrences of bar which do not have foo before them would be matched by

say "fotbar" ~~ / <!after foo> bar /;    # OUTPUT: «bar␤»

These are, as in the case of lookahead, zero-width assertions which do not consume characters, like here:

say "atfoobar" ~~ / (.**3) .**2 <?after foo> bar /;
# OUTPUT: «「atfoobar」␤ 0 => 「atf」␤»

where we capture the first 3 of the 5 characters before bar, but only if bar is preceded by foo. The fact that the assertion is zero-width allows us to use part of the characters in the assertion for capture.

Grouping and capturing

In regular (non-regex) Perl 6, you can use parentheses to group things together, usually to override operator precedence:

say 1 + 4 * 2;     # OUTPUT: «9␤», parsed as 1 + (4 * 2)
say (1 + 4) * 2;   # OUTPUT: «10␤»

The same grouping facility is available in regexes:

/ a || b c /;      # matches 'a' or 'bc'
/ ( a || b ) c /;  # matches 'ac' or 'bc'

The same grouping applies to quantifiers:

/ a b+ /;          # matches an 'a' followed by one or more 'b's
/ (a b)+ /;        # matches one or more sequences of 'ab'
/ (a || b)+ /;     # matches a string of 'a's and 'b's, except empty string

An unquantified capture produces a Match object. When a capture is quantified (except with the ? quantifier) the capture becomes a list of Match objects instead.

Capturing

The round parentheses don't just group, they also capture; that is, they make the string matched within the group available as a variable, and also as an element of the resulting Match object:

my $str =  'number 42';
if $str ~~ /'number ' (\d+) / {
    say "The number is $0";         # OUTPUT: The number is 42
    # or
    say "The number is $/[0]";      # OUTPUT: The number is 42
}

Pairs of parentheses are numbered left to right, starting from zero.

if 'abc' ~~ /(a) b (c)/ {
    say "0: $0; 1: $1";             # OUTPUT: «0: a; 1: c␤»
}

The $0 and $1 etc. syntax is shorthand. These captures are canonically available from the match object $/ by using it as a list, so $0 is actually syntactic sugar for $/[0].

Coercing the match object to a list gives an easy way to programmatically access all elements:

if 'abc' ~~ /(a) b (c)/ {
    say $/.list.join: ', '  # OUTPUT: «a, c␤»
}

Non-capturing grouping

The parentheses in regexes perform a double role: they group the regex elements inside and they capture what is matched by the sub-regex inside.

To get only the grouping behavior, you can use square brackets [ ... ] which, by default, don't capture.

if 'abc' ~~ / [a||b] (c) / {
    say ~$0;                # OUTPUT: «c␤»
}

If you do not need the captures, using non-capturing [ ... ] groups provides the following benefits:

Capture numbers

It is stated above that captures are numbered from left to right. While true in principle, this is also an over simplification.

The following rules are listed for the sake of completeness. When you find yourself using them regularly, it's worth considering named captures (and possibly subrules) instead.

Alternations reset the capture count:

/ (x) (y)  || (a) (.) (.) /
# $0  $1      $0  $1  $2

Example:

if 'abc' ~~ /(x)(y) || (a)(.)(.)/ {
    say ~$1;        # OUTPUT: «b␤»
}

If two (or more) alternations have a different number of captures, the one with the most captures determines the index of the next capture:

if 'abcd' ~~ / a [ b (.) || (x) (y) ] (.) / {
    #                 $0     $0  $1    $2
    say ~$2;            # OUTPUT: «d␤»
}

Captures can be nested, in which case they are numbered per level; level 0 gets to use the capture variables, but it will become a list with the rest of the levels behaving as elements of that list

if 'abc' ~~ / ( a (.) (.) ) / {
    say "Outer: $0";                # OUTPUT: Outer: abc
    say "Inner: $0[0] and $0[1]";   # OUTPUT: Inner: b and c
}

These capture variables are only available outside the regex.

# !!WRONG!! The $0 refers to a capture *inside* the second capture 
 say "11" ~~ /(\d) ($0)/; # OUTPUT: «Nil␤» 

In order to make them available inside the regex, you need to insert a code block behind the match; this code block may be empty if there's nothing meaningful to do:

# CORRECT: $0 is saved into a variable outside the second capture 
 # before it is used inside 
 say "11" ~~ /(\d) {} :my $c = $0; ($c)/; # OUTPUT: «「11」␤ 0 => 「1」␤ 1 => 「1」␤» 
 say "Matched $c"; # OUTPUT: «␤Matched 1␤» 

This code block publishes the capture inside the regex, so that it can be assigned to other variables or used for subsequent matches

say "11" ~~ /(\d) {} $0/; # OUTPUT: «「11」␤ 0 => 「1」␤» 

:my helps scoping the $c variable within the regex and beyond; in this case we can use it in the next sentence to show what has been matched inside the regex. This can be used for debugging inside regular expressions, for instance:

my $paragraph="line\nline2\nline3";
$paragraph ~~ rx| :my $counter = 0; ( \V* { ++$counter } ) *%% \n |;
say "Matched $counter lines"; # OUTPUT: «Matched 3 lines␤»

Since :my blocks are simply declarations, the match variable $/ or numbered matches such as $0 will not be available in them unless they are previously published by inserting the empty block (or any block):

"aba" ~~ / (a) b {} :my $c = $/; /; 
 say $c; # OUTPUT: «「ab」␤ 0 => 「a」␤» 

Any other code block will also reveal the variables and make them available in declarations:

"aba" ~~ / (a) {say "Check so far ", ~$/} b :my $c = ~$0; /; 
 # OUTPUT: «Check so far a␤» 
 say "Capture $c"; # OUTPUT: «Capture a␤» 

The :our, similarly to our in classes, can be used in Grammars to declare variables that can be accessed, via its fully qualified name, from outside the grammar:

grammar HasOur { 
     token TOP { 
         :our $our = 'Þor'; 
         $our \s+ is \s+ mighty 
     } 
 } 
 
 say HasOur.parse('Þor is mighty'); # OUTPUT: «「Þor is mighty」␤» 
 say $HasOur::our;                  # OUTPUT: «Þor␤» 

Once the parsing has been done successfully, we use the FQN name of the $our variable to access its value, that can be none other than Þor.

Named captures

Instead of numbering captures, you can also give them names. The generic, and slightly verbose, way of naming captures is like this:

if 'abc' ~~ / $<myname> = [ \w+ ] / {
    say ~$<myname>      # OUTPUT: «abc␤»
}

The square brackets in the above example, which don't usually capture, will now capture its grouping with the given name.

The access to the named capture, $<myname>, is a shorthand for indexing the match object as a hash, in other words: $/{ 'myname' } or $/<myname>.

We can also use parentheses in the above example, but they will work exactly the same as square brackets. The captured group will only be accessible by its name as a key from the match object and not from its position in the list with $/[0] or $0.

Named captures can also be nested using regular capture group syntax:

if 'abc-abc-abc' ~~ / $<string>=( [ $<part>=[abc] ]* % '-' ) / {
    say ~$<string>;          # OUTPUT: «abc-abc-abc␤»
    say ~$<string><part>;    # OUTPUT: «abc abc abc␤»
    say ~$<string><part>[0]; # OUTPUT: «abc␤»
}

Coercing the match object to a hash gives you easy programmatic access to all named captures:

if 'count=23' ~~ / $<variable>=\w+ '=' $<value>=\w+ / {
    my %h = $/.hash;
    say %h.keys.sort.join: ', ';        # OUTPUT: «value, variable␤»
    say %h.values.sort.join: ', ';      # OUTPUT: «23, count␤»
    for %h.kv -> $k, $v {
        say "Found value '$v' with key '$k'";
        # outputs two lines:
        #   Found value 'count' with key 'variable'
        #   Found value '23' with key 'value'
    }
}

A more convenient way to get named captures is by using named regex as discussed in the Subrules section.

Capture markers: <( )>

A <( token indicates the start of the match's overall capture, while the corresponding )> token indicates its endpoint. The <( is similar to other languages \K to discard any matches found before the \K.

say 'abc' ~~ / a <( b )> c/;            # OUTPUT: «「b」␤»
say 'abc' ~~ / <(a <( b )> c)>/;        # OUTPUT: «「bc」␤»

As in the example above, you can see <( sets the start point and )> sets the endpoint; since they are actually independent of each other, the inner-most start point wins (the one attached to b) and the outer-most end wins (the one attached to c).

Substitution

Regular expressions can also be used to substitute one piece of text for another. You can use this for anything, from correcting a spelling error (e.g., replacing 'Perl Jam' with 'Pearl Jam'), to reformatting an ISO8601 date from yyyy-mm-ddThh:mm:ssZ to mm-dd-yy h:m {AM,PM} and beyond.

Just like the search-and-replace editor's dialog box, the s/ / / operator has two sides, a left and right side. The left side is where your matching expression goes, and the right side is what you want to replace it with.

Lexical conventions

Substitutions are written similarly to matching, but the substitution operator has both an area for the regex to match, and the text to substitute:

s/replace/with/;           # a substitution that is applied to $_ 
 $str ~~ s/replace/with/;   # a substitution applied to a scalar 

The substitution operator allows delimiters other than the slash:

s|replace|with|;
s!replace!with!;
s,replace,with,;

Note that neither the colon : nor balancing delimiters such as {} or () can be substitution delimiters. Colons clash with adverbs such as s:i/Foo/bar/ and the other delimiters are used for other purposes.

If you use balancing curly braces, square brackets, or parentheses, the substitution works like this instead:

s[replace] = 'with';

The right-hand side is now a (not quoted) Perl 6 expression, in which $/ is available as the current match:

$_ = 'some 11 words 21';
s:g[ \d+ ] =  2 * $/;
.say;                    # OUTPUT: «some 22 words 42␤»

Like the m// operator, whitespace is ignored in the regex part of a substitution.

Replacing string literals

The simplest thing to replace is a string literal. The string you want to replace goes on the left-hand side of the substitution operator, and the string you want to replace it with goes on the right-hand side; for example:

$_ = 'The Replacements';
s/Replace/Entrap/;
.say;                    # OUTPUT: «The Entrapments␤»

Alphanumeric characters and the underscore are literal matches, just as in its cousin the m// operator. All other characters must be escaped with a backslash \ or included in quotes:

$_ = 'Space: 1999';
s/Space\:/Party like it's/;
.say                        # OUTPUT: «Party like it's 1999␤»

Note that the matching restrictions only apply to the left-hand side of the substitution expression.

By default, substitutions are only done on the first match:

$_ = 'There can be twly two';
s/tw/on/;                     # replace 'tw' with 'on' once
.say;                         # OUTPUT: «There can be only two␤»

Wildcards and character classes

Anything that can go into the m// operator can go into the left-hand side of the substitution operator, including wildcards and character classes. This is handy when the text you're matching isn't static, such as trying to match a number in the middle of a string:

$_ = "Blake's 9";
s/\d+/7/;         # replace any sequence of digits with '7'
.say;             # OUTPUT: «Blake's 7␤»

Of course, you can use any of the +, * and ? modifiers, and they'll behave just as they would in the m// operator's context.

Capturing groups

Just as in the match operator, capturing groups are allowed on the left-hand side, and the matched contents populate the $0..$n variables and the $/ object:

$_ = '2016-01-23 18:09:00';
s/ (\d+)\-(\d+)\-(\d+) /today/;   # replace YYYY-MM-DD with 'today'
.say;                             # OUTPUT: «today 18:09:00␤»
"$1-$2-$0".say;                   # OUTPUT: «01-23-2016␤»
"$/[1]-$/[2]-$/[0]".say;          # OUTPUT: «01-23-2016␤»

Any of these variables $0, $1, $/ can be used on the right-hand side of the operator as well, so you can manipulate what you've just matched. This way you can separate out the YYYY, MM and DD parts of a date and reformat them into MM-DD-YYYY order:

$_ = '2016-01-23 18:09:00';
s/ (\d+)\-(\d+)\-(\d+) /$1-$2-$0/;    # transform YYYY-MM-DD to MM-DD-YYYY
.say;                                 # OUTPUT: «01-23-2016 18:09:00␤»

Named capture can be used too:

$_ = '2016-01-23 18:09:00';
s/ $<y>=(\d+)\-$<m>=(\d+)\-$<d>=(\d+) /$<m>-$<d>-$<y>/;
.say;                                 # OUTPUT: «01-23-2016 18:09:00␤»

Since the right-hand side is effectively a regular Perl 6 interpolated string, you can reformat the time from HH:MM to h:MM {AM,PM} like so:

$_ = '18:38';
s/(\d+)\:(\d+)/{$0 % 12}\:$1 {$0 < 12 ?? 'AM' !! 'PM'}/;
.say;                                 # OUTPUT: «6:38 PM␤»

Using the modulo % operator above keeps the sample code under 80 characters, but is otherwise the same as $0 < 12 ?? $0 !! $0 - 12 . When combined with the power of the Parser Expression Grammars that really underlies what you're seeing here, you can use "regular expressions" to parse pretty much any text out there.

Common adverbs

The full list of adverbs that you can apply to regular expressions can be found elsewhere in this document (section Adverbs), but the most common are probably :g and :i.

Ordinarily, matches are only made once in a given string, but adding the :g modifier overrides that behavior, so that substitutions are made everywhere possible. Substitutions are non-recursive; for example:

$_ = q{I can say "banana" but I don't know when to stop};
s:g/na/nana,/;    # substitute 'nana,' for 'na'
.say;             # OUTPUT: «I can say "banana,nana," but I don't ...␤»

Here, na was found twice in the original string and each time there was a substitution. The substitution only applied to the original string, though. The resulting string was not impacted.

Ordinarily, matches are case-sensitive. s/foo/bar/ will only match 'foo' and not 'Foo'. If the adverb :i is used, though, matches become case-insensitive.

$_ = 'Fruit';
s/fruit/vegetable/;
.say;                          # OUTPUT: «Fruit␤»

s:i/fruit/vegetable/;
.say;                          # OUTPUT: «vegetable␤»

For more information on what these adverbs are actually doing, refer to the section Adverbs section of this document.

These are just a few of the transformations you can apply with the substitution operator. Some of the simpler uses in the real world include removing personal data from log files, editing MySQL timestamps into PostgreSQL format, changing copyright information in HTML files and sanitizing form fields in a web application.

As an aside, novices to regular expressions often get overwhelmed and think that their regular expression needs to match every piece of data in the line, including what they want to match. Write just enough to match the data you're looking for, no more, no less.

S/// non-destructive substitution

say S/o .+ d/new/ with 'old string';      # OUTPUT: «new string»
S:g/« (.)/$0.uc()/.say for <foo bar ber>; # OUTPUT: «Foo␤Bar␤Ber»

S/// uses the same semantics as the s/// operator, except it leaves the original string intact and returns the resultant string instead of $/ ($/ still being set to the same values as with s///).

Note: since the result is obtained as a return value, using this operator with the ~~ smartmatch operator is a mistake and will issue a warning. To execute the substitution on a variable that isn't the $_ this operator uses, alias it to $_ with given, with, or any other way. Alternatively, use the .subst method.

Tilde for nesting structures

The ~ operator is a helper for matching nested subrules with a specific terminator as the goal. It is designed to be placed between an opening and closing delimiter pair, like so:

/ '(' ~ ')' <expression> /

However, it mostly ignores the left argument, and operates on the next two atoms (which may be quantified). Its operation on those next two atoms is to "twiddle" them so that they are actually matched in reverse order. Hence the expression above, at first blush, is merely shorthand for:

/ '(' <expression> ')' /

But beyond that, when it rewrites the atoms it also inserts the apparatus that will set up the inner expression to recognize the terminator, and to produce an appropriate error message if the inner expression does not terminate on the required closing atom. So it really does pay attention to the left delimiter as well, and it actually rewrites our example to something more like:

$<OPEN> = '(' <SETGOAL: ')'> <expression> [ $GOAL || <FAILGOAL> ] 

FAILGOAL is a special method that can be defined by the user and it will be called on parse failure:

grammar A { token TOP { '[' ~ ']' \w+  };
            method FAILGOAL($goal) {
                die "Cannot find $goal near position {self.pos}"
            }
}

say A.parse: '[good]';  # OUTPUT: «「[good]」␤»
A.parse: '[bad';        # will throw FAILGOAL exception
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::AdHoc: Cannot find ']'  near position 4␤»

Note that you can use this construct to set up expectations for a closing construct even when there's no opening delimiter:

"3)"  ~~ / <?> ~ ')' \d+ /;  # RESULT: «「3)」»
"(3)" ~~ / <?> ~ ')' \d+ /;  # RESULT: «「3)」»

Here <?> successfully matches the null string.

The order of the regex capture is original:

"abc" ~~ /a ~ (c) (b)/;
say $0; # OUTPUT: «「c」␤»
say $1; # OUTPUT: «「b」␤»

Subrules

Just like you can put pieces of code into subroutines, you can also put pieces of regex into named rules.

my regex line { \N*\n }
if "abc\ndef" ~~ /<line> def/ {
    say "First line: ", $<line>.chomp;      # OUTPUT: «First line: abc␤»
}

A named regex can be declared with my regex named-regex { body here }, and called with <named-regex>. At the same time, calling a named regex installs a named capture with the same name.

To give the capture a different name from the regex, use the syntax <capture-name=named-regex>. If no capture is desired, a leading dot or ampersand will suppress it: <.named-regex> if it is a method declared in the same class or grammar, <&named-regex> for a regex declared in the same lexical context.

Here's more complete code for parsing ini files:

my regex header { \s* '[' (\w+) ']' \h* \n+ }
my regex identifier  { \w+ }
my regex kvpair { \s* <key=identifier> '=' <value=identifier> \n+ }
my regex section {
    <header>
    <kvpair>*
}

my $contents = q:to/EOI/;
    [passwords]
        jack=password1
        joy=muchmoresecure123
    [quotas]
        jack=123
        joy=42
EOI

my %config;
if $contents ~~ /<section>*/ {
    for $<section>.list -> $section {
        my %section;
        for $section<kvpair>.list -> $p {
            %section{ $p<key> } = ~$p<value>;
        }
        %config{ $section<header>[0] } = %section;
    }
}
say %config.perl;

# OUTPUT: «{:passwords(${:jack("password1"), :joy("muchmoresecure123")}),
#           :quotas(${:jack("123"), :joy("42")})}»

Named regexes can and should be grouped in grammars. A list of predefined subrules is listed in S05-regex of design documents.

Regex interpolation

Instead of using a literal pattern for a regex match, you can use a variable that holds that pattern. This variable can then be 'interpolated' into a regex, such that its appearance in the regex is replaced with the pattern that it holds. The advantage of using interpolation this way, is that the pattern need not be hardcoded in the source of your Perl 6 program, but may instead be variable and generated at runtime.

There are four different ways of interpolating a variable into a regex as a pattern, which may be summarized as follows:

Syntax Description
$variable Interpolates stringified contents of variable literally.
$(code) Runs Perl 6 code inside the regex, and interpolates the stringified return value literally.
<$variable> Interpolates stringified contents of variable as a regex.
<{code}> Runs Perl 6 code inside the regex, and interpolates the stringified return value as a regex.

Let's start with the first two syntactical forms: $variable and $(code). These forms will interpolate the stringified value of the variable or the stringified return value of the code literally, provided that the respective value isn't a Regex object. If the value is a Regex, it will not be stringified, but instead be interpolated as such. 'Literally' means strictly literally, that is: as if the respective stringified value is quoted with a basic Q string Q[...]. Consequently, the stringified value will not itself undergo any further interpolation.

For $variable this means the following:

my $string   = 'Is this a regex or a string: 123\w+False$pattern1 ?';
my $pattern1 = 'string';
my $pattern2 = '\w+';
my $number   = 123;
my $regex    = /\w+/;

say $string.match: / 'string' /;                      #  [1] OUTPUT: 「string」
say $string.match: / $pattern1 /;                     #  [2] OUTPUT: 「string」
say $string.match: / $pattern2 /;                     #  [3] OUTPUT: 「\w+」
say $string.match: / $regex /;                        #  [4] OUTPUT: 「Is」
say $string.match: / $number /;                       #  [5] OUTPUT: 「123」

In this example, the statements [1] and [2] are equivalent and meant to illustrate a plain case of regex interpolation. Since unescaped/unquoted alphabetic characters in a regex match literally, the single quotes in the regex of statement [1] are functionally redundant; they have merely been included to emphasize the correspondence between the first two statements. Statement [3] unambiguously shows that the string pattern held by $pattern2 is interpreted literally, and not as a regex. In case it would have been interpreted as a regex, it would have matched the first word of $string, i.e. 「Is」, as can be seen in statement [4]. Statement [5] shows how the stringified number is used as a match pattern.

This code exemplifies the use of the $(code) syntax:

my $string   = 'Is this a regex or a string: 123\w+False$pattern1 ?';
my $pattern1 = 'string';
my $pattern3 = 'gnirts';
my $pattern4 = '$pattern1';
my $bool     = True;
my sub f1    { return Q[$pattern1] };

say $string.match: / $pattern3.flip /;                #  [6] OUTPUT: Nil
say $string.match: / "$pattern3.flip()" /;            #  [7] OUTPUT: 「string」
say $string.match: / $($pattern3.flip) /;             #  [8] OUTPUT: 「string」
say $string.match: / $([~] $pattern3.comb.reverse) /; #  [9] OUTPUT: 「string」
say $string.match: / $(!$bool) /;                     # [10] OUTPUT: 「False」

say $string.match: / $pattern4 /;                     # [11] OUTPUT: 「$pattern1」
say $string.match: / $(f1) /;                         # [12] OUTPUT: 「$pattern1」

Statement [6] does not work as probably intended. To the human reader, the dot . may seem to represent the method call operator, but since a dot is not a valid character for an ordinary identifier, and given the regex context, the compiler will parse it as the regex wildcard . that matches any character. The apparent ambiguity may be resolved in various ways, for instance through the use of straightforward string interpolation from the regex as in statement [7] (note that the inclusion of the call operator () is key here), or by using the second syntax form from the above table as in statement [8], in which case the match pattern string first emerges as the return value of the flip method call. Since general Perl 6 code may be run from within the parentheses of $( ), the same effect can also be achieved with a bit more effort, like in statement [9]. Statement [10] illustrates how the stringified version of the code's return value (the boolean value False) is matched literally.

Finally, statements [11] and [12] show how the value of $pattern4 and the return value of f1 are not subject to a further round of interpolation. Hence, in general, after possible stringification, $variable and $(code) provide for a strictly literal match of the variable or return value.

Now consider the second two syntactical forms from the table above: <$variable> and <{code}>. These forms will stringify the value of the variable or the return value of the code and interpolate it as a regex. If the respective value is a Regex, it is interpolated as such:

my $string         = 'Is this a regex or a string: 123\w+$x ?';
my $pattern1       = '\w+';
my $number         = 123;
my sub f1          { return /s\w+/ };

say $string.match: / <$pattern1>  /;                  # OUTPUT: 「Is」
say $string.match: / <$number>    /;                  # OUTPUT: 「123」
say $string.match: / <{ f1 }>     /;                  # OUTPUT: 「string」

Importantly, 'to interpolate as a regex' means to interpolate/insert into the target regex without protective quoting. Consequently, if the value of the variable $variable1 is itself of the form $variable2, evaluation of <$variable1> or <{ $variable1 }> inside a target regex /.../ will cause the target regex to assume the form /$variable2/. As described above, the evaluation of this regex will then trigger further interpolation of $variable2:

my $string    = Q[Mindless \w+ $variable1 $variable2];
my $variable1 = Q[\w+];
my $variable2 = Q[$variable1];
my sub f1     { return Q[$variable2] };

# /<{ f1 }>/ ==> /$variable2/ ==> / '$variable1' /
say $string.match: / <{ f1 }>     /; # OUTPUT: 「$variable1」

# /<$variable2>/ ==> /$variable1/ ==> / '\w+' /
say $string.match: /<$variable2>/;   # OUTPUT: 「\w+」

# /<$variable1>/ ==> /\w+/
say $string.match: /<$variable1>/;   # OUTPUT: 「Mindless」

When an array variable is interpolated into a regex, the regex engine handles it like a | alternative of the regex elements (see the documentation on embedded lists, above). The interpolation rules for individual elements are the same as for scalars, so strings and numbers match literally, and Regex objects match as regexes. Just as with ordinary | interpolation, the longest match succeeds:

my @a = '2', 23, rx/a.+/;
say ('b235' ~~ /  b @a /).Str;      # OUTPUT: «b23»

The use of hashes in regexes is reserved.

Regex boolean condition check

The special operator <?{}> allows the evaluation of a boolean expression that can perform a semantic evaluation of the match before the regular expression continues. In other words, it is possible to check in a boolean context a part of a regular expression and therefore invalidate the whole match (or allow it to continue) even if the match succeeds from a syntactic point of view.

In particular the <?{}> operator requires a True value in order to allow the regular expression to match, while its negated form <!{}> requires a False value.

In order to demonstrate the above operator, please consider the following example that involves a simple IPv4 address matching:

my $localhost = '127.0.0.1'; 
 my regex ipv4-octet { \d ** 1..3 <?{ True }> } 
 $localhost ~~ / ^ <ipv4-octet> ** 4 % "." $ /; 
 say $/<ipv4-octet>;   # OUTPUT: [「127」 「0」 「0」 「1」] 

The octet regular expression matches against a number made by one up to three digits. Each match is driven by the result of the <?{}>, that being the fixed value of True means that the regular expression match has to be always considered as good. As a counter-example, using the special constant value False will invalidate the match even if the regular expression matches from a syntactic point of view:

my $localhost = '127.0.0.1'; 
 my regex ipv4-octet { \d ** 1..3 <?{ False }> } 
 $localhost ~~ / ^ <ipv4-octet> ** 4 % "." $ /; 
 say $/<ipv4-octet>;   # OUTPUT: Nil 

From the above examples, it should be clear that it is possible to improve the semantic check, for instance ensuring that each octet is really a valid IPv4 octet:

my $localhost = '127.0.0.1'; 
 my regex ipv4-octet { \d ** 1..3 <?{ $/.Int <= 255 && $/.Int >= 0 }> } 
 $localhost ~~ / ^ <ipv4-octet> ** 4 % "." $ /; 
 say $/<ipv4-octet>;   # OUTPUT: [「127」 「0」 「0」 「1」] 

Please note that it is not required to evaluate the regular expression in-line, but also a regular method can be called to get the boolean value:

my $localhost = '127.0.0.1'; 
 sub check-octet ( Int $o ){ $o <= 255 && $o >= 0 } 
 my regex ipv4-octet { \d ** 1..3 <?{ &check-octet( $/.Int ) }> } 
 $localhost ~~ / ^ <ipv4-octet> ** 4 % "." $ /; 
 say $/<ipv4-octet>;   # OUTPUT: [「127」 「0」 「0」 「1」] 

Of course, being <!{}> the negation form of <?{}> the same boolean evaluation can be rewritten in a negated form:

my $localhost = '127.0.0.1'; 
 sub invalid-octet( Int $o ){ $o < 0 || $o > 255 } 
 my regex ipv4-octet { \d ** 1..3 <!{ &invalid-octet( $/.Int ) }> } 
 $localhost ~~ / ^ <ipv4-octet> ** 4 % "." $ /; 
 say $/<ipv4-octet>;   # OUTPUT: [「127」 「0」 「0」 「1」] 

Adverbs

Adverbs, which modify how regexes work and provide convenient shortcuts for certain kinds of recurring tasks, are combinations of one or more letters preceded by a colon :.

The so-called regex adverbs apply at the point where a regex is defined; additionally, matching adverbs apply at the point that a regex matches against a string and substitution adverbs are applied exclusively in substitutions.

This distinction often blurs, because matching and declaration are often textually close but using the method form of matching, that is, .match, makes the distinction clear.

say "Abra abra CADABRA" ~~ m:exhaustive/:i a \w+ a/;
# OUTPUT: «(「Abra」 「abra」 「ADABRA」 「ADA」 「ABRA」)␤»
my $regex = /:i a \w+ a /;
say "Abra abra CADABRA".match($regex,:ex);
# OUTPUT: «(「Abra」 「abra」 「ADABRA」 「ADA」 「ABRA」)␤»

In the first example, the matching adverb (:exhaustive) is contiguous to the regex adverb (:i), and as a matter of fact, the "definition" and the "matching" go together; however, by using match it becomes clear that :i is only used when defining the $regex variable, and :ex (short for :exhaustive) as an argument when matching. As a matter of fact, matching adverbs cannot even be used in the definition of a regex:

my $regex = rx:ex/:i a \w+ a /; 
 # ===SORRY!=== Error while compiling (...)␤Adverb ex not allowed on rx 

Regex adverbs like :i go into the definition line and matching adverbs like :overlap (which can be abbreviated to :ov) are appended to the match call:

my $regex = /:i . a/;
for 'baA'.match($regex, :overlap) -> $m {
    say ~$m;
}
# OUTPUT: «ba␤aA␤»

Regex adverbs

The adverbs that appear at the time of a regex declaration are part of the actual regex and influence how the Perl 6 compiler translates the regex into binary code.

For example, the :ignorecase (:i) adverb tells the compiler to ignore the distinction between upper case, lower case and title case letters.

So 'a' ~~ /A/ is false, but 'a' ~~ /:i A/ is a successful match.

Regex adverbs can come before or inside a regex declaration and only affect the part of the regex that comes afterwards, lexically. Note that regex adverbs appearing before the regex must appear after something that introduces the regex to the parser, like 'rx' or 'm' or a bare '/'. This is NOT valid:

my $rx1 = :i/a/;      # adverb is before the regex is recognized => exception 

but these are valid:

my $rx1 = rx:i/a/;     # before
my $rx2 = m:i/a/;      # before
my $rx3 = /:i a/;      # inside

These two regexes are equivalent:

my $rx1 = rx:i/a/;      # before
my $rx2 = rx/:i a/;     # inside

Whereas these two are not:

my $rx3 = rx/a :i b/;   # matches only the b case insensitively
my $rx4 = rx/:i a b/;   # matches completely case insensitively

Square brackets and parentheses limit the scope of an adverb:

/ (:i a b) c /;         # matches 'ABc' but not 'ABC'
/ [:i a b] c /;         # matches 'ABc' but not 'ABC'

When two adverbs are used together, they keep their colon at the front

"þor is Þor" ~~ m:g:i/þ/;  # OUTPUT: «(「þ」 「Þ」)␤»

That implies that when there are two vowels together after a :, they correspond to the same adverb, as in :ov or :P5.

Ignoremark

The :ignoremark or :m adverb instructs the regex engine to only compare base characters, and ignore additional marks such as combining accents:

say so 'a' ~~ rx/ä/;                # OUTPUT: «False» 
 say so 'a' ~~ rx:ignoremark /ä/;    # OUTPUT: «True» 
 say so 'ỡ' ~~ rx:ignoremark /o/;    # OUTPUT: «True> 

Ratchet

The :ratchet or :r adverb causes the regex engine to not backtrack (see backtracking). Mnemonic: a ratchet only moves in one direction and can't backtrack.

Without this adverb, parts of a regex will try different ways to match a string in order to make it possible for other parts of the regex to match. For example, in 'abc' ~~ /\w+ ./, the \w+ first eats up the whole string, abc but then the . fails. Thus \w+ gives up a character, matching only ab, and the . can successfully match the string c. This process of giving up characters (or in the case of alternations, trying a different branch) is known as backtracking.

say so 'abc' ~~ / \w+ . /;        # OUTPUT: «True␤»
say so 'abc' ~~ / :r \w+ . /;     # OUTPUT: «False␤»

Ratcheting can be an optimization, because backtracking is costly. But more importantly, it closely corresponds to how humans parse a text. If you have a regex my regex identifier { \w+ } and my regex keyword { if | else | endif }, you intuitively expect the identifier to gobble up a whole word and not have it give up its end to the next rule, if the next rule otherwise fails.

For example, you don't expect the word motif to be parsed as the identifier mot followed by the keyword if. Instead, you expect motif to be parsed as one identifier; and if the parser expects an if afterwards, best that it should fail than have it parse the input in a way you don't expect.

Since ratcheting behavior is often desirable in parsers, there's a shortcut to declaring a ratcheting regex:

my token thing { ... }; 
 # short for 
 my regex thing { :r ... }; 

Sigspace

The :sigspace or :s adverb makes whitespace significant in a regex.

say so "I used Photoshop®"   ~~ m:i/   photo shop /;      # OUTPUT: «True␤» 
 say so "I used a photo shop" ~~ m:i :s / photo shop /;   # OUTPUT: «True␤» 
 say so "I used Photoshop®"   ~~ m:i :s / photo shop /;   # OUTPUT: «False␤» 

m:s/ photo shop / acts the same as m/ photo <.ws> shop <.ws> /. By default, <.ws> makes sure that words are separated, so a b and ^& will match <.ws> in the middle, but ab won't.

Where whitespace in a regex turns into <.ws> depends on what comes before the whitespace. In the above example, whitespace in the beginning of a regex doesn't turn into <.ws>, but whitespace after characters does. In general, the rule is that if a term might match something, whitespace after it will turn into <.ws>.

In addition, if whitespace comes after a term but before a quantifier (+, *, or ?), <.ws> will be matched after every match of the term. So, foo + becomes [ foo <.ws> ]+. On the other hand, whitespace after a quantifier acts as normal significant whitespace; e.g., "foo+ " becomes foo+ <.ws>.

In all, this code:

rx :s { 
     ^^ 
     { 
         say "No sigspace after this"; 
     } 
     <.assertion_and_then_ws> 
     characters_with_ws_after+ 
     ws_separated_characters * 
     [ 
     | some "stuff" .. . 
     | $$ 
     ] 
     :my $foo = "no ws after this"; 
     $foo 
 } 

Becomes:

rx { 
     ^^  <.ws> 
     { 
         say "No space after this"; 
     } 
     <.assertion_and_then_ws>  <.ws> 
     characters_with_ws_after+  <.ws> 
     [ws_separated_characters  <.ws> ]*  <.ws> 
     [ 
     | some  <.ws>  "stuff"  <.ws>  ..  <.ws>  .  <.ws> 
     | $$  <.ws> 
     ]  <.ws> 
     :my $foo = "no ws after this"; 
     $foo  <.ws> 
 } 

If a regex is declared with the rule keyword, both the :sigspace and :ratchet adverbs are implied.

Grammars provide an easy way to override what <.ws> matches:

grammar Demo {
    token ws {
        <!ww>       # only match when not within a word
        \h*         # only match horizontal whitespace
    }
    rule TOP {      # called by Demo.parse;
        a b '.'
    }
}

# doesn't parse, whitespace required between a and b
say so Demo.parse("ab.");                 # OUTPUT: «False␤»
say so Demo.parse("a b.");                # OUTPUT: «True␤»
say so Demo.parse("a\tb .");              # OUTPUT: «True␤»

# \n is vertical whitespace, so no match
say so Demo.parse("a\tb\n.");             # OUTPUT: «False␤»

When parsing file formats where some whitespace (for example, vertical whitespace) is significant, it's advisable to override ws.

Perl 5 compatibility adverb

The :Perl5 or :P5 adverb switch the Regex parsing and matching to the way Perl 5 regexes behave:

so 'hello world' ~~ m:Perl5/^hello (world)/;   # OUTPUT: «True␤»
so 'hello world' ~~ m/^hello (world)/;         # OUTPUT: «False␤»
so 'hello world' ~~ m/^ 'hello ' ('world')/;   # OUTPUT: «True␤»

The regular behavior is recommended and more idiomatic in Perl 6 of course, but the :Perl5 adverb can be useful when compatibility with Perl5 is required.

Matching adverbs

In contrast to regex adverbs, which are tied to the declaration of a regex, matching adverbs only make sense when matching a string against a regex.

They can never appear inside a regex, only on the outside – either as part of an m/.../ match or as arguments to a match method.

Positional adverbs

Positional adverbs make the expression match only the string in the indicated position:

my $data = "f fo foo fooo foooo fooooo foooooo";
say $data ~~ m:nth(4)/fo+/;   # OUTPUT: «「foooo」␤»
say $data ~~ m:1st/fo+/;      # OUTPUT: «「fo」␤»
say $data ~~ m:3rd/fo+/;      # OUTPUT: «「fooo」␤»
say $data ~~ m:nth(1,3)/fo+/; # OUTPUT: «(「fo」 「fooo」)␤»

As you can see, the adverb argument can also be a list. There's actually no difference between the :nth adverb and the rest. You choose them only based on legibility. From 6.d, you can also use Junctions as arguments.

my $data = "f fo foo fooo foooo fooooo foooooo";
say $data ~~ m:st(1|8)/fo+/;  # OUTPUT: «True␤»

In this case, one of them exists (1), so it returns True. Observe that we have used :st. As said above, it's functionally equivalent, although obviously less legible than using :nth, so this last form is advised.

Continue

The :continue or short :c adverb takes an argument. The argument is the position where the regex should start to search. By default, it searches from the start of the string, but :c overrides that. If no position is specified for :c, it will default to 0 unless $/ is set, in which case, it defaults to $/.to.

given 'a1xa2' {
    say ~m/a./;         # OUTPUT: «a1␤»
    say ~m:c(2)/a./;    # OUTPUT: «a2␤»
}

Note: unlike :pos, a match with :continue() will attempt to match further in the string, instead of failing:

say "abcdefg" ~~ m:c(3)/e.+/; # OUTPUT: «「efg」␤»
say "abcdefg" ~~ m:p(3)/e.+/; # OUTPUT: «False␤»

Exhaustive

To find all possible matches of a regex – including overlapping ones – and several ones that start at the same position, use the :exhaustive (short :ex) adverb.

given 'abracadabra' {
    for m:exhaustive/ a .* a / -> $match {
        say ' ' x $match.from, ~$match;
    }
}

The above code produces this output:

    abracadabra 
     abracada 
     abraca 
     abra 
        acadabra 
        acada 
        aca 
          adabra 
          ada 
            abra 

Global

Instead of searching for just one match and returning a Match object, search for every non-overlapping match and return them in a List. In order to do this, use the :global adverb:

given 'several words here' {
    my @matches = m:global/\w+/;
    say @matches.elems;         # OUTPUT: «3␤»
    say ~@matches[2];           # OUTPUT: «here␤»
}

:g is shorthand for :global.

Pos

Anchor the match at a specific position in the string:

given 'abcdef' {
    my $match = m:pos(2)/.*/;
    say $match.from;        # OUTPUT: «2␤»
    say ~$match;            # OUTPUT: «cdef␤»
}

:p is shorthand for :pos.

Note: unlike :continue, a match anchored with :pos() will fail, instead of attempting to match further down the string:

say "abcdefg" ~~ m:c(3)/e.+/; # OUTPUT: «「efg」␤»
say "abcdefg" ~~ m:p(3)/e.+/; # OUTPUT: «False␤»

Overlap

To get several matches, including overlapping matches, but only one (the longest) from each starting position, specify the :overlap (short :ov) adverb:

given 'abracadabra' {
    for m:overlap/ a .* a / -> $match {
        say ' ' x $match.from, ~$match;
    }
}

produces

    abracadabra 
        acadabra 
          adabra 
            abra 

Substitution adverbs

You can apply matching adverbs (such as :global, :pos etc.) to substitutions. In addition, there are adverbs that only make sense for substitutions, because they transfer a property from the matched string to the replacement string.

Samecase

The :samecase or :ii substitution adverb implies the :ignorecase adverb for the regex part of the substitution, and in addition carries the case information to the replacement string:

$_ = 'The cat chases the dog'; 
 s:global:samecase[the] = 'a'; 
 say $_;                 # OUTPUT: «A cat chases a dog» 

Here you can see that the first replacement string a got capitalized, because the first string of the matched string was also a capital letter.

Samemark

The :samemark or :mm adverb implies :ignoremark for the regex, and in addition, copies the markings from the matched characters to the replacement string:

given 'äộñ' { 
     say S:mm/ a .+ /uia/;           # OUTPUT: «üị̂ã» 
 } 

Samespace

The :samespace or :ss substitution modifier implies the :sigspace modifier for the regex, and in addition, copies the whitespace from the matched string to the replacement string:

say S:samespace/a ./c d/.perl given "a b";      # OUTPUT: «"c d"» 
 say S:samespace/a ./c d/.perl given "a\tb";     # OUTPUT: «"c\td"» 
 say S:samespace/a ./c d/.perl given "a\nb";     # OUTPUT: «"c\nd"» 

The ss/.../.../ syntactic form is a shorthand for s:samespace/.../.../.

Backtracking

Perl 6 defaults to backtracking when evaluating regular expressions. Backtracking is a technique that allows the engine to try different matching in order to allow every part of a regular expression to succeed. This is costly, because it requires the engine to usually eat up as much as possible in the first match and then adjust going backwards in order to ensure all regular expression parts have a chance to match.

In order to better understand backtracking, consider the following example:

my $string = 'PostgreSQL is an SQL database!'; 
 say $string ~~ /(.+)(SQL) (.+) $1/; # OUTPUT: 「PostgreSQL is an SQL」 

What happens in the above example is that the string has to be matched against the second occurrence of the word SQL, eating all characters before and leaving out the rest.

Since it is possible to execute a piece of code within a regular expression, it is also possible to inspect the Match object within the regular expression itself:

my $iteration = 0; 
 sub show-captures( Match $m ){ 
     my Str $result_split; 
     say "\n=== Iteration {++$iteration} ==="; 
     for $m.list.kv -> $i, $capture { 
         say "Capture $i = $capture"; 
         $result_split ~= '[' ~ $capture ~ ']'; 
     } 
 
     say $result_split; 
 } 
 
 $string ~~ /(.+)(SQL) (.+) $1 (.+) { show-captures( $/ );  }/; 

The show-captures method will dump all the elements of $/ producing the following output:

=== Iteration 1 === 
 Capture 0 = Postgre 
 Capture 1 = SQL 
 Capture 2 =  is an 
 [Postgre][SQL][ is an ] 

showing that the string has been split around the second occurrence of SQL, that is the repetition of the first capture ($/[1]).

With that in place, it is now possible to see how the engine backtracks to find the above match: it does suffice to move the show-captures in the middle of the regular expression, in particular before the repetition of the first capture $1 to see it in action:

my $iteration = 0; 
 sub show-captures( Match $m ){ 
     my Str $result-split; 
     say "\n=== Iteration {++$iteration} ==="; 
     for $m.list.kv -> $i, $capture { 
         say "Capture $i = $capture"; 
         $result-split ~= '[' ~ $capture ~ ']'; 
     } 
 
     say $result-split; 
 } 
 
 $string ~~ / (.+)(SQL) (.+) { show-captures( $/ );  } $1 /; 

The output will be much more verbose and will show several iterations, with the last one being the winning. The following is an excerpt of the output:

=== Iteration 1 === 
 Capture 0 = PostgreSQL is an 
 Capture 1 = SQL 
 Capture 2 =  database! 
 [PostgreSQL is an ][SQL][ database!] 
 
 === Iteration 2 === 
 Capture 0 = PostgreSQL is an 
 Capture 1 = SQL 
 Capture 2 =  database 
 [PostgreSQL is an ][SQL][ database] 
 
 ... 
 
 === Iteration 24 === 
 Capture 0 = Postgre 
 Capture 1 = SQL 
 Capture 2 =  is an 
 [Postgre][SQL][ is an ] 

In the first iteration the SQL part of PostgreSQL is kept within the word: that is not what the regular expression asks for, so there's the need for another iteration. The second iteration will move back, in particular one character back (removing thus the final !) and try to match again, resulting in a fail since again the SQL is still kept within PostgreSQL. After several iterations, the final result is match.

It is worth noting that the final iteration is number 24, and that such number is exactly the distance, in number of chars, from the end of the string to the first SQL occurrence:

say $string.chars - $string.index: 'SQL'; # OUTPUT: 23 

Since there are 23 chars from the very end of the string to the very first S of SQL the backtracking engine will need 23 "useless" matches to find the right one, that is, it will need 24 steps to get the final result.

Backtracking is a costly machinery, therefore it is possible to disable it in those cases where the matching can be found forward only.

With regards to the above example, disabling backtracking means the regular expression will not have any chance to match:

say $string ~~ /(.+)(SQL) (.+) $1/;      # OUTPUT: 「PostgreSQL is an SQL」 
 say $string ~~ / :r (.+)(SQL) (.+) $1/;  # OUTPUT: Nil 

The fact is that, as shown in the iteration 1 output, the first match of the regular expression engine will be PostgreSQL is an , SQL, database that does not leave out any room for matching another occurrence of the word SQL (as $1 in the regular expression). Since the engine is not able to get backward and change the path to match, the regular expression fails.

It is worth noting that disabling backtracking will not prevent the engine to try several ways to match the regular expression. Consider the following slightly changed example:

my $string = 'PostgreSQL is an SQL database!'; 
 say $string ~~ / (SQL) (.+) $1 /; # OUTPUT: Nil 

Since there is no specification for a character before the word SQL, the engine will match against the rightmost word SQL and go forward from there. Since there is no repetition of SQL remaining, the match fails. It is possible, again, to inspect what the engine performs introducing a dumping piece of code within the regular expression:

my $iteration = 0; 
 sub show-captures( Match $m ){ 
     my Str $result-split; 
     say "\n=== Iteration {++$iteration} ==="; 
     for $m.list.kv -> $i, $capture { 
         say "Capture $i = $capture"; 
         $result-split ~= '[' ~ $capture ~ ']'; 
     } 
 
     say $result-split; 
 } 
 
 $string ~~ / (SQL) (.+) { show-captures( $/ ); } $1 /; 

that produces a rather simple output:

=== Iteration 1 === 
 Capture 0 = SQL 
 Capture 1 =  is an SQL database! 
 [SQL][ is an SQL database!] 
 
 === Iteration 2 === 
 Capture 0 = SQL 
 Capture 1 =  database! 
 [SQL][ database!] 

Even using the :r adverb to prevent backtracking will not change things:

my $iteration = 0; 
 sub show-captures( Match $m ){ 
     my Str $result-split; 
     say "\n=== Iteration {++$iteration} ==="; 
     for $m.list.kv -> $i, $capture { 
         say "Capture $i = $capture"; 
         $result-split ~= '[' ~ $capture ~ ']'; 
     } 
 
     say $result-split; 
 } 
 
 $string ~~ / :r (SQL) (.+) { show-captures( $/ ); } $1 /; 

and the output will remain the same:

=== Iteration 1 === 
 Capture 0 = SQL 
 Capture 1 =  is an SQL database! 
 [SQL][ is an SQL database!] 
 
 === Iteration 2 === 
 Capture 0 = SQL 
 Capture 1 =  database! 
 [SQL][ database!] 

This demonstrates that disabling backtracking does not mean disabling possible multiple iterations of the matching engine, but rather disabling the backward matching tuning.

$/ changes each time a regular expression is matched

It is worth noting that each time a regular expression is used, the Match object returned (i.e., $/) is reset. In other words, $/ always refers to the very last regular expression matched:

my $answer = 'a lot of Stuff'; 
 say 'Hit a capital letter!' if $answer ~~ / <[A..Z>]> /; 
 say $/;  # OUTPUT: 「S」 
 say 'hit an x!' if $answer ~~ / x /; 
 say $/;  # OUTPUT: Nil 

The reset of $/ applies independently from the scope where the regular expression is matched:

my $answer = 'a lot of Stuff'; 
 if $answer ~~ / <[A..Z>]> / { 
    say 'Hit a capital letter'; 
    say $/;  # OUTPUT: 「S」 
 } 
 say $/;  # OUTPUT: 「S」 
 
 if True { 
   say 'hit an x!' if $answer ~~ / x /; 
   say $/;  # OUTPUT: Nil 
 } 
 
 say $/;  # OUTPUT: Nil 

The very same concept applies to named captures:

my $answer = 'a lot of Stuff'; 
 if $answer ~~ / $<capital>=<[A..Z>]> / { 
    say 'Hit a capital letter'; 
    say $/<capital>; # OUTPUT: 「S」 
 } 
 
 say $/<capital>;    # OUTPUT: 「S」 
 say 'hit an x!' if $answer ~~ / $<x>=x /; 
 say $/<x>;          # OUTPUT: Nil 
 say $/<capital>;    # OUTPUT: Nil 

Best practices and gotchas

The Regexes: Best practices and gotchas provides useful information on how to avoid common pitfalls when writing regexes and grammars.

67 Sets, bags, and mixes

Unordered collections of unique and weighted objects in Perl 6

Introduction

The six collection classes are Set, SetHash, Bag, BagHash, Mix and MixHash. They all share similar semantics.

In a nutshell, these classes hold, in general, unordered collections of objects, much like an object hash. The QuantHash role is the role that is implemented by all of these classes: therefore they are also referenced as QuantHashes.

Set and SetHash also implement the Setty role, Bag and BagHash implement the Baggy role, Mix and MixHash implement the Mixy role (which itself implements the Baggy role).

Sets only consider if objects in the collection are present or not, bags can hold several objects of the same kind, and mixes also allow fractional (and negative) weights. The regular versions are immutable, the Hash versions are mutable.

Let's elaborate on that. If you want to collect objects in a container but you do not care about the order of these objects, Perl 6 provides these unordered collection types. Being unordered, these containers can be more efficient than Lists or Arrays for looking up elements or dealing with repeated items.

On the other hand, if you want to get the contained objects (elements) without duplicates and you only care whether an element is in the collection or not, you can use a Set or SetHash.

If you want to get rid of duplicates but still preserve order, take a look at the unique routine for List.

=defn Set or SetHash Collection of distinct objects

If you want to keep track of the number of times each object appeared, you can use a Bag or BagHash. In these Baggy containers each element has a weight (an unsigned integer) indicating the number of times the same object has been included in the collection.

The types Mix and MixHash are similar to Bag and BagHash, but they also allow fractional and negative weights.

Set, Bag, and Mix are immutable types. Use the mutable variants SetHash, BagHash, and MixHash if you want to add or remove elements after the container has been constructed.

For one thing, as far as they are concerned, identical objects refer to the same element – where identity is determined using the WHICH method (i.e. the same way that the === operator checks identity). For value types like Str, this means having the same value; for reference types like Array, it means referring to the same object instance.

Secondly, they provide a Hash-like interface where the actual elements of the collection (which can be objects of any type) are the 'keys', and the associated weights are the 'values':

type of $a value of $a{$b} if $b is an element value of $a{$b} if $b is not an element
Set / SetHash True False
Bag / BagHash a positive integer 0
Mix / MixHash a non-zero real number 0

Operators with Set semantics

There are several infix operators devoted to performing common operations using QuantHash semantics. Since that is a mouthful, these operators are usually referred to as "set operators".

This does not mean that the parameters of these operators must always be Set, or even a more generic QuantHash. It just means that the logic that is applied to the operators, follows the logic of Set Theory.

These infixes can be written using the Unicode character that represents the function (like or ), or with an equivalent ASCII version (like (elem) or <(|)>.

So explicitly using Set (or Bag or Mix) objects with these infixes is unnecessary. All set operators work with all possible arguments. If necessary, a coercion will take place internally: but in many cases that is not actually needed.

However, if a Bag or Mix is one of the parameters to these set operators, then the semantics will be upgraded to that type (where Mix supersedes Bag if both types happen to be used).

Set operators that return Bool

infix (elem), infix ∈

Returns True if $a is an element of $b, else False. More information, Wikipedia definition.

infix ∉

Returns True if $a is not an element of $b, else False. More information, Wikipedia definition.

infix (cont), infix ∋

Returns True if $a contains $b as an element, else False. More information, Wikipedia definition.

infix ∌

Returns True if $a does not contain $b, else False. More information, Wikipedia definition.

infix (<=), infix ⊆

Returns True if $a is a subset or is equal to $b, else False. More information, Wikipedia definition.

infix ⊈

Returns True if $a is not a subset nor equal to $b, else False. More information, Wikipedia definition.

infix (<), infix ⊂

Returns True if $a is a strict subset of $b, else False. More information, Wikipedia definition.

infix ⊄

Returns True if $a is not a strict subset of $b, else False. More information, Wikipedia definition.

infix (>=), infix ⊇

Returns True if $a is a superset of or equal to $b, else False. More information, Wikipedia definition.

infix ⊉

Returns True if $a is not a superset nor equal to $b, else False. More information, Wikipedia definition.

infix (>), infix ⊃

Returns True if $a is a strict superset of $b, else False. More information, Wikipedia definition.

infix ⊅

Returns True if $a is not a strict superset of $b, else False. More information, Wikipedia definition.

Set operators that return a QuantHash

infix (|), infix ∪

Returns the union of all its arguments. More information, Wikipedia definition.

infix (&), infix ∩

Returns the intersection of all of its arguments. More information, Wikipedia definition.

infix (-), infix ∖

Returns the set difference of all its arguments. More information, Wikipedia definition.

infix (^), infix ⊖

Returns the symmetric set difference of all its arguments. More information, Wikipedia definition.

Set operators that return a Baggy

infix (.), infix ⊍

Returns the Baggy multiplication of its arguments. More information.

infix (+), infix ⊎

Returns the Baggy addition of its arguments. More information.

term ∅

The empty set. More information, Wikipedia definition.

68 Statement prefixes

Prefixes that alter the behavior of a statement or a set of them

Statement prefixes are written in front of a statement, and change their meaning, their output, or the moment they are going to be run. Since they have a specific behavior, they are also sometimes specific to some statement or group of statements.

lazy

As a statement prefix, lazy acts in front of any statement, including for loops, saving the execution for when the variable they are assigned to is actually needed.

my $incremented = 0; 
 my $var = lazy for <1 2 3 4> -> $d { 
     $incremented++ 
 }; 
 say $incremented; # OUTPUT: «0␤» 
 say eager $var;   # OUTPUT: «(0 1 2 3)␤» 
 say $incremented; # OUTPUT: «4␤» 

The $incremented variable is only incremented, that is, the internal part of the loop is only run when we eagerly evaluate the variable $var that contains the lazy loop. Eagerness can be applied on a variable in other ways, such as calling the .eager method on it.

my @array = lazy { (^3).map( *² )  }; 
 say @array;       # OUTPUT: «[...]» 
 say @array.eager; # OUTPUT: «[0 1 4]␤» 

This prefix can also be used in front of gather to make the inner statements behave lazily; in general, any set of statements that returns a value will be made lazy using this.

eager

The eager statement prefix will eagerly return the result of the statements behind, throwing away laziness and returning the result.

my $result := eager gather { for 1..3 { say "Hey"; take $_² } }; 
 say $result[0]; # OUTPUT: «Hey␤Hey␤Hey␤1␤» 

gather is implicitly lazy when bound to a scalar. However, with eager as a statement prefix it will run all three iterations in the loop, as shown by the printed "Hey", even if we are just requesting the first one in a row.

hyper, race

hyper and race use (maybe simultaneous) threads to run different iterations in a loop:

my @a = hyper for ^100_000 { .is-prime } 

This code is around 3x faster than the bare for. But there are a couple of caveats here:

Main difference between hyper and race is the ordering of results. Use hyper if you need the loop results to be produced in order, race if you don't care.

quietly

As a statement prefix, quietly suppresses all warnings produced by the statement it precedes.

sub marine() {}; 
 quietly say ~&marine; # OUTPUT: «marine␤» 

Calling .Str on code produces a warning. Preceding the statement with quietly will just produce the output, the name of the routine.

try

If you use try in front of a statement, it will contain the exception produced in it and store it in the $! variable, just like when it's used in front of a block.

try [].pop; 
 say $!; # OUTPUT: «Cannot pop from an empty Array␤..» 

do

do can be used as an statement prefix to disambiguate the statement they precede; this is needed, for instance, if you want to assign the result of a for statement. A bare for will fail, but this will work:

my $counter = 0; 
 my $result = do for ^5 { $counter++ }; 
 say $counter; # OUTPUT: «5␤» 
 say $result;  # OUTPUT: «(0 1 2 3 4)␤» 

do is equivalent, as in other cases, to surrounding a statement with a parenthesis. It can be used as an alternative with a (possibly more) straightforward syntax.

sink

As in the case of the routine, sink will run the statement throwing away the result. Use it in case you want to run some statement for the side effects it produces.

my $counter = 0; 
 my $result = sink for ^5 { $counter++ }; 
 say $counter; #  OUTPUT: «5␤» 
 say $result;  #  OUTPUT: «(Any)␤» 

once

Within a loop, runs the prefixed statement only once.

my $counter; 
 my $result = do for ^5 { once $counter = 0; $counter++ }; 
 say $result; # OUTPUT: «(0 1 2 3 4)␤» 

gather

gather can be used in front of a statement, receiving and gathering in a list all data structures emitted from a take run anywhere from that statement:

proto sub fact( Int ) {*} 
 multi sub fact( 1 --> 1 ) {} 
 multi sub fact( $x ) { take $x * fact( $x-1 ) } 
 
 my @factors = gather say fact(13); # OUTPUT: «6227020800» 
 say @factors; 
 # OUTPUT: «[2 6 24 120 720 5040 40320 362880 3628800 ...]» 

In this example, gather precedes say, which prints the first result of the factorial; at the same time, it's harvesting the result from every call to fact, which goes to @factor.

start

As a statement prefix, start behaves in the same way as in front of a block, that is, it runs the statement asynchronously, and returns a promise.

proto sub fact( Int ) {*} 
 multi sub fact( 1 --> 1 ) {} 
 multi sub fact( $x ) {  $x * fact( $x-1 ) } 
 
 my @promises = gather { 
     for <3 4> { 
         take start fact( 10 ** $_ ); 
     } 
 } 
 
 say await @promises; 

The Promise s created by start are gathered in an array, which returns the result of the operation once the promises have been fulfilled.

react

react can be used in concurrent programs to create blocks of code that run whenever some event occurs. It works with blocks, and also as a statement prefix.

my Channel $KXGA .= new; 
 for ^100 { 
     $KXGA.send( (100000..200000).pick ); 
 } 
 
 my @sums = ( start react whenever $KXGA -> $number { 
     say "In thread ", $*THREAD.id; 
     say "→ ", (^$number).sum; 
 } ) for ^10; 
 
 start { sleep 10; $KXGA.close(); } 
 
 await @sums; 

In this case react prefixes whenever, which makes a long sum with every number read from a channel.

supply

The keyword supply creates on-demand supplies that you can tap. It pairs with emit, which can be used anywhere from within a supply prefixed statement.

my &cards = ->  { 
     my @cards = 1..10 X~ <♠ ♥ ♦ ♣>; 
     emit($_) for @cards.pick(@cards.elems); 
 } 
 my $supply = supply cards; 
 
 $supply.tap( -> $v { say "Drawing: $v" }); 
 $supply.tap( -> $v { say "Drawing: $v" }, done => { say "No more cards" }); 
 # OUTPUT: 
 # [...] 
 # Drawing: 1♥ 
 # Drawing: 7♥ 
 # Drawing: 9♥ 
 # No more cards 

In this example, supply acts as prefix of the previously defined cards routine. It would very well be defined as a block, but giving it a name in this case might increase legibility or simply give the responsibility of defining it to other module.

69 Subscripts

Accessing data structure elements by index or key

One often needs to refer to a specific element (or slice of elements) from a collection or data structure. Borrowing from mathematical notation where the components of a vector v would be referred to as v₁, v₂, v₃, this concept is called "subscripting" (or "indexing") in Perl 6.

Basics

Perl 6 provides two universal subscripting interfaces:

elements are identified by interface name supported by
[ ] zero-based indices Positional Array, List, Buf, Match, ...
{ } string or object keys Associative Hash, Bag, Mix, Match, ...

Positional subscripting

Positional subscripting(via postcircumfix [ ]) addresses elements of an ordered collection by their position. Index 0 refers to the first element, index 1 to the second, and so on:

my @chores = "buy groceries", "feed dog", "wash car";
say @chores[0];  # OUTPUT: «buy groceries␤»
say @chores[1];  # OUTPUT: «feed dog␤»
say @chores[2];  # OUTPUT: «wash car␤»

Associative subscripting

Associative subscripting (via postcircumfix { }), does not require the collection to keep its elements in any particular order - instead, it uses a unique key to address each value. The nature of the keys depends on the collection in question: For example a standard Hash uses string keys, whereas a Mix allows arbitrary objects as keys, etc.:

my %grade = Zoe => "C", Ben => "B+";
say %grade{"Zoe"};  # OUTPUT: «C␤»
say %grade{"Ben"};  # OUTPUT: «B+␤»

my $stats = ( Date.today => 4.18, Date.new(2015,  4,  5) => 17.253 ).Mix;
say $stats{ Date.new(2015, 4, 4) + 1 };  # OUTPUT: «17.253␤»

For passing single-word string keys to { }, you can also use the angle bracketed word quoting constructs as if they were postcircumfix operators:

my %grade = Zoe => "C", Ben => "B+";
say %grade<Zoe>;    # OUTPUT: «C␤»
say %grade<Ben>;    # OUTPUT: «B+␤»

This is really just syntactic sugar that gets turned into the corresponding { } form at compile-time:

%hash<foo bar>;       # same as %hash{ <foo bar> } 
 %hash«foo "$var"»;    # same as %hash{ «foo "$var"» } 
 %hash<<foo "$var">>;  # same as %hash{ <<foo "$var">> } 

You may have noted above that we avoided having to quote Zoe by using the => operator, but that same operator did not just put invisible quotes around Date.new(2015, 4, 5), and we were able to find the same element using $stats{ Date.new(2015, 4, 4) + 1 }. This is because => only puts invisible quotes around single words, and by "word" we mean an identifier/name. The => operator is there to prevent us from accidentally calling functions or using constants with that name.

Hash subscripts do not do the same thing as =>. The default Hash has been made to behave the way new users have come to expect from using other languages, and for general ease of use. On a default Hash, subscripts coerce keys into strings, as long as those keys produce something Cool. You can use .perl on a collection to be sure whether the keys are strings or objects:

( 1  => 1 ).perl.say;            # OUTPUT: «1 => 1␤»
my %h; %h{1}   = 1; say %h.perl; # OUTPUT: «{ "1" => 1 }␤»
( 1/2 => 1 ).perl.say;           # OUTPUT: «0.5 => 1␤»
my %h; %h{1/2} = 1; say %h.perl; # OUTPUT: «{ "0.5" => 1 }␤»
( pi => 1 ).perl.say;            # OUTPUT: «:pi(1)␤»
my %h; %h{pi}  = 1; say %h.perl; # OUTPUT: «{ "3.14159265358979" => 1 }␤»

While the invisible quotes around single names is built into =>, string conversion is not built into the curly braces: it is a behavior of the default Hash. Not all types of hashes or collections do so:

my %h := MixHash.new; 
 %h{pi} = 1; %h.perl.say;         # OUTPUT: «(3.14159265358979e0=>1).MixHash␤» 

(Any name that => would convert to a string can also be used to build a pair using "adverbial notation" and will appear that way when viewed through .perl, which is why we see :pi(1) above.)

Applying subscripts

Subscripts can be applied to any expression that returns a subscriptable object, not just to variables:

say "__Hello__".match(/__(.*)__/)[0];   # OUTPUT: «「Hello」␤»
say "__Hello__".match(/__(.*)__/).[0];  # same, in method notation

Positional and associative subscripting are not mutually exclusive - for example, Match objects support both (each accessing a different set of data). Also, to make list processing more convenient, class Any provides a fallback implementation for positional subscripts which simply treats the invocant as a list of one element. (But there's no such fallback for associative subscripts, so they throw a runtime error when applied to an object that does not implement support for them.)

say 42[0];    # OUTPUT: «42␤» 
 say 42<foo>;  # ERROR: Type Int does not support associative indexing. 

Nonexistent elements

What happens when a nonexistent element is addressed by a subscript is up to the collection type in question. Standard Array and Hash collections return the type object of their value type constraint (which, by default, is Any) unless the collection has been declared with the is default trait in which case the returned value will be whatever the programmer declared it to be:

# no default values specified
my @array1;     say @array1[10];                   # OUTPUT: «(Any)␤»
my Int @array2; say @array2[10];                   # OUTPUT: «(Int)␤»

my %hash1;      say %hash1<foo>;                   # OUTPUT: «(Any)␤»
my Int %hash2;  say %hash2<foo>;                   # OUTPUT: «(Int)␤»

# default values specified
my @array3 is default('--');     say @array3[10];  # OUTPUT: «--␤»
my Int @array4 is default(17);   say @array4[10];  # OUTPUT: «17␤»

my %hash3 is default('Empty');   say %hash3<foo>;  # OUTPUT: «Empty␤»
my Int %hash4 is default(4711);  say %hash4<foo>;  # OUTPUT: «4711␤»

However, other types of collections may react differently to subscripts that address nonexistent elements:

say (0, 10, 20)[3];           # OUTPUT: «Nil␤»
say bag(<a a b b b>)<c>;      # OUTPUT: «0␤»
say array[uint8].new(1, 2)[2] # OUTPUT: «0␤»

To silently skip nonexistent elements in a subscripting operation, see #Truncating slices and the #:v adverb.

From the end

Positional indices are counted from the start of the collection, but there's also a notation for addressing elements by their position relative to the end: *-1 refers to the last element, *-2 to the second-to-last element, and so on.

my @alphabet = 'A' .. 'Z';
say @alphabet[*-1];  # OUTPUT: «Z␤»
say @alphabet[*-2];  # OUTPUT: «Y␤»
say @alphabet[*-3];  # OUTPUT: «X␤»

Note: The asterisk is important. Passing a bare negative integer (e.g. @alphabet[-1]) like you would do in many other programming languages, throws an error in Perl 6.

What actually happens here, is that an expression like *-1 declares a code object via Whatever-currying - and the [ ] subscript reacts to being given a code object as an index, by calling it with the length of the collection as argument and using the result value as the actual index. In other words, @alphabet[*-1] becomes @alphabet[@alphabet.elems - 1].

This means that you can use arbitrary expressions which depend on the size of the collection:

say @array[* div 2];  # select the middlemost element 
 say @array[$i % *];   # wrap around a given index ("modular arithmetic") 
 say @array[ -> $size { $i % $size } ];  # same as previous 

Slices

When multiple elements of a collection need to be accessed, there's a shortcut to doing multiple separate subscripting operations: Simply specify a list of indices/keys in the subscript, to get back a list of elements - also called a "slice" - in the same order.

For positional slices, you can mix normal indices with from-the-end ones:

my @alphabet = 'a' .. 'z';
say @alphabet[15, 4, *-9, 11].perl;  # OUTPUT: «("p", "e", "r", "l")␤»

In the *-number construct above, * indicates the end of the array as explained above in the From the end section. So if you want to take the last N elements of the array, you will have to create a Range that includes it.

(5802..5830).map( {.chr} )[*-10..*-5] # OUTPUT:  «(ᚽ ᚾ ᚿ ᛀ ᛁ ᛂ)␤»

Using * as the last element of the range will, effectively, return the last elements of the collection.

For associative slices, the angle brackets form often comes in handy:

my %color = kiwi => "green", banana => "yellow", cherry => "red";
say %color{"cherry", "kiwi"};  # OUTPUT: «(red green)␤»
say %color<cherry kiwi>;       # OUTPUT: «(red green)␤»
say %color{*};                 # OUTPUT: «(red yellow green)␤»

Be aware that slices are controlled by the type of what is passed to (one dimension of) the subscript, not its length. In particular the type can be any of the following:

The notable difference between * and Zen slice (empty) is that the Whatever star will cause full reification or itemization, while Zen slice won't. Both versions also de-cont.

So even a one-element list returns a slice, whereas a bare scalar value doesn't:

say @alphabet[2,];        # OUTPUT: «(c)␤» 
 say @alphabet[2,].^name;  # OUTPUT: «List␤» 
 
 say @alphabet[2];         # OUTPUT: «c␤» 
 say @alphabet[2].^name;   # OUTPUT: «Str␤» 

(The angle bracket form for associative subscripts works out because word quoting conveniently returns a Str in case of a single word, but a List in case of multiple words.)

In fact, the list structure of (the current dimension of) the subscript is preserved across the slice operation (but the kind of Iterable is not – the result is always just lists.)

say @alphabet[0, (1..2, (3,))];       # OUTPUT: «(a ((b c) (d)))␤» 
 say @alphabet[0, (1..2, [3,])];       # OUTPUT: «(a ((b c) (d)))␤» 
 say @alphabet[flat 0, (1..2, (3,))];  # OUTPUT: «(a b c d)␤» 
 say flat @alphabet[0, (1..2, (3,))];  # OUTPUT: «(a b c d)␤» 

Truncating slices

Referring to nonexistent elements in a slice subscript causes the output List to contain undefined values (or whatever else the collection in question chooses to return for nonexistent elements):

my  @letters = <a b c d e f>; 
 say @letters[3..7];  # OUTPUT: «(d e f (Any) (Any))␤» 

This behavior, while at first glance may seem unintuitive, is desirable in instances when you want to assign a value at an index in which a value does not currently exist.

my  @letters; 
 say @letters; # OUTPUT: «[]␤» 
 
 @letters[^10] = 'a'..'z'; 
 say @letters; # OUTPUT: «[a b c d e f g h i j]␤» 

If you want the resulting slice to only include existing elements, you can silently skip the non-existent elements using the #:v adverb.

my  @letters = <a b c d e f>; 
 say @letters[3..7]:v;  # OUTPUT: «(d e f)␤» 

The behavior when indexing a collection via lazy subscripts is different than when indexing with their eager counterparts. When accessing via a lazy subscript, the resulting slice will be truncated.

say @letters[lazy 3..7]; # OUTPUT: «(d e f)␤» 
 say @letters[     3..*]; # OUTPUT: «(d e f)␤» 

This behavior exists as a precaution to prevent runaway generation of massive, potentially infinite Lists and the out-of-memory issues that occur as a result.

Zen slices

If you put the subscript operator behind an object without specifying any indices/keys at all, it simply returns the subscripted object itself. Since it is empty but returns everything, it is known as a Zen slice.

Zen slicing is different from passing a Whatever-star (which, like a normal slice, always returns a List of elements no matter the type of the original object) or an empty list (which returns an empty slice):

my %bag := (orange => 1, apple => 3).Bag;
say %bag<>;    # OUTPUT: «Bag(apple(3), orange)␤»
say %bag{};    # OUTPUT: «Bag(apple(3), orange)␤»
say %bag{*};   # OUTPUT: «(1 3)␤»
say %bag{()};  # OUTPUT: «()␤»

Zen slicing does not reify or cache and merely returns the invocant. It is usually used to interpolate entire arrays / hashes into strings or to decont.

my @words = "cruel", "world";
say "Hello, @words[]!";  # OUTPUT: «Hello, cruel world!␤»

my $list = <a b c>;
.say for $list;   # OUTPUT: «(a b c)␤»
.say for $list<>; # OUTPUT: «a␤b␤c␤»
.say for $list[]; # OUTPUT: «a␤b␤c␤»

Multiple dimensions

Dimensions in subscripts are separated by a semicolon, allowing to mix lists of elements and dimensions.

my @twodim = (<a b c>, (1, 2, 3));
say @twodim;
# OUTPUT: «[(a b c) (1 2 3)]␤»

say @twodim[0,1;1]; # 2nd element of both lists
# OUTPUT: «(b 2)␤»

my %pantheon = %('Baldr' => 'consort' => 'Nanna' ,
                 'Bragi' => 'consort' => 'Iðunn' ,
                 'Nótt'  => 'consort' => 'Dellingr' );
say %pantheon{'Bragi','Nótt';'consort'}; # 'consort' value for both keys
# OUTPUT: «(Iðunn Dellingr)␤»

Multidimensional subscripts can be used to flatten nested lists when combined with Whatever.

my @toomany = [[<a b>], [1, 2]];
say @toomany;
# OUTPUT: «[[a b] [1 2]]␤»

say @toomany[*;*];
# OUTPUT: «(a b 1 2)␤»

You can use as many flattening semicolons as you want; there will be, at most, as many nesting levels flattened as the number of semicolons:

say [[1,2,[3,4]],[4,5]][*;*];     # OUTPUT: «(1 2 [3 4] 4 5)␤»
say [[1,2,[3,4]],[4,5]][*;*;*;*]; # OUTPUT: «(1 2 3 4 4 5)␤»

In the first example, with one Whatever less than the number of levels, the deepest one will not be flattened; in the second case it is, since it's greater than the number of levels.

You can use Whatever to select ranges or "rows" in multidimensional subscripts.

my @a = [[1,2], [3,4]];
say @a[*;1]; # 2nd element of each sub list
# OUTPUT: «(2 4)␤»
my @a = (<1 c 6>, <2 a 4>, <5 b 3>);
say @a.sort( { $_[1] } ); # sort by 2nd column
# OUTPUT: «((2 a 4) (5 b 3) (1 c 6))␤»

Modifying elements

TODO

Autovivification

Subscripts participate in "autovivification", i.e. the process by which arrays and hashes automatically spring into existence when needed, so that you can build nested data structures without having to pre-declare the collection type at each level:

my $beatles; 
 
 $beatles{"White Album"}[0] = "Back in the U.S.S.R.";  # autovivification! 
 
 say $beatles.perl;  # OUTPUT: «${"White Album" => $["Back in the U.S.S.R."]}␤» 

$beatles started out undefined, but became a Hash object because it was subscripted with { } in the assignment. Similarly, $beatles{"White Album"} became an Array object due to being subscripted with [ ] in the assignment.

Note that the subscripting itself does not cause autovivification: It only happens when the result of the subscripting chain is assigned to (or otherwise mutated).

TODO: Add expanded documentation on autovivification (which affects more than just subscripts, i.e. also routines like C<push>), at /language/datastructures.html, and link to it from here.

Binding

A subscripting expression may also be used as the left-hand-side of a binding statement. If supported by the subscripted collection's type, this replaces whatever value container would be naturally found at that "slot" of the collection, with the specified container.

The built-in Array and Hash types support this in order to allow building complex linked data structures:

my @a = 10, 11, 12, 13;
my $x = 1;

@a[2] := $x;  # Bound! (@a[2] and $x refer to the same container now.)

$x++; @a[2]++;

say @a;  # OUTPUT: «[10 11 3 13]␤»
say $x;  # OUTPUT: «3␤»

This can be specially useful when lazy data structures are part of a bigger one.

my @fib = 1,1, * + * … ∞; 
 my @lucas = 1,3, * + * … ∞; 
 my %sequences; 
 %sequences<f> := @fib; 
 %sequences<l> := @lucas; 
 for %sequences.keys -> $s { 
     for ^10 -> $n { 
         say %sequences{$s}[100+$n*10]/%sequences{$s}[101+$n*10]; 
     } 
 } 
 # OUTPUT: 0.6180339887498949 times 20. 

In this case, hash keys are bound to lazily generated sequences. The fact that they are bound means that whatever state has been computed is shared by the hash value and the sequence it's bound to, making computations of subsequent elements faster.

TODO: Add expanded documentation on building complex data structures at /language/datastructures.html, and link to it from here.

See #method BIND-POS and #method BIND-KEY for the underlying mechanism.

Adverbs

The return value and possible side-effect of a subscripting operation can be controlled using adverbs; these are defined on the relevant subscript operators.

Beware of the relatively loose precedence of operator adverbs, which may require you to add parentheses in compound expressions:

if $foo || %hash<key>:exists { ... }    # WRONG, tries to adverb the || op 
if $foo || (%hash<key>:exists) { ... }  # correct 
 if $foo or %hash<key>:exists { ... }    # also correct 

The supported adverbs are:

:exists

Returns whether or not the requested element exists, instead of returning the element's actual value. This can be used to distinguish between elements with an undefined value, and elements that aren't part of the collection at all:

my @foo = Any, 10;
say @foo[0].defined;    # OUTPUT: «False␤»
say @foo[0]:exists;     # OUTPUT: «True␤»
say @foo[2]:exists;     # OUTPUT: «False␤»
say @foo[0, 2]:exists;  # OUTPUT: «(True False)␤»

my %fruit = apple => Any, orange => 10;
say %fruit<apple>.defined;       # OUTPUT: «False␤»
say %fruit<apple>:exists;        # OUTPUT: «True␤»
say %fruit<banana>:exists;       # OUTPUT: «False␤»
say %fruit<apple banana>:exists; # OUTPUT: «(True False)␤»

May also be negated to test for non-existence:

say %fruit<apple banana>:!exists; # OUTPUT: «(False True)␤» 

To check if all elements of a slice exist, use an all junction:

if all %fruit<apple orange banana>:exists { ... } 

It can be used on multi-dimensional arrays and hashes:

my @multi-dim = 1, [2, 3, [4, 5]];
say @multi-dim[1;2;0]:exists;                # OUTPUT: «True␤»
say @multi-dim[1;2;5]:exists;                # OUTPUT: «False␤»

my %multi-dim = 1 => { foo => { 3 => 42 } };
say %multi-dim{1;'foo';3}:exists;            # OUTPUT: «True␤»
say %multi-dim{1;'bar';3}:exists;            # OUTPUT: «False␤»

:exists can be combined with the #:delete and #:p/#:kv adverbs - in which case the behavior is determined by those adverbs, except that any returned element value is replaced with the corresponding Bool indicating element existence.

See #method EXISTS-POS and #method EXISTS-KEY for the underlying mechanism.

:delete

Delete the element from the collection or, if supported by the collection, creates a hole at the given index, in addition to returning its value.

my @tens = 0, 10, 20, 30;
say @tens[3]:delete;     # OUTPUT: «30␤»
say @tens;               # OUTPUT: «[0 10 20]␤»

my %fruit = apple => 5, orange => 10, banana => 4, peach => 17;
say %fruit<apple>:delete;         # OUTPUT: «5␤»
say %fruit<peach orange>:delete;  # OUTPUT: «(17 10)␤»
say %fruit;                       # OUTPUT: «{banana => 4}␤»

Note that assigning Nil will revert the container at the given index to its default value. It will not create a hole. The created holes can be tested for with :exists but iteration will not skip them and produce undefined values instead.

my @a = 1, 2, 3;
@a[1]:delete;
say @a[1]:exists;
# OUTPUT: «False␤»
.say for @a;
# OUTPUT: «1␤(Any)␤3␤»

With the negated form of the adverb, the element is not actually deleted. This means you can pass a flag to make it conditional:

say %fruit<apple> :delete($flag);  # deletes the element only if $flag is 
                                    # true, but always returns the value. 

Can be combined with the #:exists and #:p/#:kv/#:k/#:v adverbs - in which case the return value will be determined by those adverbs, but the element will at the same time also be deleted.

See #method DELETE-POS and #method DELETE-KEY for the underlying mechanism.

:p

Return both the index/key and the value of the element, in the form of a Pair, and silently skip nonexistent elements:

my  @tens = 0, 10, 20, 30;
say @tens[1]:p;        # OUTPUT: «1 => 10␤»
say @tens[0, 4, 2]:p;  # OUTPUT: «(0 => 0 2 => 20)␤»

my  %month = Jan => 1, Feb => 2, Mar => 3;
say %month<Feb>:p;          # OUTPUT: «Feb => 2␤»
say %month<Jan Foo Mar>:p;  # OUTPUT: «(Jan => 1 Mar => 3)␤»

If you don't want to skip nonexistent elements, use the negated form:

say %month<Jan Foo Mar>:!p;  # OUTPUT: «(Jan => 1 Foo => (Any) Mar => 3)␤» 

Can be combined with the #:exists and #:delete adverbs.

See also the pairs routine.

:kv

Return both the index/key and the value of the element, in the form of a List, and silently skip nonexistent elements. When used on a slice, the return value is a single flat list of interleaved keys and values:

my  @tens = 0, 10, 20, 30;
say @tens[1]:kv;        # OUTPUT: «(1 10)␤»
say @tens[0, 4, 2]:kv;  # OUTPUT: «(0 0 2 20)␤»

my  %month = Jan => 1, Feb => 2, Mar => 3;
say %month<Feb>:kv;          # OUTPUT: «(Feb 2)␤»
say %month<Jan Foo Mar>:kv;  # OUTPUT: «(Jan 1 Mar 3)␤»

If you don't want to skip nonexistent elements, use the negated form:

say %month<Jan Foo Mar>:!kv;  # OUTPUT: «(Jan 1 Foo (Any) Mar 3)␤» 

This adverb is commonly used to iterate over slices:

for %month<Feb Mar>:kv -> $month, $i { 
     say "$month had {Date.new(2015, $i, 1).days-in-month} days in 2015" 
 } 

Can be combined with the #:exists and #:delete adverbs.

See also the kv routine.

:k

Return only the index/key of the element, rather than its value, and silently skip nonexistent elements:

my @tens = 0, 10, 20, 30;
say @tens[1]:k;        # OUTPUT: «1␤»
say @tens[0, 4, 2]:k;  # OUTPUT: «(0 2)␤»

my %month = Jan => 1, Feb => 2, Mar => 3;
say %month<Feb>:k;          # OUTPUT: «Feb␤»
say %month<Jan Foo Mar>:k;  # OUTPUT: «(Jan Mar)␤»

If you don't want to skip nonexistent elements, use the negated form:

say %month<Jan Foo Mar>:!k;  # OUTPUT: «(Jan Foo Mar)␤» 

See also the keys routine.

:v

Return the bare value of the element (rather than potentially returning a mutable value container), and silently skip nonexistent elements:

my @tens = 0, 10, 20, 30; 
 say @tens[1]:v;        # OUTPUT: «10␤» 
 say @tens[0, 4, 2]:v;  # OUTPUT: «(0, 20)␤» 
 @tens[3] = 31;         # OK 
 @tens[3]:v = 31;       # ERROR, Cannot modify an immutable Int (31) 
 
 my %month = Jan => 1, Feb => 2, Mar => 3; 
 say %month<Feb>:v;          # OUTPUT: «2␤» 
 say %month<Jan Foo Mar>:v;  # OUTPUT: «(1 3)␤» 

If you don't want to skip nonexistent elements, use the negated form:

say %month<Jan Foo Mar>:!v;  # OUTPUT: «(1 (Any) 3)␤» 

See also the values routine.

Custom types

The subscripting interfaces described on this page are not meant to be exclusive to Perl 6's built-in collection types - you can (and should) reuse them for any custom type that wants to provide access to data by index or key.

You don't have to manually overload the postcircumfix [ ] and postcircumfix { } operators and re-implement all their magic, to achieve that - instead, you can rely on the fact that their standard implementation dispatches to a well-defined set of low-level methods behind the scenes. For example:

when you write: this gets called behind the scenes:
%foo<aa> %foo.AT-KEY("aa")
%foo<aa>:delete %foo.DELETE-KEY("aa")
@foo[3, 4, 5] @foo.AT-POS(3), @foo.AT-POS(4), @foo.AT-POS(5)
@foo[*-1] @foo.AT-POS(@foo.elems - 1)

So in order to make subscripting work, you only have to implement or delegate those low-level methods (detailed below) for your custom type.

If you do, you should also let your type compose the Positional or Associative role, respectively. This doesn't add any functionality per se, but announces (and may be used to check) that the type implements the corresponding subscripting interface.

Custom type example

Imagine a HTTP::Header type which, despite being a custom class with special behavior, can be indexed like a hash:

my $request = HTTP::Request.new(GET => "perl6.org"); 
 say $request.header.^name;  # OUTPUT: «HTTP::Header␤» 
 
 $request.header<Accept> = "text/plain"; 
 $request.header{'Accept-' X~ <Charset Encoding Language>} = <utf-8 gzip en>; 
 $request.header.push('Accept-Language' => "fr");  # like .push on a Hash 
 
 say $request.header<Accept-Language>.perl;  # OUTPUT: «["en", "fr"]␤» 
 
 my $rawheader = $request.header.Str;  # stringify according to HTTP spec 

A simple way to implement this class would be to give it an attribute of type Hash, and delegate all subscripting and iterating related functionality to that attribute (using a custom type constraint to make sure users don't insert anything invalid into it):

class HTTP::Header does Associative { 
     subset StrOrArrayOfStr where Str | ( Array & {.all ~~ Str} ); 
 
     has %!fields of StrOrArrayOfStr 
                  handles <AT-KEY EXISTS-KEY DELETE-KEY push 
                           iterator list kv keys values>; 
 
     method Str { #`[not shown, for brevity] } 
 } 

However, HTTP header field names are supposed to be case-insensitive (and preferred in camel-case). We can accommodate this by taking the *-KEY and push methods out of the handles list, and implementing them separately like this:

method AT-KEY     ($key) is rw { %!fields{normalize-key $key}        } 
 method EXISTS-KEY ($key)       { %!fields{normalize-key $key}:exists } 
 method DELETE-KEY ($key)       { %!fields{normalize-key $key}:delete } 
 method push(*@_) { #`[not shown, for brevity] } 
 
 sub normalize-key ($key) { $key.subst(/\w+/, *.tc, :g) } 

Note that subscripting %!fields returns an appropriate rw container, which our AT-KEY can simply pass on.

However, we may prefer to be less strict about user input and instead take care of sanitizing the field values ourselves. In that case, we can remove the StrOrArrayOfStr type constraint on %!fields, and replace our AT-KEY implementation with one that returns a custom Proxy container which takes care of sanitizing values on assignment:

multi method AT-KEY (::?CLASS:D: $key) is rw { 
     my $element := %!fields{normalize-key $key}; 
 
     Proxy.new( 
         FETCH => method () { $element }, 
 
         STORE => method ($value) { 
             $element = do given $value».split(/',' \s+/).flat { 
                 when 1  { .[0] }    # a single value is stored as a string 
                 default { .Array }  # multiple values are stored as an array 
             } 
         } 
     ); 
 } 

Note that declaring the method as multi and restricting it to :D (defined invocants) makes sure that the undefined case is passed through to the default implementation provided by Any (which is involved in auto-vivification).

Methods to implement for positional subscripting

In order to make index-based subscripting via postcircumfix [ ] work for your custom type, you should implement at least elems, AT-POS and EXISTS-POS - and optionally others as detailed below.

method elems

multi method elems(::?CLASS:D:)

Expected to return a number indicating how many subscriptable elements there are in the object. May be called by users directly, and is also called by postcircumfix [ ] when indexing elements from the end, as in @foo[*-1].

If not implemented, your type will inherit the default implementation from Any that always returns 1 for defined invocants - which is most likely not what you want. So if the number of elements cannot be known for your positional type, add an implementation that fails or dies, to avoid silently doing the wrong thing.

method AT-POS

When modifying this section, please also adapt the AT-KEY section accordingly as they are very similar.
multi method AT-POS (::?CLASS:D: $index)
TODO: Cover the case of multi-dim indices (also for all the other methods below), after jnthn's ongoing refactor is finished.

Expected to return the element at position $index. This is what postcircumfix [ ] normally calls.

If you want an element to be mutable (like they are for the built-in Array type), you'll have to make sure to return it in the form of an item container that evaluates to the element's value when read, and updates it when assigned to. (Remember to use return-rw or the is rw routine trait to make that work; see the example.)

method EXISTS-POS

When modifying this section, please also adapt the EXISTS-KEY section accordingly as they are very similar.
multi method EXISTS-POS (::?CLASS:D: $index)

Expected to return a Bool indicating whether or not there is an element at position $index. This is what postcircumfix [ ] calls when invoked like @foo[42]:exists.

What "existence" of an element means, is up to your type.

If you don't implement this, your type will inherit the default implementation from Any, which returns True for 0 and False for any other index - which is probably not what you want. So if checking for element existence cannot be done for your type, add an implementation that fails or dies, to avoid silently doing the wrong thing.

method DELETE-POS

When modifying this section, please also adapt the DELETE-KEY section accordingly as they are very similar.
multi method DELETE-POS (::?CLASS:D: $index)

Expected to delete the element at position $index, and return the value it had. This is what postcircumfix [ ] calls when invoked like @foo[42]:delete.

What "deleting" an element means, is up to your type.

Implementing this method is optional; if you don't, users trying to delete elements from an object of this type will get an appropriate error message.

method ASSIGN-POS

When modifying this section, please also adapt the ASSIGN-KEY section accordingly as they are very similar.
multi method ASSIGN-POS (::?CLASS:D: $index, $new)

Expected to set the element at position $index to the value $new. Implementing this is entirely optional; if you don't, self.AT-POS($index) = $new is used instead, and if you do, you should make sure it has the same effect.

This is meant as an opt-in performance optimization, so that simple assignments like @numbers[5] = "five" can operate without having to call AT-POS (which would have to create and return a potentially expensive container object).

Note that implementing ASSIGN-POS does not relieve you from making AT-POS an rw method though, because less trivial assignments/modifications such as @numbers[5]++ will still use AT-POS.

method BIND-POS

When modifying this section, please also adapt the BIND-KEY section accordingly as they are very similar.
multi method BIND-POS (::?CLASS:D: $index, \new)

Expected to bind the value or container new to the slot at position $index, replacing any container that would be naturally found there. This is what is called when you write:

my $x = 10; 
 @numbers[5] := $x; 

The generic Array class supports this in order to allow building complex linked data structures, but for more domain-specific types it may not make sense, so don't feel compelled to implement it. If you don't, users will get an appropriate error message when they try to bind to a positional slot of an object of this type.

method STORE

When modifying this section, please also adapt the STORE section in Associative accordingly as they are very similar.
method STORE (::?CLASS:D: \values, :$initialize)

This method should only be supplied if you want to support this syntax:

my @a is Foo = 1,2,3; 

Which is used for binding your implementation of the Positional role.

STORE should accept the values to (re-)initialize the object with. The optional named parameter will contain a True value when the method is called on the object for the first time. It should return the invocant.

class DNA { 
     has $.chain is rw; 
 
     method STORE ($chain where { 
                          $chain ~~ /^^ <[ACGT]>+ $$ / and 
                          $chain.chars %% 3 
                      }, :$initialize --> DNA) { 
         if $initialize { 
             self= DNA.new( chain => $chain ) 
         } else { 
             self.chain = $chain; 
             self 
         } 
     } 
 
     method Str(::?CLASS:D:) { return $.chain.comb.rotor(3) } 
 }; 
 
 my @string is DNA = 'GAATCC'; 
 say @string.Str;    # OUTPUT: «((G A A) (T C C))␤» 
 @string = 'ACGTCG'; 
 say @string.Str;    # OUTPUT: «((A C G) (T C G))␤» 

This code takes into account the value of $initialize, which is set to True only if we are assigning a value to a variable declared using the is syntax for the first time. The STORE method should set the self variable and return it in all cases, including when the variable has already been initialized.

Methods to implement for associative subscripting

In order to make key-based subscripting via postcircumfix { } work for your custom type, you should implement at least AT-KEY and EXISTS-KEY - and optionally others as detailed below.

method AT-KEY

When modifying this section, please also adapt the AT-POS section accordingly as they are very similar.
multi method AT-KEY (::?CLASS:D: $key)

Expected to return the element associated with $key. This is what postcircumfix { } normally calls.

If you want an element to be mutable (like they are for the built-in Hash type), you'll have to make sure to return it in the form of an item container that evaluates to the element's value when read, and updates it when assigned to. (Remember to use return-rw or the is rw routine trait to make that work; see the example.)

On the other hand if you want your collection to be read-only, feel free to return non-container values directly.

method EXISTS-KEY

When modifying this section, please also adapt the EXISTS-POS section accordingly as they are very similar.
multi method EXISTS-KEY (::?CLASS:D: $key)

Expected to return a Bool indicating whether or not there is an element associated with $key. This is what postcircumfix { } calls when invoked like %foo<aa>:exists.

What "existence" of an element means, is up to your type.

If you don't implement this, your type will inherit the default implementation from Any, which always returns False - which is probably not what you want. So if checking for element existence cannot be done for your type, add an implementation that fails or dies, to avoid silently doing the wrong thing.

method DELETE-KEY

When modifying this section, please also adapt the DELETE-POS section accordingly as they are very similar.
multi method DELETE-KEY (::?CLASS:D: $key)

Expected to delete the element associated with $key, and return the value it had. This is what postcircumfix { } calls when invoked like %foo<aa>:delete.

What "deleting" an element means, is up to your type - though it should usually cause EXISTS-KEY to become False for that key.

Implementing this method is optional; if you don't, users trying to delete elements from an object of this type will get an appropriate error message.

method ASSIGN-KEY

When modifying this section, please also adapt the ASSIGN-POS section accordingly as they are very similar.
multi method ASSIGN-KEY (::?CLASS:D: $key, $new)

Expected to set the element associated with $key to the value $new. Implementing this is entirely optional; if you don't, self.AT-KEY($key) = $new is used instead, and if you do, you should make sure it has the same effect.

This is meant as an opt-in performance optimization, so that simple assignments %age<Claire> = 29 can operate without having to call AT-KEY (which would have to create and return a potentially expensive container object).

Note that implementing ASSIGN-KEY does not relieve you from making AT-KEY an rw method though, because less trivial assignments/modifications such as %age<Claire>++ will still use AT-KEY.

method BIND-KEY

When modifying this section, please also adapt the BIND-POS section accordingly as they are very similar.
multi method BIND-KEY (::?CLASS:D: $key, \new)

Expected to bind the value or container new to the slot associated with $key, replacing any container that would be naturally found there. This is what is called when you write:

my $x = 10; 
 %age<Claire> := $x; 

The generic Hash class supports this in order to allow building complex linked data structures, but for more domain-specific types it may not make sense, so don't feel compelled to implement it. If you don't, users will get an appropriate error message when they try to bind to an associative slot of an object of this type.

method STORE

When modifying this section, please also adapt the STORE section in Positional accordingly as they are very similar.
method STORE (::?CLASS:D: \values, :$initialize)

This method should only be supplied if you want to support the:

my %h is Foo = a => 42, b => 666; 

syntax for binding your implementation of the Associative role.

Should accept the values to (re-)initialize the object with, which either could consist of Pairs, or separate key/value pairs. The optional named parameter will contain a True value when the method is called on the object for the first time. Should return the invocant.

70 Syntax

General rules of Perl 6 syntax

Perl 6 borrows many concepts from human language. Which is not surprising, considering it was designed by a linguist.

It reuses common elements in different contexts, has the notion of nouns (terms) and verbs (operators), is context-sensitive (in the every day sense, not necessarily in the Computer Science interpretation), so a symbol can have a different meaning depending on whether a noun or a verb is expected.

It is also self-clocking, so that the parser can detect most of the common errors and give good error messages.

Lexical conventions

Perl 6 code is Unicode text. Current implementations support UTF-8 as the input encoding.

See also Unicode versus ASCII symbols.

Free form

Perl 6 code is also free-form, in the sense that you are mostly free to chose the amount of whitespace you use, though in some cases, the presence or absence of whitespace carries meaning.

So you can write

if True { 
     say "Hello"; 
 } 

or

    if True { 
 say "Hello"; # Bad indentation intended 
         } 

or

if True { say "Hello" } 

or even

if True {say "Hello"} 

though you can't leave out any of the remaining whitespace.

Unspace

In many places where the compiler would not allow a space you can use any amount of whitespace, as long as it is quoted with a backslash. Unspaces in tokens are not supported. Newlines that are unspaced still count when the compiler produces line numbers. Use cases for unspace are separation of postfix operators and routine argument lists.

sub alignment(+@l) { +@l };
sub long-name-alignment(+@l) { +@l };
alignment\         (1,2,3,4).say;
long-name-alignment(3,5)\   .say;
say Inf+Inf\i;

In this case, our intention was to make the . of both statements, as well as the parentheses, align, so we precede the whitespace used for padding with a \.

Separating statements with semicolons

A Perl 6 program is a list of statements, separated by semicolons ;.

say "Hello"; 
 say "world"; 

A semicolon after the final statement (or after the final statement inside a block) is optional.

say "Hello"; 
 say "world" 
if True { 
     say "Hello" 
 } 
 say "world" 

Implied separator rule (for statements ending in blocks)

Complete statements ending in bare blocks can omit the trailing semicolon, if no additional statements on the same line follow the block's closing curly brace }. This is called the "implied separator rule". For example, you don't need to write a semicolon after an if statement block as seen above, and below.

if True { say "Hello" } 
 say "world"; 

However, semicolons are required to separate a block from trailing statements in the same line.

if True { say "Hello" }; say "world"; 
 #                     ^^^ this ; is required 

This implied statement separator rule applies in other ways, besides control statements, that could end with a bare block. For example, in combination with the colon : syntax for method calls.

my @names = <Foo Bar Baz>; 
 my @upper-case-names = @names.map: { .uc }    # OUTPUT: [FOO BAR BAZ] 

For a series of blocks that are part of the same if/elsif/else (or similar) construct, the implied separator rule only applies at the end of the last block of that series. These three are equivalent:

if True { say "Hello" } else { say "Goodbye" }; say "world"; 
 #                                            ^^^ this ; is required 
if True { say "Hello" } else { say "Goodbye" } # <- implied statement separator 
 say "world"; 
if True { say "Hello" }   # still in the middle of an if/else statement 
 else    { say "Goodbye" } # <- no semicolon required because it ends in a block 
                           #    without trailing statements in the same line 
 say "world"; 

Comments

Comments are parts of the program text which are only intended for human readers; the Perl 6 compilers do not evaluate them as program text.

Comments count as whitespace in places where the absence or presence of whitespace disambiguates possible parses.

Single-line comments

The most common form of comments in Perl 6 starts with a single hash character # and goes until the end of the line.

if $age > 250 {     # catch obvious outliers 
     # this is another comment! 
     die "That doesn't look right" 
 } 

Multi-line / embedded comments

Multi-line and embedded comments start with a hash character, followed by a backtick, and then some opening bracketing character, and end with the matching closing bracketing character. Only the paired characters (), {}, [], and <> are valid for bounding comment blocks. (Unlike matches and substitutions, where pairs such as !!, || or @ may be used.) The content can not only span multiple lines, but can also be embedded inline.

if #`( why would I ever write an inline comment here? ) True { 
     say "something stupid"; 
 } 

These comments can extend multiple lines

#`[ 
 And this is how a multi would work. 
 That says why we do what we do below. 
 ] 
 say "No more"; 

Curly braces inside the comment can be nested, so in #`{ a { b } c }, the comment goes until the very end of the string. You may also use multiple curly braces, such as #`{{ double-curly-brace }}, which might help disambiguate from nested delimiters. You can embed these comments in expressions, as long as you don't insert them in the middle of keywords or identifiers.

Pod comments

Pod syntax can be used for multi-line comments

say "this is code"; 
 
 =begin comment 
 
 Here are several 
 lines 
 of comment 
 
 =end comment 
 
 say 'code again'; 

Identifiers

Identifiers are grammatical building blocks that may be used to give a name to entities/objects such as constants, variables (e.g. Scalars) and routines (e.g. Subs and Methods). In a variable name, any sigil (and twigil) precedes the identifier and does not form a part thereof.

constant c = 299792458;     # identifier "c" names an Int
my $a = 123;                # identifier "a" in the name "$a" of a Scalar
sub hello { say "Hello!" }; # identifier "hello" names a Sub

Identifiers come in different forms: ordinary, extended, and compound identifiers.

Ordinary identifiers

An ordinary identifier is composed of a leading alphabetic character which may be followed by one or more alphanumeric characters. It may also contain isolated, embedded apostrophes ' and/or hyphens -, provided that the next character is each time alphabetic.

The definitions of "alphabetic" and "alphanumeric" include appropriate Unicode characters. Which characters are "appropriate" depends on the implementation. In the Rakudo/MoarVM Perl 6 implementation alphabetic characters include characters with the Unicode General Category value Letter (L), and the underscore _. Alphanumeric characters additionally include characters with the Unicode General Category value Number, Decimal Digit (Nd).

# valid ordinary identifiers: 
 x 
 _snake_oil 
 something-longer 
 with-numbers1234 
 don't-do-that 
 piece_of_π 
 駱駝道              # "Rakuda-dō", Japanese for "Way of the camel" 
# invalid ordinary identifiers: 
 42                 # identifier does not start with alphabetic character 
 with-numbers1234-5 # embedded hyphen not followed by alphabetic character 
 is-prime?          # question mark is not alphanumeric 
 x²                 # superscript 2 is not alphanumeric (explained above) 

Extended identifiers

It is often convenient to have names that contain characters that are not allowed in ordinary identifiers. Use cases include situations where a set of entities shares a common "short" name, but still needs for each of its elements to be identifiable individually. For example, you might use a module whose short name is Dog, while its long name includes its naming authority and version:

Dog:auth<Somebody>:ver<1.0>  # long module names including author and version 
 Dog:auth<Somebody>:ver<2.0> 
 
 use Dog:auth<Somebody>:ver<2.0>; 
 # Selection of second module causes its full name to be aliased to the 
 # short name for the rest of # the lexical scope, allowing a declaration 
 # like this. 
 my Dog $spot .= new("woof"); 

Similarly, sets of operators work together in various syntactic categories with names like prefix, infix and postfix. The official names of these operators often contain characters that are excluded from ordinary identifiers. The long name is what constitutes the extended identifier, and includes this syntactic category; the short name will be included in quotes in the definition:

infix:<+>                 # the official name of the operator in $a + $b 
 infix:<*>                 # the official name of the operator in $a * $b 
 infix:«<=»                # the official name of the operator in $a <= $b 

For all such uses, you can append one or more colon-separated strings to an ordinary identifier to create a so-called extended identifier. When appended to an identifier (that is, in postfix position), this colon-separated string generates unique variants of that identifier.

These strings have the form :key<value>, wherein key or value are optional; that is, after the colon that separates it from a regular identifier, there will be a key and/or a quoting bracketing construct such as < >, « » or [' '] which quotes one or more arbitrary characters value.

Starting with Perl 6 language version 6.d, colon pairs with sym as the key (e.g. :sym<foo> ) are reserved for possible future use.

# exemplary valid extended identifiers: 
 postfix:<²>               # the official long name of the operator in $x² 
 WOW:That'sAwesome 
 WOW:That's<<🆒>> 
 party:sweet<16> 
 
 # exemplary invalid extended identifiers: 
 party:16<sweet>           # 16 is not an ordinary identifier 
 party:16sweet 
 party:!a                  # ...and neither is !a 
 party:$a                  # ...nor $a 

In an extended identifier, the postfix string is considered an integral part of the name, so infix:<+> and infix:<-> are two different operators. The bracketing characters used, however, do not count as part of it; only the quoted data matters. So these are all the same name:

infix:<+> 
 infix:<<+>> 
 infix:«+» 
 infix:['+'] 
 infix:('+') 

Similarly, all of this works:

my $foo:bar<baz> = 'quux'; 
 say $foo:bar«baz»;                               # OUTPUT: «quux␤» 
 my $take-me:<home> = 'Where the glory has no end'; 
 say $take-me:['home'];                           # OUTPUT: «Where [...]␤» 
 my $foo:bar<2> = 5; 
 say $foo:bar(1+1);                               # OUTPUT: «5␤» 

Where an extended identifier comprises two or more colon pairs, their order is generally significant:

my $a:b<c>:d<e> = 100; 
 my $a:d<e>:b<c> = 200; 
 say $a:b<c>:d<e>;               # OUTPUT: «100␤», NOT: «200␤» 

An exception to this rule is module versioning; so these identifiers effectively name the same module:

use ThatModule:auth<Somebody>:ver<2.7.18.28.18> 
 use ThatModule:ver<2.7.18.28.18>:auth<Somebody> 

Furthermore, extended identifiers support compile-time interpolation; this requires the use of constants for the interpolation values:

constant $c = 42;  # Constant binds to Int; $-sigil enables interpolation 
 my $a:foo<42> = "answer"; 
 say $a:foo«$c»;    # OUTPUT: «answer␤» 

Although quoting bracketing constructs are generally interchangeable in the context of identifiers, they are not identical. In particular, angle brackets < > (which mimic single quote interpolation characteristics) cannot be used for the interpolation of constant names.

constant $what = 'are'; 
 my @we:<are>= <the champions>; 
 say @we:«$what»;     # OUTPUT: «[the champions]␤» 
 say @we:<$what>; 
 # Compilation error: Variable '@we:<$what>' is not declared 

Compound identifiers

A compound identifier is an identifier that is composed of two or more ordinary and/or extended identifiers that are separated from one another by a double colon ::.

The double colon :: is known as the namespace separator or the package delimiter, which clarifies its semantic function in a name: to force the preceding portion of the name to be considered a package/namespace through which the subsequent portion of the name is to be located:

module MyModule {               # declare a module package
    our $var = "Hello";         # declare package-scoped variable
}
say $MyModule::var              # OUTPUT: «Hello␤»

In the example above, MyModule::var is a compound identifier, composed of the package name identifier MyModule and the identifier part of the variable name var. Altogether $MyModule::var is often referred to as a package-qualified name.

Separating identifiers with double colons causes the rightmost name to be inserted into existing (see above example) or automatically created packages:

my $foo::bar = 1; 
 say OUR::.keys;           # OUTPUT: «(foo)␤» 
 say OUR::foo.HOW          # OUTPUT: «Perl6::Metamodel::PackageHOW.new␤» 

The last lines shows how the foo package was created automatically, as a deposit for variables in that namespace.

The double colon syntax enables runtime interpolation of a string into a package or variable name using ::($expr) where you'd ordinarily put a package or variable name:

my $buz = "quux";
my $bur::quux = 7;
say $bur::($buz);               # OUTPUT: «7␤»

term term:<>

You can use term:<> to introduce new terms, which is handy for introducing constants that defy the rules of normal identifiers:

use Test; plan 1; constant &term:<👍> = &ok.assuming(True);
👍
# OUTPUT: «1..1␤ok 1 - ␤»

But terms don't have to be constant: you can also use them for functions that don't take any arguments, and force the parser to expect an operator after them. For instance:

sub term:<dice> { (1..6).pick };
say dice + dice;

can print any number between 2 and 12.

If instead we had declared dice as a regular

sub dice() {(1...6).pick }

, the expression dice + dice would be parsed as dice(+(dice())), resulting in an error since sub dice expects zero arguments.

Statements and expressions

Perl 6 programs are made of lists of statements. A special case of a statement is an expression, which returns a value. For example if True { say 42 } is syntactically a statement, but not an expression, whereas 1 + 2 is an expression (and thus also a statement).

The do prefix turns statements into expressions. So while

my $x = if True { 42 };     # Syntax error! 

is an error,

my $x = do if True { 42 };

assigns the return value of the if statement (here 42) to the variable $x.

Terms

Terms are the basic nouns that, optionally together with operators, can form expressions. Examples for terms are variables ($x), barewords such as type names (Int), literals (42), declarations (sub f() { }) and calls (f()).

For example, in the expression 2 * $salary, 2 and $salary are two terms (an integer literal and a variable).

Variables

Variables typically start with a special character called the sigil, and are followed by an identifier. Variables must be declared before you can use them.

# declaration:
my $number = 21;
# usage:
say $number * 2;

See the documentation on variables for more details.

Barewords (constants, type names)

Pre-declared identifiers can be terms on their own. Those are typically type names or constants, but also the term self which refers to an object that a method was called on (see objects), and sigilless variables:

say Int;                # OUTPUT: «(Int)␤»
#   ^^^ type name (built in)

constant answer = 42;
say answer;
#   ^^^^^^ constant

class Foo {
    method type-name {
        self.^name;
      # ^^^^ built-in term 'self'
    }
}
say Foo.type-name;     # OUTPUT: «Foo␤»
#   ^^^ type name

Packages and qualified names

Named entities, such as variables, constants, classes, modules or subs, are part of a namespace. Nested parts of a name use :: to separate the hierarchy. Some examples:

$foo                # simple identifiers 
 $Foo::Bar::baz      # compound identifiers separated by :: 
 $Foo::($bar)::baz   # compound identifiers that perform interpolations 
 Foo::Bar::bob(23)   # function invocation given qualified name 

See the documentation on packages for more details.

Literals

A literal is a representation of a constant value in source code. Perl 6 has literals for several built-in types, like strings, several numeric types, pairs and more.

String literals

String literals are surrounded by quotes:

say 'a string literal';
say "a string literal\nthat interprets escape sequences";

See quoting for many more options, including the escaping quoting q. Perl 6 uses the standard escape characters in literals: \a \b \t \n \f \r \e, with the same meaning as the ASCII escape codes, specified in the design document.

say "🔔\a";  # OUTPUT: «🔔␇␤»

Number literals

Number literals are generally specified in base ten (which can be specified literally, if needed, via the prefix 0d), unless a prefix like 0x (hexadecimal, base 16), 0o (octal, base 8) or 0b (binary, base 2) or an explicit base in adverbial notation like :16<A0> specifies it otherwise. Unlike other programming languages, leading zeros do not indicate base 8; instead a compile-time warning is issued.

In all literal formats, you can use underscores to group digits, although they don't carry any semantic information; the following literals all evaluate to the same number:

1000000 
 1_000_000 
 10_00000 
 100_00_00 

Int literals

Integers default to signed base-10, but you can use other bases. For details, see Int.

# not a single literal, but unary - operator applied to numeric literal 2 
 -2 
 12345 
 0xBEEF      # base 16 
 0o755       # base 8 
 :3<1201>    # arbitrary base, here base 3 

Rat literals

Rat literals (rationals) are very common, and take the place of decimals or floats in many other languages. Integer division also results in a Rat.

1.0 
 3.14159 
 -2.5        # Not actually a literal, but still a Rat 
 :3<21.0012> # Base 3 rational 
 ⅔ 
 2/3         # Not actually a literal, but still a Rat 

Num literals

Scientific notation with an integer exponent to base ten after an e produces floating point number:

1e0 
 6.022e23 
 1e-9 
 -2e48 
 2e2.5       # error 

Complex literals

Complex numbers are written either as an imaginary number (which is just a rational number with postfix i appended), or as a sum of a real and an imaginary number:

1+2i 
 6.123e5i    # note that this is 6.123e5 * i, not 6.123 * 10 ** (5i) 

Pair literals

Pairs are made of a key and a value, and there are two basic forms for constructing them: key => 'value' and :key('value').

Arrow pairs

Arrow pairs can have an expression, a string literal or a "bare identifier", which is a string with ordinary-identifier syntax that does not need quotes on the left-hand side:

like-an-identifier-ain't-it => 42 
 "key" => 42 
 ('a' ~ 'b') => 1 

Adverbial pairs (colon pairs)

Short forms without explicit values:

my $thing = 42; 
 :$thing                 # same as  thing => $thing 
 :thing                  # same as  thing => True 
 :!thing                 # same as  thing => False 

The variable form also works with other sigils, like :&callback or :@elements. If the value is a number literal, it can also be expressed in this short form:

:42thing            # same as  thing => 42
:٤٢thing            # same as  thing => 42

This order is inverted if you use another alphabet

:٤٢ث              # same as   ث => ٤٢

the thaa letter precedes the number.

Long forms with explicit values:

:thing($value)              # same as  thing => $value 
 :thing<quoted list>         # same as  thing => <quoted list> 
 :thing['some', 'values']    # same as  thing => ['some', 'values'] 
 :thing{a => 'b'}            # same as  thing => { a => 'b' } 

Boolean literals

True and False are Boolean literals; they will always have initial capital letter.

Array literals

A pair of square brackets can surround an expression to form an itemized Array literal; typically there is a comma-delimited list inside:

say ['a', 'b', 42].join(' ');   # OUTPUT: «a b 42␤»
#   ^^^^^^^^^^^^^^ Array constructor

If the constructor is given a single Iterable, it'll clone and flatten it. If you want an Array with just 1 element that is an Iterable, ensure to use a comma after it:

my @a = 1, 2;
say [@a].perl;  # OUTPUT: «[1, 2]␤»
say [@a,].perl; # OUTPUT: «[[1, 2],]␤»

The Array constructor does not flatten other types of contents. Use the Slip prefix operator (|) to flatten the needed items:

my @a = 1, 2;
say [@a, 3, 4].perl;  # OUTPUT: «[[1, 2], 3, 4]␤»
say [|@a, 3, 4].perl; # OUTPUT: «[1, 2, 3, 4]␤»

List type can be explicitly created from an array literal declaration without a coercion from Array, using is trait on declaration.

my @a is List = 1, 2; # a List, not an Array
# wrong: creates an Array of Lists
my List @a;

Hash literals

A leading associative sigil and pair of parenthesis %( ) can surround a List of Pairs to form a Hash literal; typically there is a comma-delimited List of Pairs inside. If a non-pair is used, it is assumed to be a key and the next element is the value. Most often this is used with simple arrow pairs.

say %( a => 3, b => 23, :foo, :dog<cat>, "french", "fries" );
# OUTPUT: «a => 3, b => 23, dog => cat, foo => True, french => fries␤»

say %(a => 73, foo => "fish").keys.join(" ");   # OUTPUT: «a foo␤»
#   ^^^^^^^^^^^^^^^^^^^^^^^^^ Hash constructor

When assigning to a %-sigiled variable on the left-hand side, the sigil and parenthesis surrounding the right-hand side Pairs are optional.

my %ages = fred => 23, jean => 87, ann => 4;

By default, keys in %( ) are forced to strings. To compose a hash with non-string keys, use curly brace delimiters with a colon prefix :{ } :

my $when = :{ (now) => "Instant", (DateTime.now) => "DateTime" };

Note that with objects as keys, you cannot access non-string keys as strings:

say :{ -1 => 41, 0 => 42, 1 => 43 }<0>;  # OUTPUT: «(Any)␤»
say :{ -1 => 41, 0 => 42, 1 => 43 }{0};  # OUTPUT: «42␤»

Particular types that implement Associative role, Map (including Hash and Stash subclasses) and QuantHash (and its subclasses), can be explicitly created from a hash literal without a coercion, using is trait on declaration:

my %hash;                    # Hash
my %hash is Hash;            # explicit Hash
my %map is Map;              # Map
my %stash is Stash;          # Stash

my %quant-hash is QuantHash; # QuantHash

my %setty is Setty;          # Setty
my %set is Set;              # Set
my %set-hash is SetHash;     # SetHash

my %baggy is Baggy;          # Baggy
my %bag is Bag;              # Bag
my %bag-hash is BagHash;     # BagHash

my %mixy is Mixy;            # Mixy
my %mix is Mix;              # Mix
my %mix-hash is MixHash;     # MixHash

Note that using a usual type declaration with a hash sigil creates a typed Hash, not a particular type:

# This is wrong: creates a Hash of Mixes, not Mix:
my Mix %mix;
# Works with $ sigil:
my Mix $mix;
# Can be typed:
my Mix[Int] $mix-of-ints;

Regex literals

A Regex is declared with slashes like /foo/. Note that this // syntax is shorthand for the full rx// syntax.

/foo/          # Short version 
 rx/foo/        # Longer version 
 Q :regex /foo/ # Even longer version 
 
 my $r = /foo/; # Regexes can be assigned to variables 

Signature literals

Signatures can be used standalone for pattern matching, in addition to the typical usage in sub and block declarations. A standalone signature is declared starting with a colon:

say "match!" if 5, "fish" ~~ :(Int, Str); # OUTPUT: «match!␤»

my $sig = :(Int $a, Str);
say "match!" if (5, "fish") ~~ $sig; # OUTPUT: «match!␤»

given "foo", 42 {
  when :(Str, Str) { "This won't match" }
  when :(Str, Int $n where $n > 20) { "This will!" }
}

See the Signatures documentation for more about signatures.

Declarations

Variable declaration

my $x;                          # simple lexical variable
my $x = 7;                      # initialize the variable
my Int $x = 7;                  # declare the type
my Int:D $x = 7;                # specify that the value must be defined (not undef)
my Int $x where { $_ > 3 } = 7; # constrain the value based on a function
my Int $x where * > 3 = 7;      # same constraint, but using Whatever shorthand

See Variable Declarators and Scope for more details on other scopes (our, has).

Subroutine declaration

# The signature is optional
sub foo { say "Hello!" }

sub say-hello($to-whom) { say "Hello $to-whom!" }

You can also assign subroutines to variables.

my &f = sub { say "Hello!" } # Un-named sub
my &f = -> { say "Hello!" }  # Lambda style syntax. The & sigil indicates the variable holds a function
my $f = -> { say "Hello!" }  # Functions can also be put into scalars

Package , Module , Class , Role , and Grammar declaration

There are several types of package, each declared with a keyword, a name, some optional traits, and a body of subroutines, methods, or rules.

package P { }

module M { }

class C { }

role R { }

grammar G { }

Several packages may be declared in a single file. However, you can declare a unit package at the start of the file (preceded only by comments or use statements), and the rest of the file will be taken as being the body of the package. In this case, the curly braces are not required.

unit module M; 
 # ... stuff goes here instead of in {}'s 

Multi-dispatch declaration

See also Multi-dispatch.

Subroutines can be declared with multiple signatures.

multi sub foo() { say "Hello!" }
multi sub foo($name) { say "Hello $name!" }

Inside of a class, you can also declare multi-dispatch methods.

multi method greet { }
multi method greet(Str $name) { }

Subroutine calls

Subroutines are created with the keyword sub followed by an optional name, an optional signature and a code block. Subroutines are lexically scoped, so if a name is specified at the declaration time, the same name can be used in the lexical scope to invoke the subroutine. A subroutine is an instance of type Sub and can be assigned to any container.

foo;   # Invoke the function foo with no arguments 
 foo(); # Invoke the function foo with no arguments 
 &f();  # Invoke &f, which contains a function 
 &f.(); # Same as above, needed to make the following work 
 my @functions = ({say 1}, {say 2}, {say 3}); 
 @functions>>.(); # hyper method call operator 

When declared within a class, a subroutine is named "method": methods are subroutines invoked against an object (i.e., a class instance). Within a method the special variable self contains the object instance (see Methods).

# Method invocation. Object (instance) is $person, method is set-name-age 
 $person.set-name-age('jane', 98);   # Most common way 
 $person.set-name-age: 'jane', 98;   # Precedence drop 
 set-name-age($person: 'jane', 98);  # Invocant marker 
 set-name-age $person: 'jane', 98;   # Indirect invocation 

For more information, see functions.

Precedence drop

In the case of method invocation (i.e., when invoking a subroutine against a class instance) it is possible to apply the precedence drop, identified by a colon : just after the method name and before the argument list. The argument list takes precedence over the method call, that on the other hand "drops" its precedence. In order to better understand consider the following simple example (extra spaces have been added just to align method calls):

my $band = 'Foo Fighters'; 
 say $band.substr( 0, 3 ) .substr( 0, 1 ); # F 
 say $band.substr: 0, 3   .substr( 0, 1 ); # Foo 

In the second method call the rightmost substr is applied to "3" and not to the result of the leftmost substr, which on the other hand yields precedence to the rightmost one.

Operators

See Operators for lots of details.

Operators are functions with a more symbol heavy and composable syntax. Like other functions, operators can be multi-dispatch to allow for context-specific usage.

There are five types (arrangements) for operators, each taking either one or two arguments.

++$x           # prefix, operator comes before single input 
 5 + 3          # infix, operator is between two inputs 
 $x++           # postfix, operator is after single input 
 <the blue sky> # circumfix, operator surrounds single input 
 %foo<bar>      # postcircumfix, operator comes after first input and surrounds second 

Metaoperators

Operators can be composed. A common example of this is combining an infix (binary) operator with assignment. You can combine assignment with any binary operator.

$x += 5     # Adds 5 to $x, same as $x = $x + 5 
 $x min= 3   # Sets $x to the smaller of $x and 3, same as $x = $x min 3 
 $x .= child # Equivalent to $x = $x.child 

Wrap an infix operator in [ ] to create a new reduction operator that works on a single list of inputs, resulting in a single value.

say [+] <1 2 3 4 5>;    # OUTPUT: «15␤»
(((1 + 2) + 3) + 4) + 5 # equivalent expanded version

Wrap an infix operator in « » (or the ASCII equivalent ) to create a new hyper operator that works pairwise on two lists.

say <1 2 3> «+» <4 5 6> # OUTPUT: «(5 7 9)␤»

The direction of the arrows indicates what to do when the lists are not the same size.

@a «+« @b # Result is the size of @b, elements from @a will be re-used 
 @a »+» @b # Result is the size of @a, elements from @b will be re-used 
 @a «+» @b # Result is the size of the biggest input, the smaller one is re-used 
 @a »+« @b # Exception if @a and @b are different sizes 

You can also wrap a unary operator with a hyper operator.

say -« <1 2 3> # OUTPUT: «(-1 -2 -3)␤»

71 System interaction

Working with the underlying operating system and running applications

Getting arguments through the command line

The simplest way is to use the @*ARGS variable to obtain arguments from the command line; this array will contain the strings that follow the program name. %*ENV will contain the environment variables, so that if you use:

export API_KEY=1967196417966160761fabc1511067 
 ./consume_api.p6 

You can use them from your program this way:

my $api-key = %*ENV<API_KEY> // die "Need the API key";

This will fail if the environment variable API_KEY has not been defined previously.

Perl 6 has a better way to deal with command line arguments if they represent file names: the $*ARGFILES dynamic variable.

for $*ARGFILES.lines -> $l { 
     say "Long lines in {$*ARGFILES.path}" 
         if $l.chars > 72 ; 
 } 

You can run this program this way argfiles.p6 *.p6, for instance, and it will print a file name every time it finds a line longer than 72 characters. $*ARGFILES contains filehandles of all files described in the command lines- .lines will read in turn one line from every one of them, changing the value of $*ARGFILES.path every time a new handle is being processed. In general, it provides a very convenient API for scripts that deal with sets of files.

Getting arguments interactively

Use prompt to have a running program query the user for data:

my UInt $num-iters = prompt "How many iterations to run: "; 

Running programs synchronously and asynchronously

There are two routines to run external programs: run and shell. Both exist in the IO role and are thus included in all classes that mix that role in, like IO::Path. Both return a Proc object, but the main difference is that run will try to avoid the system shell, if possible, while shell will run the command through the default system shell.

The key class for running all external programs is Proc::Async, which runs processes asynchronously and allows concurrent interaction with the running processes. In general, it is a good practice to interact with the system through these high-level, abstract interfaces. However, Perl 6 provides with other ways of interacting with the system through a low-level interface.

Making operating system calls through the native API

The NativeCall API can be used to interact with system libraries, as well as any other accessible library. This short tutorial explains, for instance, how to call system functions such as getaddrinfo using that interface; some other functions like kill can also be accessed that way, via declaration using the NativeCall interface.

Fortunately, you do not have to do that for all native functions. As part of her Butterfly project porting Perl 5 functions to Perl 6 as part of the ecosystem, Elizabeth Mattijsen is porting many system functions that were part of that language to modules such as P5getprotobyname, which includes functions such as endprotoent, getprotoent, getprotobyname, getprotobynumber and setprotoent. Search and install P5 modules if you want to use those functions already in p6y form.

72 Traits

Compile-time specification of behavior made easy

In Perl 6, traits are compiler hooks attached to objects and classes that modify their default behavior, functionality or representation. As such compiler hooks, they are defined in compile time, although they can be used in runtime.

Several traits are already defined as part of the language or the Rakudo compiler by using the trait_mod keyword. They are listed, and explained, next.

The is trait

Defined as

proto sub trait_mod:<is>(Mu $, |) {*}

is applies to any kind of scalar object, and can take any number of named or positional arguments. It is the most commonly used trait, and takes the following forms, depending on the type of the first argument.

is applied to classes.

The most common form, involving two classes, one that is being defined and the other existing, defines parenthood. A is B, if both are classes, defines A as a subclass of B.

is DEPRECATED can be applied to classes, Attributes or Routines, marks them as deprecated and issues a message, if provided.

Several instances of is are translated directly into attributes for the class they refer to: rw, nativesize, ctype, unsigned, hidden, array_type.

The Uninstantiable representation trait is not so much related to the representation as related to what can be done with a specific class; it effectively prevents the creation of instances of the class in any possible way.

constant @IMM = <Innie Minnie Moe>; 
 
 class don't-instantiate is repr('Uninstantiable') { 
     my $.counter; 
 
     method imm () { 
         return @IMM[ $.counter++ mod @IMM.elems ]; 
     } 
 } 
 say don't-instantiate.imm for ^10; 

Uninstantiable classes can still be used via their class variables and methods, as above. However, trying to instantiate them this way: my $do-instantiate = don't-instantiate.new; will yield the error You cannot create an instance of this type (don't-instantiate).

is repr and native representations.

Since the is trait refers, in general, to the nature of the class or object they are applied to, they are used extensively in native calls to specify the representation of the data structures that are going to be handled by the native functions via the is repr suffix; at the same time, is native is used for the routines that are actually implemented via native functions. These are the representations that can be used:

On the other hand, P6opaque is the default representation used for all objects in Perl 6.

class Thar {};
say Thar.REPR;    #OUTPUT: «P6opaque␤»

The meta object protocol uses it by default for every object and class unless specified otherwise; for that reason, it is in general not necessary unless you are effectively working with that interface.

is on routines

The is trait can be used on the definition of methods and routines to establish precedence and associativity. They act as a sub defined using trait_mod which take as argument the types and names of the traits that are going to be added. In the case of subroutines, traits would be a way of adding functionality which cuts across class and role hierarchies, or can even be used to add behaviors to independently defined routines.

73 Type system

Introduction to the type system of Perl 6

Definition of a Perl 6 type

A type defines a new object by creating a type object that provides an interface to create instances of objects or to check values against. Any type object is a subclass of Any or Mu. Introspection methods are provided via inheritance from those base classes and the introspection postfix .^. A new type is introduced to the current scope by one of the following type declarators at compile time or with the meta object protocol at runtime. All type names must be unique in their scope.

Default types

If no type is provided by the user Perl 6 assumes the type to be Any. This includes containers, base-classes, parameters and return types.

my $a = 1;
$a = Nil;
say $a.^name;
# OUTPUT: «Any␤»

class C {};
say C.^parents(:all);
# OUTPUT: «((Any) (Mu))␤»

For containers the default type is Any but the default type constraint is Mu. Please note that binding replaces the container, not just the value. The type constraint may change in this case.

Type objects

To test if an object is a type object, use smartmatch against a type constrained with a type smiley or .DEFINITE method:

my $a = Int; 
 say $a ~~ Mu:U; 
 # OUTPUT: «True␤» 
 say not $a.DEFINITE; 
 # OUTPUT: «True␤» 

.DEFINITE will return True if the invocant is an instance. If it returns False, then the invocant is a type object.

Undefinedness

Undefined objects maintain type information in Perl 6. Type objects are used to represent both undefinedness and the type of the undefined value. To provide a general undefined value use Any. If differentiation from Any, the default type for containers and arguments, is required use Mu.

Instances of objects created by .CREATE are by convention defined. The method .defined will return Bool::True to indicate definedness. The exceptions to that rule are Nil and Failure. Please note that any object is able to overload .defined and as such can carry additional information. Also, Perl 6 makes a clear distinction between definedness and trueness. Many values are defined even though they carry the meaning of wrongness or emptiness. Such values are 0, Bool::False, () (empty list) and NaN.

Values can become undefined at runtime via mixin.

my Int $i = 1 but role :: { method defined { False } };
say $i // "undefined";
# OUTPUT: «undefined␤»

To test for definedness call .defined, use //, with/without and signatures.

Coercion

Turning one type into another is done with coercion methods that have the same name as the target type. This convention is made mandatory by Signatures. The source type has to know how to turn itself into the target type. To allow built-in types to turn themselves into user defined types use augment or the MOP.

class C {
    has $.int;
    method this-is-c { put 'oi' x $!int ~ '‽' }
}

use MONKEY-TYPING;
augment class Int {
    method C { C.new(:int(self))}
}

my $i = 10;
$i.=C;
$i.this-is-c();
# OUTPUT: «oioioioioioioioioioi‽␤»

Perl 6 provides methods defined in Cool to convert to a target type before applying further operations. Most built-in types descend from Cool and as such may provide implicit coercion that may be undesired. It is the responsibility of the user to care about trap-free usage of those methods.

my $whatever = "123.6";
say $whatever.round;
# OUTPUT: «124␤»
say <a b c d>.starts-with("ab");
# OUTPUT: «False␤»

Type declarators

Type declarators introduce a new type into the given scope. Nested scopes can be separated by ::. New packages are created automatically if no such scope exists already.

class Foo::Bar::C {};
put Foo::Bar::.keys;
# OUTPUT: «C␤»

Forward declarations can be provided with a block containing only .... The compiler will check at the end of the current scope if the type is defined.

class C {...}
# many lines later
class C { has $.attr }

class

The class declarator creates a compile time construct that is compiled into a type object. The latter is a simple Perl 6 object and provides methods to construct instances by executing initializers and sub methods to fill all attributes declared in a class, and any parent class, with values. Initializers can be provided with the declaration of attributes or in constructors. It's the responsibility of the Metamodel::ClassHOW to know how to run them. This is the only magic part of building objects in Perl 6. The default parent type is Any, which in turn inherits from Mu. The latter provides the default constructor .new which is named like this by convention. Aside from this, .new does not carry any special meaning nor is treated in any special way.

For more information how to use classes see the Classes and objects tutorial.

Mixins

The type introduced by class can be extended with infix:<but> at runtime. The original type is not modified, instead a new type object is returned and can be stored in a container that type checks successful against the original type or the role that is mixed in.

class A {}
role R { method m { say 'oi‽' } }
my R $A = A but R;
my $a1 = $A.new;
$a1.m;
say [$A ~~ R, $a1 ~~ R];
# OUTPUT: «oi‽␤[True True]␤»

Introspection

Metaclass

To test if a given type object is a class, test the meta object method .HOW against Metamodel::ClassHOW.

class C {};
say C.HOW ~~ Metamodel::ClassHOW;
# OUTPUT: «True␤»

Private attributes

Private attributes are addressed with any of the twigils $!, @! and %!. They do not have public accessor methods generated automatically. As such they can not be altered from outside the class they are defined in.

class C {
    has $!priv;
    submethod BUILD { $!priv = 42 }
};

say (.name, .package, .has_accessor) for C.new.^attributes;
# OUTPUT: «($!priv (C) False)␤»

Methods

The method declarator defines objects of type Method and binds them to the provided name in the scope of a class. Methods in a class are has scoped by default. Methods that are our scoped are not added to the method cache by default and as such can not be called with the accessor sigil $.. Call them with their fully qualified name and the invocant as the first argument.

Inheritance and multis

A normal method in a subclass does not compete with multis of a parent class.

class A {
    multi method m(Int $i){ say 'Int' }
    multi method m(int $i){ say 'int' }
}

class B is A {
    method m(Int $i){ say 'B::Int' }
}

my int $i;
B.new.m($i);
# OUTPUT: «B::Int␤»

Only method

To explicitly state that a method is not a multi method use the only method declarator.

class C { 
     only method m {}; 
     multi method m {}; 
 }; 
 # OUTPUT: «X::Comp::AdHoc: Cannot have a multi candidate for 'm' when an only method is also in the package 'C'␤» 

Submethod BUILD

The submethod BUILD is (indirectly) called by .bless. It is meant to set private and public attributes of a class and receives all names attributes passed into .bless. The default constructor .new defined in Mu is the method that invokes it. Given that public accessor methods are not available in BUILD, you must use private attribute notation instead.

class C {
    has $.attr;
    submethod BUILD (:$attr = 42) {
        $!attr = $attr
    };
    multi method new($positional) {
        self.bless(:attr($positional), |%_)
   }
};

C.new.say; C.new('answer').say;
# OUTPUT: «C.new(attr => 42)␤
#          C.new(attr => "answer")␤»

Fallback method

A method with the special name FALLBACK will be called when other means to resolve the name produce no result. The first argument holds the name and all following arguments are forwarded from the original call. Multi methods and sub-signatures are supported.

class Magic {
    method FALLBACK ($name, |c(Int, Str)) {
    put "$name called with parameters {c.perl}"  }
};
Magic.new.simsalabim(42, "answer");

# OUTPUT: «simsalabim called with parameters ⌈\(42, "answer")⌋␤»

Reserved method names

Some built-in introspection methods are actually special syntax provided by the compiler, namely WHAT, WHO, HOW and VAR. Declaring methods with those names will silently fail. A dynamic call will work, what allows to call methods from foreign objects.

class A { 
     method WHAT { "ain't gonna happen" } 
 }; 
 
 say A.new.WHAT;    # OUTPUT: «(A)␤» 
 say A.new."WHAT"() # OUTPUT: «ain't gonna happen␤» 

Methods in package scope

Any our scoped method will be visible in the package scope of a class.

class C {
    our method packaged {};
    method loose {}
};
say C::.keys
# OUTPUT: «(&packaged)␤»

Setting attributes with namesake variables and methods

Instead of writing attr => $attr or :attr($attr), you can save some typing if the variable (or method call) you're setting the attribute with shares the name with the attribute:

class A { has $.i = 42 };
class B {
    has $.i = "answer";
    method m() { A.new(:$.i) }
    #                  ^^^^  Instead of i => $.i or :i($.i)
};
my $a = B.new.m;
say $a.i; # OUTPUT: «answer␤»

Since $.i method call is named i and the attribute is also named i, Perl 6 lets us shortcut. The same applies to :$var, :$!private-attribute, :&attr-with-code-in-it, and so on.

trait is nodal

Marks a List method to indicate to hyperoperator to not descend into inner Iterables to call this method. This trait generally isn't something end users would be using, unless they're subclassing or augmenting core List type.

In order to demonstrate the difference consider the following examples, the first using a method (elems) that is nodal and the second using a method (Int) which is not nodal.

say ((1.0, "2", 3e0), [^4], '5')».elems; # OUTPUT: «(3, 4, 1)␤»
say ((1.0, "2", 3e0), [^4], '5')».Int    # OUTPUT: «((1 2 3) [0 1 2 3] 5)␤»

trait handles

Defined as:

multi sub trait_mod:<handles>(Attribute:D $target, $thunk)

The trait handles applied to an attribute of a class will delegate all calls to the provided method name to the method with the same name of the attribute. The object referenced by the attribute must be initialized. A type constraint for the object that the call is delegated to can be provided.

class A      { method m(){ 'A::m has been called.' } }
class B is A { method m(){ 'B::m has been called.' } }
class C {
    has A $.delegate handles 'm';
    method new($delegate){ self.bless(delegate => $delegate) }
};
say C.new(B.new).m(); # OUTPUT: «B::m has been called.␤»

Instead of a method name, a Pair (for renaming), a list of names or Pairs, a Regex or a Whatever can be provided. In the latter case existing methods, both in the class itself and its inheritance chain, will take precedence. If even local FALLBACKs should be searched, use a HyperWhatever.

class A {
    method m1(){}
    method m2(){}
}

class C {
    has $.delegate handles <m1 m2> = A.new()
}
C.new.m2;

class D {
    has $.delegate handles /m\d/ = A.new()
}
D.new.m1;

class E {
    has $.delegate handles (em1 => 'm1') = A.new()
}
E.new.em1;

trait is

Defined as:

multi sub trait_mod:<is>(Mu:U $child, Mu:U $parent)

The trait is accepts a type object to be added as a parent class of a class in its definition. To allow multiple inheritance the trait can be applied more than once. Adding parents to a class will import their methods into the target class. If the same method name occurs in multiple parents, the first added parent will win.

If no is trait is provided the default of Any will be used as a parent class. This forces all Perl 6 objects to have the same set of basic methods to provide an interface for introspection and coercion to basic types.

class A {
    multi method from-a(){ 'A::from-a' }
}
say A.new.^parents(:all).perl;
# OUTPUT: «(Any, Mu)␤»

class B {
    method from-b(){ 'B::from-b ' }
    multi method from-a(){ 'B::from-A' }
}

class C is A is B {}
say C.new.from-a();
# OUTPUT: «A::from-a␤»

trait is rw

Defined as:

sub trait_mod:<is>(Mu:U $type, :$rw!)

The trait is rw on a class will create writable accessor methods on all public attributes of that class.

class C is rw {
    has $.a;
};
my $c = C.new.a = 42;
say $c; # OUTPUT: «42␤»

trait is required

Defined as:

multi sub trait_mod:<is>(Attribute $attr, :$required!)
multi sub trait_mod:<is>(Parameter:D $param, :$required!)

Marks a class or roles attribute as required. If the attribute is not initialized at object construction time throws X::Attribute::Required.

class Correct {
    has $.attr is required;
    submethod BUILD (:$attr) { $!attr = $attr }
}
say Correct.new(attr => 42);
# OUTPUT: «Correct.new(attr => 42)␤»

class C {
    has $.attr is required;
}
C.new;
CATCH { default { say .^name => .Str } }
# OUTPUT: «X::Attribute::Required => The attribute '$!attr' is required, but you did not provide a value for it.␤»

You can provide a reason why it's required as an argument to is required

class Correct { 
     has $.attr is required("it's so cool") 
 }; 
 say Correct.new(); 
 # OUTPUT: «The attribute '$!attr' is required because it's so cool,␤but you did not provide a value for it.␤» 

trait hides

The trait hides provides inheritance without being subject to re-dispatching.

class A {
    method m { say 'i am hidden' }
}
class B hides A {
    method m { nextsame }
    method n { self.A::m }
};

B.new.m;
B.new.n;
# OUTPUT: «i am hidden␤»

The trait is hidden allows a class to hide itself from re-dispatching.

class A is hidden {
    method m { say 'i am hidden' }
}
class B is A {
    method m { nextsame }
    method n { self.A::m }
}

B.new.m;
B.new.n;
# OUTPUT: «i am hidden␤»

trait trusts

To allow one class to access the private methods of another class use the trait trusts. A forward declaration of the trusted class may be required.

class B {...};
class A {
    trusts B;
    has $!foo;
    method !foo { return-rw $!foo }
    method perl { "A.new(foo => $!foo)" }
};
class B {
    has A $.a .= new;
    method change { $!a!A::foo = 42; self }
};
say B.new.change;
# OUTPUT: «B.new(a => A.new(foo => 42))␤»

Augmenting a class

To add methods and attributes to a class at compile time use augment in front of a class definition fragment. The compiler will demand the pragmas use MONKEY-TYPING or use MONKEY early in the same scope. Please note that there may be performance implications, hence the pragmas.

use MONKEY; augment class Str {
    method mark(Any :$set){
        state $mark //= $set; $mark
    }
};
my $s = "42";
$s.mark(set => "answer");
say $s.mark
# OUTPUT: «answer␤»

There are few limitations of what can be done inside the class fragment. One of them is the redeclaration of a method or sub into a multi. Using added attributes is not yet implemented. Please note that adding a multi candidate that differs only in its named parameters will add that candidate behind the already defined one and as such it won't be picked by the dispatcher.

Versioning and authorship

Versioning and authorship can be applied via the adverbs :ver<> and :auth<>. Both take a string as argument, for :ver the string is converted to a Version object. To query a class version and author use .^ver and ^.auth.

class C:ver<4.2.3>:auth<me@here.local> {}
say [C.^ver, C.^auth];
# OUTPUT: «[v4.2.3 me@here.local]␤»

role

Roles are class fragments, which allow the definition of interfaces that are shared by classes. The role declarator also introduces a type object that can be used for type checks. Roles can be mixed into classes and objects at runtime and compile time. The role declarator returns the created type object thus allowing the definition of anonymous roles and in-place mixins.

role Serialize {
    method to-string { self.Str }
    method to-number { self.Num }
}

class A does Serialize {}
class B does Serialize {}

my Serialize @list;
@list.push: A.new;
@list.push: B.new;

say @list».to-string;
# OUTPUT: «[A<57192848> B<57192880>]␤»

Use ... as the only element of a method body to declare a method to be abstract. Any class getting such a method mixed in has to overload it. If the method is not overloaded before the end of the compilation unit X::Comp::AdHoc will be thrown.

EVAL 'role R { method overload-this(){...} }; class A does R {}; ';
CATCH { default { say .^name, ' ', .Str } }
# OUTPUT: «X::Comp::AdHoc Method 'overload-this' must be implemented by A because it is required by roles: R.␤»

Auto-punning

A role can be used instead of a class to create objects. Since roles can't exist at runtime, a class of the same name is created that will type check successful against the role.

role R { method m { say 'oi‽' } };
R.new.^mro.say;
# OUTPUT: «((R) (Any) (Mu))␤»
say R.new.^mro[0].HOW.^name;
# OUTPUT: «Perl6::Metamodel::ClassHOW␤»
say R.new ~~ R;
# OUTPUT: «True␤»

trait does

The trait does can be applied to roles and classes providing compile time mixins. To refer to a role that is not defined yet, use a forward declaration. The type name of the class with mixed in roles does not reflect the mixin, a type check does. If methods are provided in more than one mixed in role, the method that is defined first takes precedence. A list of roles separated by comma can be provided. In this case conflicts will be reported at compile time.

role R2 {...};
role R1 does R2 {};
role R2 {};
class C does R1 {};

say [C ~~ R1, C ~~ R2];
# OUTPUT: «[True True]␤»

For runtime mixins see but and does.

Parameterized

Roles can be provided with parameters in-between [] behind a roles name. Type captures are supported.

role R[$d] { has $.a = $d };
class C does R["default"] { };

my $c = C.new;
say $c;
# OUTPUT: «C.new(a => "default")␤»

Parameters can have type constraints, where clauses are not supported for types but can be implemented via subsets.

class A {};
class B {};
subset A-or-B where * ~~ A|B;
role R[A-or-B ::T] {};
R[A.new].new;

Default parameters can be provided.

role R[$p = fail("Please provide a parameter to role R")] {};
my $i = 1 does R;
CATCH { default { say .^name, ': ', .Str} }
# OUTPUT: «X::AdHoc: Could not instantiate role 'R':␤Please provide a parameter to role R␤»

As type constraints

Roles can be used as type constraints wherever a type is expected. If a role is mixed in with does or but, its type-object is added to the type-object list of the object in question. If a role is used instead of a class (using auto-punning), the auto-generated class' type-object, of the same name as the role, is added to the inheritance chain.

role Unitish[$unit = fail('Please provide a SI unit quantifier as a parameter to the role Unitish')] { 
     has $.SI-unit-symbol = $unit; 
     method gist { 
         given self { 
             # ... 
             when * < 1 { return self * 1000 ~ 'm' ~ $.SI-unit-symbol } 
             when * < 1000 { return self ~ $.SI-unit-symbol } 
             when * < 1_000_000 { return self / 1_000 ~ 'k' ~ $.SI-unit-symbol } 
             # ... 
         } 
     } 
 } 
 
 role SI-second   does Unitish[<s>] {} 
 role SI-meter    does Unitish[<m>] {} 
 role SI-kilogram does Unitish[<g>] {} 
 
 sub postfix:<s>(Numeric $num) { ($num) does SI-second } 
 sub postfix:<m>(Numeric $num) { ($num) does SI-meter } 
 sub postfix:<g>(Numeric $num) { ($num) does SI-kilogram } 
 sub postfix:<kg>(Numeric $num){ ($num * 1000) does SI-kilogram } 
 
 constant g = 9.806_65; 
 
 role SI-Newton does Unitish[<N>] {} 
 
 multi sub N(SI-kilogram $kg, SI-meter $m, SI-second $s --> SI-Newton ){ ($kg * ($m / $s²)) does SI-Newton } 
 multi sub N(SI-kilogram $kg --> SI-Newton)                            { ($kg * g) does SI-Newton } 
 
 say [75kg, N(75kg)]; 
 # OUTPUT: «[75kg 735.49875kN]␤» 
 say [(75kg).^name, N(75kg).^name]; 
 # OUTPUT: «[Int+{SI-kilogram} Rat+{SI-Newton}]␤» 

Versioning and authorship

Versioning and authorship can be applied via the adverbs :ver<> and :auth<>. Both take a string as argument, for :ver the string is converted to a Version object. To query a role's version and author use .^ver and ^.auth.

role R:ver<4.2.3>:auth<me@here.local> {}
say [R.^ver, R.^auth];
# OUTPUT: «[v4.2.3 me@here.local]␤»

enum

Enumerations provide constant key-value-pairs with an associated type. Any key is of that type and injected as a symbol into the current scope. If the symbol is used, it is treated as a constant expression and the symbol is replaced with the value of the enum-pair. Any Enumeration inherits methods from the role Enumeration. Complex expressions for generating key-value pairs are not supported. In general, an enum is a Map whose elements have the Enumeration role mixed in; this role includes, for each element, an index which creates an order on the map.

Stringification of the symbol, which is done automatically in string context and is exactly equal to its name, which is also the key of the enum-pair.

enum Names ( name1 => 1, name2 => 2 );
say name1, ' ', name2; # OUTPUT: «name1 name2␤»
say name1.value, ' ', name2.value; # OUTPUT: «1 2␤»

Comparing symbols will use type information and the value of the enum-pair. As value types Num and Str are supported.

enum Names ( name1 => 1, name2 => 2 );
sub same(Names $a, Names $b){
   $a eqv $b
}

say same(name1, name1); # OUTPUT: «True␤»
say same(name1, name2); # OUTPUT: «False␤»
my $a = name1;
say $a ~~ Names; # OUTPUT: «True␤»
say $a.^name;    # OUTPUT: «Names␤»

All keys have to be of the same type.

enum Mass ( mg => 1/1000, g => 1/1, kg => 1000/1 );

say Mass.enums;
# OUTPUT: «Map.new((g => 1, kg => 1000, mg => 0.001))␤»

And you can use any kind of symbol:

enum Suit <♣ ♦ ♥ ♠>;

As long as you refer to that symbol using the full syntax:

say Suit::<♣>; # OUTPUT: «♣␤» 

Attempting to access unicode enum keys without said syntax will result in an error:

say ♣ ; # OUTPUT: «(exit code 1) ===SORRY!===␤Argument to "say" seems to be    malformed… 

If no value is given Int will be assumed as the values type and incremented by one per key starting at zero. As enum key types Int, Num, Rat and Str are supported.

enum Numbers <one two three four>;

say Numbers.enums;
# OUTPUT: «Map.new((four => 3, one => 0, three => 2, two => 1))␤»

A different starting value can be provided.

enum Numbers «:one(1) two three four»;

say Numbers.enums;
# OUTPUT: «Map.new((four => 4, one => 1, three => 3, two => 2))␤»

You can also do this with the () form of the initializer, but will need to quote keys that do not have a value:

enum Numbers (
  one => 1,
  'two',
  'three',
  'four'
);

Enums can also be anonymous, with the only difference with named enums being that you cannot use it in Signatures or to declare variables.

my $e = enum <one two three>;
say two;       # OUTPUT: «two␤»
say one.^name; # OUTPUT: «␤»
say $e.^name;  # OUTPUT: «Map␤»

There are various methods to get access to the keys and values of the symbols that have been defined. All of them turn the values into Str, which may not be desirable. By treating the enum as a package, we can get a list of types for the keys.

enum E(<one two>);
my @keys = E::.values;
say @keys.map: *.enums;
# OUTPUT: «(Map.new((one => 0, two => 1)) Map.new((one => 0, two => 1)))␤»

With the use of () parentheses, an enum can be defined using any arbitrary dynamically defined list. The list should consist of Pair objects:

For example, in file config we have:

a 1 b 2

We can create an enum using it with this code:

    enum ConfigValues ('config'.IO.lines.map({ my ($key, $value) = $_.words; $key => $value })); 
     say ConfigValues.enums;          # OUTPUT: «Map.new((a => 1, b => 2))␤» 

Firstly, we read lines from config file, split every line using words method and return resulting pair for every line, thus creating a List of Pairs.

Metaclass

To test if a given type object is an enum, test the meta object method .HOW against Metamodel::EnumHOW or simply test against the Enumeration role.

enum E(<a b c>);
say E.HOW ~~ Metamodel::EnumHOW; # OUTPUT: «True␤»
say E ~~ Enumeration;            # OUTPUT: «True␤»

Methods

method enums

Defined as:

method enums()

Returns the list of enum-pairs.

enum Mass ( mg => 1/1000, g => 1/1, kg => 1000/1 );
say Mass.enums; # OUTPUT: «{g => 1, kg => 1000, mg => 0.001}␤»

Coercion

If you want to coerce the value of an enum element to its proper enum object, use the coercer with the name of the enum:

my enum A (sun => 42, mon => 72);
A(72).pair.say;   # OUTPUT: «mon => 72␤»
A(1000).say; # OUTPUT: «(A)␤»

The last example shows what happens if there is no enum-pair that includes that as a value.

module

Modules are usually one or more source files that expose Perl 6 constructs, such as classes, roles, grammars, subroutines and variables. Modules are usually used for distributing Perl 6 code as libraries which can be used in another Perl 6 program.

For a full explanation see Modules.

Versioning and authorship

Versioning and authorship can be applied via the adverbs :ver<> and :auth<>. Both take a string as argument, for :ver the string is converted to a Version object. To query a modules version and author use .^ver and ^.auth.

module M:ver<4.2.3>:auth<me@here.local> {}
say [M.^ver, M.^auth];
# OUTPUT: «[v4.2.3 me@here.local]␤»

package

Packages are nested namespaces of named program elements. Modules, classes and grammars are all types of package.

For a full explanation see Packages.

grammar

Grammars are a specific type of class intended for parsing text. Grammars are composed of rules, tokens and regexes which are actually methods, since grammars are classes.

For a full explanation see Grammars.

Versioning and authorship

Versioning and authorship can be applied via the adverbs :ver<> and :auth<>. Both take a string as argument, for :ver the string is converted to a Version object. To query a grammars version and author use .^ver and ^.auth.

grammar G:ver<4.2.3>:auth<me@here.local> {}
say [G.^ver, G.^auth];
# OUTPUT: «[v4.2.3 me@here.local]␤»

subset

A subset declares a new type that will re-dispatch to its base type. If a where clause is supplied any assignment will be checked against the given code object.

subset Positive of Int where * > -1;
my Positive $i = 1;
$i = -42;
CATCH { default { put .^name,': ', .Str } }
# OUTPUT: «X::TypeCheck::Assignment: Type check failed in assignment to $i; expected Positive but got Int (-42)␤»

Subsets can be used in signatures, e.g. by typing the output:

subset Foo of List where (Int,Str);
sub a($a, $b, --> Foo) { $a, $b }
# Only a List with the first element being an Int and the second a Str will pass the type check.
a(1, "foo");  # passes
a("foo", 1);  # fails

Subsets can be anonymous, allowing inline placements where a subset is required but a name is neither needed nor desirable.

my enum E1 <A B>;
my enum E2 <C D>;
sub g(@a where { .all ~~ subset :: where E1|E2 } ) {
    say @a
}
g([A, C]);
# OUTPUT: «[A C]␤»

Subsets can be used to check types dynamically, which can be useful in conjunction with require.

require ::('YourModule'); 
 subset C where ::('YourModule::C'); 

74 Unicode

Unicode support in Perl 6

Perl 6 has a high level of support of Unicode. This document aims to be both an overview as well as description of Unicode features which don't belong in the documentation for routines and methods.

For an overview on MoarVM's internal representation of strings, see the MoarVM string documentation.

Filehandles and I/O

Normalization

Perl 6 applies normalization by default to all input and output except for file names, which are read and written as UTF8-C8; graphemes, which are user-visible forms of the characters, will use a normalized representation. For example, the grapheme á can be represented in two ways, either using one codepoint:

á (U+E1 "LATIN SMALL LETTER A WITH ACUTE") 

Or two codepoints:

a +  ́ (U+61 "LATIN SMALL LETTER A" + U+301 "COMBINING ACUTE ACCENT") 

Perl 6 will turn both these inputs into one codepoint, as is specified for Normalization Form C (NFC). In most cases this is useful and means that two inputs that are equivalent are both treated the same. Unicode has a concept of canonical equivalence which allows us to determine the canonical form of a string, allowing us to properly compare strings and manipulate them, without having to worry about the text losing these properties. By default, any text you process or output from Perl 6 will be in this “canonical” form, even when making modifications or concatenations to the string (see below for how to avoid this). For more detailed information about Normalization Form C and canonical equivalence, see the Unicode Foundation's page on Normalization and Canonical Equivalence.

One case where we don't default to this, is for the names of files. This is because the names of files must be accessed exactly as the bytes are written on the disk.

To avoid normalization you can use a special encoding format called UTF8-C8. Using this encoding with any filehandle will allow you to read the exact bytes as they are on disk, without normalization. They may look funny when printed out, if you print it out using a UTF8 handle. If you print it out to a handle where the output encoding is UTF8-C8, then it will render as you would normally expect, and be a byte for byte exact copy. More technical details on UTF8-C8 on MoarVM are described below.

UTF8-C8

UTF-8 Clean-8 is an encoder/decoder that primarily works as the UTF-8 one. However, upon encountering a byte sequence that will either not decode as valid UTF-8, or that would not round-trip due to normalization, it will use NFG synthetics to keep track of the original bytes involved. This means that encoding back to UTF-8 Clean-8 will be able to recreate the bytes as they originally existed. The synthetics contain 4 codepoints:

Under normal UTF-8 encoding, this means the unrepresentable characters will come out as something like ?xFF.

UTF-8 Clean-8 is used in places where MoarVM receives strings from the environment, command line arguments, and filesystem queries, for instance when decoding buffers:

say Buf.new(ord('A'), 0xFE, ord('Z')).decode('utf8-c8');
#  OUTPUT: «A􏿽xFEZ␤»

You can see how the two initial codepoints used by UTF8-C8 show up here, right before the "FE". You can use this type of encoding to read files with unknown encoding:

my $test-file = "/tmp/test";
given open($test-file, :w, :bin) {
  .write: Buf.new(ord('A'), 0xFA, ord('B'), 0xFB, 0xFC, ord('C'), 0xFD);
  .close;
}

say slurp($test-file, enc => 'utf8-c8');
# OUTPUT: «(65 250 66 251 252 67 253)»

Reading with this type of encoding and encoding them back to UTF8-C8 will give you back the original bytes; this would not have been possible with the default UTF-8 encoding.

Please note that this encoding so far is not supported in the JVM implementation of Rakudo.

Entering unicode codepoints and codepoint sequences

You can enter Unicode codepoints by number (decimal as well as hexadecimal). For example, the character named "latin capital letter ae with macron" has decimal codepoint 482 and hexadecimal codepoint 0x1E2:

say "\c[482]"; # OUTPUT: «Ǣ␤»
say "\x1E2";   # OUTPUT: «Ǣ␤»

You can also access Unicode codepoints by name: Perl 6 supports all Unicode names.

say "\c[PENGUIN]"; # OUTPUT: «🐧␤»
say "\c[BELL]";    # OUTPUT: «🔔␤» (U+1F514 BELL)

All Unicode codepoint names/named seq/emoji sequences are now case-insensitive: [Starting in Rakudo 2017.02]

say "\c[latin capital letter ae with macron]"; # OUTPUT: «Ǣ␤»
say "\c[latin capital letter E]";              # OUTPUT: «E␤» (U+0045)

You can specify multiple characters by using a comma separated list with \c[]. You can combine numeric and named styles as well:

say "\c[482,PENGUIN]"; # OUTPUT: «Ǣ🐧␤»

In addition to using \c[] inside interpolated strings, you can also use the uniparse:

say "DIGIT ONE".uniparse;  # OUTPUT: «1␤»
say uniparse("DIGIT ONE"); # OUTPUT: «1␤»

Name aliases

Name Aliases are used mainly for codepoints without an official name, for abbreviations, or for corrections (Unicode names never change). For full list of them see here.

Control codes without any official name:

say "\c[ALERT]";     # Not visible (U+0007 control code (also accessible as \a))
say "\c[LINE FEED]"; # Not visible (U+000A same as "\n")

Corrections:

say "\c[LATIN CAPITAL LETTER GHA]"; # OUTPUT: «Ƣ␤»
say "Ƣ".uniname; # OUTPUT: «LATIN CAPITAL LETTER OI␤»
# This one is a spelling mistake that was corrected in a Name Alias:
say "\c[PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRACKET]".uniname;
# OUTPUT: «PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET␤»

Abbreviations:

say "\c[ZWJ]".uniname;  # OUTPUT: «ZERO WIDTH JOINER␤»
say "\c[NBSP]".uniname; # OUTPUT: «NO-BREAK SPACE␤»

Named sequences

You can also use any of the Named Sequences, these are not single codepoints, but sequences of them. [Starting in Rakudo 2017.02]

say "\c[LATIN CAPITAL LETTER E WITH VERTICAL LINE BELOW AND ACUTE]";      # OUTPUT: «É̩␤»
say "\c[LATIN CAPITAL LETTER E WITH VERTICAL LINE BELOW AND ACUTE]".ords; # OUTPUT: «(201 809)␤»

Emoji sequences

Perl 6 supports Emoji sequences. For all of them see: Emoji ZWJ Sequences and Emoji Sequences. Note that any names with commas should have their commas removed, since Perl 6 uses commas to separate different codepoints/sequences inside the same \c sequence.

say "\c[woman gesturing OK]";         # OUTPUT: «🙆‍♀️␤»
say "\c[family: man woman girl boy]"; # OUTPUT: «👨‍👩‍👧‍👦␤»

75 Unicode versus ASCII symbols

Unicode symbols and their ASCII equivalents

The following Unicode symbols can be used in Perl 6 without needing to load any additional modules. Some of them have equivalents which can be typed with ASCII-only characters.

Reference is made below to various properties of unicode codepoints. The definitive list can be found here: https://www.unicode.org/Public/UCD/latest/ucd/PropList.txt.

Alphabetic characters

Any codepoint that has the Ll (Letter, lowercase), Lu (Letter, uppercase), Lt (Letter, titlecase), Lm (Letter, modifier), or the Lo (Letter, other) property can be used just like any other alphabetic character from the ASCII range.

my $Δ = 1; 
 $Δ++; 
 say $Δ; 

Numeric characters

Any codepoint that has the Nd (Number, decimal digit) property, can be used as a digit in any number. For example:

my $var = 19; # U+FF11 U+FF19
say $var + 2;  # OUTPUT: «21␤»

Numeric values

Any codepoint that has the No (Number, other) or Nl (Number, letter) property can be used standalone as a numeric value, such as ½ and ⅓. (These aren't decimal digit characters, so can't be combined.) For example:

my $var = ⅒ + 2 + Ⅻ; # here ⅒ is No and Rat and Ⅻ is Nl and Int
say $var;            # OUTPUT: «14.1␤»

Whitespace characters

Besides spaces and tabs you can use any other unicode whitespace character that has the Zs (Separator, space), Zl (Separator, line), or Zp (Separator, paragraph) property.

Other acceptable single codepoints

This list contains the single codepoints [and their ASCII equivalents] that have a special meaning in Perl 6.

Symbol Codepoint ASCII Remarks
« U+00AB << as part of «» or .« or regex left word boundary
» U+00BB >> as part of «» or .» or regex right word boundary
× U+00D7 *
÷ U+00F7 /
U+2264 <=
U+2265 >=
U+2260 !=
U+2212 -
U+2218 o
U+2245 =~=
π U+03C0 pi 3.14159_26535_89793_238e0
τ U+03C4 tau 6.28318_53071_79586_476e0
𝑒 U+1D452 e 2.71828_18284_59045_235e0
U+221E Inf
U+2026 ...
U+2018 ' as part of ‘’ or ’‘
U+2019 ' as part of ‘’ or ‚’ or ’‘
U+201A ' as part of ‚‘ or ‚’
U+201C " as part of “” or ”“
U+201D " as part of “” or ”“ or ””
U+201E " as part of „“ or „”
U+FF62 Q// as part of 「」 (Note: Q// variant cannot be used bare in regexes)
U+FF63 Q// as part of 「」 (Note: Q// variant cannot be used bare in regexes)
U+207A + (must use explicit number) as part of exponentiation
U+207B - (must use explicit number) as part of exponentiation
¯ U+00AF - (must use explicit number) as part of exponentiation (macron is an alternative way of writing a minus)
U+2070 **0 can be combined with ⁰..⁹
¹ U+00B9 **1 can be combined with ⁰..⁹
² U+00B2 **2 can be combined with ⁰..⁹
³ U+00B3 **3 can be combined with ⁰..⁹
U+2074 **4 can be combined with ⁰..⁹
U+2075 **5 can be combined with ⁰..⁹
U+2076 **6 can be combined with ⁰..⁹
U+2077 **7 can be combined with ⁰..⁹
U+2078 **8 can be combined with ⁰..⁹
U+2079 **9 can be combined with ⁰..⁹
U+2205 set() (empty set)
U+2208 (elem)
U+2209 !(elem)
U+220B (cont)
U+220C !(cont)
U+2286 (<=)
U+2288 !(<=)
U+2282 (<)
U+2284 !(<)
U+2287 (>=)
U+2289 !(>=)
U+2283 (>)
U+2285 !(>)
U+222A (|)
U+2229 (&)
U+2216 (-)
U+2296 (^)
U+228D (.)
U+228E (+)

Atomic operators

The atomic operators have U+269B ⚛ ATOM SYMBOL incorporated into them. Their ASCII equivalents are ordinary subroutines, not operators:

my atomicint $x = 42;
$x⚛++;                # Unicode version
atomic-fetch-inc($x); # ASCII version

The ASCII alternatives are as follows:

Symbol ASCII Remarks
⚛= atomic-assign
atomic-fetch this is the prefix:<⚛> operator
⚛+= atomic-add-fetch
⚛-= atomic-sub-fetch
⚛−= atomic-sub-fetch this operator uses U+2212 minus sign
++⚛ atomic-inc-fetch
⚛++ atomic-fetch-inc
--⚛ atomic-dec-fetch
⚛-- atomic-fetch-dec

Multiple codepoints

This list contains multiple-codepoint operators that require special composition for their ASCII equivalents. Note the codepoints are shown space-separated but should be entered as adjacent codepoints when used.

Symbol Codepoints ASCII Since Remarks
»=» U+00BB = U+00BB >>[=]>> v6.c uses ASCII '='
«=« U+00AB = U+00AB <<[=]<< v6.c uses ASCII '='
«=» U+00AB = U+00BB <<[=]>> v6.c uses ASCII '='
»=« U+00BB = U+00AB >>[=]<< v6.c uses ASCII '='

76 Variables

Variables in Perl 6

Variables are symbolic names for values or containers. Variable declarations or assignment of values may create a container on the fly. Variable names can start with or without a special character called a sigil, followed optionally by a second special character named twigil and then an identifier.

Sigils

There are four sigils. The scalar-sigil $, the positional-sigil @, the associative-sigil % and the callable-sigil &.

Sigils provide a link between syntax, the type system and containers. They provide a shortcut for the most common type constraints when declaring variables and serve as markers for string interpolation. The positional-sigil and the associative-sigil provide type constraint that enforce a base type subscripts require to know what methods to dispatch to. The callable-sigil does the same for function calls. The latter also tells the compiler where parentheses for calls can be omitted. The positional and associative-sigil also simplify assignment by flattening by default.

Sigil Type constraint Default type Assignment Examples
$ Mu (no type constraint) Any item Int, Str, Array, Hash
@ Positional Array list List, Array, Range, Buf
% Associative Hash list Hash, Map, Pair
& Callable Callable item Sub, Method, Block, Routine

Examples:

my $square = 9 ** 2;
my @array  = 1, 2, 3;   # Array variable with three elements
my %hash   = London => 'UK', Berlin => 'Germany';

The type to which the variable will be bound can be set with is in the declaration of the variable. Assuming we have a FailHash class:

class FailHash is Hash {
    has Bool $!final = False;
    multi method AT-KEY ( ::?CLASS:D: Str:D \key ){
        fail X::OutOfRange.new(:what("Hash key"), :got(key),
          :range(self.keys)) if $!final && !self.EXISTS-KEY(key);
        callsame  # still not final, so do normal action from Hash
    }

    method finalize() {
        $!final = True
    }
}

One can then define a %h variable of this type using is:

my %h is FailHash = oranges => "round", bananas => "bendy"; 

And then run the following code:

say %h<oranges>; 
 # OUTPUT: «round␤» 
 %h.finalize; 
 say %h<cherry>; 
 CATCH { default { put .^name, ': ', .Str } } 
 # OUTPUT: «X::OutOfRange: Hash key out of range. Is: cherry, should be in (oranges bananas)» 

For information on variables without sigils, see sigilless variables.

Item and list assignment

There are two types of variable assignment, item assignment and list assignment. Both use the equal sign = as operator. The syntax of the left-hand side determines whether an = means item or list assignment.

Item assignment places the value from the right-hand side into the variable (container) on the left.

List assignment leaves the choice of what to do to the variable on the left.

For example, Array variables (@ sigil) empty themselves on list assignment and then put all the values from the right-hand side into themselves.

The type of assignment (item or list) is decided by the first context seen in the current expression or declarator:

my $foo = 5;            # item assignment
say $foo.perl;          # OUTPUT: «5␤»

my @bar = 7, 9;         # list assignment
say @bar.^name;         # OUTPUT: «Array␤»
say @bar.perl;          # OUTPUT: «[7, 9]␤»

(my $baz) = 11, 13;     # list assignment
say $baz.^name;         # OUTPUT: «List␤»
say $baz.perl;          # OUTPUT: «$(11, 13)␤»

Thus, the behavior of an assignment contained within a list assignment depends on the expression that contains it or declarator that precedes it.

For instance, if the contained assignment is a declarator, item assignment is used, which has tighter precedence than both the comma and the list assignment:

my @array;
@array = my $num = 42, "str";   # item assignment: uses declarator for $num
say @array.perl;                # OUTPUT: «[42, "str"]␤» (an Array)
say $num.perl;                  # OUTPUT: «42␤» (a Num)

Similarly, if the internal or contained assignment is an expression that is being used as an initializer for a container declarator, the context of the internal expression determines the assignment type:

my $num;
my @array = $num = 42, "str";    # item assignment for $num: uses expression
say @array.perl;                 # OUTPUT: «[42, "str"]␤» (an Array)
say $num.perl;                   # OUTPUT: «42␤» (a Num)

The same result would be obtained if @array is declared before the assignment; $num would be still item-assigned, @array list-assigned; the assignment expression is parsed as @array = (($num = 42), "str"), because item assignment has tighter precedence than the comma. However, let's see what happens if the internal variable assignment is in a list context:

my ( @foo, $bar ); 
 @foo = ($bar) = 42, "str";       # list assignment for $bar: uses parentheses 
 say @foo.perl;                   # OUTPUT: «[(42, "str"),]␤» (an Array) 
 say $bar.perl;                   # OUTPUT: «$(42, "str")␤» (a List)# 

In this case, () is the list contextualizer, putting the assignment to $bar in a list context; $bar then decides to include all the items to the right hand side of the = sign; this is still included in a list assignment to @foo, which then becomes an array with a single element, a List.

See operators for more details on precedence.

Sigilless variables

Using the \ prefix, it's possible to create variables that do not have a sigil:

my \degrees = pi / 180;
my \θ       = 15 * degrees;

Note that sigilless variable do not have associated containers. This means degrees and θ, above, actually directly represent Nums. To illustrate, try assigning to one after you've defined it:

θ = 3; # Dies with the error "Cannot modify an immutable Num" 

Sigilless variables do not enforce context, so they can be used to pass something on as-is:

sub logged(&f, |args) {
    say('Calling ' ~ &f.name ~ ' with arguments ' ~ args.perl);
    my \result = f(|args);
    #  ^^^^^^^ not enforcing any context here
    say(&f.name ~ ' returned ' ~ result.perl);
    return |result;
}

Sigilless variables can also be used for binding. See Binding for more information.

Twigils

Twigils influence the scoping of a variable; however, they have no influence over whether the primary sigil interpolates. That is, if $a interpolates, so do $^a, $*a, $=a, $?a, $.a, etc. It only depends on the $.

Twigil Scope
none Based only on declarator
* Dynamic
? Compile-time variable
! Attribute (class member)
. Method (not really a variable)
< Index into match object (not really a variable)
^ Self-declared formal positional parameter
: Self-declared formal named parameter
= Pod variables
~ The sublanguage seen by the parser at this lexical spot

The * twigil

This twigil is used for dynamic variables which are looked up through the caller's, not through the outer, scope. Look at the example below.

Note: So far, if you use rakudo perl6, the example below cannot run correctly in the REPL. Please test it by copy-pasting it into a file, then run the file.

my $lexical   = 1; 
 my $*dynamic1 = 10; 
 my $*dynamic2 = 100; 
 
 sub say-all() { 
     say "$lexical, $*dynamic1, $*dynamic2"; 
 } 
 
 say-all();    # OUTPUT: 1, 10, 100 
 
 { 
     my $lexical   = 2; 
     my $*dynamic1 = 11; 
     $*dynamic2    = 101; 
 
     say-all(); # OUTPUT: 1, 11, 101 
 } 
 
 say-all();  # OUTPUT: 1, 10, 101 

The first time &say-all is called, it prints "1, 10, 100" just as one would expect. The second time though, it prints "1, 11, 101". This is because $lexical isn't looked up in the caller's scope but in the scope &say-all was defined in. The two dynamic variables are looked up in the caller's scope and therefore have the values 11 and 101. The third time &say-all is called $*dynamic1 isn't 11 anymore, but $*dynamic2 is still 101. This stems from the fact that we declared a new dynamic variable $*dynamic1 in the block and did not assign to the old variable as we did with $*dynamic2.

The dynamic variables differ from other variable types in that referring to an undeclared dynamic variable is not a compile time error but a runtime failure, so a dynamic variable can be used undeclared as long as it's checked for definedness or used in a boolean context before using it for anything else:

sub foo() { 
     $*FOO // 'foo'; 
 } 
 
 say foo; # OUTPUT: «foo␤» 
 
 my $*FOO = 'bar'; 
 
 say foo; # OUTPUT: «bar␤» 

Dynamic variables can have lexical scope when declared with my or package scope when declared with our. Dynamic resolution and resolution through symbol tables introduced with our are two orthogonal issues.

The ? twigil

Compile-time variables may be addressed via the ? twigil. They are known to the compiler and may not be modified after being compiled in. A popular example for this is:

say "$?FILE: $?LINE"; # OUTPUT: "hello.p6: 23"
                      # if this is the line 23 of a
                      # file named "hello.p6"

For a list of these special variables, see compile-time variables.

The ! twigil

Attributes are variables that exist per instance of a class. They may be directly accessed from within the class via !:

my class Point {
    has $.x;
    has $.y;

    method Str() {
        "($!x, $!y)"
    }
}

Note how the attributes are declared as $.x and $.y but are still accessed via $!x and $!y. This is because in Perl 6 all attributes are private and can be directly accessed within the class by using $!attribute-name. Perl 6 may automatically generate accessor methods for you though. For more details on objects, classes and their attributes see object orientation.

The . twigil

The . twigil isn't really for variables at all. In fact, something along the lines of

my class Point {
    has $.x;
    has $.y;

    method Str() {
        "($.x, $.y)" # note that we use the . instead of ! this time
    }
}

just calls the methods x and y on self, which are automatically generated for you because you used the . twigil when the attributes were declared. Note, however, that subclasses may override those methods. If you don't want this to happen, use $!x and $!y instead.

The fact that the . twigil does a method call implies that the following is also possible:

class SaySomething {
    method a() { say "a"; }
    method b() { $.a; }
}

SaySomething.b; # OUTPUT: «a␤»

For more details on objects, classes and their attributes and methods see object orientation.

The ^ twigil

The ^ twigil declares a formal positional parameter to blocks or subroutines; that is, variables of the form $^variable are a type of placeholder variable. They may be used in bare blocks to declare formal parameters to that block. So the block in the code

my @powers-of-three = 1,3,9…100;
say reduce { $^b - $^a }, 0, |@powers-of-three;
# OUTPUT: «61␤»

has two formal parameters, namely $a and $b. Note that even though $^b appears before $^a in the code, $^a is still the first formal parameter to that block. This is because the placeholder variables are sorted in Unicode order. If you have self-declared a parameter using $^a once, you may refer to it using only $a thereafter.

Although it is possible to use nearly any valid identifier as a placeholder variable, it is recommended to use short names or ones that can be trivially understood in the correct order, to avoid surprise on behalf of the reader.

Normal blocks and subroutines may also make use of placeholder variables but only if they do not have an explicit parameter list.

sub say-it    { say $^a; } # valid 
 sub say-it()  { say $^a; } # invalid 
               { say $^a; } # valid 
 -> $x, $y, $x { say $^a; } # invalid 

Placeholder variables cannot have type constraints or a variable name with a single upper-case letter (this is disallowed to enable catching some Perl5-isms).

The : twigil

The : twigil declares a formal named parameter to a block or subroutine. Variables declared using this form are a type of placeholder variable too. Therefore the same things that apply to variables declared using the ^ twigil also apply here (with the exception that they are not positional and therefore not ordered using Unicode order, of course). For instance:

say { $:add ?? $^a + $^b !! $^a - $^b }( 4, 5 ) :!add
# OUTPUT: «-1␤»

See ^ for more details about placeholder variables.

The = twigil

The = twigil is used to access Pod variables. Every Pod block in the current file can be accessed via a Pod object, such as $=data, $=SYNOPSIS or =UserBlock. That is: a variable with the same name of the desired block and a = twigil.

  =begin code 
   =begin Foo 
   ... 
   =end Foo 
 
   #after that, $=Foo gives you all Foo-Pod-blocks 
   =end code 

You may access the Pod tree which contains all Pod structures as a hierarchical data structure through $=pod.

Note that all those $=someBlockName support the Positional and the Associative roles.

The ~ twigil

The ~ twigil is for referring to sublanguages (called slangs). The following are useful:

$~MAIN the current main language (e.g. Perl statements)
$~Quote the current root of quoting language
$~Quasi the current root of quasiquoting language
$~Regex the current root of regex language
$~Trans the current root of transliteration language
$~P5Regex the current root of the Perl 5 regex language

You augment these languages in your current lexical scope.

use MONKEY-TYPING; 
 augment slang Regex {  # derive from $~Regex and then modify $~Regex 
     token backslash:std<\Y> { YY }; 
 } 

Variable declarators and scope

Most of the time it's enough to create a new variable using the my keyword:

my $amazing-variable = "World";
say "Hello $amazing-variable!"; # OUTPUT: «Hello World!␤»

However, there are many declarators that change the details of scoping beyond what #Twigils can do.

Declarator Effect
my Introduces lexically scoped names
our Introduces package-scoped names
has Introduces attribute names
anon Introduces names that are private to the construct
state Introduces lexically scoped but persistent names
augment Adds definitions to an existing name
supersede Replaces definitions of an existing name

There are also two prefixes that resemble declarators but act on predefined variables:

Prefix Effect
temp Restores a variable's value at the end of scope
let Restores a variable's value at the end of scope if the block exits unsuccessfully
constant Declares that a container value is not going to change during its lifetime

The my declarator

Declaring a variable with my gives it lexical scope. This means it only exists within the current block. For example:

{ 
     my $foo = "bar"; 
     say $foo; # OUTPUT: «"bar"␤» 
 } 
 say $foo; # Exception! "Variable '$foo' is not declared" 

This dies because $foo is only defined as long as we are in the same scope.

In order to create more than one variable with a lexical scope in the same sentence surround the variables with parentheses:

my ( $foo, $bar );

see also Declaring a list of variables with lexical or package scope.

Additionally, lexical scoping means that variables can be temporarily redefined in a new scope:

my $location = "outside";

sub outer-location {
    # Not redefined:
    say $location;
}

outer-location; # OUTPUT: «outside␤»

sub in-building {
    my $location = "inside";
    say $location;
}

in-building;    # OUTPUT: «inside␤»

outer-location; # OUTPUT: «outside␤»

If a variable has been redefined, any code that referenced the outer variable will continue to reference the outer variable. So here, &outer-location still prints the outer $location:

sub new-location { 
     my $location = "nowhere"; 
     outer-location; 
 } 
 
 new-location; # OUTPUT: «outside␤» 

To make new-location() print nowhere, make $location a dynamic variable using the * twigil. This twigil makes the compiler look up the symbol in the calling scope instead of the outer scope after trying the local scope.

my is the default scope for subroutines, so my sub x() {} and sub x() {} do exactly the same thing.

The our declarator

our variables work just like my variables, except that they also introduce an alias into the symbol table.

module M {
    our $Var;
    # $Var available here
}

# Available as $M::Var here.

In order to create more than one variable with package scope, at the same time, surround the variables with parentheses:

our ( $foo, $bar );

see also the section on declaring a list of variables with lexical or package scope.

Declaring a list of variables with lexical (my) or package (our) scope

It is possible to scope more than one variable at a time, but both my and our require variables to be placed into parentheses:

my  (@a,  $s,  %h);   # same as my @a; my $s; my %h;
our (@aa, $ss, %hh);  # same as our @aa; our $ss; our %hh;

This can be used in conjunction with destructuring assignment. Any assignment to such a list will take the number of elements provided in the left list and assign corresponding values from the right list to them. Any missing elements are left will result in undefined values according to the type of the variables.

my (Str $a, Str $b, Int $c) = <a b>;
say [$a, $b, $c].perl;
# OUTPUT: «["a", "b", Int]␤»

To destructure a list into a single value, create a list literal with one element by using ($var,). When used with a variable declarator, providing parentheses around a single variable is sufficient.

sub f { 1,2,3 };
my ($a) = f;
say $a.perl;
# OUTPUT: «1␤»

To skip elements in the list use the anonymous state variable $.

my ($,$a,$,%h) = ('a', 'b', [1,2,3], {:1th});
say [$a, %h].perl;
# OUTPUT: «["b", {:th(1)}]␤»

The has declarator

has scopes attributes to instances of a class or role, and methods to classes or roles. has is implied for methods, so has method x() {} and method x() {} do the same thing.

See object orientation for more documentation and some examples.

The anon declarator

The anon declarator prevents a symbol from getting installed in the lexical scope, the method table and everywhere else.

For example, you can use it to declare subroutines which know their own name, but still aren't installed in a scope:

my %operations =
    half   => anon sub half($x) { $x / 2 },
    square => anon sub square($x) { $x * $x },
    ;
say %operations<square>.name;       # square
say %operations<square>(8);         # 64

Since it is a declarator, it can be applied anywhere anything is declared, for instance for classes or even sigilless variables.

say anon class þ {};     # OUTPUT: «(þ)␤»
say anon sub þ  { 42 };  # OUTPUT: «&þ␤»

Since these symbols are not installed in the scope, they can't be used by name. They are useful, however, if they need to be assigned to an external variable and they need to know their own name, but this can be retrieved using introspection.

my $anon-class = anon class { 
     has $.bar; 
     method equal( ::?CLASS $foo ) { 
       return $foo.bar == $.bar; 
     } 
 }; 
 say $anon-class.new( :3bar).equal( $anon-class.new( :3bar ) ); 

The state declarator

state declares lexically scoped variables, just like my. However, initialization happens exactly once the first time the initialization is encountered in the normal flow of execution. Thus, state variables will retain their value across multiple executions of the enclosing block or routine.

Therefore, the subroutine

sub a {
    state @x;
    state $l = 'A';
    @x.push($l++);
};

say a for 1..6;

will continue to increment $l and append it to @x each time it is called. So it will output:

[A] 
 [A B] 
 [A B C] 
 [A B C D] 
 [A B C D E] 
 [A B C D E F] 

Since they have a lexical scope, they are tied to the block in which they are declared.

sub foo () { 
   for 0..1 { 
     state $foo = 1; 
     say $foo++; 
   } 
 }; 
 foo;  # OUTPUT: «1␤2␤» 
 foo;  # OUTPUT: «1␤2␤» 

In this case, a new state variable is created every time the block that runs the for loop is entered, which is why the state variable is reset in every call to foo.

This works per "clone" of the containing code object, as in this example:

({ state $i = 1; $i++.say; } xx 3).map: {$_(), $_()}; # says 1 then 2 thrice 

Note that this is not a thread-safe construct when the same clone of the same block is run by multiple threads. Also remember that methods only have one clone per class, not per object.

As with my, a declaration of multiple state variables must be placed in parentheses which can be omitted for a single variable.

Many operators come with implicit binding which can lead to actions at a distance.

Use .clone or coercion to create a new container that can be bound to.

my @a;
my @a-cloned;
sub f() {
    state $i;
    $i++;
    @a\      .push: "k$i" => $i;
    @a-cloned.push: "k$i" => $i.clone;
};

f for 1..3;
say @a;        # OUTPUT: «[k1 => 3 k2 => 3 k3 => 3]␤»
say @a-cloned; # OUTPUT: «[k1 => 1 k2 => 2 k3 => 3]␤»

State variables are shared between all threads. The result can be unexpected.

sub code(){ state $i = 0; say ++$i; $i };
await
    start { loop { last if code() >= 5 } },
    start { loop { last if code() >= 5 } };

# OUTPUT: «1␤2␤3␤4␤4␤3␤5␤»
# OUTPUT: «2␤1␤3␤4␤5␤»
# many other more or less odd variations can be produced

The $ variable

In addition to explicitly declared named state variables, $ can be used as an anonymous state variable without an explicit state declaration.

say "1-a 2-b 3-c".subst(:g, /\d/, {<one two three>[$++]});
# OUTPUT: «one-a two-b three-c␤»

Furthermore, state variables can be used outside of subroutines. You could, for example, use $ in a one-liner to number the lines in a file.

perl6 -ne 'say ++$ ~ " $_"' example.txt 

Each reference to $ within a lexical scope is in effect a separate variable.

perl6 -e '{ say ++$; say $++  } for ^5' 
 # OUTPUT: «1␤0␤2␤1␤3␤2␤4␤3␤5␤4␤» 

That is why, if you need to reference the same $ variable (or, for that matter, any of the other anon state variables @ and %) more than once, a possible solution is to bind another variable to it, although in this example it would be more straightforward to just declare state $x and not use the magical/anonymous $ variable:

sub foo () { 
     my $x := $; 
     $x++; 
     say $x; 
     $x = $x + 1; 
 } 
 
 foo() for ^3; # OUTPUT: «1␤3␤5␤» 

In general, it is better style to declare a named state variable in case you have to refer to it several times.

Note that the implicit state declarator is only applied to the variable itself, not the expression that may contain an initializer. If the initializer has to be called exactly once, the state declarator has to be provided.

for ^3 {       $ = .say } # OUTPUT: «0␤1␤2␤» 
 for ^3 { state $ = .say } # OUTPUT: «0␤» 

The @ variable

Similar to the $ variable, there is also a Positional anonymous state variable @.

sub foo($x) {
    say (@).push($x);
}

foo($_) for ^3;

# OUTPUT: «[0]
#          [0 1]
#          [0 1 2]␤»

The @ here is parenthesized in order to disambiguate the expression from a class member variable named @.push. Indexed access doesn't require this disambiguation but you will need to copy the value in order to do anything useful with it.

sub foo($x) {
    my $v = @;
    $v[$x] = $x;
    say $v;
}

foo($_) for ^3;

# OUTPUT: «[0]
#          [0 1]
#          [0 1 2]␤»

As with $, each mention of @ in a scope introduces a new anonymous array.

The % variable

In addition, there's an Associative anonymous state variable %.

sub foo($x) {
    say (%).push($x => $x);
}

foo($_) for ^3;

# OUTPUT: «{0 => 0}
#          {0 => 0, 1 => 1}
#          {0 => 0, 1 => 1, 2 => 2}␤»

The same caveat about disambiguation applies. As you may expect, indexed access is also possible (with copying to make it useful).

sub foo($x) {
    my $v = %;
    $v{$x} = $x;
    say $v;
}

foo($_) for ^3;

# OUTPUT: «{0 => 0}
#          {0 => 0, 1 => 1}
#          {0 => 0, 1 => 1, 2 => 2}␤»

As with the other anonymous state variables, each mention of % within a given scope will effectively introduce a separate variable.

The augment declarator

With augment, you can add attributes and methods to existing classes and grammars, provided you activated the MONKEY-TYPING pragma first.

Since classes are usually our scoped, and thus global, this means modifying global state, which is strongly discouraged. For almost all situations, there are better solutions.

# don't do this
use MONKEY-TYPING;
augment class Int {
    method is-answer { self == 42 }
}
say 42.is-answer;       # OUTPUT: «True␤»

(In this case, the better solution would be to use a function).

The temp prefix

Like my, temp restores the old value of a variable at the end of its scope. However, temp does not create a new variable.

my $in = 0; # temp will "entangle" the global variable with the call stack
            # that keeps the calls at the bottom in order.
sub f(*@c) {
    (temp $in)++;
     "<f>\n"
     ~ @c».indent($in).join("\n")
     ~ (+@c ?? "\n" !! "")
     ~ '</f>'
};
sub g(*@c) {
    (temp $in)++;
    "<g>\n"
    ~ @c».indent($in).join("\n")
    ~ (+@c ?? "\n" !! "")
    ~ "</g>"
};
print g(g(f(g()), g(), f()));

# OUTPUT: «<g>
#           <g>
#            <f>
#             <g>
#             </g>
#            </f>
#            <g>
#            </g>
#            <f>
#            </f>
#           </g>
#          </g>␤»

The let prefix

Restores the previous value if the block exits unsuccessfully. A successful exit means the block returned a defined value or a list.

my $answer = 42;

{
    let $answer = 84;
    die if not Bool.pick;
    CATCH {
        default { say "it's been reset :(" }
    }
    say "we made it 84 sticks!";
}

say $answer;

In the above case, if the Bool.pick returns true, the answer will stay as 84 because the block returns a defined value (say returns True). Otherwise the die statement will cause the block to exit unsuccessfully, resetting the answer to 42.

The constant prefix

The constant prefix declares that a container value is not going to change during its lifetime.

constant $pi2 = pi * 2; 
 $pi2 = 6; # OUTPUT: «(exit code 1) Cannot assign to an immutable value␤ 

The value is assigned at compile time. Please check the section on constants in the Terms page for additional information.

Type constraints and initialization

Variables have a type constraint via the container they are bound to, which goes between the declarator and the variable name. The default type constraint is Mu. You can also use the trait of to set a type constraint.

    my Int $x = 42; 
     $x = 'a string'; 
     CATCH { default { put .^name, ': ', .Str } } 
     # OUTPUT: «X::TypeCheck::Assignment: Type check failed in assignment to $x; 
     expected Int but got Str ("a string")␤» 

If a scalar variable has a type constraint but no initial value, it's initialized with the type object of the default value of the container it's bound to.

my Int $x;
say $x.^name;       # OUTPUT: «Int␤»
say $x.defined;     # OUTPUT: «False␤»

Scalar variables without an explicit type constraint are typed as Mu but default to the Any type object.

Variables with the @ sigil are initialized with an empty Array; variables with the % sigil are initialized with an empty Hash.

The default value of a variable can be set with the is default trait, and re-applied by assigning Nil to it:

my Real $product is default(1);
say $product;                       # OUTPUT: «1␤»
$product *= 5;
say $product;                       # OUTPUT: «5␤»
$product = Nil;
say $product;                       # OUTPUT: «1␤»

Default defined variables pragma

To force all variables to have a definiteness constraint, use the pragma use variables :D. The pragma is lexically scoped and can be switched off with use variables :_.

use variables :D; 
 my Int $i; 
 # OUTPUT: «===SORRY!=== Error while compiling <tmp>␤Variable definition of type Int:D (implicit :D by pragma) requires an initializer ... 
 my Int $i = 1; # that works 
 { use variables :_; my Int $i; } # switch it off in this block 

Note that assigning Nil will revert the variable to its default value, which is often not a definite value and as such would fail the constraint:

use variables :D; 
 my Int $x = 42; 
 $x = Nil; 
 # OUTPUT: «Type check failed in assignment to $x; expected type Int:D cannot be itself…» 

As the name suggests, this pragma applies only to variables. To effect the same behavior on parameters, use the use parameters :D pragma (currently NYI in Rakudo).

Special variables

Perl 6 attempts to use long, descriptive names for special variables. There are only three special variables that are extra short.

Pre-defined lexical variables

There are three special variables that are available in every block:

Variable Meaning
$_ topic variable
$/ regex match
$! exceptions

The $_ variable

$_ is the topic variable. It's the default parameter for blocks that do not have an explicit signature, so constructs like for @array { ... } and given $var { ... } bind the value or values of the variable to $_ by invoking the block.

for <a b c> { say $_ }  # sets $_ to 'a', 'b' and 'c' in turn
say $_ for <a b c>;     # same, even though it's not a block
given 'a'   { say $_ }  # sets $_ to 'a'
say $_ given 'a';       # same, even though it's not a block

CATCH blocks set $_ to the exception that was caught. The ~~ smartmatch operator sets $_ on the right-hand side expression to the value of the left-hand side.

Calling a method on $_ can be shortened by leaving off the variable name:

.say;                   # same as $_.say

m/regex/ and /regex/ regex matches and s/regex/subst/ substitutions work on $_:

say "Looking for strings with non-alphabetic characters...";
for <ab:c d$e fgh ij*> {
    .say if m/<-alpha>/;
}

# OUTPUT: «Looking for strings with non-alphabetic characters...
#          ab:c
#          d$e
#          ij*␤»

The $/ variable

$/ is the match variable. It stores the result of the last Regex match and so usually contains objects of type Match.

'abc 12' ~~ /\w+/;  # sets $/ to a Match object
say $/.Str;         # OUTPUT: «abc␤»

The Grammar.parse method also sets the caller's $/ to the resulting Match object. For the following code:

use XML::Grammar; # zef install XML 
 XML::Grammar.parse("<p>some text</p>"); 
 say $/; 
 
 # OUTPUT: «「<p>some text</p>」 
 #           root => 「<p>some text</p>」 
 #            name => 「p」 
 #            child => 「some text」 
 #             text => 「some text」 
 #             textnode => 「some text」 
 #           element => 「<p>some text</p>」 
 #            name => 「p」 
 #            child => 「some text」 
 #             text => 「some text」 
 #             textnode => 「some text」␤» 

Prior to the 6.d version, you could use $() shortcut to get the ast value from $/ Match if that value is truthy, or the stringification of the Match object otherwise.

'test' ~~ /.../;
# 6.c language only:
say $(); # OUTPUT: «tes␤»;
$/.make: 'McTesty';
say $(); # OUTPUT: «McTesty␤»;

This (non-)feature has been deprecated as of version 6.d.

Positional attributes

$/ can have positional attributes if the Regex had capture-groups in it, which are just formed with parentheses.

'abbbbbcdddddeffg' ~~ / a (b+) c (d+ef+) g /;
say $/[0]; # OUTPUT: «「bbbbb」␤»
say $/[1]; # OUTPUT: «「dddddeff」␤»

These can also be accessed by the shortcuts $0, $1, $2, etc.

say $0; # OUTPUT: «「bbbbb」␤»
say $1; # OUTPUT: «「dddddeff」␤»

To get all of the positional attributes, you can use $/.list or @$/. Before 6.d, you can also use the @() shortcut (no spaces inside the parentheses).

say @$/.join; # OUTPUT: «bbbbbdddddeff␤»

# 6.c language only:
say @().join; # OUTPUT: «bbbbbdddddeff␤»

This magic behavior of @() has been deprecated as of 6.d

Named attributes

$/ can have named attributes if the Regex had named capture-groups in it, or if the Regex called out to another Regex.

'I... see?' ~~ / \w+ $<punctuation>=[ <-[\w\s]>+ ] \s* $<final-word> = [ \w+ . ] /; 
 say $/<punctuation>; # OUTPUT: «「....」␤» 
 say $/<final-word>;  # OUTPUT: «「see?」␤» 

These can also be accessed by the shortcut $<named>.

say $<punctuation>; # OUTPUT: «「....」␤»
say $<final-word>;  # OUTPUT: «「see?」␤»

To get all of the named attributes, you can use $/.hash or %$/. Before 6.d language, you could also use the %() shortcut (no spaces inside the parentheses).

say %$/.join;       # OUTPUT: «"punctuation     ....final-word  see?"␤»

# 6.c language only
say %().join;       # OUTPUT: «"punctuation     ....final-word  see?"␤»

This behavior has been deprecated as of the 6.d version.

The $! variable

$! is the error variable. If a try block or statement prefix catches an exception, that exception is stored in $!. If no exception was caught, $! is set to the Any type object.

Note that CATCH blocks do not set $!. Rather, they set $_ inside the block to the caught exception.

Compile-time variables

All compile time variables have a question mark as part of the twigil. Being compile time they cannot be changed at runtime, however they are valuable in order to introspect the program. The most common compile time variables are the following:

$?FILE Which file am I in?
$?LINE Which line am I at? [indexed from 1]
::?CLASS Which class am I in?
%?RESOURCES The files associated with the "Distribution" of the current compilation unit.

$?FILE and $?LINE are also available from CallFrame as the file and line methods, respectively.

Other compile-time variables:

The following compile time variables allow for a deeper introspection:

$?PACKAGE Which package am I in?
$?MODULE Which module am I in?
$?CLASS Which class am I in? (as variable)
$?ROLE Which role am I in? (as variable)
$?TABSTOP How many spaces is a tab in a heredoc or virtual margin?
$?NL What a vertical newline "\n" means: LF, CR or CRLF
$?DISTRIBUTION The Distribution of the current compilation unit.

With particular regard to the $?NL, see the newline pragma.

These variables are Rakudo specific, with all the corresponding caveats:

$?BITS Number of bits of the platform the program is being compiled

&?ROUTINE

The compile time variable &?ROUTINE provides introspection about which routine the program is actually within. It returns an instance of Sub attached to the current routine. It does support the method .name to obtain the name of the called routine, as well as .signature and others method related to Sub:

sub awesome-sub { say &?ROUTINE.name }
awesome-sub # OUTPUT: awesome-sub

It also allows also for recursion:

my $counter = 10; 
 sub do-work { 
     say 'Calling myself other ' ~ $counter-- ~ ' times'; 
     &?ROUTINE() if ( $counter > 0 ); 
 } 
 do-work; 

&?BLOCK

The special compile variable ?&BLOCK behaves similarly to ?&ROUTINE but it allows to introspect a single block of code. It holds a Sub and allows for recursion within the same block:

for '.' { 
     .Str.say when !.IO.d; 
     .IO.dir()».&?BLOCK when .IO.d # lets recurse a little! 
 } 

$?DISTRIBUTION

$?DISTRIBUTION provides access to the Distribution of the current compilation unit. This gives module authors a way to reference other files in the distribution by their original relative path names, or to view the metadata (via the .meta method), without needing to know the underlying file structure (such as how CompUnit::Repository::Installation changes the file layout on installation).

unit module MyFoo; 
 
 sub module-version { 
     say "MyFoo is version:"; 
     say $?DISTRIBUTION.meta<ver>; 
 } 
 
 sub module-source { 
     say "MyFoo source code:"; 
     say $?DISTRIBUTION.content('lib/MyFoo.pm6'); 
 } 

Dynamic variables

All dynamically scoped variables have the * twigil, and their name is (conventionally) written in uppercase.

These variables are related to the arguments passed to a script.

$*ARGFILES

An IO::ArgFiles (an empty subclass of IO::CatHandle) that uses @*ARGS as source files, if it contains any files, or $*IN otherwise. When $*IN is used, its :nl-in, :chomp, :encoding, and :bin will be set on the IO::ArgFiles object.

As of the 6.d version, $*ARGFILES inside sub MAIN is always set to $*IN, even when @*ARGS is not empty. See the class documentation for examples and more context.

@*ARGS

@*ARGS is an array of Str containing the arguments from the command line.

&*ARGS-TO-CAPTURE

A dynamic variable available inside any custom ARGS-TO-CAPTURE subroutine that can be used to perform the default argument parsing. Takes the same parameters as are expected of the custom ARGS-TO-CAPTURE subroutine.

&*GENERATE-USAGE

A dynamic variable available inside any custom GENERATE-USAGE subroutine that can be used to perform the default usage message creation. Takes the same parameters as are expected of the custom GENERATE-USAGE subroutine.

Special filehandles: STDIN, STDOUT and STDERR

For more information about special filehandles please see also the Input and Output page and the IO::Special class. IO::Handle contains several examples of using $*IN for reading standard input.

Runtime environment

These dynamic variables contain information related to the environment the script or program is running in.

%*ENV

Operating system environment variables. Numeric values are provided as allomorphs.

$*REPO

This variable holds information about modules installed/loaded.

$*INIT-INSTANT

$*INIT-INSTANT is an Instant object representing program startup time. In particular, this is when the core code starts up, so the value of $*INIT-INSTANT may be a few milliseconds earlier than INIT now or even BEGIN now executed in your program.

$*TZ

$*TZ contains the system's local time zone offset, as the number of seconds from GMT.

$*CWD

It contains the Current Working Directory.

$*KERNEL

$*KERNEL contains a Kernel instance, the .gist of it being the current running kernel.

say $*KERNEL; # OUTPUT: «linux (4.4.92.31.default)␤»

$*DISTRO

This object (of type Distro) contains information about the current operating system distribution. For instance:

say "Some sort of Windows" if $*DISTRO.is-win;

$*DISTRO.name takes a set of values that depend on the operating system. These names will vary with version and implementation, so you should double-check and test before using them in your programs; since these names are implementation defined and not in the specification, they could vary and change at any moment.

The $*DISTRO gist is displayed by using say:

say $*DISTRO; # OUTPUT: «debian (9.stretch)␤»

This shows additional information on the operating system and version it's using, but as a matter of fact, this variable contains information which is useful to create portable programs, such as the path separator:

say $*DISTRO.perl;
# OUTPUT: «Distro.new(release => "42.3", is-win => Bool::False,
#          path-sep => ":", name => "opensuse",
#          auth => "https://www.opensuse.org/", version => v42.3,
#          signature => Blob, desc => "2018-12-13T08:50:59.213619+01:00")␤»

$*VM

This variable contains the current virtual machine running the code, as well as additional information on the inner workings of aforementioned VM.

say $*VM.precomp-ext, " ", $*VM.precomp-target; # OUTPUT: «moarvm mbc␤»

These two methods, for instance, will show the extension used in the precompiled bytecode scripts and the target used. This is what is found in the Moar Virtual Machine, but it could also vary with version and implementation. Other VM, such as Java, will show different values for them. $*VM.config includes all configuration values used to create the virtual machine, e.g.

say $*VM.config<versionmajor>, ".", $*VM.config<versionminor>;
# OUTPUT: «2018.11␤»

which are the version of the virtual machine, generally the same one as the one used in the interpreter and the overall Perl 6 environment.

$*PERL

This object of the Perl class contains information on the current implementation of the Perl 6 language:

say $*PERL.compiler.version; # OUTPUT: «v2018.11.52.g.06156.a.7.ca␤»

but its gist includes the name of the language, followed by the major version of the compiler:

say $*PERL; # OUTPUT: «Perl 6 (6.d)␤»

It stringifies to Perl 6:

$*PERL.put; # OUTPUT: «Perl 6␤»

$*PID

Object containing an integer describing the current Process IDentifier (operating system dependent).

$*PROGRAM-NAME

This contains the path to the current executable as it was entered on the command line, or -e if perl was invoked with the -e flag.

$*PROGRAM

Contains the location (in the form of an IO::Path object) of the Perl 6 program being executed.

&*EXIT

This is a Callable that contains the code that will be executed when doing an exit() call. Intended to be used in situations where Perl 6 is embedded in another language runtime (such as Inline::Perl6 in Perl 5).

$*EXECUTABLE

Contains an IO::Path absolute path of the perl executable that is currently running.

$*EXECUTABLE-NAME

Contains the name of the Perl executable that is currently running. (e.g. perl6-p, perl6-m). Favor $*EXECUTABLE over this one, since it's not guaranteed that the perl executable is in PATH.

$*USAGE

This is the default usage message generated from the signatures of MAIN subs available from inside sub MAIN and sub USAGE. The variable is read-only.

$*USER

An Allomorph with information about the user that is running the program. It will evaluate to the username if treated as a string and the numeric user id if treated as a number.

$*GROUP

An Allomorph with the primary group of the user who is running the program. It will evaluate to the groupname only if treated as a string and the numeric group id if treated as a number.

$*HOMEDRIVE

Contains information about the "home drive" of the user that is running the program on Windows. It's not defined in other operating systems.

$*HOMEPATH

Contains information about the path to the user directory that is running the program on Windows. It's not defined in other operating systems.

$*HOME

Contains an IO::Path object representing the "home directory" of the user that is running the program. Uses %*ENV<HOME> if set.

On Windows, uses %*ENV<HOMEDRIVE> ~ %*ENV<HOMEPATH>. If the home directory cannot be determined, it will be Any.

$*SPEC

Contains the appropriate IO::Spec sub-class for the platform that the program is running on. This is a higher-level class for the operating system; it will return Unix, for instance, in the case of Linux (in the form of the IO::Spec class used for the current implementation).

$*TMPDIR

This is an IO::Path object representing the "system temporary directory" as determined by .tmpdir IO::Spec::* method.

$*THREAD

Contains a Thread object representing the currently executing thread.

$*SCHEDULER

This is a ThreadPoolScheduler object representing the current default scheduler.

By default this imposes a maximum of 64 threads on the methods .hyper, .race and other thread-pool classes that use that scheduler such as Promises or Supplys. This is, however, implementation, dependent and might be subject to change. To change the maximum number of threads, you can either set the environment variable RAKUDO_MAX_THREADS before running perl6 or create a scoped copy with the default changed before using them:

my $*SCHEDULER = ThreadPoolScheduler.new( max_threads => 128 );

This behavior is not tested in the spec tests and is subject to change.

$*SAMPLER

The current Telemetry::Sampler used for making snapshots of system state. Only available if Telemetry has been loaded.

$*USAGE

This is a Str object that holds value of the auto-generated USAGE message.

sub MAIN($a, :$b, UInt :$ehehe) { 
     say $*USAGE; # OUTPUT: «Usage:␤  perl6.pl6 [-a=<Int>] [-b=<Str>] [--<opts>=...]» 
 } 

It is accessible only inside of MAIN sub.

Runtime variables

These variables affect the behavior of certain functions, and in some cases its value can be changed during runtime.

$*COLLATION

This is a Collation object that can be used to configure Unicode collation levels.

$*TOLERANCE

Variable used by the =~= operator, and any operations that depend on it, to decide if two values are approximately equal. Defaults to 1e-15.

$*DEFAULT-READ-ELEMS

Affects the number of bytes read by default by IO::Handle.read. Its default value is 65536.

Naming conventions

It is helpful to know our naming conventions in order to understand what codes do directly. However, there is not yet (and might never be) an official list of; still, we list several conventions that are widely held.

77 Advanced topics

~

78 Experimental features

Preview of upcoming new language features available for user evaluation

During Perl 6 development, new features are often made available for users as experimental before their design is completed. Eventually these features may be made part of the Perl 6 specification. To use these features, one uses the experimental pragma in program source code, for example, like this:

use experimental :macros;

These are the features that, for the time being, are experimental.

pack

Pack is a feature that allows binary serialization of general data structures, and is inherited from Perl's pack. The pack order creates a Buf by packing data structures in a certain way given by a packing string with the options shown in the description of unpack. You turn it on by inserting this pragma at the beginning of your program:

use experimental :pack;

For instance, we can pack numbers interpreting them as hexadecimal (H) with the pattern repeating until there are no more elements (*):

use experimental :pack; 
 say pack("H*", "414243").contents;#  OUTPUT: «(65 66 67)␤» 

There is a corresponding unpack routine that does exactly the opposite.

use experimental :pack; 
 my $buf=Buf.new(65,66,67); 
 say $buf.unpack("H*"); # OUTPUT: «414243␤» 

Not all of the symbols above are guaranteed to be implemented, and the roadmap does not include a fixed date for getting out of that stage.

Please see also documentation for pack and unpack in the Blob page.

macros

Macros are code-generating routines, that generate code in compile time, before the program is executed. In Perl 6 its use is still experimental and it needs to be turned on via the pragma

use experimental :macros;

Macro processing happens during parsing time. A macro generates an abstract syntax tree, which is grafted into the program syntax tree. quasi is the routine that performs this task.

macro does-nothing() { 
     quasi {} 
 }; 
 does-nothing; # OUTPUT: «» 

Macros are a kind of routine, so they can take arguments in exactly the same way, and act also in almost the same way.

macro is-mighty( $who ) { 
     quasi { "$who is mighty!"} 
 }; 
 say is-mighty "Freija"; # OUTPUT: « "Freija" is mighty!␤» 

"Almost" accounts for the fact that the argument is inserted as a literal, including the quotes. Please note that we can also eliminate the parentheses for a macro call, following the same rules as a routine. You can use the unquoting construct {{{}}} to get rid of this kind of thing:

macro is-mighty( $who ) { 
     quasi { {{{$who}}} ~ " is mighty!"} 
 }; 
 say is-mighty "Freija";  # OUTPUT: «Freija is mighty!␤» 

Since macro expansion happens at parse time, care must be taken when using external variables in them:

use experimental :macros; 
 my $called; 
 macro called() { 
     $called++; 
     quasi { "Called" } 
 }; 
 say called() ~ " $called times"; 
 say called() ~ " $called times"; # OUTPUT: «Called 2 times␤Called 2 times␤» 

Since macros are expanded at parse time, $called will be the result when runtime starts, which is already 2, as printed. Initializing $called with 0, however, will make this print Called 0 times since that initialization is run after the parse phase, when the macros are expanded.

Macros are terribly useful when complicated, computed initializations need to be done. However, they are still in the experimental nursery for a good reason. Although the features shown above are not very likely to change, anything, even their very presence, might change at any one time depending in necessities, so it would be best to keep them away from production code. Meanwhile, taking a look at this article by Masak as well as 007, a new macro language, might provide a glimpse into the things to come.

cached

The following pragma:

use experimental :cached;

turns on the is cached trait, which stores the result of a routine call, returning the same value if called with the same arguments.

It can be used when heavy calculations are involved, as in this sample that uses amicable numbers, taken from the 2018 Advent Calendar:

use experimental :cached; 
 
 sub aliquot-parts( $number ) is cached { 
     (^$number).grep: $number %% *; 
 } 
 
 sub infix:<amic>( $m, $n ) { 
     $m == aliquot-parts($n).sum && 
     $n == aliquot-parts($m).sum; 
 } 
 
 # Taken from https://en.wikipedia.org/wiki/Amicable_numbers 
 my @numbers = [2620, 2924, 5020, 5564, 6232, 6368, 66928, 66992]; 
 
 say "Aliquot parts of $_ are ", aliquot-parts $_ for @numbers; 
 
 for @numbers X @numbers -> @pair { 
     say "@pair[0] and @pair[1] are ", 
         @pair[0] amic @pair[1]??" "!!"not ", "amicable"; 
 } 

This code caches the computation of the aliquot parts, so that when the amic operator is called, it's only computed once; as a matter of fact, the first loop which prints these aliquot parts will be the only one that actually perform the computation.

See also the description of the trait for additional information and examples.

79 class int

Native integer

class int is Int { }

This class is used to represent integers that are native to the compiler, operating system and architecture the interpreter is compiled in.

More information in the native types page as well as in the section on native numerics.

80 Debugging

Modules and applications used to debug Perl 6 programs

There are at least two useful debuggers available for Rakudo, the Perl 6 compiler:

Debugger::UI::CommandLine

A command-line debugger frontend for Rakudo. This module installs the perl6-debug-m command-line utility, and is bundled with the Rakudo Star distributions. Please check its repository for instructions and a tutorial.

Grammar::Debugger (and Grammar::Tracer in the same distribution)

Simple tracing and debugging support for Perl 6 grammars.

Please see the documentation for these programs for further information.

Historically others have existed and others are likely to be written in the future, check the Perl 6 Modules website.

There are also environment variables that can be set to aid debugging various aspects of your program. See Perl 6 Environment Variables and Running rakudo from the command line for more information.

trace pragma

The trace pragma causes the program to print out step-by-step which lines get executed:

use trace;
sub foo { say "hi" }
foo;
# OUTPUT:
# 2 (/tmp/script.p6 line 2)
# sub foo { say "hi" }
# 5 (/tmp/script.p6 line 3)
# foo
# 3 (/tmp/script.p6 line 2)
# say "hi"
# hi

Dumper function dd

This routine is a Rakudo-specific debugging feature and not standard Perl 6.

The Tiny Data Dumper: This function takes the input list of variables and notes them (on $*ERR) in an easy to read format, along with the name of the variable. Thus,

my $a = 42; 
 my %hash = "a" => 1, "b" => 2, "c" => 3; 
 
 dd %hash, $a; 
 #`( OUTPUT: 
     Hash %hash = {:a(1), :b(2), :c(3)} 
     Int $a = 42 
 ) 

prints to the standard error stream the variables passed as argument.

Please note that dd will ignore named parameters. You can use a Capture or Array to force it to dump everything passed to it.

dd \((:a(1), :b(2)), :c(3)); 
 dd [(:a(1), :b(2)), :c(3)]; 

If you don't specify any parameters at all, it will just print the type and name of the current subroutine / method to the standard error stream:

sub a { dd }; a   # OUTPUT: «sub a()␤» 

This can be handy as a cheap trace function.

Using backtraces

The Backtrace class gets the current call stack, and can return it as a string:

my $trace = Backtrace.new;
sub inner { say ~Backtrace.new; }
sub outer { inner; }
outer;

# OUTPUT:
# perl6 /tmp/script.p6
#   in sub inner at /tmp/script.p6 line 2
#   in sub outer at /tmp/script.p6 line 3
#   in block <unit> at /tmp/script.p6 line 4

81 Reading the docs

p6doc - the Perl 6 pod reader

INTRODUCTION

Program p6doc is a command-line-interface (CLI) program that reads Perl 6 pod from installed modules' source code, in contrast to running perl6 --doc=MODULE programfile which reads Perl 6 pod from the named source file.

Note that p6doc may not be installed automatically depending upon how you installed Rakudo Perl 6. To install it use zef:

zef install p6doc 

SYNOPSIS

p6doc [switches] [arguments] 

DESCRIPTION

With no switches or arguments, p6doc lists its help to $*OUT (stdout):

You want to maintain the index? 
 To build an index for 'p6doc -f' 
           p6doc build 
 
 To list the index keys 
           p6doc list 
 
 To display module name(s) containing key 
           p6doc lookup 
 
 To show where the index file lives 
           p6doc path-to-index 
 
 What documentation do you want to read? 
 Examples: p6doc Str 
           p6doc Str.split 
           p6doc faq 
           p6doc path/to/file 
 
 You can list some top level documents: 
           p6doc -l 
 
 You can also look up specific method/routine/sub definitions: 
           p6doc -f hyper 
           p6doc -f Array.push 
 
 You can bypass the pager and print straight to stdout: 
           p6doc -n Str 

The text output can be captured and converted to other forms if desired.

If you want to use ANSI escape sequences, which will apply boldface and other enhancements to the output, you will have to set POD_TO_TEXT_ANSI, which is unset by default

export POD_TO_TEXT_ANSI=1 

LIMITATIONS

Currently p6doc can only extract embedded Perl 6 pod from installed module source files (as listed in a distribution's META6.json file). It is planned to add a feature for p6doc (in conjunction with META6.json changes) to extract all Perl 6 pod in files included with the installed distribution.

82 Shell environment variables used by Perl 6

The variables you can declare to alter its behavior or gather additional information.

The behavior of Rakudo, the Perl 6 interpreter, can be tweaked by a (growing) number of environment variables; this section attempts to document all those currently in use. They are interpreter specific in all cases, except where some use conventional names such as PATH.

The underlying virtual machine is also sensitive to a series of environment variables; they are listed in this wiki page.

Module loading

RAKUDOLIB and PERL6LIB append a comma-delimited list of paths to the search list for modules. RAKUDOLIB is evaluated first.

If true, causes the module loader to print debugging information to standard error.

Error message verbosity and strictness

If present, the print_exception routine will use a class of that name to process the exception for output. Rakudo currently ships with Exceptions::JSON (invoked by setting this variable to JSON), to override the default output. NOTE: this env var was added in version 6.d. Early implementation has been available in Rakudo compiler as of version 2018.08, and before that it was available as RAKUDO_EXCEPTIONS_HANDLER.

If true, suppresses deprecation warnings triggered by the is DEPRECATED trait.

If true, deprecation warnings become thrown exceptions.

Displays source code in stack frames surrounded by the specified number of lines of context; for instance RAKUDO_VERBOSE_STACKFRAME = 1 will use one context line.

Controls whether .setting files are included in backtraces.

Affecting precompilation

When this is set, Rakudo will look for the standard repositories (perl, vendor, site) in the specified directory. This is intended as an escape hatch for build-time bootstrapping issues, where Rakudo may be built as an unprivileged user without write access to the runtime paths in NQP's config.

These are internal variables for passing serialized state to precompilation jobs in child processes. Please do not set them manually.

If set to 1, diagnostic information about the precompilation process is emitted.

Line editor

This specifies the preferred line editor to use; valid values are Readline, Linenoise, and none. A value of none is useful if you want to avoid the recommendation message upon REPL startup.

If set to 1, will disable multiline input for the REPL.

This specifies the location of the history file used by the line editor; the default is ~/.perl6/rakudo-history.

Other

Is the default number of characters to read on an IO::Handle, defaults to 65536 (aka 64K).

Controls whether to emit ANSI codes for error highlighting. Defaults to true if unset, except on Windows.

Indicates the maximum number of threads used by default when creating a ThreadPoolScheduler. Defaults to 64.

The IO::Spec::Unix.tmpdir method will return $TMPDIR if it points to a directory with full access permissions for the current user, with a fallback default of '/tmp'.

IO::Spec::Cygwin and IO::Spec::Win32 use more Windows-appropriate lists which also include the %TEMP% and %TMP% environment variables.

The IO::Spec::Unix.path method splits $PATH as a shell would; i.e. as a colon-separated list. IO::Spec::Cygwin inherits this from IO::Spec::Unix. IO::Spec::Win32.path will read the first defined of either %PATH% or %Path% as a semicolon-delimited list.

Indicates the period in which the telemetry snapper will take a snapshot. Defaults to .1 for 10 snapshots per second.

AUTHORS

Initial version written by the Rakudo contributors, see the CREDITS file.

The initial version of this manual page was written by Reini Urban, Moritz Lenz and the Rakudo contributors.

83 class AST

Abstract representation of a piece of source code

class AST { }

An AST or Abstract Syntax Tree is a partially processed representation of a program. ASTs are return values of the quasi quoting construct, and are typically used within macros to generate code that is inserted in the calling location of the macro.

There is no API defined for ASTs yet. Hopefully that will emerge as part of the work on macros.

84 class Any

Thing/object

class Any is Mu {}

While Mu is the root of the Perl 6 class hierarchy, Any is the class that serves as a default base class for new classes, and as the base class for most built-in classes.

Since Perl 6 intentionally confuses items and single-element lists, most methods in Any are also present on class List, and coerce to List or a list-like type.

Methods

method ACCEPTS

Defined as:

multi method ACCEPTS(Any:D: Mu $other)

Usage:

EXPR.ACCEPTS(EXPR); 

Returns True if $other === self (i.e. it checks object identity).

Many built-in types override this for more specific comparisons.

method any

Defined as:

method any(--> Junction:D)

Interprets the invocant as a list and creates an any-Junction from it.

say so 2 == <1 2 3>.any;        # OUTPUT: «True␤»
say so 5 == <1 2 3>.any;        # OUTPUT: «False␤»

method all

Defined as:

method all(--> Junction:D)

Interprets the invocant as a list and creates an all-Junction from it.

say so 1 < <2 3 4>.all;         # OUTPUT: «True␤»
say so 3 < <2 3 4>.all;         # OUTPUT: «False␤»

method one

Defined as:

method one(--> Junction:D)

Interprets the invocant as a list and creates a one-Junction from it.

say so 1 == (1, 2, 3).one;      # OUTPUT: «True␤»
say so 1 == (1, 2, 1).one;      # OUTPUT: «False␤»

method none

Defined as:

method none(--> Junction:D)

Interprets the invocant as a list and creates a none-Junction from it.

say so 1 == (1, 2, 3).none;     # OUTPUT: «False␤»
say so 4 == (1, 2, 3).none;     # OUTPUT: «True␤»

method list

Defined as:

multi method list(Any:U: --> List)
multi method list(Any:D \SELF: --> List)

Applies the infix , operator to the invocant and returns the resulting List:

say 42.list.^name;           # OUTPUT: «List␤»
say 42.list.elems;           # OUTPUT: «1␤»

Subclasses of Any may choose to return any core type that does the Positional role from .list. Use .List to coerce specifically to List.

@ can also be used as a list or Positional contextualizer:

my $not-a-list-yet = $[1,2,3]; 
 say $not-a-list-yet.perl;             # OUTPUT: «$[1, 2, 3]␤» 
 my @maybe-a-list = @$not-a-list-yet; 
 say @maybe-a-list.^name;              # OUTPUT: «Array␤» 

In the first case, the list is itemized. @ as a prefix puts the initial scalar in a list context by calling .list and turning it into an Array.

method push

Defined as:

method push(|values --> Positional:D)

The method push is defined for undefined invocants and allows for autovivifying undefined to an empty Array, unless the undefined value implements Positional already. The argument provided will then be pushed into the newly created Array.

my %h;
say %h<a>;     # OUTPUT: «(Any)␤»      <-- Undefined
%h<a>.push(1); # .push on Any
say %h;        # OUTPUT: «{a => [1]}␤» <-- Note the Array

routine reverse

Defined as:

multi sub    reverse(*@list  --> Seq:D)
multi method reverse(List:D: --> Seq:D)

Returns a Seq with the same elements in reverse order.

Note that reverse always refers to reversing elements of a list; to reverse the characters in a string, use flip.

Examples:

say <hello world!>.reverse;     # OUTPUT: «(world! hello)␤»
say reverse ^10;                # OUTPUT: «(9 8 7 6 5 4 3 2 1 0)␤»

method sort

Defined as:

multi method sort()
multi method sort(&custom-routine-to-use)

Sorts iterables with cmp or given code object and returns a new Seq. Optionally, takes a Callable as a positional parameter, specifying how to sort.

Examples:

say <b c a>.sort;                           # OUTPUT: «(a b c)␤»
say 'bca'.comb.sort.join;                   # OUTPUT: «abc␤»
say 'bca'.comb.sort({$^b cmp $^a}).join;    # OUTPUT: «cba␤»
say '231'.comb.sort(&infix:«<=>»).join;     # OUTPUT: «123␤»

method map

Defined as:

multi method map(Hash:D \hash)
multi method map(Iterable:D \iterable)
multi method map(|c)
multi method map(\SELF: &block;; :$label, :$item)
multi sub map(&code, +values)

map will iterate over the invocant and apply the number of positional parameters of the code object from the invocant per call. The returned values of the code object will become elements of the returned Seq.

The :$label and :$item are useful only internally, since for loops get converted to maps. The :$label takes an existing Label to label the .map's loop with and :$item controls whether the iteration will occur over (SELF,) (if :$item is set) or SELF.

In sub form, will apply the code block to the values, which will be used as invocant.

The form with \c, Iterable:D \iterable and Hash:D \hash as signatures will fail with X::Cannot::Map, and are mainly meant to catch common traps.

method deepmap

Defined as:

method deepmap(&block --> List) is nodal

deepmap will apply &block to each element and return a new List with the return values of &block, unless the element does the Iterable role. For those elements deepmap will descend recursively into the sublist.

say [[1,2,3],[[4,5],6,7]].deepmap(* + 1);
# OUTPUT: «[[2 3 4] [[5 6] 7 8]]␤»

In the case of Associatives, it will be applied to its values:

{ what => "is", this => "thing", a => <real list> }.deepmap( *.flip ).say 
 # OUTPUT: «{a => (laer tsil), this => gniht, what => si}␤» 

method duckmap

Defined as:

method duckmap(&block) is rw is nodal

duckmap will apply &block on each element that behaves in such a way that &block can be applied. If it fails, it will descend recursively if possible, or otherwise return the item without any transformation. It will act on values if the object is Associative.

<a b c d e f g>.duckmap(-> $_ where <c d e>.any { .uc }).say; 
 # OUTPUT: «(a b C D E f g)␤» 
 (('d', 'e'), 'f').duckmap(-> $_ where <e f>.any { .uc }).say; 
 # OUTPUT: «((d E) F)␤» 
 { first => ('d', 'e'), second => 'f'}.duckmap(-> $_ where <e f>.any { .uc }).say; 
 # OUTPUT: «{first => (d E), second => F}␤» 

In the first case, it is applied to c, d and e which are the ones that meet the conditions for the block ({ .uc }) to be applied; the rest are returned as is.

In the second case, the first item is a list that does not meet the condition, so it's visited; that flat list will behave in the same way as the first one. In this case:

say [[1,2,3],[[4,5],6,7]].duckmap( *² ); # OUTPUT: «[9 9]␤»

You can square anything as long as it behaves like a number. In this case, there are two arrays with 3 elements each; these arrays will be converted into the number 3 and squared. In the next case, however

say [[1,2,3],[[4,5],6.1,7.2]].duckmap( -> Rat $_ { $_²} );
# OUTPUT: «[[1 2 3] [[4 5] 37.21 51.84]]␤»

3-item lists are not Rat, so it descends recursively, but eventually only applies the operation to those that walk (or slither, as the case may be) like a Rat.

Although on the surface (and name), duckmap might look similar to deepmap, the latter is applied recursively regardless of the type of the item.

method nodemap

Defined as:

method nodemap(&block --> List) is nodal

nodemap will apply &block to each element and return a new List with the return values of &block. In contrast to deepmap it will not descend recursively into sublists if it finds elements which do the Iterable role.

say [[1,2,3], [[4,5],6,7], 7].nodemap(*+1);
# OUTPUT: «(4, 4, 8)␤»

say [[2, 3], [4, [5, 6]]]».nodemap(*+1)
# OUTPUT: «((3 4) (5 3))␤»

The examples above would have produced the exact same results if we had used map instead of nodemap. The difference between the two lies in the fact that map flattens out slips while nodemap doesn't.

say [[2,3], [[4,5],6,7], 7].nodemap({.elems == 1 ?? $_ !! slip});
# OUTPUT: «(() () 7)␤»
say [[2,3], [[4,5],6,7], 7].map({.elems == 1 ?? $_ !! slip});
# OUTPUT: «(7)␤»

When applied to Associatives, it will act on the values:

{ what => "is", this => "thing" }.nodemap( *.flip ).say;
# OUTPUT: «{this => gniht, what => si}␤»

method flat

Defined as:

method flat() is nodal

Interprets the invocant as a list, flattens non-containerized Iterables into a flat list, and returns that list. Keep in mind Map and Hash types are Iterable and so will be flattened into lists of pairs.

say ((1, 2), (3), %(:42a));      # OUTPUT: «((1 2) 3 {a => 42})␤»
say ((1, 2), (3), %(:42a)).flat; # OUTPUT: «(1 2 3 a => 42)␤»

Note that Arrays containerize their elements by default, and so flat will not flatten them. You can use hyper method call to call .List method on all the inner Iterables and so de-containerize them, so that flat can flatten them:

say [[1, 2, 3], [(4, 5), 6, 7]]      .flat; # OUTPUT: «([1 2 3] [(4 5) 6 7])␤»
say [[1, 2, 3], [(4, 5), 6, 7]]».List.flat; # OUTPUT: «(1 2 3 4 5 6 7)␤»

For more fine-tuned options, see deepmap, duckmap, and signature destructuring

method eager

Defined as:

method eager() is nodal

Interprets the invocant as a List, evaluates it eagerly, and returns that List.

my  $range = 1..5;
say $range;         # OUTPUT: «1..5␤»
say $range.eager;   # OUTPUT: «(1 2 3 4 5)␤»

method elems

Defined as:

multi method elems(Any:U: --> 1)
multi method elems(Any:D:)

Interprets the invocant as a list, and returns the number of elements in the list.

say 42.elems;                   # OUTPUT: «1␤»
say <a b c>.elems;              # OUTPUT: «3␤»
say Whatever.elems ;            # OUTPUT: «1␤»

It will also return 1 for classes.

method end

multi method end(Any:U: --> 0)
multi method end(Any:D:)

Interprets the invocant as a list, and returns the last index of that list.

say 6.end;                      # OUTPUT: «0␤»
say <a b c>.end;                # OUTPUT: «2␤»

method pairup

Defined as:

multi method pairup(Any:U:)
multi method pairup(Any:D:)

Returns an empty Seq if the invocant is a type object

Range.pairup.say; # OUTPUT: «()␤»

Interprets the invocant as a list, and constructs a list of pairs from it, in the same way that assignment to a Hash does. That is, it takes two consecutive elements and constructs a pair from them, unless the item in the key position already is a pair (in which case the pair is passed through, and the next list item, if any, is considered to be a key again). It returns a Seq of Pairs.

say (a => 1, 'b', 'c').pairup.perl;     # OUTPUT: «(:a(1), :b("c")).Seq␤»

sub item

Defined as:

multi item(\x)
multi item(|c)
multi item(Mu $a)

Forces given object to be evaluated in item context and returns the value of it.

say item([1,2,3]).perl;              # OUTPUT: «$[1, 2, 3]␤»
say item( %( apple => 10 ) ).perl;   # OUTPUT: «${:apple(10)}␤»
say item("abc").perl;                # OUTPUT: «"abc"␤»

You can also use $ as item contextualizer.

say $[1,2,3].perl;                   # OUTPUT: «$[1, 2, 3]␤»
say $("abc").perl;                   # OUTPUT: «"abc"␤»

method Array

Defined as:

method Array(--> Array:D) is nodal

Coerces the invocant to an Array.

method List

Defined as:

method List(--> List:D) is nodal

Coerces the invocant to List, using the list method.

method serial

Defined as

multi method serial()

This method is Rakudo specific, and is not included in the Perl 6 spec.

The method returns the self-reference to the instance itself:

my $b;                 # defaults to Any 
 say $b.serial.^name;   # OUTPUT: «Any␤» 
 say $b.^name;          # OUTPUT: «Any␤» 
 my $breakfast = 'food'; 
 $breakfast.serial.say; # OUTPUT: «food␤» 

This is apparently a no-op, as exemplified by the third example above. However, in HyperSeqs and RaceSeqs it returns a serialized Seq, so it can be considered the opposite of the hyper/race methods. As such, it ensures that we are in serial list-processing mode, as opposed to the autothreading mode of those methods.

method Hash

Defined as:

multi method Hash( --> Hash:D)

Coerces the invocant to Hash.

method hash

Defined as:

multi method hash(Any:U:)
multi method hash(Any:D:)

When called on a type object, returns an empty Hash. On instances, it is equivalent to assigning the invocant to a %-sigiled variable and returning that.

Subclasses of Any may choose to return any core type that does the Associative role from .hash. Use .Hash to coerce specifically to Hash.

my $d; # $d is Any 
 say $d.hash; # OUTPUT: {} 
 
 my %m is Map = a => 42, b => 666; 
 say %m.hash;  # Map.new((a => 42, b => 666)) 
 say %m.Hash;  # {a => 42, b => 666} 

method Slip

Defined as:

method Slip(--> Slip:D) is nodal

Coerces the invocant to Slip.

method Map

Defined as:

method Map(--> Map:D) is nodal

Coerces the invocant to Map.

method Bag

Defined as:

method Bag(--> Bag:D) is nodal

Coerces the invocant to Bag, whereby Positionals are treated as lists of values.

method BagHash

Defined as:

method BagHash(--> BagHash:D) is nodal

Coerces the invocant to BagHash, whereby Positionals are treated as lists of values.

method Set

Defined as:

method Set(--> Set:D) is nodal

Coerces the invocant to Set, whereby Positionals are treated as lists of values.

method SetHash

Defined as:

method SetHash(--> SetHash:D) is nodal

Coerces the invocant to SetHash, whereby Positionals are treated as lists of values.

method Mix

Defined as:

method Mix(--> Mix:D) is nodal

Coerces the invocant to Mix, whereby Positionals are treated as lists of values.

method MixHash

Defined as:

method MixHash(--> MixHash:D) is nodal

Coerces the invocant to MixHash, whereby Positionals are treated as lists of values.

method Supply

Defined as:

method Supply(--> Supply:D) is nodal

First, it coerces the invocant to a list by applying its .list method, and then to a Supply.

method min

Defined as:

multi method min()
multi method min(&by)
multi sub min(+args, :&by!)
multi sub min(+args)

Coerces the invocant to Iterable and returns the numerically smallest element. In sub form, the invocant is passed as an argument.

If a Callable positional argument is provided, each value is passed into the filter, and its return value is compared instead of the original value. The original value is still the one returned from min.

say (1,7,3).min();              # OUTPUT:«1␤»
say (1,7,3).min({1/$_});        # OUTPUT:«7␤»
say min(1,7,3);                 # OUTPUT: «1␤»
say min(1,7,3,:by( { 1/$_ } )); # OUTPUT: «7␤»

method max

Defined as:

multi method max()
multi method max(&by)
multi sub max(+args, :&by!)
multi sub max(+args)

Coerces the invocant to Iterable and returns the numerically largest element.

If a Callable positional argument is provided, each value is passed into the filter, and the return value is compared instead of the original value. The original value is still the one returned from max.

say (1,7,3).max();              # OUTPUT:«7␤»
say (1,7,3).max({1/$_});        # OUTPUT:«1␤»
say max(1,7,3,:by( { 1/$_ } )); # OUTPUT: «1␤»
say max(1,7,3);                 # OUTPUT: «7␤»

method minmax

Defined as:

multi method minmax()
multi method minmax(&by)
multi sub minmax(+args, :&by!)
multi sub minmax(+args)

Returns a Range from the smallest to the largest element.

If a Callable positional argument is provided, each value is passed into the filter, and its return value is compared instead of the original value. The original values are still used in the returned Range.

say (1,7,3).minmax();        # OUTPUT:«1..7␤»
say (1,7,3).minmax({-$_});   # OUTPUT:«7..1␤»
say minmax(1,7,3);           # OUTPUT: «1..7␤»
say minmax(1,7,3,:by( -* )); # OUTPUT: «7..1␤»

method minpairs

Defined as:

multi method minpairs(Any:D:)

Calls .pairs and returns a Seq with all of the Pairs with minimum values, as judged by the cmp operator:

<a b c a b c>.minpairs.perl.put; # OUTPUT: «(0 => "a", 3 => "a").Seq␤»
%(:42a, :75b).minpairs.perl.put; # OUTPUT: «(:a(42),).Seq␤»

method maxpairs

Defined as:

multi method maxpairs(Any:D:)

Calls .pairs and returns a Seq with all of the Pairs with maximum values, as judged by the cmp operator:

<a b c a b c>.maxpairs.perl.put; # OUTPUT: «(2 => "c", 5 => "c").Seq␤»
%(:42a, :75b).maxpairs.perl.put; # OUTPUT: «(:b(75),).Seq␤»

method keys

Defined as:

multi method keys(Any:U: --> List)
multi method keys(Any:D: --> List)

For defined Any returns its keys after calling list on it, otherwise calls list and returns it.

my $setty = Set(<Þor Oðin Freija>);
say $setty.keys; # OUTPUT: «(Þor Oðin Freija)␤»

See also List.keys.

Trying the same on a class will return an empty list, since most of them don't really have keys.

method flatmap

Defined as:

method flatmap(&block, :$label)

DEPRECATION NOTICE: This method is deprecated in 6.d and will be removed in 6.e. Use .map followed by .flat instead.

Applies map to every element with the block and Label used as an argument and flattens out the result using .flat.

say "aabbccc".comb.Mix.flatmap: "→ " ~ *; # OUTPUT: «(→ b␉2 → c␉3 → a␉2)␤»

In this case, the elements of the Mix are itemized to key␉value, and then mapped and flattened. Same result as

say "aabbccc".comb.Mix.map( "→ " ~ * ).flat

Which is why it is deprecated in 6.d and will be eventually eliminated in 6.e.

method roll

Defined as:

multi method roll(--> Any)
multi method roll($n --> Seq)

Coerces the invocant to a list by applying its .list method and uses List.roll on it.

my Mix $m = ("þ" xx 3, "ð" xx 4, "ß" xx 5).Mix;
say $m.roll;    # OUTPUT: «ð␤»
say $m.roll(5); # OUTPUT: «(ß ß þ ß þ)␤»

$m, in this case, is converted into a list and then a (weighted in this case) dice is rolled on it. See also List.roll for more information.

method iterator

Defined as:

multi method iterator(Any:)

Returns the object as an iterator after converting it to a list. This is the function called from the for statement.

.say for 3; # OUTPUT: «3␤»

Most subclasses redefine this method for optimization, so it's mostly types that do not actually iterate the ones that actually use this implementation.

method pick

Defined as:

multi method pick(--> Any)
multi method pick($n --> Seq)

Coerces the invocant to a list by applying its .list method and uses List.pick on it.

my Range $rg = 'α'..'ω';
say $rg.pick(3); # OUTPUT: «(β α σ)␤»

method skip

Defined as:

multi method skip()
multi method skip(Whatever)
multi method skip(Callable:D $w)
multi method skip(Int() $n)

Creates a Seq from 1-item list's iterator and uses Seq.skip on it, please check that document for real use cases; calling skip without argument is equivalent to skip(1).

Calling it with Whatever will return an empty iterator:

say <1 2 3>.skip(*);   # OUTPUT: «()␤»

The multi that uses a Callable is intended mainly to be used this way:

say <1 2 3>.skip(*-1); # OUTPUT: «(3)␤»

Instead of throwing away the first $n elements, it throws away everything but the elements indicated by the WhateverCode, in this case all but the last one.

method prepend

Defined as:

multi method prepend(--> Array)
multi method prepend(@values --> Array)

Called with no arguments on an empty variable, it initializes it as an empty Array; if called with arguments, it creates an array and then applies Array.prepend on it.

my $a;
say $a.prepend; # OUTPUT: «[]␤»
say $a;         # OUTPUT: «[]␤»
my $b;
say $b.prepend(1,2,3); # OUTPUT: «[1 2 3]␤»

method unshift

Defined as:

multi method unshift(--> Array)
multi method unshift(@values --> Array)

Initializes Any variable as empty Array and calls Array.unshift on it.

my $a;
say $a.unshift; # OUTPUT: «[]␤»
say $a;         # OUTPUT: «[]␤»
my $b;
say $b.unshift([1,2,3]); # OUTPUT: «[[1 2 3]]␤»

method first

Defined as:

multi method first(Bool:D $t)
multi method first(Regex:D $test, :$end, *%a)
multi method first(Callable:D $test, :$end, *%a is copy)
multi method first(Mu $test, :$end, *%a)
multi method first(:$end, *%a)
multi sub first(Bool:D $t, |)
multi sub first(Mu $test, +values, *%a)

In general, coerces the invocant to a list by applying its .list method and uses List.first on it.

However, this is a multi with different signatures, which are implemented with (slightly) different behavior, although using it as a subroutine is equivalent to using it as a method with the second argument as the object.

For starters, using a Bool as the argument will always return a Failure. The form that uses a $test will return the first element that smartmatches it, starting from the end if :end is used.

say (3..33).first;           # OUTPUT: «3␤»
say (3..33).first(:end);     # OUTPUT: «33␤»
say (⅓,⅔…30).first( 0xF );   # OUTPUT: «15␤»
say first 0xF, (⅓,⅔…30);     # OUTPUT: «15␤»
say (3..33).first( /\d\d/ ); # OUTPUT: «10␤»

The third and fourth examples use the Mu $test forms which smartmatches and returns the first element that does. The last example uses as a test a regex for numbers with two figures, and thus the first that meets that criterion is number 10. This last form uses the Callable multi:

say (⅓,⅔…30).first( * %% 11, :end, :kv ); # OUTPUT: «(65 22)␤»

Besides, the search for first will start from the :end and returns the set of key/values in a list; the key in this case is simply the position it occupies in the Seq. The :kv argument, which is part of the %a argument in the definitions above, modifies what first returns, providing it as a flattened list of keys and values; for a listy object, the key will always be the index.

From version 6.d, the test can also be a Junction:

say (⅓,⅔…30).first( 3 | 33, :kv ); # OUTPUT: «(8 3)␤»

method unique

Defined as:

multi method unique()
multi method unique( :&as!, :&with! )
multi method unique( :&as! )
multi method unique( :&with! )

Creates a sequence of unique elements either of the object or of values in the case it's called as a sub.

<1 2 2 3 3 3>.unique.say; # OUTPUT: «(1 2 3)␤»
say unique <1 2 2 3 3 3>; # OUTPUT: «(1 2 3)␤»

The :as and :with parameters receive functions that are used for transforming the item before checking equality, and for checking equality, since by default the === operator is used:

("1", 1, "1 ", 2).unique( as => Int, with => &[==] ).say; #OUTPUT: «(1 2)␤»

Please see unique for additional examples that use its sub form.

method repeated

Defined as:

multi method repeated()
multi method repeated( :&as!, :&with! )
multi method repeated( :&as! )
multi method repeated( :&with! )

Similarly to unique, finds repeated elements in values (as a routine) or in the object, using the :as associative argument as a normalizing function and :with as equality function.

<1 -1 2 -2 3>.repeated(:as(&abs),:with(&[==])).say; # OUTPUT: «(-1 -2)␤»
(3+3i, 3+2i, 2+1i).repeated(as => *.re).say;        # OUTPUT: «(3+2i)␤»

It returns the last repeated element before normalization, as shown in the example above. See repeated for more examples that use its sub form.

method squish

Defined as:

multi method squish( :&as!, :&with = &[===] )
multi method squish( :&with = &[===] )

Similar to .repeated, returns the sequence of first elements of contiguous sequences of equal elements, after normalization by the function :as, if present, and using as an equality operator the :with argument or === by default.

"aabbccddaa".comb.squish.say;             # OUTPUT: «(a b c d a)␤» 
 "aABbccdDaa".comb.squish( :as(&lc) ).say; # OUTPUT: «(a B c d a)␤» 
 (3+2i,3+3i,4+0i).squish( as => *.re, with => &[==]).put; #OUTPUT: «3+2i 4+0i␤» 

As shown in the last example, a sequence can contain a single element. See squish for additional sub examples.

method permutations

Defined as:

method permutations(|c)

Coerces the invocant to a list by applying its .list method and uses List.permutations on it.

say <a b c>.permutations;
# OUTPUT: «((a b c) (a c b) (b a c) (b c a) (c a b) (c b a))␤»
say set(1,2).permutations;
# OUTPUT: «((2 => True 1 => True) (1 => True 2 => True))␤»

method join

Defined as

method join($separator = '') is nodal

Converts the object to a list by calling self.list, and calls .join on the list. Can take a separator, which is an empty string by default.

(1..3).join.say;       # OUTPUT: «123␤»
<a b c>.join("❧").put; # OUTPUT: «a❧b❧c␤»

method categorize

Defined as:

multi method categorize()
multi method categorize(Whatever)
multi method categorize($test, :$into!, :&as)
multi method categorize($test, :&as)
multi sub categorize($test, +items, :$into!, *%named )
multi sub categorize($test, +items, *%named )

The two first forms fail with an error message.

In its simplest form, it uses a $test whose result will be used as a key; the values of the key will be an array of the elements that produced that key as a result of the test.

say (1..13).categorize( * %% 3); 
 say categorize( * %% 3, 1..13) 
 # OUTPUT: «{False => [1 2 4 5 7 8 10 11 13], True => [3 6 9 12]}␤» 

The :as argument will normalize before categorizing

say categorize( * %% 3, -5..5, as => &abs ) 
 # OUTPUT: «{False => [5 4 2 1 1 2 4 5], True => [3 0 3]}␤» 

The $into associative argument can be used to put the result instead of returning a new Hash

my %leap-years; 
 my @years = (2002..2009).map( { Date.new( $_~"-01-01" ) } ); 
 @years.categorize( *.is-leap-year , into => %leap-years ); 
 say %leap-years 
 # OUTPUT: 
 # «{ False 
 # => [2002-01-01 2003-01-01 2005-01-01 2006-01-01 2007-01-01 2009-01-01], 
 #    True => [2004-01-01 2008-01-01]}␤» 

The function used to categorize can return an array indicating all possible bins their argument can be put into:

sub divisible-by( Int $n --> Array(Seq) ) { 
     gather { 
         for <2 3 5 7> { 
             take $_ if $n %% $_; 
         } 
     } 
 } 
 
 say (3..13).categorize( &divisible-by ); 
 # OUTPUT: 
 # «{2 => [4 6 8 10 12], 3 => [3 6 9 12], 5 => [5 10], 7 => [7]}␤» 

In this case, every number in the range is classified in as many bins as it can be divided by.

method classify

Defined as:

multi method classify()
multi method classify(Whatever)
multi method classify($test, :$into!, :&as)
multi method classify($test, :&as)
multi sub classify($test, +items, :$into!, *%named )
multi sub classify($test, +items, *%named )

The two first forms will fail. The rest include a $test, which is a function that will return a scalar for every input; these will be used as keys of a hash whose values will be arrays with the elements that output that key for the test function.

my @years = (2003..2008).map( { Date.new( $_~"-01-01" ) } ); 
 @years.classify( *.is-leap-year , into => my %leap-years ); 
 say %leap-years; 
 # OUTPUT: «{False => [2003-01-01 2005-01-01 2006-01-01 2007-01-01], 
 #           True => [2004-01-01 2008-01-01]}␤» 

Similarly to .categorize, elements can be normalized by the Callable passed with the :as argument, and it can use the :into named argument to pass a Hash the results will be classified into; in the example above, it's defined on the fly.

From version 6.d, .classify will also work with Junctions.

method reduce

Defined as:

multi method reduce(Any:U: & --> Nil)
multi method reduce(Any:D: &with)
multi sub reduce (&with, +list)

Applying it to a class will always produce Nil. Applies its argument (or first argument, in case it's a sub) as an operator to all the elements in the object (or second argument), producing a single result. The argument must be an infix operator or take, in any case, two positional arguments.

(1..13).reduce( &[*] ).say; # OUTPUT: «6227020800␤»

method produce

Defined as:

multi method produce(Any:U: & --> Nil)
multi method produce(Any:D: &with)
multi sub produce (&with, +list)

This is similar to reduce, but returns a list with the accumulated values instead of a single result.

<10 5 3>.reduce( &[*] ).say ; # OUTPUT: «150␤» 
 <10 5 3>.produce( &[*] ).say; # OUTPUT: «(10 50 150)␤» 

The last element of the produced list would be the output produced by the .reduce method.

If it's a class, it will simply return Nil.

method pairs

Defined as:

multi method pairs(Any:U:)
multi method pairs(Any:D:)

Returns an empty List if the invocant is a type object:

say Num.pairs; # OUTPUT: «()␤»

For a value object, it converts the invocant to a List via the list method and returns the result of List.pairs on it.

<1 2 2 3 3 3>.Bag.pairs.say;# OUTPUT: «(1 => 1 3 => 3 2 => 2)␤»

In this case, every element (with weight) in a bag is converted to a pair.

method antipairs

Defined as:

multi method antipairs(Any:U:)
multi method antipairs(Any:D:)

Returns an empty List if the invocant is a type object

Range.antipairs.say; # OUTPUT: «()␤»

If it's a value object, it returns the inverted list of pairs after converting it to a list of pairs; the values will become keys and the other way round.

%(s => 1, t=> 2, u => 3).antipairs.say ;# OUTPUT: «(2 => t 1 => s 3 => u)␤»

method invert

Defined as:

multi method invert(Any:U:)
multi method invert(Any:D:)

Applied to a type object will return an empty list; applied to an object will convert it to a list and apply List.invert to it, that is, interchange key with value in every Pair. The resulting list needs to be a list of Pairs.

"aaabbcccc".comb.Bag.invert.say; # OUTPUT: «(4 => c 3 => a 2 => b)␤»

In this case, a Bag can be converted to a list of Pairs. If the result of converting the object to a list is not a list of pairs, the method will fail.

method kv

Defined as:

multi method kv(Any:U:)
multi method kv(Any:D:)
multi sub    kv($x)

Returns an empty List if the invocant is a type object:

Sub.kv.say ;# OUTPUT: «()␤»

It calls list on the invocant for value objects and returns the result of List.kv on it as a list where keys and values will be ordered and contiguous

<1 2 3>.kv.say; # OUTPUT: «(0 1 1 2 2 3)␤»

In the case of Positionals, the indices will be considered keys.

method toggle

Defined as:

method toggle(Any:D: *@conditions where .all ~~ Callable:D, Bool :$off  --> Seq:D)

Iterates over the invocant, producing a Seq, toggling whether the received values are propagated to the result on and off, depending on the results of calling Callables in @conditions:

say (1..15).toggle(* < 5, * > 10, * < 15); # OUTPUT: «(1 2 3 4 11 12 13 14)␤» 
 say (1..15).toggle(:off, * > 2, * < 5, * > 10, * < 15); # OUTPUT: «(3 4 11 12 13 14)␤» 

Imagine a switch that's either on or off (True or False), and values are produced if it's on. By default, the initial state of that switch is in "on" position, unless :$off is set to a true value, in which case the initial state will be "off".

A Callable from the head of @conditions is taken (if any are available) and it becomes the current tester. Each value from the original sequence is tested by calling the tester Callable with that value. The state of our imaginary switch is set to the return value from the tester: if it's truthy, set switch to "on", otherwise set it to "off".

Whenever the switch is toggled (i.e. switched from "off" to "on" or from "on" to "off"), the current tester Callable is replaced by the next Callable in @conditions, if available, which will be used to test any further values. If no more tester Callables are available, the switch will remain in its current state until the end of iteration.

# our original sequence of elements: 
 say list ^10; # OUTPUT: «(0 1 2 3 4 5 6 7 8 9)␤» 
 # toggled result: 
 say ^10 .toggle: * < 4, * %% 2, &is-prime; # OUTPUT: «(0 1 2 3 6 7)␤» 
 
 # First tester Callable is `* < 4` and initial state of switch is "on". 
 # As we iterate over our original sequence: 
 # 0 => 0 < 4 === True  switch is on, value gets into result, switch is 
 #                      toggled, so we keep using the same Callable: 
 # 1 => 1 < 4 === True  same 
 # 2 => 2 < 4 === True  same 
 # 3 => 3 < 4 === True  same 
 # 4 => 4 < 4 === False switch is now off, "4" does not make it into the 
 #                      result. In addition, our switch got toggled, so 
 #                      we're switching to the next tester Callable 
 # 5 => 5 %% 2 === False  switch is still off, keep trying to find a value 
 # 6 => 6 %% 2 === True   switch is now on, take "6" into result. The switch 
 #                        toggled, so we'll use the next tester Callable 
 # 7 => is-prime(7) === True  switch is still on, take value and keep going 
 # 8 => is-prime(8) === False switch is now off, "8" does not make it into 
 #                            the result. The switch got toggled, but we 
 #                            don't have any more tester Callables, so it 
 #                            will remain off for the rest of the sequence. 

Since the toggle of the switch's state loads the next tester Callable, setting :$off to a True value affects when first tester is discarded:

# our original sequence of elements: 
 say <0 1 2>; # OUTPUT: «(0 1 2)␤» 
 # toggled result: 
 say <0 1 2>.toggle: * > 1; # OUTPUT: «()␤» 
 
 # First tester Callable is `* > 1` and initial state of switch is "on". 
 # As we iterate over our original sequence: 
 # 0 => 0 > 1 === False  switch is off, "0" does not make it into result. 
 #                      In addition, switch got toggled, so we change the 
 #                      tester Callable, and since we don't have any more 
 #                      of them, the switch will remain "off" until the end 

The behavior changes when :off is used:

# our original sequence of elements: 
 say <0 1 2>; # OUTPUT: «(0 1 2)␤» 
 # toggled result: 
 say <0 1 2>.toggle: :off, * > 1; # OUTPUT: «(2)␤» 
 
 # First tester Callable is `* > 1` and initial state of switch is "off". 
 # As we iterate over our original sequence: 
 # 0 => 0 > 1 === False  switch is off, "0" does not make it into result. 
 #                       The switch did NOT get toggled this time, so we 
 #                       keep using our current tester Callable 
 # 1 => 1 > 1 === False  same 
 # 2 => 2 > 1 === True   switch is on, "2" makes it into the result 

method head

Defined as:

multi method head(Any:D:) is raw
multi method head(Any:D: Callable:D $w)
multi method head(Any:D: $n)

Returns either the first element in the object, or the first $n if that's used.

"aaabbc".comb.Mix.head.put; # OUTPUT: «c␉1␤»
"aaabbc".comb.Mix.head.put; # OUTPUT: «a␉3␤»
say ^10 .head(5);           # OUTPUT: «(0 1 2 3 4)␤»
say ^∞ .head(5);            # OUTPUT: «(0 1 2 3 4)␤»
say ^10 .head;              # OUTPUT: «0␤»
say ^∞ .head;               # OUTPUT: «0␤»

In the first two cases, the results are different since there's no defined order in Mixes. In the other cases, it returns a Seq. A Callable can be used to return all but the last elements:

say (^10).head( * - 3 );# OUTPUT: «(0 1 2 3 4 5 6)␤»

method tail

Defined as:

multi method tail() is raw
multi method tail($n)

Returns the last or the list of the $n last elements of an object. $n can be a Callable, usually a WhateverCode, which will be used to get all but the first n elements of the object.

say (^12).reverse.tail ;     # OUTPUT: «0␤» 
 say (^12).reverse.tail(3);   # OUTPUT: «(2 1 0)␤» 
 say (^12).reverse.tail(*-7); # OUTPUT: «(4 3 2 1 0)␤» 

method tree

Defined as:

multi method tree(Any:U:)
multi method tree(Any:D:)
multi method tree(Any:D: Whatever )
multi method tree(Any:D: Int(Cool) $count)
multi method tree(Any:D: @ [&first, *@rest])
multi method tree(Any:D: &first, *@rest)

Returns the class if it's undefined or if it's not Iterable, returns the result of applying the tree method to its invocant otherwise.

say Any.tree; # OUTPUT: «Any␤»

.tree has different prototypes for Iterable elements.

my @floors = ( 'A', ('B','C', ('E','F','G'))); 
 say @floors.tree(1).flat.elems; # OUTPUT: «6␤» 
 say @floors.tree(2).flat.elems; # OUTPUT: «2␤» 
 say @floors.tree( *.join("-"),*.join("—"),*.join("|"));# OUTPUT: «A-B—C—E|F|G␤» 

With a number, it iteratively applies tree to every element in the lower level; the first instance will apply .tree(0) to every element in the array, and likewise for the next example.

The second prototype applies the Whatever code passed as arguments to every level in turn; the first argument will go to level 1 and so on. tree can, thus, be a great way to process complex all levels of complex, multi-level, data structures.

method nl-out

Defined as:

method nl-out(--> Str)

Returns Str with the value of "\n". See IO::Handle.nl-out for the details.

Num.nl-out.print;     # OUTPUT: «␤»
Whatever.nl-out.print;# OUTPUT: «␤»
33.nl-out.print;      # OUTPUT: «␤»

method combinations

Defined as:

method combinations(|c)

Coerces the invocant to a list by applying its .list method and uses List.combinations on it.

say (^3).combinations; # OUTPUT: «(() (0) (1) (2) (0 1) (0 2) (1 2) (0 1 2))␤» 

method grep

Defined as:

method grep(Mu $matcher, :$k, :$kv, :$p, :$v --> Seq)

Coerces the invocant to a list by applying its .list method and uses List.grep on it.

Based on $matcher value can be either ((Any)) or empty List.

my $a;
say $a.grep({ True }); # OUTPUT: «((Any))␤»
say $a.grep({ $_ });   # OUTPUT: «()␤»

method append

Defined as:

multi method append(Any:U \SELF: |values --> Array)

In the case the instance is not a positional-thing, it instantiates it as a new Array, otherwise clone the current instance. After that, it appends the values passed as arguments to the array obtained calling Array.append on it.

my $a;
say $a.append; # OUTPUT: «[]␤»
my $b;
say $b.append((1,2,3)); # OUTPUT: «[1 2 3]␤»

method values

Defined as:

multi method values(Any:U:)
multi method values(Any:D:)

Will return an empty list for undefined or class arguments, and the object converted to a list otherwise.

say (1..3).values; # OUTPUT: «(1 2 3)␤»
say List.values;   # OUTPUT: «()␤»

method collate

Defined as:

method collate()

Collate sorts taking into account Unicode grapheme characteristics; that is, sorting more or less as one would expect instead of using the order in which their codepoints appear. collate will behave this way if the object it is applied to is Iterable.

say ('a', 'Z').sort; # (Z a) 
 say ('a', 'Z').collate; # (a Z) 
 say <ä a o ö>.collate; # (a ä o ö) 
 my %hash = 'aa' => 'value', 'Za' => 'second'; 
 say %hash.collate; # (aa => value Za => second); 

This method is affected by the $*COLLATION variable, which configures the four collation levels. While the Primary, Secondary and Tertiary mean different things for different scripts, for the Latin script used in English they mostly correspond with Primary being Alphabetic, Secondary being Diacritics and Tertiary being Case.

In the example below you can see how when we disable tertiary collation which in Latin script generally is for case, and also disable quaternary which breaks any ties by checking the codepoint values of the strings, we get Same back for A and a:

$*COLLATION.set(:quaternary(False), :tertiary(False));
say 'a' coll 'A'; #OUTPUT: «Same␤»
say ('a','A').collate == ('A','a').collate; # OUTPUT: «True␤»

The variable affects the coll operator as shown as well as this method.

method cache

Defined as:

method cache()

Provides a List representation of the object itself, calling the method list on the instance.

method batch

Defined as:

multi method batch(Int:D $batch)
multi method batch(Int:D :$elems!)

Coerces the invocant to a list by applying its .list method and uses List.batch on it.

method rotor

Defined as:

multi method rotor(Any:D: Int:D $batch, :$partial)
multi method rotor(Any:D: *@cycle, :$partial)

Groups the elements of the object in lists of $batch elements.

say (3..9).rotor(3); # OUTPUT: «((3 4 5) (6 7 8))␤»

With the :partial named argument, it will also include lists that do not get to be the $batch size:

say (3..10).rotor(3, :partial); # OUTPUT: «((3 4 5) (6 7 8) (9 10))␤»

.rotor can be called with an array of integers and pairs, which will be applied in turn. While integers will establish the batch size, as above, Pairs will use the key as batch size and the value as number of elements to skip if it's positive, or overlap if it's negative.

say (3..11).rotor(3, 2 => 1, 3 => -2, :partial);
# OUTPUT: «((3 4 5) (6 7) (9 10 11) (10 11))␤»

In this case, the first batch (ruled by an integer) has 3 elements; the second one has 2 elements (key of the pair), but skips one (the number 8); the third one has size 2 (because partials are allowed), and an overlap of 2 also.

Please see also list.rotor for examples applied to lists.

method sum

Defined as:

method sum() is nodal

If the content is iterable, it returns the sum of the values after pulling them one by one.

(3,2,1).sum; # OUTPUT: «6␤» 
 say 3.sum;   # OUTPUT: «3␤» 

It will fail if any of the elements cannot be converted to a number.

85 class Array

Sequence of itemized values

class Array is List {}

An Array is a List which forces all its elements to be scalar containers, which means you can assign to array elements.

Array implements Positional and as such provides support for subscripts.

Note from version 6.d, .perl can be called on multi-dimensional arrays.

Methods

method gist

Exactly the same as List.gist, except using square brackets for surrounding delimiters.

routine pop

Defined as:

multi sub    pop(Array:D )
multi method pop(Array:D:)

Removes and returns the last item from the array. Fails for an empty array.

Example:

my @foo = <a b>; # a b
@foo.pop;        # b
pop @foo;        # a
pop @foo;
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Cannot::Empty: Cannot pop from an empty Array␤»

routine push

Defined as:

multi sub    push(Array:D, **@values --> Array:D)
multi method push(Array:D: **@values --> Array:D)

Adds the @values to the end of the array, and returns the modified array. Throws for lazy arrays.

Example:

my @foo = <a b c>;
@foo.push: 'd';
say @foo;                   # OUTPUT: «[a b c d]␤»

Note that push does not attempt to flatten its argument list. If you pass an array or list as the thing to push, it becomes one additional element:

my @a = <a b c>;
my @b = <d e f>;
@a.push: @b;
say @a.elems;               # OUTPUT: «4␤»
say @a[3].join;             # OUTPUT: «def␤»

Only if you supply multiple values as separate arguments to push are multiple values added to the array:

my @a = '1';
my @b = <a b>;
my @c = <E F>;
@a.push: @b, @c;
say @a.elems;                # OUTPUT: «3␤»

See method append for when you want to append multiple values that are stored in a single array.

method append

Defined as

sub append(\array, |elems)
multi method append(Array:D: \values)
multi method append(Array:D: **@values is raw)

Appends the argument list to the array passed as the first argument. This modifies the array in-place. Returns the modified array. Throws for lazy arrays.

The difference from method push is that if you append a single array or list argument, append will flatten that array / list, whereas push appends the list / array as just a single element.

Example:

my @a = <a b c>;
my @b = <d e f>;
@a.append: @b;
say @a.elems;               # OUTPUT: «6␤»
say @a;                     # OUTPUT: «[a b c d e f]␤»

method elems

Defined as:

method elems(Array:D: --> Int:D)

Returns the number of elements in the invocant. Throws X::Cannot::Lazy exception if the invocant is lazy. For shaped arrays, returns the outer dimension; see shape if you need information for all dimensions.

say [<foo bar ber>] .elems; # OUTPUT: «3␤»
say (my @a[42;3;70]).elems; # OUTPUT: «42␤»

try [-∞...∞].elems;
say $!.^name;               # OUTPUT: «X::Cannot::Lazy␤»

method clone

Defined as:

method clone(Array:D: --> Array:D)

Clones the original Array. Modifications of elements in the clone are not propagated to the original and vice-versa:

my @a = <a b c>; my @b = @a.clone;
@b[1] = 42; @a.push: 72;
say @b; # OUTPUT: «[a 42 c]␤»
say @a; # OUTPUT: «[a b c 72]␤»

However, note that the reifier is shared between the two Arrays, so both Arrays will have the same elements even when each is randomly-generated on reification and each element will be reified just once, regardless of whether the reification was done by the clone or the original Array. Note: just as reifying an Array from multiple threads is not safe, so is, for example, reifying the clone from one thread while reifying the original from another thread is not safe.

my @a = 1, {rand} … ∞; my @b = @a.clone;
say @b[^3]; # OUTPUT: «(1 0.0216426755282736 0.567660896142156)␤»
say @a[^3]; # OUTPUT: «(1 0.0216426755282736 0.567660896142156)␤»

routine shift

Defined as:

multi sub    shift(Array:D )
multi method shift(Array:D:)

Removes and returns the first item from the array. Fails for an empty arrays.

Example:

my @foo = <a b>;
say @foo.shift;             # OUTPUT: «a␤»
say @foo.shift;             # OUTPUT: «b␤»
say @foo.shift;
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Cannot::Empty: Cannot shift from an empty Array␤»

routine unshift

Defined as:

multi sub    unshift(Array:D, **@values --> Array:D)
multi method unshift(Array:D: **@values --> Array:D)

Adds the @values to the start of the array, and returns the modified array. Fails if @values is a lazy list.

Example:

my @foo = <a b c>;
@foo.unshift: 1, 3 ... 11;
say @foo;                   # OUTPUT: «[(1 3 5 7 9 11) a b c]␤»

The notes in the documentation for method push apply, regarding how many elements are added to the array.

#method prepend is the equivalent for adding multiple elements from one list or array.

method prepend

Defined as

sub prepend(\array, |elems)
multi method prepend(Array:D: \values)
multi method prepend(Array:D: **@values is raw)

Adds the elements from LIST to the front of the array, modifying it in-place.

Example:

my @foo = <a b c>;
@foo.prepend: 1, 3 ... 11;
say @foo;                   # OUTPUT: «[1 3 5 7 9 11 a b c]␤»

The difference from method unshift is that if you prepend a single array or list argument, prepend will flatten that array / list, whereas unshift prepends the list / array as just a single element.

routine splice

Defined as:

multi sub    splice(@list,   $start = 0, $elems?, *@replacement --> Array)
multi method splice(Array:D: $start = 0, $elems?, *@replacement --> Array)

Deletes $elems elements starting from index $start from the Array, returns them and replaces them by @replacement. If $elems is omitted or is larger than the number of elements starting from $start, all the elements starting from index $start are deleted. If both $start and $elems are omitted, all elements are deleted from the Array and returned.

Each of $start and $elems can be specified as a Whatever or as a Callable that returns an int-compatible value.

A Whatever $start uses the number of elements of @list (or invocant). A Callable $start is called with one argument—the number of elements in @list—and its return value is used as $start.

A Whatever $elems deletes from $start to end of @list (same as no $elems). A Callable $elems is called with just one argument—the number of elements in @list minus the value of $start—and its return value is used the value of $elems.

Example:

my @foo = <a b c d e f g>;
say @foo.splice(2, 3, <M N O P>);        # OUTPUT: «[c d e]␤»
say @foo;                                # OUTPUT: «[a b M N O P f g]␤»

method shape

Defined as:

method shape() { (*,) }

Returns the shape of the array as a list.

Example:

my @foo[2;3] = ( < 1 2 3 >, < 4 5 6 > ); # Array with fixed dimensions
say @foo.shape;                          # OUTPUT: «(2 3)␤»
my @bar = ( < 1 2 3 >, < 4 5 6 > );      # Normal array (of arrays)
say @bar.shape;                          # OUTPUT: «(*)␤»

method default

Defined as:

method default

Returns the default value of the invocant, i.e. the value which is returned when trying to access an element in the Array which has not been previously initialized or when accessing an element which has explicitly been set to Nil. Unless the Array is declared as having a default value by using the is default trait the method returns the type object (Any).

my @a1 = 1, "two", 2.718; 
 say @a1.default;                               # OUTPUT: «(Any)␤» 
 say @a1[4];                                    # OUTPUT: «(Any)␤» 
 
 my @a2 is default(17) = 1, "two", 3; 
 say @a2.default;                               # OUTPUT: «17␤» 
 say @a2[4];                                    # OUTPUT: «17␤» 
 @a2[1] = Nil;                                  # (resets element to its default) 
 say @a2[1];                                    # OUTPUT: «17␤» 

method of

Defined as:

method of

Returns the type constraint for the values of the invocant. By default, i.e. if no type constraint is given during declaration, the method returns (Mu).

my @a1 = 1, 'two', 3.14159;              # (no type constraint specified)
say @a1.of;                              # OUTPUT: «(Mu)␤»

my Int @a2 = 1, 2, 3;                    # (values must be of type Int)
say @a2.of;                              # OUTPUT: «(Int)␤»
@a2.push: 'd';
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::TypeCheck::Assignment: Type check failed in assignment to @a2; expected Int but got Str ("d")␤»

routine dynamic

Defined as:

method dynamic(Array:D: --> Bool:D)

Returns True if the invocant has been declared with the is dynamic trait.

my @a;
say @a.dynamic;                          # OUTPUT: «False␤»

my @b is dynamic;
say @b.dynamic;                          # OUTPUT: «True␤»

If you declare a variable with the * twigil is dynamic is implied.

my @*b;
say @*b.dynamic;                         # OUTPUT: «True␤»

Note that in the Scalar case you have to use the VAR method in order to get correct information.

my $s is dynamic = [1, 2, 3];
say $s.dynamic;                          # OUTPUT: «False␤»  (wrong, don't do this)
say $s.VAR.dynamic;                      # OUTPUT: «True␤»   (correct approach)

86 role Associative

Object that supports looking up values by key

role Associative[::TValue = Mu, ::TKey = Str(Any)] { }

A common role for types that support name-based lookup through postcircumfix:<{ }>, for example Hash and Map. It is used for type checks in operators that expect to find specific methods to call. See Subscripts for details.

The % sigil restricts variables to objects that do Associative, so you will have to mix in that role if you want to use it for your classes.

class Whatever {}; 
 my %whatever := Whatever.new; 
 # OUTPUT: «Type check failed in binding; expected Associative but got Whatever 

Please note that we are using binding := here, since by default % assignments expect a Hash in the right-hand side. However, with the Associative role:

class Whatever is Associative {};
my %whatever := Whatever.new;

will be syntactically correct.

Methods

method of

Defined as:

method of()

Associative is actually a parameterized role which can use different classes for keys and values. As seen at the top of the document, by default it coerces to Str for the key and uses a very generic Mu for value.

my %any-hash;
say %any-hash.of;#  OUTPUT: «(Mu)␤»

The value is the first parameter you use when instantiating Associative with particular classes:

class DateHash is Hash does Associative[Cool,DateTime] {};
my %date-hash := DateHash.new;
say %date-hash.of; # OUTPUT: «(Cool)␤»

method keyof

Defined as:

method keyof()

Returns the parameterized key used for the Associative role, which is Any coerced to Str by default. This is the class used as second parameter when you use the parameterized version of Associative.

my %any-hash;
%any-hash.keyof; #OUTPUT: «(Str(Any))␤»

Methods that should be provided

You need to provide these methods if you want your class to implement the Associative role.

method AT-KEY

method AT-KEY(\key)

Should return the value / container at the given key.

method EXISTS-KEY

method EXISTS-KEY(\key)

Should return a Bool indicating whether the given key actually has a value.

method STORE

method STORE(\values, :$initialize)

This method should only be supplied if you want to support the:

my %h is Foo = a => 42, b => 666; 

syntax for binding your implementation of the Associative role.

Should accept the values to (re-)initialize the object with, which either could consist of Pairs, or separate key/value pairs. The optional named parameter will contain a True value when the method is called on the object for the first time. Should return the invocant.

See also

See Methods to implement for positional subscripting for information about additional methods that can be implemented for the Associative role.

87 class Attribute

Member variable

class Attribute { }

In Perl 6 lingo, an attribute refers to a per-instance/object storage slot. An Attribute is used to talk about classes' and roles' attributes at the meta level.

Normal usage of attributes does not require the user to use this class explicitly.

Traits

Trait is default

An attribute that is assigned Nil will revert to its default value set with the trait is default. In the case of arrays or associatives, the argument of is default will set the default item value or hash value.

class C {
    has $.a is default(42) is rw = 666
}
my $c = C.new;
say $c;
$c.a = Nil;
say $c;
# OUTPUT: «C.new(a => 666)␤C.new(a => 42)␤»

Trait is required

Defined as:

multi sub trait_mod:<is> (Attribute $attr, :$required!)

The trait is required will mark the attribute as to be filled with a value when the object is instantiated. Failing to do so will result in a runtime error.

class C {
    has $.a is required
}
my $c = C.new;
CATCH{ default { say .^name, ': ', .Str } }
# OUTPUT: «X::Attribute::Required: The attribute '$!a' is required, but you did not provide a value for it.␤»

Available as of 6.d language version (early implementation exists in Rakudo compiler 2018.08+): You can specify a reason why the attribute is required:

class D { 
     has $.a is required("it is a good idea"); 
 } 
 my $d = D.new; 
 CATCH{ default { say .^name, ': ', .Str } } 
 # OUTPUT: «X::Attribute::Required: The attribute '$!a' is required because it is a good idea,␤but you did not provide a value for it.␤» 

is required doesn't just affect the default constructor, it checks for the attribute at a lower level, so it will work for custom constructors written using bless.

trait is DEPRECATED

multi sub trait_mod:<is>(Attribute:D $r, :$DEPRECATED!)

Marks an attribute as deprecated, optionally with a message what to use instead.

class C {
    has $.foo is DEPRECATED("'bar'");
}
my $c = C.new( foo => 42 );  # doesn't trigger with initialization (yet)
say $c.foo;                  # does trigger on usage

After the program is finished, this will show something like this on STDERR:

# Saw 1 occurrence of deprecated code.
# =====================================
# Method foo (from C) seen at:
# script.p6, line 5
# Please use 'bar' instead.

trait is rw

Defined as:

multi sub trait_mod:<is> (Attribute:D $attr, :$rw!)

Marks an attribute as read/write as opposed to the default readonly. The default accessor for the attribute will return a writable value.

class Boo {
   has $.bar is rw;
   has $.baz;
};

my $boo = Boo.new;
$boo.bar = 42; # works
$boo.baz = 42;
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Assignment::RO: Cannot modify an immutable Any␤»

Methods

The usual way to obtain an object of type Attribute is by introspection:

class Useless {
    has @!things;
}
my $a = Useless.^attributes(:local)[0];
say $a.perl;            # OUTPUT: «Attribute.new␤»
say $a.name;            # OUTPUT: «@!things␤»
say $a.package;         # OUTPUT: «(Useless)␤»
say $a.has_accessor;    # OUTPUT: «False␤»

Modifying a private attribute from the outside is usually not possible, but since Attribute is at the level of the meta class, all is fair game.

method name

Defined as:

method name(Attribute:D: --> Str:D)

Returns the name of the attribute. Note that this is always the private name, so if an attribute is declared as has $.a, the name returned is $!a.

class Foo {
    has @!bar;
}
my $a = Foo.^attributes(:local)[0];
say $a.name;            # OUTPUT: «@!bar␤»

method package

Defined as:

method package()

Returns the package (class/grammar/role) to which this attribute belongs.

class Boo {
    has @!baz;
}
my $a = Boo.^attributes(:local)[0];
say $a.package;         # OUTPUT: «(Boo)␤»

method has_accessor

Defined as:

method has_accessor(Attribute:D: --> Bool:D)

Returns True if the attribute has a public accessor method.

class Container {
    has $!private;
    has $.public;
}
my $private = Container.^attributes(:local)[0];
my $public = Container.^attributes(:local)[1];
say $private.has_accessor; # OUTPUT: «False␤»
say $public.has_accessor;  # OUTPUT: «True␤»

method rw

Defined as:

method rw(Attribute:D: --> Bool:D)

Returns True for attributes that have the "is rw" trait applied to them.

class Library {
    has $.address; # Read-only value
    has @.new-books is rw;
}
my $addr = Library.^attributes(:local)[0];
my $new-books = Library.^attributes(:local)[1];
say $addr.rw;      # OUTPUT: «False␤»
say $new-books.rw; # OUTPUT: «True␤»

method readonly

Defined as:

method readonly(Attribute:D: --> Bool:D)

Returns True for readonly attributes, which is the default, or False for attributes marked as is rw.

class Library {
    has $.address; # Read-only value
    has @.new-books is rw;
}
my $addr = Library.^attributes(:local)[0];
my $new-books = Library.^attributes(:local)[1];
say $addr.readonly;      # OUTPUT: «True␤»
say $new-books.readonly; # OUTPUT: «False␤»

method required

Defined as:

method required(Attribute:D: --> Any:D)

Returns 1 for attributes that have the "is required" trait applied, or Mu if the attribute did not have that trait applied. If the "is required" trait is applied with a string, then that string will be returned instead of 1.

class Library {
    has $.address is required;
    has @.new-books is required("we always need more books");
}
my $addr = Library.^attributes(:local)[0];
my $new-books = Library.^attributes(:local)[1];
say $addr.required;      # OUTPUT: «1␤»
say $new-books.readonly; # OUTPUT: «"we always need more books"␤»

method type

Defined as:

method type(Attribute:D: --> Mu)

Returns the type constraint of the attribute.

class TypeHouse {
    has Int @.array;
    has $!scalar;
    has @.mystery;
}
my @types = TypeHouse.^attributes(:local)[0..2];
for 0..2 { say @types[$_].type }
# OUTPUT: «(Positional[Int])
# (Mu)
# (Positional)␤»

method get_value

Defined as:

method get_value(Mu $obj)

Returns the value stored in this attribute of object $obj.

class Violated {
    has $!private-thing = 5;
}
my $private = Violated.^attributes(:local)[0];
say $private.get_value(Violated.new); # OUTPUT: «5␤»

Note that this method violates encapsulation of the object, and should be used with care. Here be dragons.

method set_value

Defined as:

method set_value(Mu $obj, Mu \new_val)

Binds the value new_val to this attribute of object $obj.

class A {
    has $!a = 5;
    method speak() { say $!a; }
}
my $attr = A.^attributes(:local)[0];
my $a = A.new;
$a.speak; # OUTPUT: «5␤»
$attr.set_value($a, 42);
$a.speak; # OUTPUT: «42␤»

Note that this method violates encapsulation of the object, and should be used with care. Here be dragons.

method gist

Defined as

multi method gist(Attribute:D:)

Returns the name of the type followed by the name of the attribute.

class Hero { 
     has @!inventory; 
     has Str $.name; 
     submethod BUILD( :$name, :@inventory ) { 
         $!name = $name; 
         @!inventory = @inventory 
     } 
 } 
 say Hero.^attributes(:local)[0]; # OUTPUT: «Positional @!inventory» 

Since say implicitly calls .gist, that is what produces the output here.

Optional introspection

DEPRECATED

If an attribute is marked as DEPRECATED, then calling the DEPRECATED method is possible and will return "something else" (if no specific reason was specified) or the string that was specified with the DEPRECATED trait.

If an attribute is not marked as DEPRECATED, one cannot not call the DEPRECATED method. Therefore, the .?method syntax should be used.

class Hangout {
    has $.table;
    has $.bar is DEPRECATED("the patio");
}
my $attr-table = Hangout.^attributes(:local)[0];
my $attr-bar = Hangout.^attributes(:local)[1];
with $attr-table.?DEPRECATED -> $text {     # does not trigger
    say "Table is deprecated with '$text'";
    # OUTPUT:
}
with $attr-table.?DEPRECATED -> $text {
    say "Bar is deprecated with '$text'";
    # OUTPUT: «Bar is deprecated with 'the patio'"␤»
}

88 class Backtrace

Snapshot of the dynamic call stack

class Backtrace {}

A backtrace contains the dynamic call stack, usually leading up to a point where an exception was thrown, and is a List of Backtrace::Frame objects. Its default stringification excludes backtrace frames that are deemed unnecessary or confusing; for example routines like &die are hidden by default. Being a list, you can also access individual elements.

sub zipi { { { die "Something bad happened" }() }() }; 
 try { 
     zipi; 
 } 
 if ($!) { 
     say $!.backtrace[*-1].perl; 
 } 

This will print the last frame in the list, pointing at the line where it's happened.

Methods

method new

Defined as:

multi method new()
multi method new(Int:D $offset)
multi method new(Mu \ex)
multi method new(Mu \ex, Int:D $offset)
multi method new(List:D $bt)
multi method new(List:D $bt, Int:D $offset)

Creates a new backtrace, using its calling location as the origin of the backtrace or the $offset that is passed as a parameter. If an object or a list (that will already contain a backtrace in list form) is passed, they will be used instead of the current code.

my $backtrace = Backtrace.new;

method gist

Defined as:

multi method gist(Backtrace:D:)

Returns string "Backtrace(42 frames)" where the number indicates the number of frames available via list method.

method Str

Defined as:

multi method Str(Backtrace:D:)

Returns a concise string representation of the backtrace, omitting routines marked as is hidden-from-backtrace, and at the discretion of the implementation, also some routines from the setting.

my $backtrace = Backtrace.new;
say $backtrace.Str;

method next-interesting-index

Defined as:

method next-interesting-index(Backtrace:D: Int $idx = 0, :$named, :$noproto, :$setting)

Returns the index of the next interesting frame, once hidden and other settings are taken into account. $named will decide whether to printed only those with a name, $noproto will hide protos, and $setting will hide those are considered setting.

sub zipi { { { die "Something bad happened" }() }() }; 
 try zipi; 
 say $!.backtrace.next-interesting-index;           # OUTPUT: «2␤» 
 say $!.backtrace.next-interesting-index( :named ); #  OUTPUT: «4␤» 

method outer-caller-idx

Defined as:

method outer-caller-idx(Backtrace:D: Int $startidx)

Returns as a list the index of the frames that called the current one.

sub zipi { { { die "Something bad happened" }() }() }; 
 try zipi; 
 say $!.backtrace.outer-caller-idx( 4 ); # OUTPUT: «[6]␤» 

method nice

Defined as:

method nice(Backtrace:D: :$oneline)

Returns the backtrace as a list of interesting frames. If :$oneline is set, will stop after the first frame.

sub zipi { { { die "Something bad happened" }() }() }; 
 try zipi; 
 say $!.backtrace.nice( :oneline ) if $!; 
 # OUTPUT: «  in sub zipi at /tmp/... line 1␤␤» 

method full

Defined as:

multi method full(Backtrace:D:)

Returns a full string representation of the backtrace, including hidden frames, compiler-specific frames, and those from the setting.

my $backtrace = Backtrace.new;
say $backtrace.full;

method list

Defined as:

multi method list(Backtrace:D:)

Returns a list of Backtrace::Frame objects for this backtrace.

method summary

Defined as:

method summary(Backtrace:D: --> Str:D)

Returns a summary string representation of the backtrace, filtered by !.is-hidden && (.is-routine || !.is-setting).

This program:

sub inner { say Backtrace.new.summary }
sub outer { inner; }
outer;

results in:

in method new at SETTING::src/core/Backtrace.pm6 line 85 
 in sub inner at test.p6 line 1 
 in sub outer at test.p6 line 2 
 in block <unit> at test.p6 line 3 

method concise

Defined as:

method concise(Backtrace:D:)

Returns a concise string representation of the backtrace, filtered by !.is-hidden && .is-routine && !.is-setting.

This program:

sub inner { say Backtrace.new.concise }
sub outer { inner; }
outer;

results in:

in sub inner at test.p6 line 1 
 in sub outer at test.p6 line 2 

method map

Defined as:

multi method map(Backtrace:D: &block --> Seq:D)

It invokes &block for each element and gathers the return values in a sequence and returns it.

This program:

sub inner { Backtrace.new.map({ say "{$_.file}: {$_.line}" }); }
sub outer { inner; }
outer;

results in:

SETTING::src/core/Backtrace.pm6: 85 
 SETTING::src/core/Backtrace.pm6: 85 
 test.p6: 1 
 test.p6: 2 
 test.p6: 3 
 test.p6: 1 

method flat

Defined as:

multi method flat(Backtrace:D:)

Returns the backtrace same as list.

89 class Backtrace::Frame

Single frame of a Backtrace

class Backtrace::Frame { }

A single backtrace frame. It identifies a location in the source code.

Methods

method file

Defined as:

method file(Backtrace::Frame:D --> Str)

Returns the file name.

my $bt = Backtrace.new;
my $btf = $bt[0];
say $btf.file;

method line

Defined as:

method line(Backtrace::Frame:D --> Int)

Returns the line number (line numbers start counting from 1).

my $bt = Backtrace.new;
my $btf = $bt[0];
say $btf.line;

method code

Defined as:

method code(Backtrace::Frame:D)

Returns the code object into which .file and .line point, if available.

my $bt = Backtrace.new;
my $btf = $bt[0];
say $btf.code;

method subname

Defined as:

method subname(Backtrace::Frame:D --> Str)

Returns the name of the enclosing subroutine.

my $bt = Backtrace.new;
my $btf = $bt[0];
say $btf.subname;

method is-hidden

Defined as:

method is-hidden(Backtrace::Frame:D --> Bool:D)

Returns True if the frame is marked as hidden with the is hidden-from-backtrace trait.

my $bt = Backtrace.new;
my $btf = $bt[0];
say $btf.is-hidden;

method is-routine

Defined as:

method is-routine(Backtrace::Frame:D --> Bool:D)

Return True if the frame points into a routine (and not into a mere Block).

my $bt = Backtrace.new;
my $btf = $bt[0];
say $btf.is-routine;

method is-setting

Defined as:

method is-setting(Backtrace::Frame:D --> Bool:D)

Returns True if the frame is part of a setting.

my $bt = Backtrace.new;
my $btf = $bt[0];
say $btf.is-setting; # OUTPUT: «True␤»

90 class Bag

Immutable collection of distinct objects with integer weights

class Bag does Baggy { }

A Bag is an immutable bag/multiset implementing Associative, meaning a collection of distinct elements in no particular order that each have an integer weight assigned to them signifying how many copies of that element are considered "in the bag". (For mutable bags, see BagHash instead.)

Bags are often used for performing weighted random selections - see .pick and .roll.

Objects/values of any type are allowed as bag elements. Within a Bag, items that would compare positively with the === operator are considered the same element, with the number of how many there are as its weight. But of course you can also easily get back the expanded list of items (without the order):

my $breakfast = bag <spam eggs spam spam bacon spam>; 
 
 say $breakfast.elems;      # OUTPUT: «3␤» 
 say $breakfast.keys.sort;  # OUTPUT: «bacon eggs spam␤» 
 
 say $breakfast.total;      # OUTPUT: «6␤» 
 say $breakfast.kxxv.sort;  # OUTPUT: «bacon eggs spam spam spam spam␤» 

Bags can be treated as object hashes using the { } postcircumfix operator, or the < > operator for literal string keys, which returns the corresponding integer weight for keys that are elements of the bag, and 0 for keys that aren't:

my $breakfast = bag <spam eggs spam spam bacon spam>;
say $breakfast<bacon>;    # OUTPUT: «1␤»
say $breakfast<spam>;     # OUTPUT: «4␤»
say $breakfast<sausage>;  # OUTPUT: «0␤»

Creating Bag objects

Bags can be composed using the bag subroutine (or Bag.new, for which it is a shorthand). Any positional parameters, regardless of their type, become elements of the bag:

my $n = bag "a" => 0, "b" => 1, "c" => 2, "c" => 2;
say $n.keys.perl;        # OUTPUT: «(:c(2), :b(1), :a(0)).Seq␤»
say $n.keys.map(&WHAT);  # OUTPUT: «((Pair) (Pair) (Pair))␤»
say $n.values.perl;      # OUTPUT: «(2, 1, 1).Seq␤»

Alternatively, the .Bag coercer (or its functional form, Bag()) can be called on an existing object to coerce it to a Bag. Its semantics depend on the type and contents of the object. In general it evaluates the object in list context and creates a bag with the resulting items as elements, although for Hash-like objects or Pair items, only the keys become elements of the bag, and the (cumulative) values become the associated integer weights:

my $n = ("a" => 0, "b" => 1, "c" => 2, "c" => 2).Bag;
say $n.keys.perl;        # OUTPUT: «("b", "c").Seq␤»
say $n.keys.map(&WHAT);  # OUTPUT: «((Str) (Str))␤»
say $n.values.perl;      # OUTPUT: «(1, 4).Seq␤»

Furthermore, you can get a Bag by using bag operators (see next section) on objects of other types such as List, which will act like they internally call .Bag on them before performing the operation. Be aware of the tight precedence of those operators though, which may require you to use parentheses around arguments:

say (1..5) (+) 4;  # OUTPUT: «bag(1, 2, 3, 4(2), 5)␤»

Of course, you can also create a Bag with the .new method.

my $breakfast = Bag.new( <spam eggs spam spam bacon spam> );

Since 6.d (2019.03 and later) you can also use this syntax for parameterization of the Bag, to specify which type of values are acceptable:

# only allow strings (Str) in the Bag
my $breakfast = Bag[Str].new( <spam eggs spam spam bacon spam> );

# only allow whole numbers (Int) in the Bag
my $breakfast = Bag[Int].new( <spam eggs spam spam bacon spam> );
# Type check failed in binding; expected Int but got Str ("spam")

Finally, you can create Bag masquerading as a hash by using the is trait:

my %b is Bag = <a b c>;
say %b<a>;  # True
say %b<d>;  # False

Since 6.d (2019.03 and later), this syntax also allows you to specify the type of values you would like to allow:

# limit to strings
my %b is Bag[Str] = <a b c>;
say %b<a>;  # True
say %b<d>;  # False

# limit to whole numbers
my %b is Bag[Int] = <a b c>;
# Type check failed in binding; expected Int but got Str ("a")

Operators

Perl 6 provides common set and bag operators, which can take Bags (or any other collections) as input, and return result as Bool, Set or Bag values. For example:

my ($a, $b) = bag(2, 2, 4), bag(2, 3, 3, 4); 
 
 say $a (<) $b;   # OUTPUT: «False␤» 
 say $a (<+) $b;  # OUTPUT: «False␤» 
 say $a (^) $b;   # OUTPUT: «bag(3(2), 2)␤» 
 say $a (+) $b;   # OUTPUT: «bag(2(3), 4(2), 3(2))␤» 
 
 # Unicode versions: 
 say $a ⊂ $b;  # OUTPUT: «False␤» 
 say $a ≼ $b;  # OUTPUT: «False␤» 
 say $a ⊖ $b;  # OUTPUT: «bag(3(2), 2)␤» 
 say $a ⊎ $b;  # OUTPUT: «bag(2(3), 4(2), 3(2))␤» 

See Set/Bag Operators for a complete list of set and bag operators with detailed explanations.

Subroutines

sub bag

sub bag(*@args --> Bag)

Creates a new Bag from @args.

Note on reverse and ordering

This method is inherited from Any, however, Mixes do not have an inherent order and you should not trust it returning a consistent output.

See also

Sets, Bags, and Mixes

91 class BagHash

Mutable collection of distinct objects with integer weights

class BagHash does Baggy { }

A BagHash is a mutable bag/multiset, meaning a collection of distinct elements in no particular order that each have an integer weight assigned to them signifying how many copies of that element are considered "in the bag". (For immutable bags, see Bag instead.)

Objects/values of any type are allowed as bag elements. Within a BagHash, items that would compare positively with the === operator are considered the same element, with the number of how many there were as its weight. But of course you can also easily get back the expanded list of items (without the order):

my $breakfast = <spam eggs spam spam bacon spam>.BagHash; 
 
 say $breakfast.elems;      # OUTPUT: «3␤» 
 say $breakfast.keys.sort;  # OUTPUT: «bacon eggs spam␤» 
 
 say $breakfast.total;      # OUTPUT: «6␤» 
 say $breakfast.kxxv.sort;  # OUTPUT: «bacon eggs spam spam spam spam␤» 

BagHashes can be treated as object hashes using the { } postcircumfix operator, which returns the corresponding integer weight for keys that are elements of the bag, and 0 for keys that aren't. It can also be used to modify weights; setting a weight to 0 automatically removes that element from the bag, and setting a weight to a positive number adds that element if it didn't already exist:

my $breakfast = <spam eggs spam spam bacon spam>.BagHash; 
 say $breakfast<bacon>;     # OUTPUT: «1␤» 
 say $breakfast<spam>;      # OUTPUT: «4␤» 
 say $breakfast<sausage>;   # OUTPUT: «0␤» 
 
 $breakfast<sausage> = 2; 
 $breakfast<bacon>--; 
 say $breakfast.kxxv.sort;  # OUTPUT: «eggs sausage sausage spam spam spam spam␤» 

Creating BagHash objects

BagHashes can be composed using BagHash.new. Any positional parameters, regardless of their type, become elements of the bag:

my $n = BagHash.new: "a", "b", "c", "c";
say $n.perl;             # OUTPUT: «("b"=>1,"a"=>1,"c"=>2).BagHash␤»
say $n.keys.perl;        # OUTPUT: «("b", "a", "c").Seq␤»
say $n.values.perl;      # OUTPUT: «(1, 1, 2).Seq␤»

Besides, BagHash.new-from-pairs can create a BagHash with items and their occurrences.

my $n = BagHash.new-from-pairs: "a" => 0, "b" => 1, "c" => 2, "c" => 2;
say $n.perl;             # OUTPUT: «("b"=>1,"c"=>4).BagHash␤»
say $n.keys.perl;        # OUTPUT: «("b", "c").Seq␤»
say $n.values.perl;      # OUTPUT: «(1, 4).Seq␤»

Alternatively, the .BagHash coercer (or its functional form, BagHash()) can be called on an existing object to coerce it to a BagHash. Its semantics depend on the type and contents of the object. In general it evaluates the object in list context and creates a bag with the resulting items as elements, although for Hash-like objects or Pair items, only the keys become elements of the bag, and the (cumulative) values become the associated integer weights:

my $m = ("a", "b", "c", "c").BagHash;
my $n = ("a" => 0, "b" => 1, "c" => 2, "c" => 2).BagHash;
say $m.perl;             # OUTPUT: «("b"=>1,"a"=>1,"c"=>2).BagHash␤»
say $n.perl;             # OUTPUT: «("b"=>1,"c"=>4).BagHash␤»

You can also create BagHash masquerading as a hash by using the is trait:

my %bh is BagHash = <a b b c c c>;
say %bh<b>;  # 2
say %bh<d>;  # 0

Since 6.d (2019.03 and later) it is also possible to specify the type of values you would like to allow in a BagHash. This can either be done when calling .new:

# only allow strings
my $n = BagHash[Str].new: <a b b c c c>;

or using the masquerading syntax:

# only allow strings
my %bh is BagHash[Str] = <a b b c c c>;
say %bh<b>;  # 2
say %bh<d>;  # 0

# only allow whole numbers
my %bh is BagHash[Int] = <a b b c c c>;
# Type check failed in binding; expected Int but got Str ("a")

Operators

Perl 6 provides common set and bag operators, which can take BagHashes (or any other collections) as input, and return result as Bool, Set or Bag values. For example:

my ($a, $b) = BagHash.new(2, 2, 4), BagHash.new(2, 3, 3, 4); 
 
 say $a (<) $b;   # OUTPUT: «False␤» 
 say $a (<+) $b;  # OUTPUT: «False␤» 
 say $a (^) $b;   # OUTPUT: «Bag(3(2), 2)␤» 
 say $a (+) $b;   # OUTPUT: «Bag(2(3), 4(2), 3(2))␤» 
 
 # Unicode versions: 
 say $a ⊂ $b;  # OUTPUT: «False␤» 
 say $a ≼ $b;  # OUTPUT: «False␤» 
 say $a ⊖ $b;  # OUTPUT: «Bag(3(2), 2)␤» 
 say $a ⊎ $b;  # OUTPUT: «Bag(2(3), 4(2), 3(2))␤» 

See Set/Bag Operators for a complete list of set and bag operators with detailed explanations.

Note on reverse and ordering.

BagHash inherits reverse from Any, however, Bags do not have an inherent order and you should not trust it returning a consistent output.

If you sort a BagHash, the result is a list of pairs, at which point reverse makes perfect sense:

my $a = BagHash.new(2, 2, 18, 3, 4); 
 say $a;  # OUTPUT: «BagHash(18, 2(2), 3, 4)␤» 
 
 say $a.sort;  # OUTPUT: «(2 => 2 3 => 1 4 => 1 18 => 1)␤» 
 say $a.sort.reverse;  # OUTPUT: «(18 => 1 4 => 1 3 => 1 2 => 2)␤» 

See Also

Sets, Bags, and Mixes

92 role Baggy

Collection of distinct weighted objects

role Baggy does QuantHash { }

A role for collections of weighted objects. See Bag, BagHash, and Mixy.

Methods

method new-from-pairs

Defined as:

method new-from-pairs(*@pairs --> Baggy:D)

Constructs a Baggy objects from a list of Pair objects given as positional arguments:

say Mix.new-from-pairs: 'butter' => 0.22, 'sugar' => 0.1, 'sugar' => 0.02;
# OUTPUT: «mix(butter(0.22), sugar(0.12))␤»

Note: be sure you aren't accidentally passing the Pairs as positional arguments; the quotes around the keys in the above example are significant.

method grab

Defined as:

multi method grab(Baggy:D: --> Any)
multi method grab(Baggy:D: $count --> Seq:D)

Like pick, a grab returns a random selection of elements, weighted by the values corresponding to each key. Unlike pick, it works only on mutable structures, e.g. BagHash. Use of grab on an immutable structure results in an X::Immutable exception. If * is passed as $count, or $count is greater than or equal to the total of the invocant, then total elements from the invocant are returned in a random sequence; i.e. they are returned shuffled.

Grabbing decrements the grabbed key's weight by one (deleting the key when it reaches 0). By definition, the total of the invocant also decreases by one, so the probabilities stay consistent through subsequent grab operations.

my $cars = ('Ford' => 2, 'Rover' => 3).BagHash;
say $cars.grab;                                   # OUTPUT: «Ford␤»
say $cars.grab(2);                                # OUTPUT: «(Rover Rover)␤»
say $cars.grab(*);                                # OUTPUT: «(Rover Ford)␤»

my $breakfast = ('eggs' => 2, 'bacon' => 3).Bag;
say $breakfast.grab;
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Immutable: Cannot call 'grab' on an immutable 'Bag'␤»

method grabpairs

Defined as:

multi method grabpairs(Baggy:D: --> Any)
multi method grabpairs(Baggy:D: $count --> Seq:D)

Returns a Pair or a Seq of Pairs depending on the version of the method being invoked. Each Pair returned has an element of the invocant as its key and the elements weight as its value. Unlike pickpairs, it works only on mutable structures, e.g. BagHash. Use of grabpairs on 'an immutable structure results in an X::Immutable exception. If * is passed as $count, or $count is greater than or equal to the number of elements of the invocant, then all element/weight Pairs from the invocant are returned in a random sequence.

What makes grabpairs different from pickpairs is that the 'grabbed' elements are in fact removed from the invocant.

my $breakfast = (eggs => 2, bacon => 3).BagHash;
say $breakfast.grabpairs;                         # OUTPUT: «bacon => 3␤»
say $breakfast;                                   # OUTPUT: «BagHash.new(eggs(2))␤»
say $breakfast.grabpairs(1);                      # OUTPUT: «(eggs => 2)␤»
say $breakfast.grabpairs(*);                      # OUTPUT: «()␤»

my $diet = ('eggs' => 2, 'bacon' => 3).Bag;
say $diet.grabpairs;
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Immutable: Cannot call 'grabpairs' on an immutable 'Bag'␤»

method pick

Defined as:

multi method pick(Baggy:D: --> Any)
multi method pick(Baggy:D: $count --> Seq:D)

Like an ordinary list pick, but returns keys of the invocant weighted by their values, as if the keys were replicated the number of times indicated by the corresponding value and then list pick used. The underlying metaphor for picking is that you're pulling colored marbles out a bag. (For "picking with replacement" see roll instead). If * is passed as $count, or $count is greater than or equal to the total of the invocant, then total elements from the invocant are returned in a random sequence.

Note that each pick invocation maintains its own private state and has no effect on subsequent pick invocations.

my $breakfast = bag <eggs bacon bacon bacon>;
say $breakfast.pick;                              # OUTPUT: «eggs␤»
say $breakfast.pick(2);                           # OUTPUT: «(eggs bacon)␤»

say $breakfast.total;                             # OUTPUT: «4␤»
say $breakfast.pick(*);                           # OUTPUT: «(bacon bacon bacon eggs)␤»

method pickpairs

Defined as:

multi method pickpairs(Baggy:D: --> Pair:D)
multi method pickpairs(Baggy:D: $count --> Seq:D)

Returns a Pair or a Seq of Pairs depending on the version of the method being invoked. Each Pair returned has an element of the invocant as its key and the elements weight as its value. The elements are 'picked' without replacement. If * is passed as $count, or $count is greater than or equal to the number of elements of the invocant, then all element/weight Pairs from the invocant are returned in a random sequence.

Note that each pickpairs invocation maintains its own private state and has no effect on subsequent pickpairs invocations.

my $breakfast = bag <eggs bacon bacon bacon>;
say $breakfast.pickpairs;                         # OUTPUT: «eggs => 1␤»
say $breakfast.pickpairs(1);                      # OUTPUT: «(bacon => 3)␤»
say $breakfast.pickpairs(*);                      # OUTPUT: «(eggs => 1 bacon => 3)␤»

method roll

Defined as:

multi method roll(Baggy:D: --> Any:D)
multi method roll(Baggy:D: $count --> Seq:D)

Like an ordinary list roll, but returns keys of the invocant weighted by their values, as if the keys were replicated the number of times indicated by the corresponding value and then list roll used. The underlying metaphor for rolling is that you're throwing $count dice that are independent of each other, which (in bag terms) is equivalent to picking a colored marble out your bag and then putting it back, and doing this $count times. In dice terms, the number of marbles corresponds to the number of sides, and the number of marbles of the same color corresponds to the number of sides with the same color. (For "picking without replacement" see pick instead).

If * is passed to $count, returns a lazy, infinite sequence of randomly chosen elements from the invocant.

my $breakfast = bag <eggs bacon bacon bacon>;
say $breakfast.roll;                                  # OUTPUT: «bacon␤»
say $breakfast.roll(3);                               # OUTPUT: «(bacon eggs bacon)␤»

my $random_dishes := $breakfast.roll(*);
say $random_dishes[^5];                               # OUTPUT: «(bacon eggs bacon bacon bacon)␤»

method pairs

Defined as:

method pairs(Baggy:D: --> Seq:D)

Returns all elements and their respective weights as a Seq of Pairs where the key is the element itself and the value is the weight of that element.

my $breakfast = bag <bacon eggs bacon>;
my $seq = $breakfast.pairs;
say $seq.sort;                                    # OUTPUT: «(bacon => 2 eggs => 1)␤»

method antipairs

Defined as:

method antipairs(Baggy:D: --> Seq:D)

Returns all elements and their respective weights as a Seq of Pairs, where the element itself is the value and the weight of that element is the key, i.e. the opposite of method pairs.

my $breakfast = bag <bacon eggs bacon>;
my $seq = $breakfast.antipairs;
say $seq.sort;                                    # OUTPUT: «(1 => eggs 2 => bacon)␤»

method invert

Defined as:

method invert(Baggy:D: --> Seq:D)

Returns all elements and their respective weights as a Seq of Pairs, where the element itself is the value and the weight of that element is the key, i.e. the opposite of method pairs. Except for some esoteric cases invert on a Baggy type returns the same result as antipairs.

my $breakfast = bag <bacon eggs bacon>;
my $seq = $breakfast.invert;
say $seq.sort;                                    # OUTPUT: «(1 => eggs 2 => bacon)␤»

method classify-list

Defined as:

multi method classify-list(&mapper, *@list --> Baggy:D)
multi method classify-list(%mapper, *@list --> Baggy:D)
multi method classify-list(@mapper, *@list --> Baggy:D)

Populates a mutable Baggy by classifying the possibly-empty @list of values using the given mapper. The @list cannot be lazy.

say BagHash.new.classify-list: { $_ %% 2 ?? 'even' !! 'odd' }, ^10;
# OUTPUT: BagHash.new(even(5), odd(5))

my @mapper = <zero one two three four five>;
say MixHash.new.classify-list: @mapper, 1, 2, 3, 4, 4, 6;
# OUTPUT: MixHash.new((Any), two, three, four(2), one)

The mapper can be a Callable that takes a single argument, an Associative, or an Iterable. With Associative and an Iterable mappers, the values in the @list represent the key and index of the mapper's value respectively. A Callable mapper will be executed once per each item in the @list, with that item as the argument and its return value will be used as the mapper's value.

The mapper's value is used as the key of the Baggy that will be incremented by 1. See .categorize-list if you wish to classify an item into multiple categories at once.

Note: unlike the Hash's .classify-list, returning an Iterable mapper's value will throw, as Baggy types do not support nested classification. For the same reason, Baggy's .classify-list does not accept :&as parameter.

method categorize-list

Defined as:

multi method categorize-list(&mapper, *@list --> Baggy:D)
multi method categorize-list(%mapper, *@list --> Baggy:D)
multi method categorize-list(@mapper, *@list --> Baggy:D)

Populates a mutable Baggy by categorizing the possibly-empty @list of values using the given mapper. The @list cannot be lazy.

say BagHash.new.categorize-list: {
    gather {
        take 'largish' if $_ > 5;
        take .is-prime ?? 'prime' !! 'non-prime';
        take $_ %% 2   ?? 'even'  !! 'odd';
    }
}, ^10;
# OUTPUT: BagHash.new(largish(4), even(5), non-prime(6), prime(4), odd(5))

my %mapper = :sugar<sweet white>, :lemon<sour>, :cake('sweet', 'is a lie');
say MixHash.new.categorize-list: %mapper, <sugar lemon cake>;
# OUTPUT: MixHash.new(is a lie, sour, white, sweet(2))

The mapper can be a Callable that takes a single argument, an Associative, or an Iterable. With Associative and an Iterable mappers, the values in the @list represent the key and index of the mapper's value respectively. A Callable mapper will be executed once per each item in the @list, with that item as the argument and its return value will be used as the mapper's value.

The mapper's value is used as a possibly-empty list of keys of the Baggy that will be incremented by 1.

Note: unlike the Hash's .categorize-list, returning a list of Iterables as mapper's value will throw, as Baggy types do not support nested categorization. For the same reason, Baggy's .categorize-list does not accept :&as parameter.

method keys

Defined as:

method keys(Baggy:D: --> Seq:D)

Returns a Seq of all keys in the Baggy object without taking their individual weights into account as opposed to kxxv.

my $breakfast = bag <eggs spam spam spam>;
say $breakfast.keys.sort;                        # OUTPUT: «(eggs spam)␤»

my $n = ("a" => 5, "b" => 2).BagHash;
say $n.keys.sort;                                # OUTPUT: «(a b)␤»

method values

Defined as:

method values(Baggy:D: --> Seq:D)

Returns a Seq of all values, i.e. weights, in the Baggy object.

my $breakfast = bag <eggs spam spam spam>;
say $breakfast.values.sort;                      # OUTPUT: «(1 3)␤»

my $n = ("a" => 5, "b" => 2, "a" => 1).BagHash;
say $n.values.sort;                              # OUTPUT: «(2 6)␤»

method kv

Defined as:

method kv(Baggy:D: --> Seq:D)

Returns a Seq of keys and values interleaved.

my $breakfast = bag <eggs spam spam spam>;
say $breakfast.kv;                                # OUTPUT: «(spam 3 eggs 1)␤»

my $n = ("a" => 5, "b" => 2, "a" => 1).BagHash;
say $n.kv;                                        # OUTPUT: «(a 6 b 2)␤»

method kxxv

Defined as:

method kxxv(Baggy:D: --> Seq:D)

Returns a Seq of the keys of the invocant, with each key multiplied by its weight. Note that kxxv only works for Baggy types which have integer weights, i.e. Bag and BagHash.

my $breakfast = bag <spam eggs spam spam bacon>;
say $breakfast.kxxv.sort;                         # OUTPUT: «(bacon eggs spam spam spam)␤»

my $n = ("a" => 0, "b" => 1, "b" => 2).BagHash;
say $n.kxxv;                                      # OUTPUT: «(b b b)␤»

method elems

Defined as:

method elems(Baggy:D: --> Int:D)

Returns the number of elements in the Baggy object without taking the individual elements weight into account.

my $breakfast = bag <eggs spam spam spam>;
say $breakfast.elems;                             # OUTPUT: «2␤»

my $n = ("b" => 9.4, "b" => 2).MixHash;
say $n.elems;                                     # OUTPUT: «1␤»

method total

Defined as:

method total(Baggy:D:)

Returns the sum of weights for all elements in the Baggy object.

my $breakfast = bag <eggs spam spam bacon>;
say $breakfast.total;                             # OUTPUT: «4␤»

my $n = ("a" => 5, "b" => 1, "b" => 2).BagHash;
say $n.total;                                     # OUTPUT: «8␤»

method default

Defined as:

method default(Baggy:D: --> Int:D)

Returns zero.

my $breakfast = bag <eggs bacon>;
say $breakfast.default;                           # OUTPUT: «0␤»

method hash

Defined as:

method hash(Baggy:D: --> Hash:D)

Returns a Hash where the elements of the invocant are the keys and their respective weights the values.

my $breakfast = bag <eggs bacon bacon>;
my $h = $breakfast.hash;
say $h.^name;                    # OUTPUT: «Hash[Any,Any]␤»
say $h;                          # OUTPUT: «{bacon => 2, eggs => 1}␤»

method Bool

Defined as:

method Bool(Baggy:D: --> Bool:D)

Returns True if the invocant contains at least one element.

my $breakfast = ('eggs' => 1).BagHash;
say $breakfast.Bool;                              # OUTPUT: «True   (since we have one element)␤»
$breakfast<eggs> = 0;                             # weight == 0 will lead to element removal
say $breakfast.Bool;                              # OUTPUT: «False␤»

method Set

Defined as:

method Set(--> Set:D)

Returns a Set whose elements are the keys of the invocant.

my $breakfast = (eggs => 2, bacon => 3).BagHash;
say $breakfast.Set;                               # OUTPUT: «set(bacon, eggs)␤»

method SetHash

Defined as:

method SetHash(--> SetHash:D)

Returns a SetHash whose elements are the keys of the invocant.

my $breakfast = (eggs => 2, bacon => 3).BagHash;
my $sh = $breakfast.SetHash;
say $sh.^name;                            # OUTPUT: «SetHash␤»
say $sh.elems;                            # OUTPUT: «2␤»

method ACCEPTS

Defined as:

method ACCEPTS($other --> Bool:D)

Used in smartmatching if the right-hand side is a Baggy.

If the right-hand side is the type object, i.e. Baggy, the method returns True if $other does Baggy otherwise False is returned.

If the right-hand side is a Baggy object, True is returned only if $other has the same elements, with the same weights, as the invocant.

my $breakfast = bag <eggs bacon>;
say $breakfast ~~ Baggy;                            # OUTPUT: «True␤»
say $breakfast.does(Baggy);                         # OUTPUT: «True␤»

my $second-breakfast = (eggs => 1, bacon => 1).Mix;
say $breakfast ~~ $second-breakfast;                # OUTPUT: «True␤»

my $third-breakfast = (eggs => 1, bacon => 2).Bag;
say $second-breakfast ~~ $third-breakfast;          # OUTPUT: «False␤»

See Also

Sets, Bags, and Mixes

93 role Blob

Immutable buffer for binary data ('Binary Large OBject')

role Blob[::T = uint8] does Positional[T] does Stringy { }

The Blob role is an immutable interface to binary types, and offers a list-like interface to lists of integers, typically unsigned integers.

Methods

method new

Defined as:

multi method new(Blob:)
multi method new(Blob: Blob:D $blob)
multi method new(Blob: int @values)
multi method new(Blob: @values)
multi method new(Blob: *@values)

Creates an empty Blob, or a new Blob from another Blob, or from a list of integers or values (which will have to be coerced into integers):

my $blob = Blob.new([1, 2, 3]);
say Blob.new(<1 2 3>); # OUTPUT: «Blob:0x<01 02 03>␤»

method Bool

Defined as:

multi method Bool(Blob:D:)

Returns False if and only if the buffer is empty.

my $blob = Blob.new();
say $blob.Bool; # OUTPUT: «False␤»
$blob = Blob.new([1, 2, 3]);
say $blob.Bool; # OUTPUT: «True␤»

method Capture

Defined as:

method Capture(Blob:D)

Equivalent to calling .List.Capture on the invocant.

method elems

Defined as:

multi method elems(Blob:D:)
multi method elems(Blob:U: --> 1)

Returns the number of elements of the buffer.

my $blob = Blob.new([1, 2, 3]);
say $blob.elems; # OUTPUT: «3␤»

It will also return 1 on the class object.

method bytes

Defined as:

method bytes(Blob:D: --> Int:D)

Returns the number of bytes used by the elements in the buffer.

say Blob.new([1, 2, 3]).bytes;      # OUTPUT: «3␤»
say blob16.new([1, 2, 3]).bytes;    # OUTPUT: «6␤»
say blob64.new([1, 2, 3]).bytes;    # OUTPUT: «24␤»

method chars

Defined as:

method chars(Blob:D:)

Throws X::Buf::AsStr with chars as payload.

method Str

Defined as:

multi method Str(Blob:D:)

Throws X::Buf::AsStr with Str as payload. In order to convert to a Str you need to use .decode.

method Stringy

Defined as:

multi method Stringy(Blob:D:)

Throws X::Buf::AsStr with Stringy as payload.

method decode

Defined as:

multi method decode(Blob:D: $encoding = self.encoding // "utf-8")
multi method decode(Blob:D: $encoding, Str :$replacement!, 
                     Bool:D :$strict = False) 
multi method decode(Blob:D: $encoding, Bool:D :$strict = False)

Applies an encoding to turn the blob into a Str; the encoding will be UTF-8 by default.

my Blob $blob = "string".encode('utf-8');
say $blob.decode('utf-8'); # OUTPUT: «string␤»

On malformed utf-8 .decode will throw X::AdHoc. To handle sloppy utf-8 use utf8-c8.

method list

Defined as:

multi method list(Blob:D:)

Returns the list of codepoints:

say "zipi".encode("ascii").list; # OUTPUT: «(122 105 112 105)␤»

method gist

Defined as:

method gist(Blob:D: --> Str:D)

Returns the string containing the "gist" of the Blob, listing up to the first 100 elements, separated by space, appending an ellipsis if the Blob has more than 100 elements.

put Blob.new(1, 2, 3).gist; # OUTPUT: «Blob:0x<01 02 03>␤»
put Blob.new(1..2000).gist;
# OUTPUT:
# Blob:0x<01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15
# 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C
# 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43
# 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A
# 5B 5C 5D 5E 5F 60 61 62 63 64 ...>

method subbuf

Defined as:

multi method subbuf(Int $from, Int $len = self.elems --> Blob:D)
multi method subbuf(Range $range --> Blob:D)

Extracts a part of the invocant buffer, starting from the index with elements $from, and taking $len elements (or less if the buffer is shorter), and creates a new buffer as the result.

say Blob.new(1..10).subbuf(2, 4);    # OUTPUT: «Blob:0x<03 04 05 06>␤»
say Blob.new(1..10).subbuf(*-2);     # OUTPUT: «Blob:0x<09 0a>␤»
say Blob.new(1..10).subbuf(*-5,2);   # OUTPUT: «Blob:0x<06 07>␤»

For convenience, also allows a Range to be specified to indicate which part of the invocant buffer you would like:

say Blob.new(1..10).subbuf(2..5);    # OUTPUT: «Blob:0x<03 04 05 06>␤»

method allocate

Defined as:

multi method allocate(Blob:U: Int:D $elements)
multi method allocate(Blob:U: Int:D $elements, int $value)
multi method allocate(Blob:U: Int:D $elements, Int:D \value)
multi method allocate(Blob:U: Int:D $elements, Mu:D $got)
multi method allocate(Blob:U: Int:D $elements, int @values)
multi method allocate(Blob:U: Int:D $elements, Blob:D $blob)
multi method allocate(Blob:U: Int:D $elements, @values)

Returns a newly created Blob object with the given number of elements. Optionally takes a second argument that indicates the pattern with which to fill the Blob: this can be a single (possibly native) integer value, or any Iterable that generates integer values, including another Blob. The pattern will be repeated if not enough values are given to fill the entire Blob.

my Blob $b0 = Blob.allocate(10,0);
$b0.say; # OUTPUT: «Blob:0x<00 00 00 00 00 00 00 00 00 00>␤»

If the pattern is a general Mu value, it will fail.

method unpack

This method is considered experimental, in order to use it you will need to do:

use experimental :pack;

Defined as:

multi method unpack(Blob:D: Str:D $template)
multi method unpack(Blob:D: @template)
multi sub unpack(Blob:D \blob, Str:D $template)
multi sub unpack(Blob:D \blob, @template)

Extracts features from the blob according to the template string, and returns them as a list.

The template string consists of zero or more units that begin with an ASCII letter, and are optionally followed by a quantifier. The quantifier can be * (which typically stands for "use up the rest of the Blob here"), or a positive integer (without a +).

Whitespace between template units is ignored.

Examples of valid templates include "A4 C n*" and "A*".

The following letters are recognized:

Letter Meaning
A Extract a string, where each element of the Blob maps to a codepoint
a Same as A
C Extract an element from the blob as an integer
H Extracts a hex string
L Extracts four elements and returns them as a single unsigned integer
n Extracts two elements and combines them in "network" (BigEndian) byte order into a single integer
N Extracts four elements and combines them in "network" (BigEndian) byte order into a single integer
S Extracts two elements and returns them as a single unsigned integer
v Same as S
V Same as L
x Drop an element from the blob (that is, ignore it)
Z Same as A

Example:

use experimental :pack;
say Blob.new(1..10).unpack("C*");
# OUTPUT: «(1 2 3 4 5 6 7 8 9 10)␤»

sub pack

This subroutine is considered experimental, in order to use it you will need to do:

use experimental :pack; 
multi sub pack(Str $template, *@items) 
 multi sub pack(@template, *@items) 

Packs the given items according to the template and returns a buffer containing the packed bytes.

The template string consists of zero or more units that begin with an ASCII letter, and are optionally followed by a quantifier. For details, see unpack.

method reverse

Defined as:

method reverse(Blob:D: --> Blob:D)

Returns a Blob with all elements in reversed order.

say Blob.new([1, 2, 3]).reverse;    # OUTPUT: «Blob:0x<03 02 01>␤»
say blob16.new([2]).reverse;        # OUTPUT: «Blob[uint16]:0x<02>␤»
say buf32.new([16, 32]).reverse;    # OUTPUT: «Buf[uint32]:0x<20 10>␤»

Methods on blob8 only (6.d, 2018.12 and later)

These methods are available on the blob8 (and buf8) types only. They allow low level access to reading bytes from the underlying data and interpreting them in different ways with regards to type (integer or floating point (num)), size (8, 16, 32, 64 or 128 bits), signed or unsigned (for integer values) and endianness (native, little and big endianness). The returned values are always expanded to a 64 bit native value where possible, and to a (big) integer value if that is not possible.

Endianness must be indicated by using values of the Endian enum as the second parameter to these methods. If no endianness is specified, NativeEndian will be assumed. Other values are LittleEndian and BigEndian.

method read-uint8

Defined as:

method read-uint8(blob8:D: uint $pos, $endian = NativeEndian --> uint)

Returns an unsigned native integer value for the byte at the given position. The $endian parameter has no meaning, but is available for consistency.

method read-int8

Defined as:

method read-int8(blob8:D: uint $pos, $endian = NativeEndian --> int)

Returns a native int value for the byte at the given position. The $endian parameter has no meaning, but is available for consistency.

method read-uint16

Defined as:

method read-uint16(blob8:D: uint $pos, $endian = NativeEndian --> uint)

Returns a native uint value for the two bytes starting at the given position.

method read-int16

Defined as:

method read-int16(blob8:D: uint $pos, $endian = NativeEndian --> int)

Returns a native int value for the two bytes starting at the given position.

method read-uint32

Defined as:

method read-uint32(blob8:D: uint $pos, $endian = NativeEndian --> uint)

Returns a native uint value for the four bytes starting at the given position.

method read-int32

Defined as:

method read-int32(blob8:D: uint $pos, $endian = NativeEndian --> int)

Returns a native int value for the four bytes starting at the given position.

method read-uint64

Defined as:

method read-uint64(blob8:D: uint $pos, $endian = NativeEndian --> UInt:D)

Returns an unsigned integer value for the eight bytes starting at the given position.

method read-int64

Defined as:

method read-int64(blob8:D: uint $pos, $endian = NativeEndian --> int)

Returns a native int value for the eight bytes starting at the given position.

method read-uint128

Defined as:

method read-uint128(blob8:D: uint $pos, $endian = NativeEndian --> UInt:D)

Returns an unsigned integer value for the sixteen bytes starting at the given position.

method read-int128

Defined as:

method read-int128(blob8:D: uint $pos, $endian = NativeEndian --> Int:D)

Returns an integer value for the sixteen bytes starting at the given position.

method read-num32

Defined as:

method read-num32(blob8:D: uint $pos, $endian = NativeEndian --> int)

Returns a native num value for the four bytes starting at the given position.

method read-num64

Defined as:

method read-num64(blob8:D: uint $pos, $endian = NativeEndian --> int)

Returns a native num value for the eight bytes starting at the given position.

Methods on blob8 only (6.d, 2019.03 and later)

method read-ubits

Defined as:

method read-ubits(blob8:D: uint $pos, uint $bits --> UInt:D)

Returns an unsigned integer value for the bits from the given bit offset and given number of bits. The endianness of the bits is assumed to be BigEndian.

method read-bits

Defined as:

method read-bits(blob8:D: uint $pos, uint $bits --> Int:D)

Returns a signed integer value for the bits from the given bit offset and given number of bits. The endianness of the bits is assumed to be BigEndian.

94 class Block

Code object with its own lexical scope

class Block is Code { }

A Block is a code object meant for small-scale code reuse. A block is created syntactically by a list of statements enclosed in curly braces.

Without an explicit signature or placeholder arguments, a block has $_ as a positional argument

my $block = { uc $_; };
say $block.^name;           # OUTPUT: «Block␤»
say $block('hello');        # OUTPUT: «HELLO␤»

A block can have a Signature between -> or <-> and the block:

my $add = -> $a, $b = 2 { $a + $b };
say $add(40);               # OUTPUT: «42␤»

If the signature is introduced with <-> , then the parameters are marked as rw by default:

my $swap = <-> $a, $b { ($a, $b) = ($b, $a) };
my ($a, $b) = (2, 4);
$swap($a, $b);
say $a;                     # OUTPUT: «4␤»

Blocks that aren't of type Routine (which is a subclass of Block) are transparent to return.

sub f() {
    say <a b c>.map: { return 42 };
                   #   ^^^^^^   exits &f, not just the block
}

The last statement is the implicit return value of the block.

say {1}.(); # OUTPUT: «1␤»

Bare blocks are automatically executed in the order they appear:

say 1;                # OUTPUT: «1␤»
{
    say 2;            # OUTPUT: «2␤»; executed directly, not a Block object
}
say 3;                # OUTPUT: «3␤»

95 enum Bool

Logical boolean

enum Bool <False True>

An enum for boolean true/false decisions.

Methods

method ACCEPTS

method ACCEPTS(Bool:D: --> Bool:D)

Used for smartmatch comparison. When the right side is True returns always True, when the right side of the match is False returns always False. In particular, ACCEPTS returns always the instance on which it is invoked, that is the right side of a smartmatch. As an example:

my $b = Bool.new( True ); 
 # when True on the right side returns 
 # always True 
 True  ~~ $b;     # True 
 False ~~ $b;     # True 
 
 $b = Bool.new( False ); 
 # when False on the right side 
 # returns always False 
 False ~~ $b;     # False 
 True ~~ $b;      # False 

routine succ

method succ(--> Bool:D)

Returns True.

say True.succ;                                    # OUTPUT: «True␤»
say False.succ;                                   # OUTPUT: «True␤»

succ is short for "successor"; it returns the next enum value. Bool is a special enum with only two values, False and True. When sorted, False comes first, so True is its successor. And since True is the "highest" Bool enum value, its own successor is also True.

routine pred

method pred(--> Bool:D)

Returns False.

say True.pred;                                    # OUTPUT: «False␤»
say False.pred;                                   # OUTPUT: «False␤»

pred is short for "predecessor"; it returns the previous enum value. Bool is a special enum with only two values, False and True. When sorted, False comes first, so False is the predecessor to True. And since False is the "lowest" Bool enum value, its own predecessor is also False.

routine enums

method enums(--> Hash:D)

Returns a Hash of enum-pairs. Works on both the Bool type and any key.

say Bool.enums;                                   # OUTPUT: «{False => 0, True => 1}␤»
say False.enums;                                  # OUTPUT: «{False => 0, True => 1}␤»

routine pick

multi method pick(Bool:U --> Bool:D)
multi method pick(Bool:U $count --> Seq:D)

Returns True or False if called without any argument. Otherwise returns $count elements chosen at random (without repetition) from the enum. If * is passed as $count, or $count is greater than or equal to two, then both elements are returned in random order.

say Bool.pick;                                    # OUTPUT: «True␤»
say Bool.pick(1);                                 # OUTPUT: «(False)␤»
say Bool.pick(*);                                 # OUTPUT: «(False True)␤»

routine roll

multi method roll(Bool:U --> Bool:D)
multi method roll(Bool:U $count --> Seq:D)

Returns True or False if called without any argument. Otherwise returns $count elements chosen at random. Note that each random choice from the enum is made independently, like a separate coin toss where each side of the coin represents one of the two values of the enum. If * is passed as $count an infinite Seq of Bools is returned.

say Bool.roll;                                    # OUTPUT: «True␤»
say Bool.roll(3);                                 # OUTPUT: «(True False False)␤»
say Bool.roll(*);                                 # OUTPUT: «(...)␤»

routine Int

multi method Int(Bool:D --> Int:D)

Returns the value part of the enum pair.

say False.Int;                                # OUTPUT: «0␤»
say True.Int;                                 # OUTPUT: «1␤»

routine Numeric

multi method Numeric(Bool:D --> Int:D)

Returns the value part of the enum pair.

say False.Numeric;                                # OUTPUT: «0␤»
say True.Numeric;                                 # OUTPUT: «1␤»

Operators

prefix ?

multi sub prefix:<?>(Mu --> Bool:D)

Coerces its argument to Bool.

prefix so

multi sub prefix:<so>(Mu --> Bool:D)

Coerces its argument to Bool, has looser precedence than prefix:<?> .

96 role Buf

Mutable buffer for binary data

role Buf[::T = uint8] does Blob[T] is repr('VMArray') is array_type(T){ ... }

A Buf does the role of a mutable sequence of (usually unsigned) integers.

my $b = Buf.new(1, 2, 3);
$b[1] = 42;

However, it's a parameterized type, and you can instantiate with several integer types:

my $b = Buf[int32].new( 3, -3, 0xff32, -44) 
 # OUTPUT: «Buf[int32]:0x<03 -3 FF32 -2C>» 

By default, Buf uses 8-bit unsigned integers, that is, it is equivalent to Buf[uint8]. Some other types of Bufs which are used often get their own class name.

buf8 Buf[uint8]
buf16 Buf[uint16]
buf32 Buf[uint32]
buf64 Buf[uint64]

You can use these in pretty much the same way you would with Buf:

my $buf = buf8.new(3,6, 254);
say $buf; # OUTPUT: «Buf[uint8]:0x<03 06 fe>␤»

Plus there are some object methods, like encode that might return a buf8 in some cases where it is the best representation for a particular encoding.

Methods

method subbuf-rw

method subbuf-rw($from = 0, $elems = self.elems - $from) is rw

A mutable version of subbuf that returns a Proxy functioning as a writable reference to a part of a buffer. Its first argument, $from specifies the index in the buffer from which a substitution should occur, and its last argument, $elems specifies how many elements are to be replaced.

For example, to replace one element at index 3 with two elements, 100 and 101:

my Buf $b .= new(0..5);
$b.subbuf-rw(3,1) = Buf.new(100, 101);
say $b.perl;   # OUTPUT: «Buf.new(0,1,2,100,101,4,5)␤»

In the case the $elems argument is not specified, the substitution happens at the specified index $from removing all trailing elements:

my Buf $b .= new(0..5);
$b.subbuf-rw(3) = Buf.new(200);
say $b.perl;   # OUTPUT: «Buf.new(0,1,2,200)␤»

In the case the $from argument is not specified, the substitution happens from the very beginning of the buffer:

my Buf $b .= new(0..5);
$b.subbuf-rw = Buf.new(123, 123);
say $b.perl;   # OUTPUT: «Buf.new(123, 123)␤»

routine subbuf-rw

Declared as

multi sub subbuf-rw(Buf:D \b) is rw
multi sub subbuf-rw(Buf:D \b, Int() $from) is rw
multi sub subbuf-rw(Buf:D \b, $from, $elems) is rw

Returns a writable reference to a part of a buffer. Invokes the subbuf-rw method on the specified Buf:

my Buf $b .= new(1,2,3);
subbuf-rw($b,2,1) = Buf.new(42);
say $b.perl;   # OUTPUT: «Buf.new(1,2,42)␤»

method reallocate

method reallocate($elems)

Change the number of elements of the Buf, returning the changed Buf. The size of Buf will be adapted depending on the number of $elems specified: if it is smaller than the actual size of the Buf the resulting Buf will be shrunk down, otherwise it will be enlarged to fit the number of $elems. In the case the Buf is enlarged, newly created items will be assigned a Virtual Machine specific null value, therefore you should not rely upon their value since it could be inconsistent across different virtual machines.

my Buf $b .= new(^10);
$b.reallocate(5);
say $b.perl;  # OUTPUT: «Buf.new(0,1,2,3,4)␤»

$b = Buf.new( 1..3 );
$b.reallocate( 10 );
$b.perl.say; # OUTPUT: «Buf.new(1,2,3,0,0,0,0,0,0,0)␤»

method list

Defined as:

multi method list(Buf:D:)

Returns a Seq of codepoints.

say Buf.new(122,105,112,205).list; # OUTPUT: «(122 105 112 205)␤»

method push

method push( $elems )

Adds elements at the end of the buffer

my @φ =  1,1, * + * … ∞;
my $bú = Buf.new( @φ[^5] );
$bú.push( @φ[5] );
say $bú.perl; # OUTPUT: «Buf.new(1,1,2,3,5,8)»

method pop

method pop()

Extracts the last element of the buffer

say $bú.pop(); # OUTPUT: «8» 
 say $bú.perl; # OUTPUT: «Buf.new(1,1,2,3,5)» 

method append

method append( $elems )

Appends at the end of the buffer

$bú.append( @φ[5..10] ); 
 say $bú.perl; # OUTPUT: «Buf.new(1,1,2,3,5,8,13,21,34,55,89)» 

method prepend

method prepend( $elems )

Adds elements at the beginning of the buffer

$bú.prepend( 0 ); 
 say $bú.perl; # OUTPUT: «Buf.new(0,1,1,2,3,5,8,13,21,34,55,89)» 

method shift

method shift()

Takes out the first element of the buffer

$bú.shift(); 
 say $bú.perl; # OUTPUT: «Buf.new(1,1,2,3,5,8,13,21,34,55,89)» 

method unshift

method unshift()

Adds elements at the beginning of the buffer

$bú.unshift( 0 ); 
 say $bú.perl; # OUTPUT: «Buf.new(0,1,1,2,3,5,8,13,21,34,55,89)» 

method splice

method splice( Buf:D: $start = 0, $elems?, *@replacement --> Buf)

Substitutes elements of the buffer by other elements

$bú.splice:  0, 3, <3 2 1>; 
 say $bú.perl; # OUTPUT: «Buf.new(3,2,1,2,3,5,8,13,21,34,55,89)» 

Methods on buf8 only (6.d, 2018.12 and later)

These methods are available on the buf8 type only. They allow low level access to writing bytes to the underlying data and in different ways with regards to type (integer or floating point (num)), size (8, 16, 32, 64 or 128 bits), signed or unsigned (for integer values) and endianness (native, little and big endianness). These methods always return Nil.

Endianness must be indicated by using values of the Endian enum as the third parameter to these methods. If no endianness is specified, NativeEndian will be assumed. Other values are LittleEndian and BigEndian.

The buffer will be automatically resized to support any bytes being written if it is not large enough yet.

method write-uint8

Defined as:

method write-uint8(buf8:D: uint $pos, uint8 $value, $endian = NativeEndian --> Nil)

Writes an unsigned 8-bit integer value at the given position. The $endian parameter has no meaning, but is available for consistency.

method write-int8

Defined as:

method write-int8(buf8:D: uint $pos, int8 $value, $endian = NativeEndian --> Nil)

Writes a signed 8-bit integer value at the given position. The $endian parameter has no meaning, but is available for consistency.

method write-uint16

Defined as:

method write-uint16(buf8:D: uint $pos, uint16 $value, $endian = NativeEndian --> Nil)

Writes an unsigned 16-bit integer value at the given position with the given endianness.

method write-int16

Defined as:

method write-int16(buf8:D: uint $pos, int16 $value, $endian = NativeEndian --> Nil)

Writes a signed 16-bit integer value at the given position with the given endianness.

method write-uint32

Defined as:

method write-uint32(buf8:D: uint $pos, uint32 $value, $endian = NativeEndian --> Nil)

Writes an unsigned 32-bit integer value at the given position with the given endianness.

method write-int32

Defined as:

method write-int32(buf8:D: uint $pos, int32 $value, $endian = NativeEndian --> Nil)

Writes a signed 32-bit integer value at the given position with the given endianness.

method write-uint64

Defined as:

method write-uint64(buf8:D: uint $pos, uint64 $value, $endian = NativeEndian --> Nil)

Writes an unsigned 64-bit integer value at the given position with the given endianness.

method write-int64

Defined as:

method write-int64(buf8:D: uint $pos, Int:D $value, $endian = NativeEndian --> Nil)

Writes a signed 64-bit integer value at the given position with the given endianness.

method write-uint128

Defined as:

method write-uint128(buf8:D: uint $pos, UInt:D $value, $endian = NativeEndian --> Nil)

Writes an unsigned 128-bit integer value at the given position with the given endianness.

method write-int128

Defined as:

method write-int128(buf8:D: uint $pos, Int:D $value, $endian = NativeEndian --> Nil)

Writes a signed 128-bit integer value at the given position with the given endianness.

method write-num32

Defined as:

method write-num32(buf8:D: uint $pos, num32 $value, $endian = NativeEndian --> Nil)

Writes a native num32 IEEE floating point value at the given position with the given endianness.

method write-num64

Defined as:

method write-num64(buf8:D: uint $pos, num64 $value, $endian = NativeEndian --> Nil)

Writes a native num64 IEEE floating point value at the given position with the given endianness.

Methods on buf8 only (6.d, 2019.03 and later)

method write-ubits

Defined as:

method write-ubits(buf8:D: uint $pos, uint $bits, UInt:D $value --> Nil)

Writes an unsigned integer value to the bits from the given bit offset and given number of bits. The endianness of the bits is assumed to be BigEndian. Always returns Nil.

method write-bits

Defined as:

method write-bits(buf8:D: uint $pos, uint $bits, Int:D $value --> Nil)

Writes a signed integer value for the bits from the given bit offset and given number of bits. The endianness of the bits is assumed to be BigEndian. Always returns Nil.

97 role CX::Done

Done control exception

role CX::Done does X::Control { }

A control exception to be used to indicate a supply block is finished by calling done.

Methods

method message

Defined as:

method message()

Returns "<done control exception>"

98 role CX::Emit

Emit control exception

role CX::Emit does X::Control { }

A control exception to be used when emit is used inside a Supply block.

Methods

method message

Defined as:

method message()

Returns "<emit control exception>"

99 role CX::Last

Last control exception

role CX::Last does X::Control { }

A control exception that is thrown when last is called.

Methods

method message

Defined as:

method message()

Returns "<last control exception>". Since this type of exception is to be consumed by type and not really by the content of the message, this is a generic message, similar to all other CX::* exceptions.

100 role CX::Next

Next control exception

role CX::Next does X::Control { }

A control exception that is triggered when next is called.

for ^10 { 
     CONTROL { 
       when CX::Next { say "We're next" }; 
     } 
     next if $_ %% 2; 
     say "We're in $_"; 
 } 

This will print:

We're next 
 We're in 1 
 We're next 
 We're in 3 
 We're next 
 We're in 5 
 We're next 
 We're in 7 
 We're next 
 We're in 9 

Methods

method message

Defined as:

method message()

Returns "<next control exception>"

101 role CX::Proceed

Proceed control exception

role CX::Proceed does X::Control { }

A control exception to be used when proceed is used within when or default blocks.

Methods

method message

Defined as:

method message()

Returns "<proceed control exception>"

102 role CX::Redo

Redo control exception

role CX::Redo does X::Control { }

A control exception thrown when redo is called.

Methods

method message

Defined as:

method message()

Returns "<redo control exception>".

103 role CX::Return

Return control exception

role CX::Next does X::Control { }

A control exception to be used when return is called from within a sub.

Methods

method message

Defined as:

method message()

Returns "<return control exception>"

104 role CX::Succeed

Succeed control exception

role CX::Succeed does X::Control { }

A control exception thrown when succeed is called from a when or default block.

Methods

method message

Defined as:

method message()

Returns "<next control exception>"

105 role CX::Take

Take control exception

role CX::Take does X::Control { }

A control exception triggered by take.

Methods

method message

Defined as:

method message()

Returns "<take control exception>".

106 role CX::Warn

Control exception warning

role CX::Warn does X::Control { }

A control exception triggered when warn is called to warn about any incidence.

Methods

method new

CX::Warn objects are created when a warning is thrown in any block.

107 class CallFrame

Captures the current frame state

class CallFrame {}

A CallFrame will be usually captured from the current state of a program using the callframe subroutine.

my $frame = callframe;
say "The above line of code ran at {$frame.file}:{$frame.line}.";

With no arguments the callframe will give you frame information for the line calling callframe. The file and line annotations will be identical to those in $?FILE and $?LINE.

You may, however, pass a number to callframe to specify a different frame level. A positive number will move upward through the levels of frame. A negative number will move downward into the callframe method and class itself at the point at which they are running to construct this information for you.

The frames themselves do not necessarily match only method or subroutine calls. Perl constructs a frames for blocks and such as well, so if you need a callframe for a particular method call, do not assume it is a fixed number of levels up.

Each frame stores annotations, including the file and line annotations, which have convenience methods for accessing them directly. You can also retrieve a reference to the code block of the currently executing frame using the code method. The frame also captures all lexical variables stored with the frame, which are available by calling my on the frame object.

Here's a short example that will find the calling routine and print the package of the caller using the callframe interface.

sub calling-frame() {
    for 1..* -> $level {
        given callframe($level) -> $frame {
            when $frame ~~ CallFrame {
                    next unless $frame.code ~~ Routine;
                    say $frame.code.package;
                    last;
            }
            default {
                    say "no calling routine or method found";
                    last;
            }
        }
    }
}

calling-frame;

If you just need to trace caller information, Backtrace may provide a better means of getting it. CallFrame contains more information about a specific frame, but provides a tedious interface for enumerating a call stack.

Methods

Note From version 6.d, .perl can be called on CallFrame.

method code

method code()

Return the callable code for the current block. When called on the object returned by callframe(0), this will be the same value found in &?BLOCK.

my $frame; 
 for ^3 { FIRST $frame = callframe; say $_ * 3 }; 
 say $frame.code() 

The $frame variable will hold the Code for the block inside the loop in this case.

method file

method file()

This is a shortcut for looking up the file annotation. Therefore, the following code prints True.

my $frame = callframe(0);
say $frame.file eq $frame.annotations<file>;

method line

method line()

This is a shortcut for looking up the line annotation. For example, the following two calls are identical.

say callframe(1).line;
say callframe(1).annotations<line>;

method annotations

method annotations()

Returns a Map containing the invocants annotations, i.e. line and file. An easier way to get hold of the annotation information is to use one of the convenience methods instead.

say callframe.annotations.^name;                   # OUTPUT: «Map␤»
say callframe.annotations<file> eq callframe.file; # OUTPUT: «True␤»

method my

method my()

Return a Hash that names all the variables and their values associated with the lexical scope of the frame.

sub some-value {
    my $the-answer = 42;
    callframe(0);
}

my $frame = some-value();
say $frame.my<$the-answer>; # OUTPUT: «42␤»

Routines

sub callframe

sub callframe(Int:D $level = 0)

Returns a CallFrame object for the given level. If no level is given, the default level is 0. Positive levels move up the frame stack and negative levels move down (into the call to callframe and deeper).

Returns Mu if there is no call information for the given level. Negative levels may result in an exception.

108 role Callable

Invocable code object

role Callable { ... }

Role for objects which support calling them. It's used in Block, Routine, Sub, Method, Submethod and Macro types.

Callables can be stored in &-sigiled containers, the default type constraint of such a container is Callable.

A signature object can be used to force a check against the signature of the Callable to be stored into the container.
my &a = {;}; # Empty block needs a semicolon
my &b = -> {};
my &c = sub () {};
sub foo() {};
my &d = &foo;
commented out until it's implemented for code :skip-test my &f:(Int) = sub bar(Int) {}; # Not yet implemented my &f:(Str) = -> Str {}; # Not yet implemented

Methods

method CALL-ME

method CALL-ME(Callable:D $self: |arguments)

This method is required for postfix:«( )» and postfix:«.( )». It's what makes an object actually call-able and needs to be overloaded to let a given object act like a routine. If the object needs to be stored in a &-sigiled container, is has to implement Callable.

class A does Callable {
    submethod CALL-ME(|c){ 'called' }
}
my &a = A;
say a(); # OUTPUT: «called␤»

method Capture

Defined as:

method Capture()

Throws X::Cannot::Capture.

109 class Cancellation

Removal of a task from a Scheduler before normal completion

my class Cancellation {}

A low level part of the Perl 6 concurrency system. Some Scheduler objects return a Cancellation with the .cue method which can be used to cancel the scheduled execution before normal completion. Cancellation.cancelled is a boolean that is true after #cancel is called.

Methods

method cancel

Defined as:

method cancel()

Usage:

Cancellation.cancel 

Cancels the scheduled execution of a task before normal completion.

110 class Capture

Argument list suitable for passing to a Signature

class Capture { } 

A Capture is a container for passing arguments to a code object. Captures are the flip-side of Signatures – Captures are the caller defined arguments, while Signatures are the callee defined parameters.

When you call print $a, $b, the $a, $b part is a Capture.

Captures contain a list-like part for positional arguments and a hash-like part for named arguments, thus behaving as Positional and Associative, although it does not actually mixes in those roles. For the named arguments, Captures use a slightly different syntax than a normal List. There are two easy ways to make a named argument: 1) use an unquoted key naming a parameter, followed by =>, followed by the argument and 2) use a colon-pair literal named after the parameter:

say unique 1, -2, 2, 3, as => { abs $_ };   # OUTPUT: «(1 -2 3)␤»
# ... is the same thing as:
say unique 1, -2, 2, 3, :as({ abs $_ });    # OUTPUT: «(1 -2 3)␤»
# Be careful not to quote the name of a named parameter:
say unique 1, -2, 2, 3, 'as' => { abs $_ };
# OUTPUT: «(1 -2 2 3 as => -> ;; $_? is raw { #`(Block|78857320) ... })␤»

A stand-alone Capture can also be made, stored, and used later. A literal Capture can be created by prefixing a term with a backslash \. Commonly, this term will be a List of terms, from which any Pair literal will be placed in the named part, and all other terms will be placed in the positional part.

my $c = \(42);          # Capture with one positional part
$c = \(1, 2, a => 'b'); # Capture with two positional and one named parts

To use such a Capture, you may use '|' before it in a function call, and it will be as if the values in the Capture were passed directly to the function as arguments – named arguments will be passed as named arguments and positional arguments will be passed as positional arguments. You may re-use the Capture as many times as you want, even with different functions.

my $c = \(4, 2, 3);
reverse(|$c).say; # OUTPUT: «3 2 4␤»
sort(5,|$c).say;  # OUTPUT: «2 3 4 5␤»

Inside a Signature, a Capture may be created by prefixing a sigilless parameter with a vertical bar |. This packs the remainder of the argument list into that parameter.

f(1, 2, 3, a => 4, b => 5);
sub f($a, |c) {
    # c  is  \(2, 3, a => 4, b => 5)
}

Note that Captures are still Lists in that they may contain containers, not just values:

my $b = 1;
my $c = \(4, 2, $b, 3);
sort(|$c).say;        # OUTPUT: «1 2 3 4␤»
$b = 6;
sort(|$c).say;        # OUTPUT: «2 3 4 6␤»

Methods

method list

Defined as:

method list(Capture:D:)

Returns the positional part of the Capture.

my Capture $c = \(2, 3, 5, apples => (red => 2));
say $c.list;                                      # OUTPUT: «(2 3 5)␤»

method hash

Defined as:

method hash(Capture:D:)

Returns the named/hash part of the Capture.

my Capture $c = \(2, 3, 5, apples => (red => 2));
say $c.hash; # OUTPUT: «Map.new((:apples(:red(2))))␤»

method elems

Defined as:

method elems(Capture:D: --> Int:D)

Returns the number of positional elements in the Capture.

my Capture $c = \(2, 3, 5, apples => (red => 2));
say $c.elems;                                  # OUTPUT: «3␤»

method keys

Defined as:

multi method keys(Capture:D: --> Seq:D)

Returns a Seq containing all positional keys followed by all named keys. For positional arguments the keys are the respective arguments ordinal position starting from zero.

my $capture = \(2, 3, 5, apples => (red => 2));
say $capture.keys;                             # OUTPUT: «(0 1 2 apples)␤»

method values

Defined as:

multi method values(Capture:D: --> Seq:D)

Returns a Seq containing all positional values followed by all named argument values.

my $capture = \(2, 3, 5, apples => (red => 2));
say $capture.values;                           # OUTPUT: «(2 3 5 red => 2)␤»

method kv

Defined as:

multi method kv(Capture:D: --> Seq:D)

Returns a Seq of alternating keys and values. The positional keys and values, if any, comes first followed by the named keys and values.

my $capture = \(2, 3, apples => (red => 2));
say $capture.kv;                                  # OUTPUT: «(0 2 1 3 apples red => 2)␤»

method pairs

Defined as:

multi method pairs(Capture:D: --> Seq:D)

Returns all arguments, the positional followed by the named, as a Seq of Pairs. Positional arguments have their respective ordinal value, starting at zero, as key while the named arguments have their names as key.

my Capture $c = \(2, 3, apples => (red => 2));
say $c.pairs;                                     # OUTPUT: «(0 => 2 1 => 3 apples => red => 2)␤»

method antipairs

Defined as:

multi method antipairs(Capture:D: --> Seq:D)

Returns all arguments, the positional followed by the named, as a Seq of pairs where the keys and values have been swapped, i.e. the value becomes the key and the key becomes the value. This behavior is the opposite of the pairs method.

my $capture = \(2, 3, apples => (red => 2));
say $capture.antipairs;                           # OUTPUT: «(2 => 0 3 => 1 (red => 2) => apples)␤»

method Bool

Defined as:

method Bool(Capture:D: --> Bool:D)

Returns True if the Capture contains at least one named or one positional argument.

say \(1,2,3, apples => 2).Bool;                   # OUTPUT: «True␤»
say \().Bool;                                     # OUTPUT: «False␤»

method Capture

Defined as:

method Capture(Capture:D: --> Capture:D)

Returns itself, i.e. the invocant.

say \(1,2,3, apples => 2).Capture; # OUTPUT: «\(1, 2, 3, :apples(2))␤»

method Numeric

Defined as:

method Numeric(Capture:D: --> Int:D)

Returns the number of positional elements in the Capture.

say \(1,2,3, apples => 2).Numeric;                # OUTPUT: «3␤»

111 class Channel

Thread-safe queue for sending values from producers to consumers

class Channel {}

A Channel is a thread-safe queue that helps you to send a series of objects from one or more producers to one or more consumers. Each object will arrive at only one such consumer, selected by the scheduler. If there is only one consumer and one producer, the order of objects is guaranteed to be preserved. Sending on a Channel is non-blocking.

my $c = Channel.new;
await (^10).map: {
    start {
        my $r = rand;
        sleep $r;
        $c.send($r);
    }
}
$c.close;
say $c.list;

Further examples can be found in the concurrency page

Methods

method send

Defined as:

method send(Channel:D: \item)

Enqueues an item into the Channel. Throws an exception of type X::Channel::SendOnClosed if the channel has been closed already. This call will not block waiting for a consumer to take the object. There is no set limit on the number of items that may be queued, so care should be taken to prevent runaway queueing.

my $c = Channel.new;
$c.send(1);
$c.send([2, 3, 4, 5]);
$c.close;
say $c.list; # OUTPUT: «(1 [2 3 4 5])␤»

method receive

Defined as:

method receive(Channel:D:)

Receives and removes an item from the channel. It blocks if no item is present, waiting for a send from another thread.

Throws an exception of type X::Channel::ReceiveOnClosed if the channel has been closed, and the last item has been removed already, or if close is called while receive is waiting for an item to arrive.

If the channel has been marked as erratic with method fail, and the last item has been removed, throws the argument that was given to fail as an exception.

See method poll for a non-blocking version that won't throw exceptions.

my $c = Channel.new;
$c.send(1);
say $c.receive; # OUTPUT: «1␤»

method poll

Defined as:

method poll(Channel:D:)

Receives and removes an item from the channel. If no item is present, returns Nil instead of waiting.

my $c = Channel.new;
Promise.in(2).then: { $c.close; }
^10 .map({ $c.send($_); });
loop {
    if $c.poll -> $item { $item.say };
    if $c.closed  { last };
    sleep 0.1;
}

See method receive for a blocking version that properly responds to channel closing and failure.

method close

Defined as:

method close(Channel:D:)

Close the Channel, normally. This makes subsequent send calls die with X::Channel::SendOnClosed. Subsequent calls of .receive may still drain any remaining items that were previously sent, but if the queue is empty, will throw an X::Channel::ReceiveOnClosed exception. Since you can produce a Seq from a Channel by contextualizing to array with @() or by calling the .list method, these methods will not terminate until the channel has been closed. A whenever-block will also terminate properly on a closed channel.

my $c = Channel.new; 
 $c.close; 
 $c.send(1); 
 CATCH { default { put .^name, ': ', .Str } }; 
 # OUTPUT: «X::Channel::SendOnClosed: Cannot send a message on a closed channel␤» 

Please note that any exception thrown may prevent .close from being called, this may hang the receiving thread. Use a LEAVE phaser to enforce the .close call in this case.

method list

Defined as:

method list(Channel:D: --> List:D)

Returns a list based on the Seq which will iterate items in the queue and remove each item from it as it iterates. This can only terminate once the close method has been called.

my $c = Channel.new; $c.send(1); $c.send(2);
$c.close;
say $c.list; # OUTPUT: «(1 2)␤»

method closed

Defined as:

method closed(Channel:D: --> Promise:D)

Returns a promise that will be kept once the channel is closed by a call to method close.

my $c = Channel.new;
$c.closed.then({ say "It's closed!" });
$c.close;
sleep 1;

method fail

Defined as:

method fail(Channel:D: $error)

Closes the Channel (that is, makes subsequent send calls die), and enqueues the error to be thrown as the final element in the channel. Method receive will throw that error as an exception. Does nothing if the channel has already been closed or .fail has already been called on it.

my $c = Channel.new;
$c.fail("Bad error happens!");
$c.receive;
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::AdHoc: Bad error happens!␤»

method Capture

Defined as:

method Capture(Channel:D --> Capture:D)

Equivalent to calling .List.Capture on the invocant.

method Supply

Defined as:

method Supply(Channel:D:)

This returns an on-demand Supply that emits a value for every value received on the Channel. done will be called on the Supply when the Channel is closed.

my $c = Channel.new;
my Supply $s1 = $c.Supply;
my Supply $s2 = $c.Supply;
$s1.tap(-> $v { say "First $v" });
$s2.tap(-> $v { say "Second $v" });
^10 .map({ $c.send($_) });
sleep 1;

Multiple calls to this method produce multiple instances of Supply, which compete over the values from the Channel.

sub await

Defined as:

multi sub await(Channel:D)
multi sub await(*@)

Waits until all of one or more channels has a value available, and returns those values (it calls .receive on the channel). Also works with promises.

my $c = Channel.new;
Promise.in(1).then({$c.send(1)});
say await $c;

Since 6.d, it no longer blocks a thread while waiting.

112 class Code

Code object

class Code is Any does Callable {}

Code is the ultimate base class of all code objects in Perl 6. It exposes functionality that all code objects have. While thunks are directly of type Code, most code objects (such as those resulting from blocks, subroutines or methods) will belong to some subclass of Code.

Methods

method ACCEPTS

multi method ACCEPTS(Code:D: Mu $topic)

Usually calls the code object and passes $topic as an argument. However, when called on a code object that takes no arguments, the code object is invoked with no arguments and $topic is dropped. The result of the call is returned.

method arity

Defined as:

method arity(Code:D: --> Int:D)

Returns the minimum number of positional arguments that must be passed in order to call the code object. Any optional or slurpy parameters in the code object's Signature do not contribute, nor do named parameters.

sub argless() { }
sub args($a, $b?) { }
sub slurpy($a, $b, *@c) { }
say &argless.arity;             # OUTPUT: «0␤»
say &args.arity;                # OUTPUT: «1␤»
say &slurpy.arity;              # OUTPUT: «2␤»

method assuming

method assuming(Callable:D $self: |primers)

Returns a Callable that implements the same behavior as the original, but has the values passed to .assuming already bound to the corresponding parameters.

my sub slow($n){ my $i = 0; $i++ while $i < $n; $i };

# takes only one parameter and as such wont forward $n
sub bench(&c){ c, now - ENTER now };

say &slow.assuming(10000000).&bench; # OUTPUT: «(10000000 7.5508834)␤»

For a sub with arity greater than one, you can use Whatever * for all of the positional parameters that are not "assumed".

sub first-and-last ( $first, $last ) {
    say "Name is $first $last";
}

my &surname-smith = &first-and-last.assuming( *, 'Smith' );

&surname-smith.( 'Joe' ); # OUTPUT: «Name is Joe Smith␤»

You can handle any combination of assumed and not assumed positional parameters:

sub longer-names ( $first, $middle, $last, $suffix ) { 
     say "Name is $first $middle $last $suffix"; 
 } 
 
 my &surname-public = &longer-names.assuming( *, *, 'Public', * ); 
 
 &surname-public.( 'Joe', 'Q.', 'Jr.'); # OUTPUT: «Name is Joe Q. Public Jr.␤» 

Named parameters can be assumed as well:

sub foo { say "$^a $^b $:foo $:bar" }
&foo.assuming(13, :42foo)(24, :72bar); # OUTPUT: «13 24 42 72␤»

And you can use .assuming on all types of Callables, including Methods and Blocks:

# We use a Whatever star for the invocant:
my &comber = Str.^lookup('comb').assuming: *, /P \w+/;
say comber 'Perl is awesome! Python is great! And PHP is OK too';
# OUTPUT: «(Perl Python PHP)␤»

my &learner = {
    "It took me $:months months to learn $^lang"
}.assuming: 'Perl 6';
say learner :6months;  # OUTPUT: «It took me 6 months to learn Perl 6␤»

method count

Defined as:

method count(Code:D: --> Real:D)

Returns the maximum number of positional arguments that may be passed when calling the code object. For code objects that can accept any number of positional arguments (that is, they have a slurpy parameter), count will return Inf. Named parameters do not contribute.

sub argless() { }
sub args($a, $b?) { }
sub slurpy($a, $b, *@c) { }
say &argless.count;             # OUTPUT: «0␤»
say &args.count;                # OUTPUT: «2␤»
say &slurpy.count;              # OUTPUT: «Inf␤»

method of

Defined as:

method of(Code:D: --> Mu)

Returns the return type constraint of the Code:

say -> () --> Int {}.of; # OUTPUT: «(Int)␤»

method signature

Defined as:

multi method signature(Code:D: --> Signature:D)

Returns the Signature object for this code object, which describes its parameters.

sub a(Int $one, Str $two) {};
say &a.signature; # OUTPUT: «(Int $one, Str $two)␤»

method cando

method cando(Capture $c)

Returns a list of candidates that can be called with the given Capture. Since Code objects do not have any multiple dispatch, this either returns a list with the object, or an empty list.

my $single = \'a';         # a single argument Capture
my $plural = \('a', 42);   # a two argument Capture
my &block = { say $^a };   # a Block object, that is a subclass of Code, taking one argument
say &block.cando($single); # OUTPUT: «(-> $a { #`(Block|94212856419136) ... })␤»
say &block.cando($plural); # OUTPUT: «()␤»

method Str

Defined as:

multi method Str(Code:D: --> Str:D)

Will output the method name, but also produce a warning. Use .perl or .gist instead.

sub marine() { }
say ~&marine;
# OUTPUT: «Sub object coerced to string (please use .gist or .perl to do that)␤marine␤»
say &marine.Str;
# OUTPUT: «Sub object coerced to string (please use .gist or .perl to do that)␤marine␤»
say &marine.perl; # OUTPUT: «sub marine { #`(Sub|94280758332168) ... }␤»

method file

Defined as:

method file(Code:D: --> Str:D)

Returns the name of the file in which the code object was declared.

say &infix:<+>.file;

method line

Defined as

method line(Code:D: --> Int:D)

Returns the line number in which the code object was declared.

say &infix:<+>.line;

113 class Collation

Encapsulates how strings are sorted

class Collation { } 

Collation is the class that allows proper sorting, taking into account all Unicode characteristics. It's the class the object $*COLLATION is instantiated to, and thus includes collation levels, that is, what kind of features should be looked up when comparing two strings and in which order.

Methods

Method set

Defined as:

method set ( 
     Int :$primary    = 1, 
     Int :$secondary  = 1, 
     Int :$tertiary   = 1, 
     Int :$quaternary = 1) 

Sets if the different levels should be used in ascending or descending order, or if they are going to be ignored (when set to 0).

my $*COLLATION = Collation.new; 
 say 'a' coll 'z'; # OUTPUT: «Less» 
 $*COLLATION.set(:primary(-1)); 
 say 'a' coll 'z'; # OUTPUT: «More» 

method primary

Defined as:

method primary

Returns the state of the primary collation level.

method secondary

Defined as:

method secondary

Returns the state of the secondary collation level.

method tertiary

Defined as:

method tertiary

Returns the state of the tertiary collation level.

method quaternary

Defined as:

method quaternary

Returns the state of the quaternary collation level.

114 class CompUnit

CompUnit

class CompUnit {}

The CompUnit represents the meta-information about a compilation unit. This usually relates to source code that resides in a file on a filesystem, rather than code that is executed using an EVAL statement.

Methods

method auth

method auth(--> Str:D)

Returns the authority information with which the CompUnit object was created (if any).

method distribution

method distribution(--> Distribution:D)

Returns the Distribution object with which the CompUnit object was created (if any).

method from

method from(--> Str:D)

Returns the name of the language with which the CompUnit object was created (if any). It will be Perl6 by default.

method precompiled

method precompiled(--> Bool:D)

Returns whether the CompUnit object originated from a precompiled source.

method repo

method repo(--> CompUnit::Repository:D)

Returns the CompUnit::Repository object with which the CompUnit object was created.

method repo-id

method repo-id(--> Str:D)

Returns the identification string with which the CompUnit object can be identified in the associated repo.

method short-name

method short-name(--> Str:D)

Returns The short name with which the CompUnit object was created (if any).

method version

method version(--> Version:D)

Returns the version information with which the CompUnit object was created (if any).

115 role CompUnit::Repository

CompUnit::Repository

The CompUnit::Repository role defines the interface of the implementation of CompUnit::Repositories such as CompUnit::Repository::Installation and CompUnit::Repository::FileSystem.

Methods

method resolve

method resolve(CompUnit::DependencySpecification $spec --> CompUnit:D)

Returns a CompUnit mapped to the highest version distribution matching $spec from the first repository in the repository chain that contains any version of a distribution matching $spec.

method need

Loads and returns a CompUnit which is mapped to the highest version distribution matching $spec from the first repository in the repository chain that contains any version of a distribution matching $spec.

method load

method load(IO::Path:D $file --> CompUnit:D)

Load the $file and return a CompUnit object representing it.

method loaded

method loaded(--> Iterable:D)

Returns all CompUnits this repository has loaded.

116 class CompUnit::Repository::FileSystem

CompUnit::Repository::FileSystem

class CompUnit::Repository::FileSystem 
     does CompUnit::Repository::Locally 
     does CompUnit::Repository 
     { } 

A CompUnit::Repository implementation backed by the filesystem typically used in development situations. This is what is used by -I . / -I lib (which are actually -I file#. and -I file#lib) or use lib "." / use lib "lib". Unlike CompUnit::Repository::Installation, this represents a single distribution.

Methods

method candidates

multi method candidates(Str:D $name, :$auth, :$ver, :$api)
multi method candidates(CompUnit::DependencySpecification $spec)

Return all distributions that contain a module matching the specified $name, auth, ver, and api.

# assuming one is cloned into the zef git repository...
my $repo = CompUnit::Repository::FileSystem.new(prefix => $*CWD);
with $repo.candidates("Zef").head -> $dist {
    say "Zef version: " ~ $dist.meta<version>;
}
else {
    say "No candidates for 'Zef' found";
}

method files

multi method files(Str:D $name, :$auth, :$ver, :$api)
multi method files(CompUnit::DependencySpecification $spec)

Return all distributions that match the specified auth ver and api, and contains a non-module file matching the specified $name.

# assuming one is cloned into the zef git repository...
my $repo = CompUnit::Repository::FileSystem.new(prefix => $*CWD);
say $repo.files('bin/zef', :ver<419.0+>).head.<name>              // "Nada"; # OUTPUT: «Nada␤»
say $repo.files('resources/config.txt', :ver<419.0+>).head.<name> // "Nada"; # OUTPUT: «Nada␤»

say $repo.files('bin/zef', :ver<0.4.0+>).head.<name>;                        # OUTPUT: «zef␤»
say $repo.files('resources/config.txt', :ver<0.4.0+>).head.<name>;           # OUTPUT: «zef␤»

method resolve

method resolve(CompUnit::DependencySpecification $spec --> CompUnit:D)

Returns a CompUnit mapped to the highest version distribution matching $spec from the first repository in the repository chain that contains any version of a distribution matching $spec.

method need

    method need( 
         CompUnit::DependencySpecification $spec, 
         CompUnit::PrecompilationRepository $precomp = self.precomp-repository(), 
         CompUnit::PrecompilationStore :@precomp-stores = self!precomp-stores(), 
         --> CompUnit:D) 

Loads and returns a CompUnit which is mapped to the highest version distribution matching $spec from the first repository in the repository chain that contains any version of a distribution matching $spec.

method load

method load(IO::Path:D $file --> CompUnit:D)

Load the $file and return a CompUnit object representing it.

method loaded

method loaded(--> Iterable:D)

Returns all CompUnits this repository has loaded.

method short-id

method short-id()

Returns the repo short-id, which for this repository is file.

117 class CompUnit::Repository::Installation

CompUnit::Repository::Installation

class CompUnit::Repository::Installation 
     does CompUnit::Repository::Locally 
     does CompUnit::Repository::Installable 
     { } 

A CompUnit::Repository implementation backed by the filesystem, but uses an internal storage format to:

Because of the internal storage format the usual way to add a distribution is not by copying files but by calling CompUnit::Repository::Installation#method_install.

Methods

method install

method install(Distribution $distribution, Bool :$force)

Copies modules into a special location so that they can be loaded afterwards.

:$force will allow installing over an existing distribution that has the same name, auth, api, and ver. Otherwise such a situation will result in Failure.

my $inst-repo = CompUnit::RepositoryRegistry.repository-for-name("site");
my $dist = Distribution::Path.new(...);
$inst-repo.install($dist);

method uninstall

method uninstall(Distribution $distribution)

Removes the $distribution from the repository. $distribution should be obtained from the repository it is being removed from:

my $inst-repo = CompUnit::RepositoryRegistry.repository-for-name("site");
my $dist = $inst-repo.candidates("Acme::Unused").head;
$inst-repo.uninstall($dist);

method candidates

multi method candidates(Str:D $name, :$auth, :$ver, :$api)
multi method candidates(CompUnit::DependencySpecification $spec)

Return all distributions that contain a module matching the specified $name, auth, ver, and api.

my $inst-repo-path = CompUnit::RepositoryRegistry.repository-for-name("perl").prefix;
my $inst-repo = CompUnit::Repository::Installation.new(prefix => $inst-repo-path);
my $dist = $inst-repo.candidates("Test").head;
say "Test version: " ~ $dist.meta<ver>; # OUTPUT: «6.d␤»

method files

multi method files(Str:D $name, :$auth, :$ver, :$api)
multi method files(CompUnit::DependencySpecification $spec)

Return all distributions that match the specified auth ver and api, and contains a non-module file matching the specified $name.

# assuming Zef is installed to the default location...
my $repo = CompUnit::RepositoryRegistry.repository-for-name("site");

say $repo.files('bin/zef', :ver<419.0+>).head.<name>              // "Nada"; # OUTPUT: «Nada␤»
say $repo.files('resources/config.txt', :ver<419.0+>).head.<name> // "Nada"; # OUTPUT: «Nada␤»

say $repo.files('bin/zef', :ver<0.4.0+>).head.<name>;                        # OUTPUT: «zef␤»
say $repo.files('resources/config.txt', :ver<0.4.0+>).head.<name>;           # OUTPUT: «zef␤»

method resolve

method resolve(CompUnit::DependencySpecification $spec --> CompUnit:D)

Returns a CompUnit mapped to the highest version distribution matching $spec from the first repository in the repository chain that contains any version of a distribution matching $spec.

method need

method need( 
     CompUnit::DependencySpecification $spec, 
     CompUnit::PrecompilationRepository $precomp = self.precomp-repository(), 
     CompUnit::PrecompilationStore :@precomp-stores = self!precomp-stores(), 
     --> CompUnit:D) 

Loads and returns a CompUnit which is mapped to the highest version distribution matching $spec from the first repository in the repository chain that contains any version of a distribution matching $spec.

method load

method load(IO::Path:D $file --> CompUnit:D)

Load the $file and return a CompUnit object representing it.

method loaded

method loaded(--> Iterable:D)

Returns all CompUnits this repository has loaded.

method short-id

method short-id()

Returns the repo short-id, which for this repository is inst.

118 class Compiler

Information related to the compiler that is being used

class Compiler does Systemic {}

Built-in class for providing compiler related information. Usually accessed through the compiler attribute of the $*PERL dynamic variable.

say $*PERL.compiler; # OUTPUT: «rakudo (2019.03.1.385.ga.643.b.8.be.1)␤»

Methods

method id

Returns an unique identifier, a long hexadecimal string

method release

It's empty, but it might contain the release number for specific releases.

method codename

It's empty, but it might contain the codename for specific releases.

method build-date

method build-date()

Up to version 2019.03.1, it returns the date when it was built.

say $*PERL.compiler.build-date; #OUTPUT: «2018-05-05T21:49:43Z␤»

method verbose-config

method verbose-config(:$say)

If $say is True, it prints the different items included in the configuration of the compiler; if it is not, returns a Hash with the same information.

say $*PERL.compiler.verbose-config; # OUTPUT: «distro::auth=https://www.opensuse.org/␤distro::desc=2018-05-06T09:19:17.571307+02:00␤» ... And the rest of the configuration

See Also: Systemic

119 class Complex

Complex number

class Complex is Cool does Numeric {}

Represents a number in the complex plane.

Complex objects are immutable.

Operators

postfix i

Adding a trailing i to a number literal makes it a Complex, for example:

say 2i;     # same as Complex.new(0, 2);
say 1-2e3i; # same as Complex.new(1, -2e3);

Methods

method new

Defined as:

multi method new(Real $re, Real $im --> Complex:D)

Creates a new Complex object from real and imaginary parts.

my $complex = Complex.new(1, 1);
say $complex;    # OUTPUT: «1+1i␤»

When created without arguments, both parts are considered to be zero.

say Complex.new; # OUTPUT: «0+0i␤»

method re

Defined as:

method re(Complex:D: --> Real:D)

Returns the real part of the complex number.

say (3+5i).re;    # OUTPUT: «3␤»

method im

Defined as:

method im(Complex:D: --> Real:D)

Returns the imaginary part of the complex number.

say (3+5i).im;    # OUTPUT: «5␤»

method reals

Defined as:

method reals(Complex:D: --> Positional:D)

Returns a two-element list containing the real and imaginary parts for this value.

say (3+5i).reals;    # OUTPUT: «(3 5)␤»

method isNaN

Defined as:

method isNaN(Complex:D: --> Bool:D)

Returns true if the real or imaginary part is NaN (not a number).

say (NaN+5i).isNaN; # OUTPUT: «True␤»
say (7+5i).isNaN;   # OUTPUT: «False␤»

method polar

Defined as:

method polar(Complex:D: --> Positional:D)

Returns a two-element list of the polar coordinates for this value, i.e. magnitude and angle in radians.

say (10+7i).polar; # OUTPUT: «(12.2065556157337 0.610725964389209)␤»

method floor

Defined as:

method floor(Complex:D: --> Complex:D)

Returns self.re.floor + self.im.floor. That is, each of the real and imaginary parts is rounded to the highest integer not greater than the value of that part.

say (1.2-3.8i).floor;           # OUTPUT: «1-4i␤»

method ceiling

Defined as:

method ceiling(Complex:D: --> Complex:D)

Returns self.re.ceiling + self.im.ceiling. That is, each of the real and imaginary parts is rounded to the lowest integer not less than the value of that part.

say (1.2-3.8i).ceiling;         # OUTPUT: «2-3i␤»

method round

Defined as:

multi method round(Complex:D: --> Complex:D)
multi method round(Complex:D: Real() $scale --> Complex:D)

With no arguments, rounds both the real and imaginary parts to the nearest integer and returns a new Complex number. If $scale is given, rounds both parts of the invocant to the nearest multiple of $scale. Uses the same algorithm as Real.round on each part of the number.

say (1.2-3.8i).round;           # OUTPUT: «1-4i␤»
say (1.256-3.875i).round(0.1);  # OUTPUT: «1.3-3.9i␤»

method truncate

Defined as:

method truncate(Complex:D: --> Complex:D)

Removes the fractional part of both the real and imaginary parts of the number, using Real.truncate, and returns the result as a new Complex.

say (1.2-3.8i).truncate;        # OUTPUT: «1-3i␤»

method abs

Defined as:

method abs(Complex:D: --> Num:D)
multi sub abs(Complex:D $z --> Num:D)

Returns the absolute value of the invocant (or the argument in sub form). For a given complex number $z the absolute value |$z| is defined as sqrt($z.re * $z.re + $z.im * $z.im).

say (3+4i).abs;                 # OUTPUT: «5␤»
                                # sqrt(3*3 + 4*4) == 5

method conj

Defined as:

method conj(Complex:D: --> Complex:D)

Returns the complex conjugate of the invocant (that is, the number with the sign of the imaginary part negated).

say (1-4i).conj;                # OUTPUT: «1+4i␤»

method sqrt

Defined as:

method sqrt(Complex:D: --> Complex:D)

Returns the complex square root of the invocant, i.e. the root where the real part is ≥ 0 and the imaginary part has the same sign as the imaginary part of the invocant.

say (3-4i).sqrt;                # OUTPUT: «2-1i␤»
say (-3+4i).sqrt;               # OUTPUT: «1+2i␤»

method gist

Defined as:

method gist(Complex:D: --> Str:D)

Returns a string representation of the form "1+2i", without internal spaces. (Str coercion also returns this.)

say (1-4i).gist;                # OUTPUT: «1-4i␤»

method perl

Defined as:

method perl(Complex:D: --> Str:D)

Returns an implementation-specific string that produces an equivalent object when given to EVAL.

say (1-3i).perl;                # OUTPUT: «<1-3i>␤»

method Real

Defined as:

multi method Real(Complex:D: --> Num:D)
multi method Real(Complex:U: --> Num:D)

Coerces the invocant to Num. If the imaginary part isn't approximately zero, coercion fails with X::Numeric::Real.

The :D variant returns the result of that coercion. The :U variant issues a warning about using an uninitialized value in numeric context and then returns value 0e0.

sub infix:<**>

Declared as

multi sub infix:<**>(Complex:D \a, Complex:D \b --> Complex:D)
multi sub infix:<**>(Num(Real) \a, Complex:D \b --> Complex:D)
multi sub infix:<**>(Complex:D \a, Num(Real) \b --> Complex:D)

The exponentiation operator coerces the second argument to Complex and calculates the left-hand-side raised to the power of the right-hand side. Since 6.d, either argument can be equal to zero.

say i ** i; # OUTPUT: «0.20787957635076193+0i␤»
say 2 ** i; # OUTPUT: «0.7692389013639721+0.6389612763136348i␤»
say i ** 2; # OUTPUT: «-1+1.2246467991473532e-16i␤»
say 0 ** 1; # OUTPUT: «0+0i␤»

120 class ComplexStr

Dual value complex number and string

class ComplexStr is Complex is Str {}

The dual value types (often referred to as allomorphs) allow for the representation of a value as both a string and a numeric type. Typically they will be created for you when the context is "stringy" but they can be determined to be numbers, such as in some quoting constructs:

my $f = <42+0i>; say $f.^name; # OUTPUT: «ComplexStr␤»

As a subclass of both Complex and Str, a ComplexStr will be accepted where either is expected. However, ComplexStr does not share object identity with Complex- or Str-only variants:

my $complex-str = < 42+0i >;
my Complex $complex = $complex-str; # OK!
my Str     $str     = $complex-str; # OK!
say 42+0i ∈ <42+0i  55  1>; # False; ∈ operator cares about object identity

Methods

method new

method new(Complex $i, Str $s)

The constructor requires both the Complex and the Str value, when constructing one directly the values can be whatever is required:

my $f = ComplexStr.new(42+0i, "forty two (but complicated)");
say +$f; # OUTPUT: «42+0i␤»
say ~$f; # OUTPUT: «"forty two (but complicated)"␤»

method Bool

Defined as:

multi method Bool(ComplexStr:D: --> Bool:D)

This method may be provided by the parent classes and not implemented in ComplexStr directly.

Returns False if the invocant is numerically ±0±0i, otherwise returns True. String portion is not considered.

method Capture

Defined as:

method Capture(ComplexStr:D --> Capture:D)

Equivalent to Mu.Capture.

method Complex

method Complex

Returns the Complex value of the ComplexStr.

method Numeric

Defined as:

multi method Numeric(ComplexStr:D: --> Complex:D)
multi method Numeric(ComplexStr:U: --> Complex:D)

The :D variant returns the numeric portion of the invocant. The :U variant issues a warning about using an uninitialized value in numeric context and then returns value <0+0i>.

method Real

Defined as:

multi method Real(ComplexStr:D: --> Num:D)
multi method Real(ComplexStr:U: --> Num:D)

Coerces the numeric portion of the invocant to Num. If the imaginary part isn't approximately zero, coercion fails with X::Numeric::Real.

The :D variant returns the result of that coercion. The :U variant issues a warning about using an uninitialized value in numeric context and then returns value 0e0.

method Str

Returns the string value of the ComplexStr.

method ACCEPTS

Defined as:

multi method ACCEPTS(ComplexStr:D: Any:D $value)

If $value is Numeric (including another allomorph), checks if invocant's Numeric part ACCEPTS the $value. If $value is Str, checks if invocant's Str part ACCEPTS the $value. If value is anything else, checks if both Numeric and Str parts ACCEPTS the $value.

say < 5+0i> ~~ "5.0"; # OUTPUT: «False␤»
say < 5+0i> ~~  5.0 ; # OUTPUT: «True␤»
say < 5+0i> ~~ <5.0>; # OUTPUT: «True␤»

Operators

infix cmp

multi sub infix:<cmp>(ComplexStr:D $a, ComplexStr:D $b)

Compare two ComplexStr objects. The comparison is done on the Complex value first and then on the Str value. If you want to compare in a different order then you would coerce to the Complex or Str values first:

my $f = ComplexStr.new(42+0i, "smaller");
my $g = ComplexStr.new(43+0i, "larger");
say $f cmp $g;          # OUTPUT: «Less␤»
say $f.Str cmp $g.Str;  # OUTPUT: «More␤»

121 class Cool

Object that can be treated as both a string and number

class Cool is Any { }

Cool, also known as the Convenient OO Loop, is a base class employed by a number of built-in classes whose instances can be meaningfully coerced to a string and a number. For example, an Array can be used in mathematical operations, where its numerical representation is the number of elements it contains. At the same time, it can be concatenated to a string, where its stringy representation is all of its elements joined by a space. Because Array is Cool, the appropriate coercion happens automatically.

Methods in Cool coerce the invocant to a more specific type, and then call the same method on that type. For example both Int and Str inherit from Cool, and calling method substr on an Int converts the integer to Str first.

123.substr(1, 1);   # '2', same as 123.Str.substr(1, 1)

The following built-in types inherit from Cool: Array Bool Complex Cool Duration Map FatRat Hash Instant Int List Match Nil Num Range Seq Stash Str.

The following table summarizes the methods that Cool provides, and what type they coerce to:

method coercion type
abs Numeric
conj Numeric
sqrt Numeric
sign Real
rand Numeric
sin Numeric
asin Numeric
cos Numeric
acos Numeric
tan Numeric
tanh Numeric
atan Numeric
atan2 Numeric
atanh Numeric
sec Numeric
asec Numeric
cosec Numeric
acosec Numeric
cotan Numeric
cotanh Numeric
acotan Numeric
sinh Numeric
asinh Numeric
cosh Numeric
acosh Numeric
sech Numeric
asech Numeric
cosech Numeric
acosech Numeric
acotanh Numeric
cis Numeric
log Numeric
exp Numeric
roots Numeric
log10 Numeric
unpolar Numeric
round Numeric
floor Numeric
ceiling Numeric
truncate Numeric
chr Int
ord Str
chars Str
fmt Str
uniname Str
uninames Seq
unival Str
univals Str
uniprop Str
unimatch Str
uc Str
lc Str
fc Str
tc Str
tclc Str
flip Str
trans Str
contains Str
index Str
rindex Str
ords Str
split Str
match Str
comb Str
subst Str
sprintf Str
printf Str
samecase Str
trim Str
trim-leading Str
trim-trailing Str
EVAL Str
chomp Str
chop Str
codes Str

Methods

routine abs

Defined as:

sub abs(Numeric() $x)
method abs()

Coerces the invocant (or in the sub form, the argument) to Numeric and returns the absolute value (that is, a non-negative number).

say (-2).abs;       # OUTPUT: «2␤»
say abs "6+8i";     # OUTPUT: «10␤»

method conj

Defined as:

method conj()

Coerces the invocant to Numeric and returns the complex conjugate (that is, the number with the sign of the imaginary part negated).

say (1+2i).conj;        # OUTPUT: «1-2i␤»

routine EVAL

Defined as:

method EVAL(*%_) 

It calls the subroutine form with the invocant as the first argument, $code, passing along named args, if any.

routine sqrt

Defined as:

sub sqrt(Numeric(Cool) $x)
method sqrt()

Coerces the invocant to Numeric (or in the sub form, the argument) and returns the square root, that is, a non-negative number that, when multiplied with itself, produces the original number.

say 4.sqrt;             # OUTPUT: «2␤»
say sqrt(2);            # OUTPUT: «1.4142135623731␤»

method sign

Defined as:

method sign()

Coerces the invocant to Numeric and returns its sign, that is, 0 if the number is 0, 1 for positive and -1 for negative values.

say 6.sign;             # OUTPUT: «1␤»
say (-6).sign;          # OUTPUT: «-1␤»
say "0".sign;           # OUTPUT: «0␤»

method rand

Defined as:

method rand()

Coerces the invocant to Num and returns a pseudo-random value between zero and the number.

say 1e5.rand;           # OUTPUT: «33128.495184283␤»

routine sin

Defined as:

sub sin(Numeric(Cool))
method sin()

Coerces the invocant (or in the sub form, the argument) to Numeric, interprets it as radians, returns its sine.

say sin(0);             # OUTPUT: «0␤»
say sin(pi/4);          # OUTPUT: «0.707106781186547␤»
say sin(pi/2);          # OUTPUT: «1␤»

Note that Perl 6 is no computer algebra system, so sin(pi) typically does not produce an exact 0, but rather a very small floating-point number.

routine asin

Defined as:

sub asin(Numeric(Cool))
method asin()

Coerces the invocant (or in the sub form, the argument) to Numeric, and returns its arc-sine in radians.

say 0.1.asin;               # OUTPUT: «0.10016742116156␤»
say asin(0.1);              # OUTPUT: «0.10016742116156␤»

routine cos

Defined as:

sub cos(Numeric(Cool))
method cos()

Coerces the invocant (or in sub form, the argument) to Numeric, interprets it as radians, returns its cosine.

say 0.cos;                  # OUTPUT: «1␤»
say pi.cos;                 # OUTPUT: «-1␤»
say cos(pi/2);              # OUTPUT: «6.12323399573677e-17␤»

routine acos

Defined as:

sub acos(Numeric(Cool))
method acos()

Coerces the invocant (or in sub form, the argument) to Numeric, and returns its arc-cosine in radians.

say 1.acos;                 # OUTPUT: «0␤»
say acos(-1);               # OUTPUT: «3.14159265358979␤»

routine tan

Defined as:

sub tan(Numeric(Cool))
method tan()

Coerces the invocant (or in sub form, the argument) to Numeric, interprets it as radians, returns its tangent.

say tan(3);                 # OUTPUT: «-0.142546543074278␤»
say 3.tan;                  # OUTPUT: «-0.142546543074278␤»

routine atan

Defined as:

sub atan(Numeric(Cool))
method atan()

Coerces the invocant (or in sub form, the argument) to Numeric, and returns its arc-tangent in radians.

say atan(3);                # OUTPUT: «1.24904577239825␤»
say 3.atan;                 # OUTPUT: «1.24904577239825␤»

routine atan2

Defined as:

method atan2($y = 1e0)

Coerces self and argument to Numeric, using them to compute the two-argument arc-tangent in radians.

say 3.atan2;                # OUTPUT: «1.24904577239825␤»
say ⅔.atan2(⅓);             # OUTPUT: «1.1071487177940904␤»

The first argument defaults to 1, so in the first case the function will return the angle θ in radians between a vector that goes from origin to the point (3, 1) and the x axis.

routine sec

Defined as:

sub sec(Numeric(Cool))
method sec()

Coerces the invocant (or in sub form, its argument) to Numeric, interprets it as radians, returns its secant, that is, the reciprocal of its cosine.

say 45.sec;                 # OUTPUT: «1.90359440740442␤»
say sec(45);                # OUTPUT: «1.90359440740442␤»

routine asec

Defined as:

sub asec(Numeric(Cool))
method asec()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its arc-secant in radians.

say 1.asec;                 # OUTPUT: «0␤»
say sqrt(2).asec;           # OUTPUT: «0.785398163397448␤»

routine cosec

Defined as:

sub cosec(Numeric(Cool))
method cosec()

Coerces the invocant (or in sub form, its argument) to Numeric, interprets it as radians, returns its cosecant, that is, the reciprocal of its sine.

say 0.45.cosec;             # OUTPUT: «2.29903273150897␤»
say cosec(0.45);            # OUTPUT: «2.29903273150897␤»

routine acosec

Defined as:

sub acosec(Numeric(Cool))
method acosec()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its arc-cosecant in radians.

say 45.acosec;              # OUTPUT: «0.0222240516182672␤»
say acosec(45)              # OUTPUT: «0.0222240516182672␤»

routine cotan

Defined as:

sub cotan(Numeric(Cool))
method cotan()

Coerces the invocant (or in sub form, its argument) to Numeric, interprets it as radians, returns its cotangent, that is, the reciprocal of its tangent.

say 45.cotan;               # OUTPUT: «0.617369623783555␤»
say cotan(45);              # OUTPUT: «0.617369623783555␤»

routine acotan

Defined as:

sub acotan(Numeric(Cool))
method acotan()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its arc-cotangent in radians.

say 45.acotan;              # OUTPUT: «0.0222185653267191␤»
say acotan(45)              # OUTPUT: «0.0222185653267191␤»

routine sinh

Defined as:

sub sinh(Numeric(Cool))
method sinh()

Coerces the invocant (or in method form, its argument) to Numeric, and returns its Sine hyperbolicus.

say 1.sinh;                 # OUTPUT: «1.1752011936438␤»
say sinh(1);                # OUTPUT: «1.1752011936438␤»

routine asinh

Defined as:

sub asinh(Numeric(Cool))
method asinh()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its Inverse Sine hyperbolicus.

say 1.asinh;                # OUTPUT: «0.881373587019543␤»
say asinh(1);               # OUTPUT: «0.881373587019543␤»

routine cosh

Defined as:

sub cosh(Numeric(Cool))
method cosh()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its Cosine hyperbolicus.

say cosh(0.5);              # OUTPUT: «1.12762596520638␤»

routine acosh

Defined as:

sub acosh(Numeric(Cool))
method acosh()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its Inverse Cosine hyperbolicus.

say acosh(45);              # OUTPUT: «4.4996861906715␤»

routine tanh

Defined as:

sub tanh(Numeric(Cool))
method tanh()

Coerces the invocant (or in sub form, its argument) to Numeric, interprets it as radians and returns its Tangent hyperbolicus.

say tanh(0.5);              # OUTPUT: «0.46211715726001␤»
say tanh(atanh(0.5));       # OUTPUT: «0.5␤»

routine atanh

Defined as:

sub atanh(Numeric(Cool))
method atanh()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its Inverse tangent hyperbolicus.

say atanh(0.5);             # OUTPUT: «0.549306144334055␤»

routine sech

Defined as:

sub sech(Numeric(Cool))
method sech()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its Secant hyperbolicus.

say 0.sech;                 # OUTPUT: «1␤»

routine asech

Defined as:

sub asech(Numeric(Cool))
method asech()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its Inverse hyperbolic secant.

say 0.8.asech;              # OUTPUT: «0.693147180559945␤»

routine cosech

Defined as:

sub cosech(Numeric(Cool))
method cosech()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its Hyperbolic cosecant.

say cosech(pi/2);           # OUTPUT: «0.434537208094696␤»

routine acosech

Defined as:

sub acosech(Numeric(Cool))
method acosech()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its Inverse hyperbolic cosecant.

say acosech(4.5);           # OUTPUT: «0.220432720979802␤»

routine cotanh

Defined as:

sub cotanh(Numeric(Cool))
method cotanh()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its Hyperbolic cotangent.

say cotanh(pi);             # OUTPUT: «1.00374187319732␤»

routine acotanh

Defined as:

sub acotanh(Numeric(Cool))
method acotanh()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns its Inverse hyperbolic cotangent.

say acotanh(2.5);           # OUTPUT: «0.423648930193602␤»

routine cis

Defined as:

sub cis(Numeric(Cool))
method cis()

Coerces the invocant (or in sub form, its argument) to Numeric, and returns cos(argument) + i*sin(argument).

say cis(pi/4);              # OUTPUT: «0.707106781186548+0.707106781186547i␤»

routine log

Defined as:

multi sub log(Numeric(Cool) $number, Numeric(Cool) $base?)
multi method log(Cool:D: Cool:D $base?)

Coerces the arguments (including the invocant in the method form) to Numeric, and returns its Logarithm to base $base, or to base e (Euler's Number) if no base was supplied (Natural logarithm). Returns NaN if $base is negative. Throws an exception if $base is 1.

say (e*e).log;              # OUTPUT: «2␤»

routine log10

Defined as:

multi sub log10(Cool(Numeric))
multi method log10()

Coerces the invocant (or in the sub form, the invocant) to Numeric, and returns its Logarithm to base 10, that is, a number that approximately produces the original number when raised to the power of 10. Returns NaN for negative arguments and -Inf for 0.

say log10(1001);            # OUTPUT: «3.00043407747932␤»

routine exp

Defined as:

multi sub exp(Cool:D $pow, Cool:D $base?)
multi method exp(Cool:D: Cool:D $base?)

Coerces the arguments (including the invocant in the method from) to Numeric, and returns $base raised to the power of the first number. If no $base is supplied, e (Euler's Number) is used.

say 0.exp;      # OUTPUT: «1␤»
say 1.exp;      # OUTPUT: «2.71828182845905␤»
say 10.exp;     # OUTPUT: «22026.4657948067␤»

method unpolar

Defined as:

method unpolar(Numeric(Cool))

Coerces the arguments (including the invocant in the method form) to Numeric, and returns a complex number from the given polar coordinates. The invocant (or the first argument in sub form) is the magnitude while the argument (i.e. the second argument in sub form) is the angle. The angle is assumed to be in radians.

say sqrt(2).unpolar(pi/4);      # OUTPUT: «1+1i␤»

routine round

Defined as:

multi sub round(Numeric(Cool))
multi method round(Cool:D: $unit = 1)

Coerces the invocant (or in sub form, its argument) to Numeric, and rounds it to the unit of $unit. If $unit is 1, rounds to the nearest integer.

say 1.7.round;          # OUTPUT: «2␤»
say 1.07.round(0.1);    # OUTPUT: «1.1␤»
say 21.round(10);       # OUTPUT: «20␤»

Always rounds up if the number is at mid-point:

say (−.5 ).round;       # OUTPUT: «0␤»
say ( .5 ).round;       # OUTPUT: «1␤»
say (−.55).round(.1);   # OUTPUT: «-0.5␤»
say ( .55).round(.1);   # OUTPUT: «0.6␤»

Pay attention to types when using this method, as ending up with the wrong type may affect the precision you seek to achieve. For Real types, the type of the result is the type of the argument (Complex argument gets coerced to Real, ending up a Num). If rounding a Complex, the result is Complex as well, regardless of the type of the argument.

9930972392403501.round(1)      .perl.say; # OUTPUT: «9930972392403501␤»
9930972392403501.round(1e0)    .perl.say; # OUTPUT: «9.9309723924035e+15␤»
9930972392403501.round(1e0).Int.perl.say; # OUTPUT: «9930972392403500␤»

routine floor

Defined as:

multi sub floor(Numeric(Cool))
multi method floor

Coerces the invocant (or in sub form, its argument) to Numeric, and rounds it downwards to the nearest integer.

say "1.99".floor;       # OUTPUT: «1␤»
say "-1.9".floor;       # OUTPUT: «-2␤»
say 0.floor;            # OUTPUT: «0␤»

method fmt

Defined as:

method fmt($format = '%s')

Uses $format to return a formatted representation of the invocant; equivalent to calling sprintf with $format as format and the invocant as the second argument. The $format will be coerced to Stringy and defaults to '%s'.

For more information about formats strings, see sprintf.

say 11.fmt('This Int equals %03d');         # OUTPUT: «This Int equals 011␤»
say '16'.fmt('Hexadecimal %x');             # OUTPUT: «Hexadecimal 10␤»

routine ceiling

Defined as:

multi sub ceiling(Numeric(Cool))
multi method ceiling

Coerces the invocant (or in sub form, its argument) to Numeric, and rounds it upwards to the nearest integer.

say "1".ceiling;        # OUTPUT: «1␤»
say "-0.9".ceiling;     # OUTPUT: «0␤»
say "42.1".ceiling;     # OUTPUT: «43␤»

routine truncate

Defined as:

multi sub truncate(Numeric(Cool))
multi method truncate()

Coerces the invocant (or in sub form, its argument) to Numeric, and rounds it towards zero.

say 1.2.truncate;       # OUTPUT: «1␤»
say truncate -1.2;      # OUTPUT: «-1␤»

routine ord

Defined as:

sub ord(Str(Cool))
method ord()

Coerces the invocant (or in sub form, its argument) to Str, and returns the Unicode code point number of the first code point.

say 'a'.ord;            # OUTPUT: «97␤»

The inverse operation is chr.

Mnemonic: returns an ordinal number

method path

Defined as:

method path()

DEPRECATED. It's been deprecated as of the 6.d version. Will be removed in the next ones.

Stringifies the invocant and converts it to IO::Path object. Use the .IO method instead.

routine chr

Defined as:

sub chr(Int(Cool))
method chr()

Coerces the invocant (or in sub form, its argument) to Int, interprets it as a Unicode code points, and returns a string made of that code point.

say '65'.chr;       # OUTPUT: «A␤»

The inverse operation is ord.

Mnemonic: turns an integer into a character.

routine chars

Defined as:

multi sub chars(Cool $x)
multi sub chars(Str:D $x)
multi sub chars(str $x --> int)
method chars(--> Int:D)

Coerces the invocant (or in sub form, its argument) to Str, and returns the number of characters in the string. Please note that on the JVM, you currently get codepoints instead of graphemes.

say 'møp'.chars;    # OUTPUT: «3␤»
say 'ã̷̠̬̊'.chars;     # OUTPUT: «1␤»
say '👨‍👩‍👧‍👦🏿'.chars;    # OUTPUT: «1␤»

If the string is native, the number of chars will be also returned as a native int.

Graphemes are user visible characters. That is, this is what the user thinks of as a “character”.

Graphemes can contain more than one codepoint. Typically the number of graphemes and codepoints differs when Prepend or Extend characters are involved (also known as Combining characters), but there are many other cases when this may happen. Another example is \c[ZWJ] (Zero-width joiner).

You can check Grapheme_Cluster_Break property of a character in order to see how it is going to behave:

say ‘ã̷̠̬̊’.uniprops(‘Grapheme_Cluster_Break’); # OUTPUT: «(Other Extend Extend Extend Extend)␤»
say ‘👨‍👩‍👧‍👦🏿’.uniprops(‘Grapheme_Cluster_Break’); # OUTPUT: «(E_Base_GAZ ZWJ E_Base_GAZ ZWJ E_Base_GAZ ZWJ E_Base_GAZ E_Modifier)␤»

You can read more about graphemes in the Unicode Standard, which Perl 6 tightly follows, using a method called NFG, normal form graphemes for efficiently representing them.

routine codes

Defined as:

sub codes(Str(Cool))
method codes()

Coerces the invocant (or in sub form, its argument) to Str, and returns the number of Unicode code points.

say 'møp'.codes;    # OUTPUT: «3␤»

The same result will be obtained with

say +'møp'.ords;    # OUTPUT: «3␤»

ords first obtains the actual codepoints, so there might be a difference in speed.

routine flip

Defined as:

sub flip(Cool $s --> Str:D)
method flip()

Coerces the invocant (or in sub form, its argument) to Str, and returns a reversed version.

say 421.flip;       # OUTPUT: «124␤»

routine trim

Defined as:

sub trim(Str(Cool))
method trim()

Coerces the invocant (or in sub form, its argument) to Str, and returns the string with both leading and trailing whitespace stripped.

my $stripped = '  abc '.trim;
say "<$stripped>";          # OUTPUT: «<abc>␤»

routine trim-leading

Defined as:

sub trim-leading(Str(Cool))
method trim-leading()

Coerces the invocant (or in sub form, its argument) to Str, and returns the string with leading whitespace stripped.

my $stripped = '  abc '.trim-leading;
say "<$stripped>";          # OUTPUT: «<abc >␤»

routine trim-trailing

Defined as:

sub trim-trailing(Str(Cool))
method trim-trailing()

Coerces the invocant (or in sub form, its argument) to Str, and returns the string with trailing whitespace stripped.

my $stripped = '  abc '.trim-trailing;
say "<$stripped>";          # OUTPUT: «<  abc>␤»

routine lc

Defined as:

sub lc(Str(Cool))
method lc()

Coerces the invocant (or in sub form, its argument) to Str, and returns it case-folded to lower case.

say "ABC".lc;       # OUTPUT: «abc␤»

routine uc

Defined as:

sub uc(Str(Cool))
method uc()

Coerces the invocant (or in sub form, its argument) to Str, and returns it case-folded to upper case (capital letters).

say "Abc".uc;       # OUTPUT: «ABC␤»

routine fc

Defined as:

sub fc(Str(Cool))
method fc()

Coerces the invocant (or in sub form, its argument) to Str, and returns the result a Unicode "case fold" operation suitable for doing caseless string comparisons. (In general, the returned string is unlikely to be useful for any purpose other than comparison.)

say "groß".fc;       # OUTPUT: «gross␤»

routine tc

Defined as:

sub tc(Str(Cool))
method tc()

Coerces the invocant (or in sub form, its argument) to Str, and returns it with the first letter case-folded to title case (or where not available, upper case).

say "abC".tc;       # OUTPUT: «AbC␤»

routine tclc

Defined as:

sub tclc(Str(Cool))
method tclc()

Coerces the invocant (or in sub form, its argument) to Str, and returns it with the first letter case-folded to title case (or where not available, upper case), and the rest of the string case-folded to lower case.

say 'abC'.tclc;     # OUTPUT: «Abc␤»

routine wordcase

Defined as:

sub wordcase(Str(Cool) $input, :&filter = &tclc, Mu :$where = True)
method wordcase(:&filter = &tclc, Mu :$where = True)

Coerces the invocant (or in sub form, the first argument) to Str, and filters each word that smartmatches against $where through the &filter. With the default filter (first character to upper case, rest to lower) and matcher (which accepts everything), this title-cases each word:

say "perl 6 programming".wordcase;      # OUTPUT: «Perl 6 Programming␤»

With a matcher:

say "have fun working on perl".wordcase(:where({ .chars > 3 }));
                                        # Have fun Working on Perl

With a customer filter too:

say "have fun working on perl".wordcase(:filter(&uc), :where({ .chars > 3 }));
                                        # HAVE fun WORKING on PERL

routine samecase

Defined as:

sub samecase(Cool $string, Cool $pattern)
method samecase(Cool:D: Cool $pattern)

Coerces the invocant (or in sub form, the first argument) to Str, and returns a copy of $string with case information for each individual character changed according to $pattern.

Note: The pattern string can contain three types of characters, i.e. uppercase, lowercase and caseless. For a given character in $pattern its case information determines the case of the corresponding character in the result.

If $string is longer than $pattern, the case information from the last character of $pattern is applied to the remaining characters of $string.

say "perL 6".samecase("A__a__"); # OUTPUT: «Perl 6␤»
say "pERL 6".samecase("Ab");     # OUTPUT: «Perl 6␤»

routine uniprop

Defined as:

multi sub uniprop(Str:D, |c)
multi sub uniprop(Int:D $code)
multi sub uniprop(Int:D $code, Stringy:D $propname)
multi method uniprop(|c)

Returns the unicode property of the first character. If no property is specified returns the General Category. Returns a Bool for Boolean properties. A uniprops routine can be used to get the property for every character in a string.

say 'a'.uniprop;               # OUTPUT: «Ll␤»
say '1'.uniprop;               # OUTPUT: «Nd␤»
say 'a'.uniprop('Alphabetic'); # OUTPUT: «True␤»
say '1'.uniprop('Alphabetic'); # OUTPUT: «False␤»

sub uniprops

Defined as:

sub uniprops(Str:D $str, Stringy:D $propname = "General_Category")

Interprets the invocant as a Str, and returns the unicode property for each character as a Seq. If no property is specified returns the General Category. Returns a Bool for Boolean properties. Similar to uniprop, but for each character in the passed string.

routine uniname

Defined as:

sub uniname(Str(Cool) --> Str)
method uniname(--> Str)

Interprets the invocant or first argument as a Str, and returns the Unicode codepoint name of the first codepoint of the first character. See uninames for a routine that works with multiple codepoints, and uniparse for the opposite direction.

# Camelia in Unicode
say ‘»ö«’.uniname;
# OUTPUT: «"RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK"␤»
say "Ḍ̇".uniname; # Note, doesn't show "COMBINING DOT ABOVE"
# OUTPUT: «"LATIN CAPITAL LETTER D WITH DOT BELOW"␤»

# Find the char with the longest Unicode name.
say (0..0x1FFFF).sort(*.uniname.chars)[*-1].chr.uniname;
# OUTPUT: ««ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA INITIAL FORM␤»␤»

routine uninames

Defined as:

sub uninames(Str:D)
method uninames()

Returns of a Seq of Unicode names for the all the codepoints in the Str provided.

say ‘»ö«’.uninames.perl;
# OUTPUT: «("RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK", "LATIN SMALL LETTER O WITH DIAERESIS", "LEFT-POINTING DOUBLE ANGLE QUOTATION MARK").Seq␤»

Note this example, which gets a Seq where each element is a Seq of all the codepoints in that character.

say "Ḍ̇'oh".comb>>.uninames.perl;
# OUTPUT: «(("LATIN CAPITAL LETTER D WITH DOT BELOW", "COMBINING DOT ABOVE").Seq, ("APOSTROPHE",).Seq, ("LATIN SMALL LETTER O",).Seq, ("LATIN SMALL LETTER H",).Seq)␤»

See uniparse for the opposite direction.

routine unimatch

Defined as:

multi sub unimatch(Str:D $str, |c)
multi unimatch(Int:D $code, Stringy:D $pvalname, Stringy:D $propname = $pvalname)

Checks if the given integer codepoint or the first letter of the string given have a unicode property equal to the value you give. If you supply the Unicode property to be checked it will only return True if that property matches the given value.

say unimatch 'A', 'Latin';           # OUTPUT: «True␤»
say unimatch 'A', 'Latin', 'Script'; # OUTPUT: «True␤»
say unimatch 'A', 'Ll';              # OUTPUT: «True␤»

routine chop

Defined as:

sub chop(Str(Cool))
method chop()

Coerces the invocant (or in sub form, its argument) to Str, and returns it with the last character removed.

say 'perl'.chop;                        # OUTPUT: «per␤»

routine chomp

Defined as:

sub chomp(Str(Cool))
method chomp()

Coerces the invocant (or in sub form, its argument) to Str, and returns it with the last character removed, if it is a logical newline.

say 'ab'.chomp.chars;                   # OUTPUT: «2␤»
say "a\n".chomp.chars;                  # OUTPUT: «1␤»

routine substr

Defined as:

sub substr(Str(Cool) $str, |c)
method substr(|c)

Coerces the invocant (or in the sub form, the first argument) to Str, and calls Str.substr with the arguments.

routine substr-rw

Defined as:

multi method substr-rw(|) is rw
multi sub substr-rw(|) is rw

Coerces the invocant (or in the sub form, the first argument) to Str, and calls Str.substr-rw with the arguments.

routine ords

Defined as:

sub ords(Str(Cool) $str)
method ords()

Coerces the invocant (or in the sub form, the first argument) to Str, and returns a list of Unicode codepoints for each character.

say "Camelia".ords;              # OUTPUT: «67 97 109 101 108 105 97␤»
say ords 10;                     # OUTPUT: «49 48␤»

This is the list-returning version of ord. The inverse operation in chrs. If you are only interested in the number of codepoints, codes is a possibly faster option.

routine chrs

Defined as:

sub chrs(*@codepoints --> Str:D)
method chrs()

Coerces the invocant (or in the sub form, the argument list) to a list of integers, and returns the string created by interpreting each integer as a Unicode codepoint, and joining the characters.

say <67 97 109 101 108 105 97>.chrs;   # OUTPUT: «Camelia␤»

This is the list-input version of chr. The inverse operation is ords.

routine split

Defined as:

multi sub    split(  Str:D $delimiter, Str(Cool) $input, $limit = Inf, :$k, :$v, :$kv, :$p, :$skip-empty)
multi sub    split(Regex:D $delimiter, Str(Cool) $input, $limit = Inf, :$k, :$v, :$kv, :$p, :$skip-empty)
multi sub    split(@delimiters, Str(Cool) $input, $limit = Inf, :$k, :$v, :$kv, :$p, :$skip-empty)
multi method split(  Str:D $delimiter, $limit = Inf, :$k, :$v, :$kv, :$p, :$skip-empty)
multi method split(Regex:D $delimiter, $limit = Inf, :$k, :$v, :$kv, :$p, :$skip-empty)
multi method split(@delimiters, $limit = Inf, :$k, :$v, :$kv, :$p, :$skip-empty)

the comb routine is a much better choice for many tasks that in other languages are handled by the split .

Coerces the invocant (or in the sub form, the second argument) to Str, and splits it into pieces based on delimiters found in the string.

If $delimiter is a string, it is searched for literally and not treated as a regex. You can also provide multiple delimiters by specifying them as a list; mixing Cool and Regex objects is OK.

say split(';', "a;b;c").perl;               # OUTPUT: «("a", "b", "c")␤»
say split(';', "a;b;c", 2).perl;            # OUTPUT: «("a", "b;c").Seq␤»

say split(';', "a;b;c,d").perl;             # OUTPUT: «("a", "b", "c,d")␤»
say split(/\;/, "a;b;c,d").perl;            # OUTPUT: «("a", "b", "c,d")␤»
say split(/<[;,]>/, "a;b;c,d").perl;        # OUTPUT: «("a", "b", "c", "d")␤»

say split(['a', /b+/, 4], '1a2bb345').perl; # OUTPUT: «("1", "2", "3", "5")␤»

By default, split omits the matches, and returns a list of only those parts of the string that did not match. Specifying one of the :k, :v, :kv, :p adverbs changes that. Think of the matches as a list that is interleaved with the non-matching parts.

The :v interleaves the values of that list, which will be either Match objects, if a Regex was used as a matcher in the split, or Str objects, if a Cool was used as matcher. If multiple delimiters are specified, Match objects will be generated for all of them, unless all of the delimiters are Cool.

say 'abc'.split(/b/, :v);               # OUTPUT: «(a 「b」 c)␤»
say 'abc'.split('b', :v);               # OUTPUT: «(a b c)␤»

:k interleaves the keys, that is, the indexes:

say 'abc'.split(/b/, :k);               # OUTPUT: «(a 0 c)␤»

:kv adds both indexes and matches:

say 'abc'.split(/b/, :kv);               # OUTPUT: «(a 0 「b」 c)␤»

and :p adds them as Pairs, using the same types for values as :v does:

say 'abc'.split(/b/, :p);               # OUTPUT: «(a 0 => 「b」 c)␤»
say 'abc'.split('b', :p);               # OUTPUT: «(a 0 => b c)␤»

You can only use one of the :k, :v, :kv, :p adverbs in a single call to split.

Note that empty chunks are not removed from the result list. For that behavior, use the :skip-empty named argument:

say ("f,,b,c,d".split: /","/             ).perl;  # OUTPUT: «("f", "", "b", "c", "d")␤»
say ("f,,b,c,d".split: /","/, :skip-empty).perl;  # OUTPUT: «("f", "b", "c", "d")␤»

routine lines

Defined as:

sub lines(Str(Cool))
method lines()

Coerces the invocant (and in sub form, the argument) to Str, decomposes it into lines (with the newline characters stripped), and returns the list of lines.

say lines("a\nb\n").join('|');          # OUTPUT: «a|b␤»
say "some\nmore\nlines".lines.elems;    # OUTPUT: «3␤»

This method can be used as part of an IO::Path to process a file line-by-line, since IO::Path objects inherit from Cool, e.g.:

for 'huge-csv'.IO.lines -> $line { 
     # Do something with $line 
 } 
 
 # or if you'll be processing later 
 my @lines = 'huge-csv'.IO.lines; 

Without any arguments, sub lines operates on $*ARGFILES, which defaults to $*IN in the absence of any filenames.

To modify values in place use is copy to force a writable container.

for $*IN.lines -> $_ is copy { s/(\w+)/{$0 ~ $0}/; .say } 

method words

Defined as:

method words(Cool:D: |c)

Coerces the invocant (or first argument, if it is called as a subroutine) to Str, and returns a list of words that make up the string. Check Str.words for additional arguments and its meaning.

say <The quick brown fox>.words.join('|');     # OUTPUT: «The|quick|brown|fox␤» 
 say <The quick brown fox>.words(2).join('|');  # OUTPUT: «The|quick␤» 

Cool is the base class for many other classes, and some of them, like Match, can be converted to a string. This is what happens in this case:

say ( "easy come, easy goes" ~~ m:g/(ea\w+)/).words(Inf);
# OUTPUT: «(easy easy)␤»
say words( "easy come, easy goes" ~~ m:g/(ea\w+)/ , ∞);
# OUTPUT: «(easy easy)␤»

The example above illustrates two of the ways words can be invoked, with the first argument turned into invocant by its signature. Of course, Inf is the default value of the second argument, so in both cases (and forms) it can be simply omitted.

Only whitespace (including no-break space) counts as word boundaries

say <Don't we ♥ Perl 6>.words.join('|');  # OUTPUT: «Don't|we|♥|Perl|6␤»

In this case, Perl 6 includes an (visible only in the source) no-break space; words still splits the (resulting) Str on it, even if the original array only had 4 elements:

say <Don't we ♥ Perl 6>.join("|");  # OUTPUT: «Don't|we|♥|Perl 6␤»

Please see Str.words for more examples and ways to invoke it.

routine comb

Defined as:

multi sub comb(Regex $matcher, Cool $input, $limit = *)
multi sub comb(Str $matcher, Cool $input, $limit = *)
multi sub comb(Int:D $size, Cool $input, $limit = *)
multi method comb(|c)

Returns a Seq of all (or if supplied, at most $limit) matches of the invocant (method form) or the second argument (sub form) against the Regex, string or defined number.

say "6 or 12".comb(/\d+/).join(", ");           # OUTPUT: «6, 12␤»
say comb(/\d <[1..9]> /,(11..30)).join("--");
# OUTPUT:
# «11--12--13--14--15--16--17--18--19--21--22--23--24--25--26--27--28--29␤»

The second statement exemplifies the first form of comb, with a Regex that excludes multiples of ten, and a Range (which is Cool) as $input. comb stringifies the Range before applying .comb on the resulting string. Check Str.comb for its effect on different kind of input strings. When the first argument is an integer, it indicates the (maximum) size of the chunks the input is going to be divided in

say comb(3,[3,33,333,3333]).join("*");  # OUTPUT: «3 3*3 3*33 *333*3␤»

In this case the input is a list, which after transformation to Str (which includes the spaces) is divided in chunks of size 3.

method contains

Defined as:

method contains(Cool:D: |c)

Coerces the invocant Str, and calls Str.contains on it. Please refer to that version of the method for arguments and general syntax.

say 123.contains("2")# OUTPUT: «True␤»

Since Int is a subclass of Cool, 123 is coerced to a Str and then contains is called on it.

say (1,1, * + * … * > 250).contains(233)# OUTPUT: «True␤»

Seqs are also subclasses of Cool, and they are stringified to a comma-separated form. In this case we are also using an Int, which is going to be stringified also; "233" is included in that sequence, so it returns True. Please note that this sequence is not lazy; the stringification of lazy sequences does not include each and every one of their components for obvious reasons.

routine index

Defined as:

multi sub index(Cool $s, Cool $needle, Cool $pos = 0)
method    index(Cool:D: |c)

Coerces the first two arguments (in method form, also counting the invocant) to a Str, and searches for $needle in the string $s starting from $startpos. It returns the offset into the string where $needle was found, and an undefined value if it was not found.

See the documentation in type Str for examples.

routine rindex

Defined as:

multi sub    rindex(Str(Cool) $haystack, Str(Cool) $needle, Int(Cool) $startpos = $haystack.chars)
multi method rindex(Str(Cool) $haystack: Str(Cool) $needle, Int(Cool) $startpos = $haystack.chars)

Coerces the first two arguments (including the invocant in method form) to Str and $startpos to Int, and returns the last position of $needle in $haystack not after $startpos. Returns an undefined value if $needle wasn't found.

See the documentation in type Str for examples.

method match

Defined as:

multi method match(Cool:D: $target, *%adverbs)

Coerces the invocant to Str and calls the method match on it.

routine roots

Defined as:

multi sub roots(Numeric(Cool) $x, Int(Cool) $n)
multi method roots(Int(Cool) $n)

Coerces the first argument (and in method form, the invocant) to Numeric and the second ($n) to Int, and produces a list of $n Complex $n-roots, which means numbers that, raised to the $nth power, approximately produce the original number.

For example

my $original = 16; 
 my @roots = $original.roots(4); 
 say @roots; 
 
 for @roots -> $r { 
     say abs($r ** 4 - $original); 
 } 
 
 # OUTPUT:«2+0i 1.22464679914735e-16+2i -2+2.44929359829471e-16i -3.67394039744206e-16-2i␤» 
 # OUTPUT:«1.77635683940025e-15␤» 
 # OUTPUT:«4.30267170434156e-15␤» 
 # OUTPUT:«8.03651692704705e-15␤» 
 # OUTPUT:«1.04441561648202e-14␤» 

method match

Defined as:

method match(|)

Coerces the invocant to Stringy and calls Str.match.

method subst

Defined as:

method subst(|)

Coerces the invocant to Stringy and calls Str.subst.

method trans

Defined as:

method trans(|)

Coerces the invocant to Str and calls Str.trans

method IO

Defined as:

method IO(--> IO::Path:D)

Coerces the invocant to IO::Path.

.say for '.'.IO.dir;        # gives a directory listing 

122 class CurrentThreadScheduler

Scheduler that synchronously executes code on the current thread

class CurrentThreadScheduler does Scheduler {} 

CurrentThreadScheduler executes tasks on the current threads. This means that method cue blocks until the code has finished executing.

123 class Cursor

Synonym of Match

my constant Cursor = Match

Initially, it was used to keep track of initial position in regex matches. In current versions, it's an alias for Match.

124 class Date

Calendar date

class Date { }

A Date is an immutable object identifying a day in the Gregorian calendar.

Date objects support addition and subtraction of integers, where an integer is interpreted as the number of days. You can compare Date objects with the numeric comparison operators ==, <, <=, >, >=, != . Their stringification in YYYY-MM-DD format means that comparing them with the string operators eq, lt, le etc. also gives the right result.

Date.today creates an object the current day according to the system clock.

my $d = Date.new(2015, 12, 24); # Christmas Eve!
say $d;                         # OUTPUT: «2015-12-24␤»
say $d.year;                    # OUTPUT: «2015␤»
say $d.month;                   # OUTPUT: «12␤»
say $d.day;                     # OUTPUT: «24␤»
say $d.day-of-week;             # OUTPUT: «4␤» (Thursday)
say $d.later(days => 20);       # OUTPUT: «2016-01-13␤»
my $n = Date.new('2015-12-31'); # New Year's Eve
say $n - $d;                    # OUTPUT: «7␤», 7 days between New Years/Christmas Eve
say $n + 1;                     # OUTPUT: «2016-01-01␤»

Note since version 6.d, .perl can be called on Date.

Methods

method new

Defined as:

multi method new($year, $month, $day, :&formatter --> Date:D)
multi method new(:$year!, :$month = 1, :$day = 1  --> Date:D)
multi method new(Str $date                        --> Date:D)
multi method new(Instant:D $dt                    --> Date:D)
multi method new(DateTime:D $dt                   --> Date:D)

Creates a new Date object, either from a triple of (year, month, day) that can be coerced to integers, or from a string of the form YYYY-MM-DD (ISO 8601), or from an Instant or DateTime object. Optionally accepts a formatter as a named parameter.

my $date = Date.new(2042, 1, 1);
$date = Date.new(year => 2042, month => 1, day => 1);
$date = Date.new("2042-01-01");
$date = Date.new(Instant.from-posix: 1482155532);
$date = Date.new(DateTime.now);

method new-from-daycount

Defined as:

method new-from-daycount($daycount,:&formatter --> Date:D)

Creates a new Date object given $daycount which is the number of days from epoch Nov. 17, 1858, i.e. the Modified Julian Day. Optionally accepts a formatter as a named parameter.

say Date.new-from-daycount(49987);          # OUTPUT: «1995-09-27␤»

method clone

Defined as:

method clone(:$year, :$month, :$day, :&formatter)

Creates a new Date object based on the invocant, but with the given arguments overriding the values from the invocant.

say Date.new('2015-11-24').clone(month => 12);    # OUTPUT: «2015-12-24␤»

method today

Defined as:

method today(:&formatter --> Date:D)

Returns a Date object for the current day. Optionally accepts a formatter named parameter.

say Date.today;

method later

Defined as:

method later(Date:D: *%unit)

Returns a Date object based on the current one, but with a date delta applied. The date delta can be passed as a named argument where the argument name is the unit.

Allowed units are day, days, week, weeks, month, months, year, years. Please note that the plural forms can only be used with the later method.

Please note that the special ":2nd" named parameter syntax can be a compact and self-documenting way of specifying the delta

say Date.new('2015-12-24').later(:2years);  # OUTPUT: «2017-12-24␤»

Since addition of several different time units is not commutative, only one unit may be passed.

my $d = Date.new('2015-02-27');
say $d.later(month => 1).later(:2days);  # OUTPUT: «2015-03-29␤»
say $d.later(days => 2).later(:1month);  # OUTPUT: «2015-04-01␤»
say $d.later(days => 2).later(:month);   # same, as +True === 1

Negative offsets are allowed, though #method earlier is more idiomatic for that.

method earlier

Defined as:

method earlier(Date:D: *%unit)

Returns a Date object based on the current one, but with a date delta towards the past applied. See #method later for usage.

my $d = Date.new('2015-02-27');
say $d.earlier(month => 5).earlier(:2days);  # OUTPUT: «2014-09-25␤»

method truncated-to

Defined as:

method truncated-to(Date:D: Cool $unit)

Returns a Date truncated to the first day of its year, month or week. For example

my $c = Date.new('2012-12-24');
say $c.truncated-to('year');     # OUTPUT: «2012-01-01␤»
say $c.truncated-to('month');    # OUTPUT: «2012-12-01␤»
say $c.truncated-to('week');     # OUTPUT: «2012-12-24␤», because it's Monday already

method succ

Defined as:

method succ(Date:D: --> Date:D)

Returns a Date of the following day. "succ" is short for "successor".

say Date.new("2016-02-28").succ;   # OUTPUT: «2016-02-29␤»

method pred

Defined as:

method pred(Date:D: --> Date:D)

Returns a Date of the previous day. "pred" is short for "predecessor".

say Date.new("2016-01-01").pred;   # OUTPUT: «2015-12-31␤»

method Str

Defined as:

multi method Str(Date:D: --> Str:D)

Returns a string representation of the invocant, as specified by the formatter. If no formatter was specified, an (ISO 8601) date will be returned.

say Date.new('2015-12-24').Str;                     # OUTPUT: «2015-12-24␤»

my $fmt = { sprintf "%02d/%02d/%04d", .month, .day, .year };
say Date.new('2015-12-24', formatter => $fmt).Str;  # OUTPUT: «12/24/2015␤»

method gist

Defined as:

multi method gist(Date:D: --> Str:D)

Returns the date in YYYY-MM-DD format (ISO 8601)

say Date.new('2015-12-24').gist;                    # OUTPUT: «2015-12-24␤»

method Date

Defined as:

method Date(--> Date)

Returns the invocant.

say Date.new('2015-12-24').Date;  # OUTPUT: «2015-12-24␤»
say Date.Date;                    # OUTPUT: «(Date)␤»

method DateTime

Defined as:

multi method DateTime(Date:U --> DateTime:U)
multi method DateTime(Date:D --> DateTime:D)

Converts the invocant to DateTime

say Date.new('2015-12-24').DateTime; # OUTPUT: «2015-12-24T00:00:00Z␤»
say Date.DateTime;                   # OUTPUT: «(DateTime)␤»

Functions

sub sleep

sub sleep($seconds = Inf --> Nil)

Attempt to sleep for the given number of $seconds. Returns Nil on completion. Accepts Int, Num, Rat, or Duration types as an argument since all of these also do Real.

sleep 5;                # Int 
 sleep 5.2;              # Num 
 sleep (5/2);            # Rat 
 sleep (now - now + 5);  # Duration 

It is thus possible to sleep for a non-integer amount of time. For instance, the following code shows that sleep (5/2) sleeps for 2.5 seconds and sleep 5.2 sleeps for 5.2 seconds:

my $before = now;
sleep (5/2);
my $after = now;
say $after-$before;  # OUTPUT: «2.502411561␤»

$before = now;
sleep 5.2;
$after = now;
say $after-$before;  # OUTPUT: «5.20156987␤»

sub sleep-timer

sub sleep-timer(Real() $seconds = Inf --> Duration:D)

This function is implemented like sleep, but unlike the former it does return a Duration instance with the number of seconds the system did not sleep.

In particular, the returned Duration will handle the number of seconds remaining when the process has been awakened by some external event (e.g., Virtual Machine or Operating System events). Under normal condition, when sleep is not interrupted, the returned Duration has a value of 0, meaning no extra seconds remained to sleep. Therefore, in normal situations:

say sleep-timer 3.14;  # OUTPUT: «0␤»

The same result applies to edge cases, when a negative or zero time to sleep is passed as argument:

say sleep-timer -2; # OUTPUT: 0 
 say sleep-timer 0;  # OUTPUT: 0 

See also sleep-until.

sub sleep-until

sub sleep-until(Instant $until --> Bool)

Works similar to sleep but checks the current time and keeps sleeping until the required instant in the future has been reached. It uses internally the sleep-timer method in a loop to ensure that, if accidentally woken up early, it will wait again for the specified amount of time remaining to reach the specified instant. goes back to sleep

Returns True if the Instant in the future has been achieved (either by mean of sleeping or because it is right now), False in the case an Instant in the past has been specified.

To sleep until 10 seconds into the future, one could write something like this:

say sleep-until now+10;   # OUTPUT: «True␤»

Trying to sleep until a time in the past doesn't work:

my $instant = now - 5;
say sleep-until $instant; # OUTPUT: «False␤»

However if we put the instant sufficiently far in the future, the sleep should run:

my $instant = now + 30; 
 # assuming the two commands are run within 30 seconds of one another... 
 say sleep-until $instant; # OUTPUT: «True␤» 

To specify an exact instant in the future, first create a DateTime at the appropriate point in time, and cast to an Instant.

my $instant = DateTime.new( 
     year => 2020, 
     month => 9, 
     day => 1, 
     hour => 22, 
     minute => 5); 
 say sleep-until $instant.Instant; # True (eventually...) 

This could be used as a primitive kind of alarm clock. For instance, say you need to get up at 7am on the 4th of September 2015, but for some reason your usual alarm clock is broken and you only have your laptop. You can specify the time to get up (being careful about time zones, since DateTime.new uses UTC by default) as an Instant and pass this to sleep-until, after which you can play an mp3 file to wake you up instead of your normal alarm clock. This scenario looks roughly like this:

# DateTime.new uses UTC by default, so get time zone from current time 
 my $timezone = DateTime.now.timezone; 
 my $instant = DateTime.new( 
     year => 2015, 
     month => 9, 
     day => 4, 
     hour => 7, 
     minute => 0, 
     timezone => $timezone 
 ).Instant; 
 sleep-until $instant; 
 qqx{mplayer wake-me-up.mp3}; 

sub infix:<->

multi sub infix:<-> (Date:D, Int:D --> Date:D)
multi sub infix:<-> (Date:D, Date:D --> Int:D)

Takes a date to subtract from and either an Int, representing the number of days to subtract, or another Date object. Returns a new Date object or the number of days between the two dates, respectively.

say Date.new('2016-12-25') - Date.new('2016-12-24'); # OUTPUT: «1␤»
say Date.new('2015-12-25') - Date.new('2016-11-21'); # OUTPUT: «-332␤»
say Date.new('2016-11-21') - 332;                    # OUTPUT: «2015-12-25␤»

sub infix:<+>

multi sub infix:<+> (Date:D, Int:D --> Date:D)
multi sub infix:<+> (Int:D, Date:D --> Date:D)

Takes an Int and adds that many days to the given Date object.

say Date.new('2015-12-25') + 332; # OUTPUT: «2016-11-21␤»
say 1 + Date.new('2015-12-25');   # OUTPUT: «2015-12-26␤»

125 class DateTime

Calendar date with time

class DateTime does Dateish {}

For handling points in civil time, a DateTime object stores year, month, day, hour, minute (all Int), second (potentially fractional) and a time zone.

It provides methods for calculating with date and time.

DateTime methods are immutable; if you are tempted to modify one, create a modified copy instead.

Time zones are handled as Integers in seconds offset from UTC, not by time zone name.

my $dt = DateTime.new( 
     year    => 2015, 
     month   => 11, 
     day     => 21, 
     hour    => 16, 
     minute  => 1, 
 ); 
 
 say $dt;                            # OUTPUT: «2015-11-21T16:01:00Z␤» 
 say $dt.later(days => 20);          # OUTPUT: «2015-12-11T16:01:00Z␤» 
 say $dt.truncated-to('hour');       # OUTPUT: «2015-11-21T16:00:00Z␤» 
 say $dt.in-timezone(-8 * 3600);     # OUTPUT: «2015-11-21T08:01:00-0800␤» 
 
 my $now = DateTime.now(formatter => { sprintf "%02d:%02d", .hour, .minute }); 
 say $now;                           # 12:45 (or something like that) 

Methods

method new

Defined as:

multi method new(Int :$year!, Int :$month = 1, Int :$day = 1, 
                  Int :$hour = 0, Int :$minute = 0, :$second = 0, 
                  Int :$timezone = 0, :&formatter) 
 multi method new(Date :$date!, 
                  Int :$hour = 0, Int :$minute = 0, :$second = 0, 
                  Int :$timezone = 0, :&formatter) 
 multi method new(Int() $year, Int() $month, Int() $day, 
                  Int() $hour, Int $minute, $second, 
                  Int() :$timezone = 0, :&formatter) 
 multi method new(Instant:D $i,  :$timezone=0, :&formatter) 
 multi method new(Int:D $posix,  :$timezone=0, :&formatter) 
 multi method new(Str:D $format, :$timezone=0, :&formatter) 

Creates a new DateTime object. One option for creating a new DateTime object is from the components (year, month, day, hour, ...) separately. Another is to pass a Date object for the date component, and specify the time component-wise. Yet another is to obtain the time from an Instant, and only supply the time zone and formatter. Or instead of an Instant you can supply an Int as a UNIX timestamp.

You can also supply a Str formatted in ISO 8601 timestamp notation or as a full RFC 3339 date and time. Strings should be formatted as yyyy-mm-ddThh:mm:ssZ or yyyy-mm-ddThh:mm:ss+0100. We are somewhat less restrictive than the ISO 8601 standard, as we allow Unicode digits and mixing of condensed and extended time formats.

An invalid input string throws an exception of type X::Temporal::InvalidFormat. If you supply a string that includes a time zone and supply the timezone named argument, an exception of type X::DateTime::TimezoneClash is thrown.

my $datetime = DateTime.new(year => 2015,
                            month => 1,
                            day => 1,
                            hour => 1,
                            minute => 1,
                            second => 1,
                            timezone => 1);
$datetime = DateTime.new(date => Date.new('2015-12-24'),
                         hour => 1,
                         minute => 1,
                         second => 1,
                         timezone => 1);
$datetime = DateTime.new(2015, 1, 1, # First January of 2015
                         1, 1, 1);   # Hour, minute, second with default time zone
$datetime = DateTime.new(now);                       # Instant.
# from a Unix timestamp
say $datetime = DateTime.new(1470853583);            # OUTPUT: «2016-08-10T18:26:23Z␤»
$datetime = DateTime.new("2015-01-01T03:17:30+0500") # Formatted string

method now

Defined as:

method now(:$timezone = $*TZ, :&formatter --> DateTime:D)

Creates a new DateTime object from the current system time. A custom formatter and timezone can be provided. The :$timezone is the offset in seconds from GMT and defaults to the value of $*TZ variable.

say DateTime.now; # OUTPUT: «2018-01-08T13:05:32.703292-06:00␤»

Note that one may use the methods shown below chained to the .now to easily express current values, e.g.,

say DateTime.now.year; # OUTPUT: «2018␤»

method clone

Defined as:

method clone(:$year, :$month, :$day, :$hour, :$minute, :$second, :$timezone, :&formatter)

Creates a new DateTime object based on the invocant, but with the given arguments overriding the values from the invocant.

say DateTime.new('2015-12-24T12:23:00Z').clone(hour => 0);
# OUTPUT: «2015-12-24T00:23:00Z␤»

Note that this can lead to invalid dates in some circumstances:

say DateTime.new("2012-02-29T12:34:56Z").clone(year => 2015);
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::OutOfRange: Day out of range. Is: 29, should be in 1..28␤»

method hh-mm-ss

Defined as:

method hh-mm-ss(DateTime:D: --> Str:D)

Returns the time represented by the object as a string in 24-hour HH:MM:SS format:

say DateTime.new("2052-02-29T22:34:56Z").hh-mm-ss;
# OUTPUT: «22:34:56␤»

method hour

Defined as:

method hour(DateTime:D: --> Int:D)

Returns the hour component.

say DateTime.new('2012-02-29T12:34:56Z').hour;      # OUTPUT: «12␤»

method minute

Defined as:

method minute(DateTime:D: --> Int:D)

Returns the minute component.

say DateTime.new('2012-02-29T12:34:56Z').minute;     # OUTPUT: «34␤»

method second

Defined as:

method second(DateTime:D:)

Returns the second component, including potentially fractional seconds.

say DateTime.new('2012-02-29T12:34:56Z').second;     # OUTPUT: «56␤»
say DateTime.new('2012-02-29T12:34:56.789Z').second; # OUTPUT: «56.789␤»
say DateTime.new('2012-02-29T12:34:56,789Z').second; # comma also ok

method whole-second

Defined as:

method whole-second(DateTime:D:)

Returns the second component, rounded down to an Int.

say DateTime.new('2012-02-29T12:34:56.789Z').whole-second;      # OUTPUT: «56␤»

method timezone

Defined as:

method timezone(DateTime:D: --> Int:D)

Returns the time zone in seconds as an offset from UTC.

say DateTime.new('2015-12-24T12:23:00+0200').timezone;          # OUTPUT: «7200␤»

method offset

Defined as:

method offset(DateTime:D: --> Int:D)

Returns the time zone in seconds as an offset from UTC. This is an alias for #method timezone.

say DateTime.new('2015-12-24T12:23:00+0200').offset;            # OUTPUT: «7200␤»

method offset-in-minutes

Defined as:

method offset-in-minutes(DateTime:D: --> Real:D)

Returns the time zone in minutes as an offset from UTC.

say DateTime.new('2015-12-24T12:23:00+0200').offset-in-minutes; # OUTPUT: «120␤»

method offset-in-hours

Defined as:

method offset-in-hours(DateTime:D: --> Real:D)

Returns the time zone in hours as an offset from UTC.

say DateTime.new('2015-12-24T12:23:00+0200').offset-in-hours;   # OUTPUT: «2␤» 

method Str

Defined as:

method Str(DateTime:D: --> Str:D)

Returns a string representation of the invocant, as done by the formatter. If no formatter was specified, an ISO 8601 timestamp will be returned.

say DateTime.new('2015-12-24T12:23:00+0200').Str; 
 # OUTPUT: «2015-12-24T12:23:00+02:00␤» 

method Instant

Defined as:

method Instant(DateTime:D: --> Instant:D)

Returns an Instant object based on the invocant.

say DateTime.new('2015-12-24T12:23:00+0200').Instant; # OUTPUT: «Instant:1450952616␤»

method posix

Defined as:

method posix(Bool:D: $ignore-timezone = False --> Int:D)

Returns the date and time as a POSIX/UNIX timestamp (seconds since the Epoch, 1st January 1970 UTC).

If $ignore-timezone is True, the DateTime object will be treated as if the time zone offset is zero.

say DateTime.new('2015-12-24T12:23:00Z').posix;       # OUTPUT: «1450959780␤» 

method later

Defined as:

method later(DateTime:D: *%unit)

Returns a DateTime object based on the current one, but with a time delta applied. The time delta can be passed as a named argument where the argument name is the unit.

Unless the given unit is second or seconds, the given value will be converted to an Int.

Allowed units are second, seconds, minute, minutes, hour, hours, day, days, week, weeks, month, months, year, years. Please note that the plural forms can only be used with the later and earlier methods.

The :2nd form of colonpairs can be used as a compact and self-documenting way of specifying the delta:

say DateTime.new('2015-12-24T12:23:00Z').later(:2years);
# OUTPUT: «2017-12-24T12:23:00Z␤»

Since addition of several different time units is not commutative, only one unit may be passed.

my $d = DateTime.new(date => Date.new('2015-02-27'));
say $d.later(month => 1).later(:2days);  # OUTPUT: «2015-03-29T00:00:00Z␤»
say $d.later(days => 2).later(:1month);  # OUTPUT: «2015-04-01T00:00:00Z␤»
say $d.later(days => 2).later(:month);   # same, as +True === 1

If the resultant time has value 60 for seconds, yet no leap second actually exists for that time, seconds will be set to 59:

say DateTime.new('2008-12-31T23:59:60Z').later: :1day;
# OUTPUT: «2009-01-01T23:59:59Z␤»

Negative offsets are allowed, though earlier is more idiomatic for that.

method earlier

Defined as:

method earlier(DateTime:D: *%unit)

Returns a DateTime object based on the current one, but with a time delta towards the past applied. Unless the given unit is second or seconds, the given value will be converted to an Int. See #method later for usage.

my $d = DateTime.new(date => Date.new('2015-02-27'));
say $d.earlier(month => 1).earlier(:2days);  # OUTPUT: «2015-01-25T00:00:00Z␤»

If the resultant time has value 60 for seconds, yet no leap second actually exists for that time, seconds will be set to 59:

say DateTime.new('2008-12-31T23:59:60Z').earlier: :1day;
# OUTPUT: «2008-12-30T23:59:59Z␤»

Negative offsets are allowed, though later is more idiomatic for that.

method truncated-to

Defined as:

method truncated-to(DateTime:D: Cool $unit)

Returns a copy of the invocant, with everything smaller than the specified unit truncated to the smallest possible value.

my $d = DateTime.new("2012-02-29T12:34:56.946314Z");
say $d.truncated-to('second');      # OUTPUT: «2012-02-29T12:34:56Z␤»
say $d.truncated-to('minute');      # OUTPUT: «2012-02-29T12:34:00Z␤»
say $d.truncated-to('hour');        # OUTPUT: «2012-02-29T12:00:00Z␤»
say $d.truncated-to('day');         # OUTPUT: «2012-02-29T00:00:00Z␤»
say $d.truncated-to('month');       # OUTPUT: «2012-02-01T00:00:00Z␤»
say $d.truncated-to('year');        # OUTPUT: «2012-01-01T00:00:00Z␤»

DateTimes with fractional seconds can be truncated to whole seconds with .truncated-to('second').

method Date

Defined as:

multi method Date(DateTime:U --> Date:U)
multi method Date(DateTime:D --> Date:D)

Converts the invocant to Date.

say DateTime.new("2012-02-29T12:34:56.946314Z").Date; # OUTPUT: «2012-02-29␤» 
 say DateTime.Date;                                    # OUTPUT: «(Date)␤» 

method DateTime

Defined as:

method DateTime(--> DateTime)

Returns the invocant.

say DateTime.new("2012-02-29T12:34:56.946314Z").DateTime;
# OUTPUT: «2012-02-29T12:34:56.946314Z␤»
say DateTime.DateTime;
# OUTPUT: «(DateTime)␤»

method utc

Defined as:

method utc(DateTime:D: --> DateTime:D)

Returns a DateTime object for the same time, but in time zone UTC.

say DateTime.new('2015-12-24T12:23:00+0200').utc;
# OUTPUT: «2015-12-24T10:23:00Z␤»

method in-timezone

Defined as:

method in-timezone(DateTime:D: Int(Cool) $timezone = 0 --> DateTime:D)

Returns a DateTime object for the same time, but in the specified $timezone, which is the offset in seconds from GMT.

say DateTime.new('2015-12-24T12:23:00Z').in-timezone(3600 + 1800); # OUTPUT: «2015-12-24T13:53:00+0130␤»

Per RFC 7164, leap seconds do not respect local time and always occur at the end of the UTC day:

say DateTime.new: '2017-01-01T00:59:60+01:00'
# OUTPUT: «2017-01-01T00:59:60+01:00␤»

method local

Defined as:

method local(DateTime:D: --> DateTime:D)

Returns a DateTime object for the same time, but in the local time zone ($*TZ).

my $*TZ = -3600;
say DateTime.new('2015-12-24T12:23:00+0200').local; # OUTPUT: «2015-12-24T09:23:00-0100␤»

sub infix:<->

multi sub infix:<-> (DateTime:D, Duration:D --> DateTime:D)
multi sub infix:<-> (DateTime:D, DateTime:D --> Duration:D)

Takes a DateTime to subtract from and either a Duration or another DateTime object. Returns a new DateTime object or the Duration between the two dates, respectively. When subtracting Duration, time zone of the original DateTime is preserved in the returned DateTime object.

say perl DateTime.new(:2016year) - DateTime.new(:2015year):;
# OUTPUT: «Duration.new(31536001.0)␤»
say DateTime.new(:2016year, :3600timezone) - Duration.new(31536001.0);
# OUTPUT: «2015-01-01T00:00:00+01:00␤»

sub infix:<+>

multi sub infix:<+> (DateTime:D, Duration:D --> DateTime:D)
multi sub infix:<+> (Duration:D, DateTime:D --> DateTime:D)

Takes a DateTime and increases it by the given Duration, preserving the time zone.

say DateTime.new(:2015year) + Duration.new(31536001.0);
# OUTPUT: «2016-01-01T00:00:00Z␤»
say Duration.new(42) + DateTime.new(:2015year, :3600timezone);
# OUTPUT: «2015-01-01T00:00:42+01:00␤»

sub infix:«<=>»

multi sub infix:«<=>»(DateTime:D \a, DateTime:D \b --> Order:D)

Compares the equivalent instant, returns the Order.

say DateTime.now <=> DateTime.now; # OUTPUT: «Less␤»

sub infix:«cmp»

multi sub infix:«cmp»(DateTime:D \a, DateTime:D \b --> Order:D)

Compares the equivalent instant, returns the Order.

sub infix:«<»

multi sub infix:«<»(DateTime:D \a, DateTime:D \b --> Bool:D)

Compares the equivalent instant, returns a Bool

sub infix:«>»

multi sub infix:«>»(DateTime:D \a, DateTime:D \b --> Bool:D)

Compares the equivalent instant, returns a Bool

sub infix:«<=»

multi sub infix:«<=»(DateTime:D \a, DateTime:D \b --> Bool:D)

Compares the equivalent instant, returns a Bool

sub infix:«>=»

multi sub infix:«>=»(DateTime:D \a, DateTime:D \b --> Bool:D)

Compares the equivalent instant, returns a Bool

sub infix:«==»

multi sub infix:«==»(DateTime:D \a, DateTime:D \b --> Bool:D)

Compares the equivalent instant, returns a Bool

sub infix:«!=»

multi sub infix:«!=»(DateTime:D \a, DateTime:D \b --> Bool:D)

Compares the equivalent instant, returns a Bool

126 role Dateish

Object that can be treated as a date

role Dateish { ... }

Both Date and DateTime support accessing a year, month and day-of-month, as well as related functionality such as calculating the day of the week.

Methods

method year

Defined as:

method year(Date:D: --> Int:D)

Returns the year of the date.

say Date.new('2015-12-31').year;                                  # OUTPUT: «2015␤»
say DateTime.new(date => Date.new('2015-12-24'), hour => 1).year; # OUTPUT: «2015␤»

method month

Defined as:

method month(Date:D: --> Int:D)

Returns the month of the date (1..12).

say Date.new('2015-12-31').month;                                  # OUTPUT: «12␤»
say DateTime.new(date => Date.new('2015-12-24'), hour => 1).month; # OUTPUT: «12␤»

method day

Defined as:

method day(Date:D: --> Int:D)

Returns the day of the month of the date (1..31).

say Date.new('2015-12-31').day;                                  # OUTPUT: «31␤»
say DateTime.new(date => Date.new('2015-12-24'), hour => 1).day; # OUTPUT: «24␤»

method formatter

Defined as:

method formatter(Dateish:D:)

Returns the formatting function which is used for conversion to Str. If none was provided at object construction, a default formatter is used. In that case the method will return a Callable type object.

The formatting function is called by DateTime method Str with the invocant as its only argument.

my $dt = Date.new('2015-12-31');  # (no formatter specified)
say $dt.formatter.^name;          # OUTPUT: «Callable␤»
my $us-format = sub ($self) { sprintf "%02d/%02d/%04d", .month, .day, .year given $self; };
$dt = Date.new('2015-12-31', formatter => $us-format);
say $dt.formatter.^name;           # OUTPUT: «Sub␤»
say $dt;                          # OUTPUT: «12/31/2015␤»

method is-leap-year

Defined as:

method is-leap-year(--> Bool:D)

Returns True if the year of the Dateish object is a leap year.

say DateTime.new(:year<2016>).is-leap-year; # OUTPUT: «True␤»
say Date.new("1900-01-01").is-leap-year;    # OUTPUT: «False␤»

method day-of-month

Defined as:

method day-of-month(Date:D: --> Int:D)

Returns the day of the month of the date (1..31). Synonymous to the day method.

say Date.new('2015-12-31').day-of-month;                                  # OUTPUT: «31␤»
say DateTime.new(date => Date.new('2015-12-24'), hour => 1).day-of-month; # OUTPUT: «24␤»

method day-of-week

Defined as:

method day-of-week(Date:D: --> Int:D)

Returns the day of the week, where 1 is Monday, 2 is Tuesday and Sunday is 7.

say Date.new('2015-12-31').day-of-week;                                  # OUTPUT: «4␤»
say DateTime.new(date => Date.new('2015-12-24'), hour => 1).day-of-week; # OUTPUT: «4␤»

method day-of-year

Defined as:

method day-of-year(Date:D: --> Int:D)

Returns the day of the year (1..366).

say Date.new('2015-12-31').day-of-year;                                  # OUTPUT: «365␤»
say DateTime.new(date => Date.new('2015-03-24'), hour => 1).day-of-year; # OUTPUT: «83␤»

method days-in-month

Defined as:

method days-in-month(Dateish:D: --> Int:D)

Returns the number of days in the month represented by the Dateish object:

say Date.new("2016-01-02").days-in-month;                # OUTPUT: «31␤»
say DateTime.new(:year<10000>, :month<2>).days-in-month; # OUTPUT: «29␤»

method week

Defined as:

method week()

Returns a list of two integers: the year, and the week number. This is because at the start or end of a year, the week may actually belong to the other year.

my ($year, $week) = Date.new("2014-12-31").week;
say $year;                       # OUTPUT: «2015␤»
say $week;                       # OUTPUT: «1␤»
say Date.new('2015-01-31').week; # OUTPUT: «(2015 5)␤»

method week-number

Defined as:

method week-number(Date:D: --> Int:D)

Returns the week number (1..53) of the date specified by the invocant. The first week of the year is defined by ISO as the one which contains the fourth day of January. Thus, dates early in January often end up in the last week of the prior year, and similarly, the final few days of December may be placed in the first week of the next year.

say Date.new("2014-12-31").week-number;   # 1  (first week of 2015)
say Date.new("2016-01-02").week-number;   # 53 (last week of 2015)

method week-year

Defined as:

method week-year(Date:D: --> Int:D)

Returns the week year of the date specified by the invocant. Normally week-year is equal to Date.year. Note however that dates early in January often end up in the last week of the prior year, and similarly, the final few days of December may be placed in the first week of the next year.

say Date.new("2015-11-15").week-year;   # 2015
say Date.new("2014-12-31").week-year;   # 2015 (date belongs to the first week of 2015)
say Date.new("2016-01-02").week-year;   # 2015 (date belongs to the last week of 2015)

method weekday-of-month

Defined as:

method weekday-of-month(Date:D: --> Int:D)

Returns a number (1..5) indicating the number of times a particular day-of-week has occurred so far during that month, the day itself included.

say Date.new("2003-06-09").weekday-of-month;  # 2  (second Monday of the month)

method yyyy-mm-dd

Defined as:

method yyyy-mm-dd(Date:D: --> Str:D) 

Returns the date in YYYY-MM-DD format (ISO 8601)

say Date.new("2015-11-15").yyyy-mm-dd;   # OUTPUT: «2015-11-15␤» 
 say DateTime.new(1470853583).yyyy-mm-dd; # OUTPUT: «2016-08-10␤» 

method daycount

Defined as:

method daycount(Dateish:D: --> Int:D)

Returns the number of days from the epoch Nov. 17, 1858 to the day of the invocant. The daycount returned by this method is the MJD, i.e. the Modified Julian Day, which is used routinely by e.g. astronomers, geodesists, scientists and others. The MJD convention is designed to facilitate simplified chronological calculations.

say Date.new('1995-09-27').daycount;    # OUTPUT: «49987␤»

method IO

Defined as:

method IO(Dateish:D: --> IO::Path:D)

Returns an IO::Path object representing the stringified value of the Dateish object:

Date.today.IO.say;   # OUTPUT: «"2016-10-03".IO␤»
DateTime.now.IO.say; # OUTPUT: «"2016-10-03T11:14:47.977994-04:00".IO␤»

PORTABILITY NOTE: some operating systems (e.g. Windows) do not permit colons (:) in filenames, which would be present in IO::Path created from a DateTime object.

127 role Distribution

Distribution

role Distribution { }

Interface for objects that provide API access mapping META6 data to the files its represents. Objects that fulfill the Distribution role can be read by e.g. CompUnit::Repository::Installation. Generally a Distribution provides read access to a set of modules and metadata. These may be backed by the filesystem (Distribution::Path, Distribution::Hash) but could also read from an e.g. tar file or socket.

Required Methods

method meta

method meta(--> Hash:D) { ... }

Returns a Hash with the representation of the metadata. Please note that an actual META6.json file does not need to exist, just a representation in that format.

method content

method content($name-path --> IO::Handle:D) { ... }

Returns an IO::Handle to the file represented by $name-path. $name-path is a relative path as it would be found in the metadata such as lib/Foo.pm6 or resources/foo.txt.

128 class Distribution::Hash

Distribution::Hash

    class Distribution::Hash does Distribution::Locally { } 

A Distribution implementation backed by the filesystem. It does not require a META6.json file, essentially providing a lower level Distribution::Path.

Methods

method new

method new($hash, :$prefix)

Creates a new Distribution::Hash instance from the metadata contained in $hash. All paths in the metadata will be prefixed with :$prefix.

method meta

method meta()

Returns a Hash with the representation of the metadata.

method content

Please check the content method in Distribution::Locally.

Returns an IO::Handle to the file represented by $name-path. $name-path is a relative path as it would be found in the metadata such as lib/Foo.pm6 or resources/foo.txt.

129 class Distribution::Locally

Distribution::Locally

role Distribution::Locally does Distribution { }

Provides read access to specific files pointed at by a distributions metadata, providing the Distribution#method_content method for Distribution::Path and Distribution::Hash.

Methods

method prefix

A prefix path to be used in conjuncture with the paths found in the metadata.

method content

Provides Distribution#method_content

Returns an IO::Handle to the file represented by $name-path. $name-path is a relative path as it would be found in the metadata such as lib/Foo.pm6 or resources/foo.txt, and these paths will be prefixed with Distribution#method_prefix.

130 class Distribution::Path

Distribution::Path

    class Distribution::Path does Distribution::Locally { } 

A Distribution implementation backed by the filesystem. It requires a META6.json file at its root.

Methods

method new

method new(IO::Path $prefix, IO::Path :$meta-file = IO::Path)

Creates a new Distribution::Path instance from the META6.json file found at the given $prefix, and from which all paths in the metadata will be prefixed with. :$meta-file may optionally be passed if a filename other than META6.json needs to be used.

method meta

method meta()

Returns a Hash with the representation of the metadata.

method content

Distribution::Locally#method_content

Returns an IO::Handle to the file represented by $name-path. $name-path is a relative path as it would be found in the metadata such as lib/Foo.pm6 or resources/foo.txt.

131 class Distro

Distribution related information

class Distro does Systemic { }

Built-in class for providing distribution related information. Usually accessed through the $*DISTRO dynamic variable.

Methods

method is-win

Instance method returning a Bool indicating whether the distribution is a version of the Windows operating system.

method path-sep

Instance method returning the string that can be used to delimit elements in a path specification.

method release

Instance method returning the release information of the Distro object. Dies if the release information could not be established.

132 class Duration

Length of time

class Duration is Cool does Real { }

A Duration represents a length of time in atomic seconds, with fractions. Like an Instant, it is epoch-agnostic.

Durations can be subtracted from or added to Instants to yield another, new Instant. Subtracting one Instant from another yields a Duration. A Duration can also result from mathematical operations between two Durations when it makes sense (namely, the addition, subtraction, or modulus of two Durations). It can also be added, subtracted or divided modulo Real numbers.

The type of object returned for other numeric operations is currently unspecified.

133 role Encoding

Support for character encodings.

role Encoding { ... }

The Encoding role is implemented by classes that provide a character encoding, such as ASCII or UTF-8. Besides being used by the built-in character encodings, it may also be implemented by users to provide new encodings. Instances of objects doing this role are typically obtained using Encoding::Registry. For a list of supported encodings, see IO::Handle.

All methods provided by this role are stubs; they should be implemented by consumers of the role.

Methods

method name

method name(--> Str)

Abstract method that would return the primary name of the encoding.

method alternative-names

method alternative-names()

Abstract methods that should get a list of alternative names for the encoding.

method decoder

method decoder(*%options --> Encoding::Decoder)

Should get a character decoder instance for this encoding, configured with the provided options. Options vary by encoding. The built-in encodings all support translate-nl, which if True will translate \r\n into \n while decoding.

method encoder

Defined as:

method encoder(*%options --> Encoding::Encoder)

Gets a character encoder instance for this encoding, configured with the provided options. Options vary by encoding. The built-in encodings all support both replacement (either a Str replacement sequence or True to use a default replacement sequence for unencodable characters) and translate-nl (when set to True, turns \n into \r\n if the current platform is Windows).

134 class Encoding::Registry

Management of available encodings

class Encoding::Registry {}

Encoding::Registry is initialized with a list of encoding that is available for any Perl 6 application, namely:

Methods

method name

method register(Encoding $enc --> Nil)

Register a new Encoding.

method find

method find(Str() $name)

Finds an encoding by its name. Returns an Encoding::Encoder or Encoding::Decoder, depending on what had been registered.

135 enum Endian

Indicate endianness (6.d, 2018.12 and later)

enum Endian <NativeEndian LittleEndian BigEndian>;

An enum for indicating endianness, specifically with methods on blob8 and buf8. Consists of NativeEndian, LittleEndian and BigEndian.

Methods

routine Numeric

multi method Numeric(Endian:D --> Int:D)

Returns the value part of the enum pair.

say NativeEndian.Numeric;    # OUTPUT: «0␤»
say LittleEndian.Numeric;    # OUTPUT: «1␤»
say BigEndian.Numeric;       # OUTPUT: «2␤»

Note that the actual numeric values are subject to change. So please use the named values instead.

136 role Enumeration

Working with the role behind the enum type

role Enumeration { }

This is the role implemented by the enum-pairs in the enum type. In general, it is used to create constant sets, the elements of which become also constant symbols in the current namespace and to establish a relationship between the symbols belonging to the same set. In general, you will find Enumeration in enum types:

enum norse-gods <Þor Oðin Loki>;
my $one-of-them = norse-gods.pick;
say $one-of-them ~~ Enumeration; # OUTPUT: «True␤»

but nothing prevents you from using it in your own programs if you want to restrict somehow the relationship between the key and the value:

class DNA does Enumeration { 
     my %pairings = %( A => "T", 
                       T => "A", 
                       C => "G", 
                       G => "C" ); 
 
     method new( $base-pair where "A" | "C" | "G" | "T" )  { 
         self.bless( key => $base-pair, 
                     value => %pairings{$base-pair}); 
     } 
 
     multi method gist(::?CLASS:D:) { 
         return "$!key → $!value"; 
     } 
 
 } 
 
 enum Chain (); 
 constant length = 16; 
 for <A C G T>.roll( length ) -> $letter { 
     my DNA $base = DNA.new( $letter ); 
     Chain.HOW.add_enum_value( Chain, $base ); 
 } 
 
 for ^length { 
     my $base = Chain.pick; 
     say "{$base.key} and {$base.value}"; 
 } 

In this code, DNA consumes the Enumeration role, which is from this point of view a pair of key and value; we can use the generated DNA objects to compose an enum type from which elements can be picked one by one, with the output shown below.

T and A 
 C and G 
 T and A 
 # and so on... 

Methods

These are the methods included in this role:

method key

An Enumeration property.

enum Norse-gods <Þor Oðin Freija>;
say Freija.key; # OUTPUT: «Freija␤»

method value

These are Enumeration properties.

enum Norse-gods <Þor Oðin Freija>;
say Oðin.value; # OUTPUT: «1␤»

The value is assigned automatically by the enum type starting at 0. Oðin gets 1 since it is the second in the enum.

method enums

Defined as:

method enums()

Returns a Map of enum values. Works both on the enum type and any key.

enum Mass ( mg => 1/1000, g => 1/1, kg => 1000/1 );
say Mass.enums; # OUTPUT: «Map.new((g => 1, kg => 1000, mg => 0.001))␤»
say g.enums;    # OUTPUT: «Map.new((g => 1, kg => 1000, mg => 0.001))␤»

method kv

Defined as:

multi method kv(::?CLASS:D:)

Returns a list with key and value of the enum-pair.

say g.kv; # OUTPUT: «(g 1)␤» 

method pair

Defined as:

method pair(::?CLASS:D:)

Returns it as a Pair.

say g.pair; # OUTPUT: «g => 1␤» 

method CALL-ME

Defined as:

multi method CALL-ME(|)

Returns an Enumeration instance given an enum value.

enum Mass ( mg => 1/1000, g => 1/1, kg => 1000/1 );
say Mass(1/1000); # OUTPUT: mg

method pick

Defined as:

multi method pick(::?CLASS:U:)
multi method pick(::?CLASS:U: \n)
multi method pick(::?CLASS:D: *@pos)

It works on the defined class, selecting one element and eliminating it.

say Norse-gods.pick() for ^3;  # OUTPUT: «Þor␤Freija␤Oðin␤» 

method roll

Defined as:

multi method roll(::?CLASS:U:)
multi method roll(::?CLASS:U: \n)
multi method roll(::?CLASS:D: *@pos)

They work on the defined class selecting one or n elements without eliminating them.

say Norse-gods.roll() for ^3;  # OUTPUT: «Freija␤Freija␤Oðin␤» 

method pred

Defined as:

method pred(::?CLASS:D:)
say Freija.pred;  # OUTPUT: «Oðin␤» 

method succ

Defined as:

method succ(::?CLASS:D:)
say Oðin.succ;  # OUTPUT: «Freija␤» 

method Numeric

Defined as:

multi method Numeric(::?CLASS:D:)

Takes a value of an enum and returns it after coercion to Numeric:

enum Numbers ( cool => '42', almost-pi => '3.14', sqrt-n-one => 'i' );
say cool.Numeric;       # OUTPUT: «42␤»
say almost-pi.Numeric;  # OUTPUT: «3.14␤»
say sqrt-n-one.Numeric; # OUTPUT: «0+1i␤»

Note that if the value cannot be coerced to Numeric, an exception will be thrown.

method Int

Defined as:

multi method Int(::?CLASS:D:)

Takes a value of an enum and returns it after coercion to Int:

enum Numbers ( cool => '42', almost-pi => '3.14', sqrt-n-one => 'i' );
say cool.Int;           # OUTPUT: «42␤»
say almost-pi.Int;      # OUTPUT: «3␤»
try say sqrt-n-one.Int;
say $!.message if $!;   # OUTPUT: «Cannot convert 0+1i to Int: imaginary part not zero␤»

Note that if the value cannot be coerced to Int, an exception will be thrown.

method Real

Defined as:

multi method Real(::?CLASS:D:)

Takes a value of an enum and returns it after coercion to Real:

enum Numbers ( cool => '42', almost-pi => '3.14', sqrt-n-one => 'i' );
say cool.Real;           # OUTPUT: «42␤»
say almost-pi.Real;      # OUTPUT: «3.14␤»
try say sqrt-n-one.Real;
say $!.message if $!;    # OUTPUT: «Cannot convert 0+1i to Real: imaginary part not zero␤»

Note that if the value cannot be coerced to Real, an exception will be thrown.

method ===

Defined as

multi infix:<===> (Enumeration:D \a, Enumeration:D \b)

Equality of Enumeration symbols:

say Norse-gods.pick() === Freija for ^3; # OUTPUT: «False␤False␤True␤» 

137 class Exception

Anomalous event capable of interrupting normal control-flow

class Exception {}

All exceptions that are placed into the $! variable (or into $_ in CATCH blocks) inherit from Exception. When you call die or fail with a non-Exception argument, it is wrapped into an X::AdHoc object, which also inherits from Exception.

User-defined exception classes should inherit from Exception too, and define at least a method message.

class X::YourApp::SomeError is Exception {
    method message() {
        "A YourApp-Specific error occurred: out of coffee!";
    }
}

Methods

method message

Defined as:

method message(Exception:D: --> Str:D)

This is a stub that must be overwritten by subclasses, and should return the exception message.

Special care should be taken that this method does not produce an exception itself.

try die "Something bad happened";
if ($!) {
    say $!.message; # OUTPUT: «Something bad happened.␤»
}

method backtrace

Defined as:

method backtrace(Exception:D:)

Returns the backtrace associated with the exception in a Backtrace object or an empty string if there is none. Only makes sense on exceptions that have been thrown at least once.

try die "Something bad happened";
with $! { .backtrace.print ; }

method throw

Defined as:

method throw(Exception:D:)

Throws the exception.

my $exception = X::AdHoc.new;    # Totally fine
try $exception.throw;            # Throws
if ($!) { #`( some handling ) }; # Suppress the exception

method resume

Defined as:

method resume(Exception:D:)

Resumes control flow where .throw left it when handled in a CATCH block.

# For example, resume control flow for any exception
CATCH { default { .resume } }

method rethrow

Defined as:

method rethrow(Exception:D:)

Rethrows an exception that has already been thrown at least once. This is different from throw in that it preserves the original backtrace.

my $e = X::AdHoc.new(payload => "Bad situation");
sub f() { die 'Bad' };
sub g() { try f; CATCH { default { .rethrow } } };
g;
CATCH { default { say .backtrace.full } };

method fail

Defined as:

multi sub    fail(*@text)
multi sub    fail(Exception $e)
method fail(Exception:D:)

Exits the calling Routine and returns a Failure object wrapping the exception $e - or, for the *@text form, an X::AdHoc exception constructed from the concatenation of @text. If the caller activated fatal exceptions via the pragma use fatal;, the exception is thrown instead of being returned as a Failure.

# A custom exception defined
class ForbiddenDirectory is Exception {
    has Str $.name;

    method message { "This directory is forbidden: '$!name'" }
}

sub copy-directory-tree ($dir) {
    # We don't allow for non-directories to be copied
    fail "$dir is not a directory" if !$dir.IO.d;
    # We don't allow 'foo' directory to be copied too
    fail ForbiddenDirectory.new(:name($dir)) if $dir eq 'foo';
    # or above can be written in method form as:
    # ForbiddenDirectory.new(:name($dir)).fail if $dir eq 'foo';
    # Do some actual copying here
    ...
}

# A Failure with X::AdHoc exception object is returned and
# assigned, so no throwing Would be thrown without an assignment
my $result = copy-directory-tree("cat.jpg");
say $result.exception; # OUTPUT: «cat.jpg is not a directory␤»

# A Failure with a custom Exception object is returned
$result = copy-directory-tree('foo');
say $result.exception; # OUTPUT: «This directory is forbidden: 'foo'␤»

method gist

Defined as:

multi method gist(Exception:D:)

Returns whatever the exception printer should produce for this exception. The default implementation returns message and backtrace separated by a newline.

my $e = X::AdHoc.new(payload => "This exception is pretty bad");
try $e.throw;
if ($!) { say $!.gist; };
# OUTPUT: «This exception is pretty bad
#   in block <unit> at <unknown file> line 1␤»

sub die

Defined as:

multi sub die()
multi sub die(*@message)
multi sub die(Exception:D $e)
method    die(Exception:D:)

Throws a fatal Exception. The default exception handler prints each element of the list to $*ERR (STDERR).

die "Important reason"; 

If the subroutine form is called without arguments, the value of $! variable is checked. If it is set to a .DEFINITE value, its value will be used as the Exception to throw if it's of type Exception, otherwise, it will be used as payload of X::AdHoc exception. If $! is not .DEFINITE, X::AdHoc with string "Died" as payload will be thrown.

die will print by default the line number where it happens

die "Dead"; 
 # OUTPUT: «(exit code 1) Dead␤ 
 # in block <unit> at /tmp/dead.p6 line 1␤␤» 

However, that default behavior is governed at the Exception level and thus can be changed to anything we want by capturing the exception using CATCH. This can be used, for instance, to suppress line numbers.

CATCH { 
   default { 
     .payload.say 
   } 
 }; 
 die "Dead" # OUTPUT: «Dead␤» 

sub warn

Defined as:

multi sub warn(*@message)

Throws a resumable warning exception, which is considered a control exception, and hence is invisible to most normal exception handlers. The outermost control handler will print the warning to $*ERR. After printing the warning, the exception is resumed where it was thrown. To override this behavior, catch the exception in a CONTROL block. A quietly {...} block is the opposite of a try {...} block in that it will suppress any warnings but pass fatal exceptions through.

To simply print to $*ERR, please use note instead. warn should be reserved for use in threatening situations when you don't quite want to throw an exception.

warn "Warning message";

138 class Failure

Delayed exception

class Failure is Nil { }

A Failure is a soft or unthrown Exception, usually generated by calling &fail. It acts as a wrapper around an Exception object.

Sink (void) context causes a Failure to throw, i.e. turn into a normal exception. The use fatal pragma causes this to happen in all contexts within the pragma's scope. Inside try blocks, use fatal is automatically set, and you can disable it with no fatal.

That means that Failures are generally only useful in cases of code that normally would produce an rvalue; Failures are more or less equivalent to Exceptions in code that will frequently be called in sink context (i.e., for its side-effects, such as with say).

Similarly, you should generally use &fail only inside code that is normally expected to return something.

Checking a Failure for truth (with the Bool method) or definedness (with the defined method) marks the failure as handled, and causes it not to throw in sink context anymore.

You can call the handled method to check if a failure has been handled.

Calling methods on unhandled failures propagates the failure. The specification says the result is another Failure, in Rakudo it causes the failure to throw.

Because a Failure is Nil, which is undefined, a common idiom for safely executing code that may fail uses a with/else statement:

sub may_fail( --> Numeric:D ) { 
   my $value = (^10).pick || fail "Zero is unacceptable"; 
   fail "Odd is also not okay" if $value % 2; 
   return $value; 
 } 
 
 with may_fail() -> $value { # defined, so didn't fail 
   say "I know $value isn't zero or odd." 
 } else { # undefined, so failed, and the Failure is the topic 
   say "Uh-oh: {.exception.message}." 
 } 

Methods

method new

Defined as:

method new(Failure:D: $payload --> Failure)

Returns a new Failure instance with the given payload. The latter can be either an Exception or a payload for an Exception. A typical payload would be a Str with an error message. A list of payloads is also accepted.

my $e = Failure.new(now.DateTime, 'WELP‼');
say $e;
CATCH{ default { say .^name, ': ', .Str } }
# OUTPUT: «X::AdHoc: 2017-09-10T11:56:05.477237ZWELP‼␤»

method handled

Defined as:

method handled(Failure:D: --> Bool:D)

Returns True for handled failures, False otherwise.

sub f() { fail }; my $v = f; say $v.handled; # OUTPUT: «False␤»

The handled method is an lvalue, which means you can also use it to set the handled state:

sub f() { fail }
my $v = f;
$v.handled = True;
say $v.handled; # OUTPUT: «True␤»

method exception

Defined as:

method exception(Failure:D: --> Exception)

Returns the Exception object that the failure wraps.

sub failer() { fail };
my $failure = failer;
my $ex = $failure.exception;
put "$ex.^name(): $ex";
# OUTPUT: «X::AdHoc: Failed␤»

method self

Defined as:

method self(Failure:D: --> Failure:D)

If the invocant is a handled Failure, returns it as is. If not handled, throws its Exception. Since Mu type provides .self for every class, calling this method is a handy way to explosively filter out Failures:

my $num1 = '♥'.Int;
# $num1 now contains a Failure object, which may not be desirable

my $num2 = '♥'.Int.self;
# .self method call on Failure causes an exception to be thrown

my $num3 = '42'.Int.self;
# Int type has a .self method, so here $num3 has `42` in it

(my $stuff = '♥'.Int).so;
say $stuff.self; # OUTPUT: «(HANDLED) Cannot convert string to number…»
# Here, Failure is handled, so .self just returns it as is

method Bool

Defined as:

multi method Bool(Failure:D: --> Bool:D)

Returns False, and marks the failure as handled.

sub f() { fail }; my $v = f; say $v.handled; $v.Bool; say $v.handled;
# OUTPUT: «False␤
# True␤»

method Capture

Defined as:

method Capture()

Throws X::Cannot::Capture if the invocant is a type object or a handled Failure. Otherwise, throws the invocant's exception.

method defined

Defined as:

multi method defined(Failure:D: --> Bool:D)

Returns False (failures are officially undefined), and marks the failure as handled.

sub f() { fail }; my $v = f; say $v.defined; # OUTPUT: «False␤»

139 class FatRat

Rational number (arbitrary-precision)

class FatRat is Cool does Rational[Int, Int] {}

A FatRat is a rational number stored with arbitrary size numerator and denominator. Arithmetic operations involving a FatRat and optionally Int or Rat objects return a FatRat, avoiding loss of precision.

Since, unlike Rat, FatRat arithmetics do not fall back Num at some point, there is a risk that repeated arithmetic operations generate pathologically large numerators and denominators.

There are two common ways to generate FatRat objects: through the FatRat.new(Int, Int) constructor, which generates them from numerator and denominator, or by calling the .FatRat method on an Int or Rat object.

Methods

method perl

multi method perl(FatRat:D: --> Str:D)

Returns an implementation-specific string that produces an equivalent object when given to EVAL.

say FatRat.new(1, 2).perl; # OUTPUT: «FatRat.new(1, 2)␤»

140 class ForeignCode

Rakudo-specific class that wraps around code in other languages (generally NQP)

class ForeignCode does Callable {}

This is a Rakudo specific class, and as such it is advisable not to use it in your own code, since its interface might change or even disappear in the future. This is provided here only as a reference

ForeignCode is a Perl 6 wrapper around code that is not written originally in that language; its intention is to use these blocks of code in Callable contexts easily. For instance, subs have some anonymous functions that are actually ForeignCode.

sub does-nothing(){}; 
 say $_.name ~ ' → ' ~ $_.^name for &does-nothing.^methods; 
 # OUTPUT: «<anon> → ForeignCode␤<anon> → ForeignCode␤soft → Method␤…» 

This script will map method names to their class, and it shows that routines, in particular, have several methods that are actually ForeignCode instead of Method s.

Methods

method arity

method arity()

Returns the arity of the enclosed code.

method count

method count()

Returns the number of arguments the enclosed code needs.

method signature

method signature( ForeignCode:D: )

Returns the signature of the enclosed code.

method name

method name()

Returns the name of the enclosed code, or <anon> if it has not received any.

method gist

method gist( ForeignCode:D: )

Returns the name of the code by calling name.

method Str

method Str( ForeignCode:D: )

Returns the name of the code by calling name.

141 class Grammar

Formal grammar made up of named regexes

class Grammar is Cursor {}

Every type declared with grammar and not explicitly stating its superclass, becomes a subclass of Grammar.

grammar Identifier {
    token TOP       { <initial> <rest>* }
    token initial   { <+myletter +[_]> }
    token rest      { <+myletter +mynumber +[_]> }
    token myletter  { <[A..Za..z]> }
    token mynumber  { <[0..9]> }
}

say Identifier.isa(Grammar);                # OUTPUT: «True␤»
my $match = Identifier.parse('W4anD0eR96');
say ~$match;                                # OUTPUT: «W4anD0eR96␤»

More documentation on grammars is available.

Methods

method parse

Defined as:

method parse($target, :$rule = 'TOP',  Capture() :$args = \(), Mu :$actions = Mu, *%opt)

Parses the $target, which will be coerced to Str if it isn't one, using $rule as the starting rule. Additional $args will be passed to the starting rule if provided.

grammar RepeatChar {
    token start($character) { $character+ }
}

say RepeatChar.parse('aaaaaa', :rule('start'), :args(\('a')));
say RepeatChar.parse('bbbbbb', :rule('start'), :args(\('b')));

# OUTPUT:
# 「aaaaaa」
# 「bbbbbb」

If the action named argument is provided, it will be used as an action object, that is, for each successful regex match, a method of the same name, if it exists, is called on the action object, passing the match object as the sole positional argument.

my $actions = class { method TOP($/) { say "7" } };
grammar { token TOP { a { say "42" } b } }.parse('ab', :$actions);
# OUTPUT : «42␤7␤»

Additional named arguments are used as options for matching, so you can specify things like :pos(4) to start parsing from the fourth (zero-base) character. All matching adverbs are allowed, but not all of them take effect. There are several types of adverbs that a regex can have, some of which apply at compile time, like :s and :i. You cannot pass those to .parse, because the regexes have already been compiled. But, you can pass those adverbs that affect the runtime behavior, such as :pos and :continue.

say RepeatChar.parse('bbbbbb', :rule('start'), :args(\('b')), :pos(4)).Str; 
 # OUTPUT : «bb␤» 

Method parse only succeeds if the cursor has arrived at the end of the target string when the match is over. Use method subparse if you want to be able to stop in the middle.

Returns a Match object on success, and Nil on failure.

method subparse

Defined as:

method subparse($target, :$rule = 'TOP', Capture() :$args = \(),  Mu :$actions = Mu, *%opt)

Does exactly the same as method parse, except that cursor doesn't have to reach the end of the string to succeed. That is, it doesn't have to match the whole string.

Note that unlike method parse, subparse always returns a Match object, which will be a failed match (and thus falsy), if the grammar failed to match.

grammar RepeatChar {
    token start($character) { $character+ }
}

say RepeatChar.subparse('bbbabb', :rule('start'), :args(\('b')));
say RepeatChar.parse('bbbabb', :rule('start'), :args(\('b')));
say RepeatChar.subparse('bbbabb', :rule('start'), :args(\('a')));
say RepeatChar.subparse('bbbabb', :rule('start'), :args(\('a')), :pos(3));


# OUTPUT:
# 「bbb」
# Nil
# #<failed match>
# 「a」

method parsefile

Defined as:

method parsefile(Str(Cool) $filename, :$enc, *%opts)

Reads file $filename encoding by $enc, and parses it. All named arguments are passed on to method parse.

grammar Identifiers {
    token TOP        { [<identifier><.ws>]+ }
    token identifier { <initial> <rest>* }
    token initial    { <+myletter +[_]> }
    token rest       { <+myletter +mynumber +[_]> }
    token myletter   { <[A..Za..z]> }
    token mynumber   { <[0..9]> }
}

say Identifiers.parsefile('users.txt', :enc('UTF-8'))
    .Str.trim.subst(/\n/, ',', :g);

# users.txt :
# TimToady
# lizmat
# jnthn
# moritz
# zoffixznet
# MasterDuke17

# OUTPUT : «TimToady,lizmat,jnthn,moritz,zoffixznet,MasterDuke17␤»

142 class Hash

Mapping from strings to itemized values

class Hash is Map { }

A Hash is a mutable Map; it implements Associative through its inheritance of Map and as such provides support for looking up values using keys, providing support for associative subscripting.

Although the order of the hashes is guaranteed to be random in every single call, still successive calls to .keys and .values are guaranteed to return them in the same order:

my %orig = :1a, :2b; my %new = :5b, :6c;
%orig{ %new.keys } = %new.values;
say %orig.perl; # OUTPUT: «{:a(1), :b(5), :c(6)}␤»

In this case, b will always be associated to 5 and c to 6; even if two successive calls to keys will return them in different order. Successive calls to any of them separately and repeatedly will always return the same order in any program invocation.

Please see the section on hash literals for different ways to declare a hash. Additionally, they can be declared using curly braces as long as these rules are followed:

given 3 { say WHAT {3 => 4, :b}  };     # OUTPUT: «(Hash)␤» 
 given 3 { say WHAT {3 => 4, :b($_)} };  # OUTPUT: «(Block)␤» 
 given 3 { say WHAT {3 => 4, :b(.Num)} };# OUTPUT: «(Block)␤» 
 say { 'a',:b(3), 'c' }.^name;           # OUTPUT: «Block␤» 

The next-to-last two cases are examples of the generation of Blocks in the presence of the topic variable $_. The last case does not meet the third criterium for generating a hash, and thus generates a Block.

A % in front of parentheses or square brackets will generate a Hash as long as the elements can be paired.

say %( 'a', 3, :b(3), 'c', 3 ).^name; # OUTPUT: «Hash␤»

Elements in this hash can be paired both sides of the Pair :b(3).

say %(«a b c 1 2 3»).^name;           # OUTPUT: «Hash␤»

An empty hash can be initialized either with empty curly braces or, since 6.d, %().

say %().^name; # OUTPUT: «Hash␤»
say {}.^name;  # OUTPUT: «Hash␤»

Methods

method classify-list

Defined as:

multi method classify-list(&mapper, *@list, :&as --> Hash:D)
multi method classify-list(%mapper, *@list, :&as --> Hash:D)
multi method classify-list(@mapper, *@list, :&as --> Hash:D)

Populates a Hash by classifying the possibly-empty @list of values using the given mapper, optionally altering the values using the :&as Callable. The @list cannot be lazy.

The mapper can be a Callable that takes a single argument, an Associative, or an Iterable. With Associative and an Iterable mappers, the values in the @list represent the key and index of the mapper's value respectively. A Callable mapper will be executed once per each item in the @list, with that item as the argument and its return value will be used as the mapper's value.

Simple classification

In simple classification mode, each mapper's value is any non-Iterable and represents a key to classify @list's item under:

say % .classify-list: { $_ %% 2 ?? 'even' !! 'odd' }, ^10; 
 # OUTPUT: «{even => [0 2 4 6 8], odd => [1 3 5 7 9]}␤» 
 
 my @mapper = <zero one two three four five>; 
 my %hash = foo => 'bar'; 
 say %hash.classify-list: @mapper, 1, 2, 3, 4, 4; 
 # OUTPUT: «{foo => bar, four => [4 4], one => [1], three => [3], two => [2]}␤» 

The mapper's value is used as the key of the Hash to which the @list's item will be push ed. See .categorize-list if you wish to classify an item into multiple categories at once.

Multi-level classification

In multi-level classification mode, each mapper's value is an Iterable that represents a tree of hash keys to classify @list's item under:

say % .classify-list: {
    [
        (.is-prime ?? 'prime' !! 'non-prime'),
        ($_ %% 2   ?? 'even'  !! 'odd'      ),
    ]
}, ^10;
# OUTPUT:
# {
#     non-prime => {
#         even => [0 4 6 8],
#         odd  => [1 9]
#     },
#     prime => {
#         even => [2],
#         odd  => [3 5 7]
#     }
# }

NOTE: each of those Iterables must have the same number of elements, or the method will throw an exception. This restriction exists to avoid conflicts when the same key is a leaf of one value's classification but a node of another value's classification.

:&as value modifier

If :&as Callable argument is specified, it will be called once per each item of @list, with the value as the argument, and its return value will be used instead of the original @list's item:

say % .classify-list: :as{"Value is $_"}, { $_ %% 2 ?? 'even' !! 'odd' }, ^5;
# OUTPUT (slightly altered manually, for clarity):
# {
#     even => ['Value is 0', 'Value is 2', 'Value is 4'],
#     odd  => ['Value is 1', 'Value is 3']
# }

method categorize-list

Defined as:

multi method categorize-list(&mapper, *@list, :&as --> Hash:D)
multi method categorize-list(%mapper, *@list, :&as --> Hash:D)
multi method categorize-list(@mapper, *@list, :&as --> Hash:D)

Populates a Hash by classifying the possibly-empty @list of values using the given mapper, optionally altering the values using the :&as Callable. The @list cannot be lazy.

The mapper can be a Callable that takes a single argument, an Associative, or an Iterable. With Associative and an Iterable mappers, the values in the @list represent the key and index of the mapper's value respectively. A Callable mapper will be executed once per each item in the @list, with that item as the argument and its return value will be used as the mapper's value.

Simple categorization

The mapper's value is expected to be a possibly empty list of non-Iterables that represent categories to place the value into:

say % .categorize-list: {
    gather {
        take 'prime'   if .is-prime;
        take 'largish' if $_ > 5;
        take $_ %% 2 ?? 'even' !! 'odd';
    }
}, ^10;

# OUTPUT:
# {
#     prime   => [2 3 5 7]
#     even    => [0 2 4 6 8],
#     odd     => [1 3 5 7 9],
#     largish => [6 7 8 9],
# }

Notice how some items, e.g. 6 and 7, are present in several categories.

Multi-level categorization

In multi-level categorization, the categories produced by the mapper can are Iterables and categorization combines features of classify, by producing nested hashes of classifications for each category.

say % .categorize-list: {
    [
        $_ > 5    ?? 'largish' !! 'smallish',
        .is-prime ?? 'prime'   !! 'non-prime',
    ],
}, ^10;

# OUTPUT:
# {
#     largish => {
#         non-prime => [6 8 9],
#         prime     => [7]
#     },
#     smallish => {
#         non-prime => [0 1 4],
#         prime     => [2 3 5]
#     }
# }

The mapper in above snippet produces single-item list (note the significant trailing comma) with a two-item Array in it. The first item in that array indicates the first level of classification: the largish/smallish categories the routine produces. The second item in that array indicates further levels of classification, in our case the classification into prime/non-prime inside of each category.

NOTE: each of category Iterables must have the same number of elements, or the method will throw an exception. This restriction exists to avoid conflicts when the same key is a leaf of one value's classification but a node of another value's classification.

:&as value modifier

If :&as Callable argument is specified, it will be called once per each item of @list, with the value as the argument, and its return value will be used instead of the original @list's item:

say % .categorize-list: :as{"Value is $_"}, { $_ %% 2 ?? 'even' !! 'odd' }, ^5;
# OUTPUT (slightly altered manually, for clarity):
# {
#     even => ['Value is 0', 'Value is 2', 'Value is 4'],
#     odd  => ['Value is 1', 'Value is 3']
# }

method push

Defined as:

multi method push(Hash:D: *@new)

Adds the @new elements to the hash with the same semantics as hash assignment, but with three exceptions:

Example:

my %h  = a => 1;
%h.push: (a => 1);              # a => [1,1]
%h.push: (a => 1) xx 3 ;        # a => [1,1,1,1,1]
%h.push: (b => 3);              # a => [1,1,1,1,1], b => 3
%h.push('c' => 4);              # a => [1,1,1,1,1], b => 3, c => 4
push %h, 'd' => 5;              # a => [1,1,1,1,1], b => 3, c => 4, d => 5

Please note that Pairs or colon pairs as arguments to push will be treated as extra named arguments and as such wont end up the Hash. The same applies to the sub push.

my %h .= push(e => 6);
push %h, f => 7;
say %h.perl;
# OUTPUT: «{}␤»

Also note that push can be used as a replacement for assignment during hash initialization very useful ways. Take for instance the case of an inverted index:

my %wc = 'hash' => 323, 'pair' => 322, 'pipe' => 323;
(my %inv).push: %wc.invert;
say %inv;                     # OUTPUT: «{322 => pair, 323 => [pipe hash]}␤»

Note that such an initialization could also be written as

my %wc = 'hash' => 323, 'pair' => 322, 'pipe' => 323;
my %inv .= push: %wc.invert;

Note: Compared to append, push will add the given value as is, whereas append will slip it in:

my %ha = :a[42, ]; %ha.push: "a" => <a b c a>;
say %ha; # OUTPUT: «{a => [42 (a b c a)]}␤»

my %hb = :a[42, ]; %hb.append: "a" => <a b c a>;
say %hb; # OUTPUT: «{a => [42 a b c a]}␤»

method append

Defined as:

method append(+@values)

Append the provided Pairs or even sized list to the Hash. If a key already exists, turn the existing value into an Array and push new value onto that Array. Please note that you can't mix even sized lists and lists of Pairs. Also, bare Pairs or colon pairs will be treated as named arguments to .append.

my %h = a => 1;
%h.append('b', 2, 'c', 3);
%h.append( %(d => 4) );
say %h;
# OUTPUT: «{a => 1, b => 2, c => 3, d => 4}␤»
%h.append('a', 2);
# OUTPUT: «{{a => [1 2], b => 2, c => 3, d => 4}␤»

Note: Compared to push, append will slip in the given value, whereas push will add it as is:

my %hb = :a[42, ]; %hb.append: "a" => <a b c a>;
say %hb; # OUTPUT: «{a => [42 a b c a]}␤»

my %ha = :a[42, ]; %ha.push: "a" => <a b c a>;
say %ha; # OUTPUT: «{a => [42 (a b c a)]}␤»

method default

Defined as:

method default()

Returns the default value of the invocant, i.e. the value which is returned when a non existing key is used to access an element in the Hash. Unless the Hash is declared as having a default value by using the is default trait the method returns the type object (Any).

my %h1 = 'apples' => 3, 'oranges' => 7;
say %h1.default;                                       # OUTPUT: «(Any)␤»
say %h1{'bananas'};                                    # OUTPUT: «(Any)␤»

my %h2 is default(1) = 'apples' => 3, 'oranges' => 7;
say %h2.default;                                       # OUTPUT: «1␤»
say %h2{'apples'} + %h2{'bananas'};                    # OUTPUT: «4␤»

method keyof

Defined as:

method keyof()

Returns the type constraint for the keys of the invocant. For normal hashes the method returns the coercion type (Str(Any)) while for non-string keys hashes the type used in the declaration of the Hash is returned.

my %h1 = 'apples' => 3, 'oranges' => 7;  # (no key type specified)
say %h1.keyof;                           # OUTPUT: «(Str(Any))␤»

my %h2{Str} = 'oranges' => 7;            # (keys must be of type Str)
say %h2.keyof;                           # (Str)
%h2{3} = 'apples';                       # throws exception
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::TypeCheck::Binding: Type check failed in binding to key; expected Str but got Int (3)␤»

my %h3{Int};                             # (this time, keys must be of type Int)
%h3{42} = 4096;
say %h3.keyof;                           # (Int)

method of

Defined as:

method of()

Returns the type constraint for the values of the invocant. By default, i.e. if no type constraint is given during declaration, the method returns (Mu).

my %h1 = 'apples' => 3, 'oranges' => 7;  # (no type constraint specified)
say %h1.of;                              # OUTPUT: «(Mu)␤»

my Int %h2 = 'oranges' => 7;             # (values must be of type Int)
say %h2.of;                              # OUTPUT: «(Int)␤»

routine dynamic

Defined as:

method dynamic(--> Bool:D)

Returns True if the invocant has been declared with the is dynamic trait.

my %a;
say %a.dynamic;                          # OUTPUT: «False␤»

my %b is dynamic;
say %b.dynamic;                          # OUTPUT: «True␤»

If you declare a variable with the * twigil is dynamic is implied.

my %*b;
say %*b.dynamic;                         # OUTPUT: «True␤»

Note that in the Scalar case you have to use the VAR method in order to get correct information.

my $s is dynamic = %('apples' => 5);
say $s.dynamic;                   # OUTPUT: «False␤»  (wrong, don't do this)
say $s.VAR.dynamic;               # OUTPUT: «True␤»   (correct approach)

Subscript Adverbs

Some methods are implemented as adverbs on subscripts (consult the operators documentation for more information).

:exists

The adverb :exists returns Bool::True if a key exists in the Hash. If more than one key is supplied it returns a List of Bool.

my %h = a => 1, b => 2;
say %h<a>:exists;   # OUTPUT: «True␤»
say %h<a b>:exists; # OUTPUT: «(True True)␤»

:delete

Use :delete to remove a Pair from the Hash.

my %h = a => 1;
say %h;         # OUTPUT: «{a => 1}␤»
say %h.elems;   # OUTPUT: «1␤»

%h<a>:delete;
say %h;         # OUTPUT: «{}␤»
say %h.elems;   # OUTPUT: «0␤»

:p

The adverb :p returns a Pair or a List of Pair instead of just the value.

my %h = a => 1, b => 2;
say %h<a>:p;    # OUTPUT: «a => 1␤»
say %h<a b>:p;  # OUTPUT: «(a => 1 b=> 2)␤»

:v and :k

The adverbs :v and :k return the key or value or a list thereof.

my %h = a => 1, b => 2;
say %h<a>:k;    # OUTPUT: «a␤»
say %h<a b>:k;  # OUTPUT: «(a b)␤»

The adverb :kv returns a list of keys and values.

my %h = a => 1, b => 2, c => 3;
say %h<a c>:kv;  # OUTPUT: «(a 1 c 3)␤»

You can also use the adverbs without knowing anything about the hash by using empty angle brackets in which case all the keys and values will be listed:

my %h1 = a => 1;
my %h2 = a => 1, b => 2;
say %h1<>:k; # OUTPUT: «(a)␤»
say %h1<>:v; # OUTPUT: «(1)␤»
say %h2<>:k; # OUTPUT: «(a b)␤»
say %h2<>:v; # OUTPUT: «(1 2)␤»

143 class HyperSeq

An object for performing batches of work in parallel with ordered output

class HyperSeq does Iterable does Sequence { }

An HyperSeq is the intermediate object used when the operator hyper is invoked on a Seq. In general, it's not intended for direct consumption by the developer.

Methods

method iterator

method iterator(HyperSeq:D: --> Iterator:D)

Returns the underlying iterator.

method grep

method grep(HyperSeq:D: $matcher, *%options)

Applies grep to the HyperSeq similarly to how it would do it on a Seq.

my @hyped = (^10000).map(*²).hyper; 
 @hyped.grep( * %% 3 ).say; 
 # OUTPUT: «(0 9 36 81 144…» 

When you use hyper on a Seq, this is the method that is actually called.

method map

method map(HyperSeq:D: $matcher, *%options)

Uses maps on the HyperSeq, generally created by application of hyper to a preexisting Seq.

method invert

method invert(HyperSeq:D:)

Inverts the HyperSeq created from a Seq by .hyper.

method hyper

method hyper(HyperSeq:D:)

Returns the object.

method race

method race(HyperSeq:D:)

Creates a RaceSeq object out of the current one.

method serial

multi method serial(HyperSeq:D:)

Converts the object to a Seq and returns it.

method is-lazy

method is-lazy(--> False )

Returns False.

method sink

Defined as:

method sink(--> Nil)

Sinks the underlying data structure, producing any side effects.

144 class HyperWhatever

Placeholder for multiple unspecified values/arguments

class HyperWhatever { }

HyperWhatever is very similar in functionality to Whatever. The difference lies in HyperWhatever standing in for multiple values, rather than a single one.

Standalone term

Just like with Whatever, if a HyperWhatever is used as a term on its own, no currying is done and the HyperWhatever object will be used as-is:

sub foo ($arg) { say $arg.^name }
foo **; # OUTPUT: «HyperWhatever␤»

You can choose to interpret such a value as standing for multiple values in your own routines. In core, a HyperWhatever can be used with this meaning when smartmatching with Lists:

say (1, 8)                ~~ (1, **, 8); # OUTPUT: «True␤»
say (1, 2, 4, 5, 6, 7, 8) ~~ (1, **, 8); # OUTPUT: «True␤»
say (1, 2, 8, 9)          ~~ (1, **, 8); # OUTPUT: «False␤»

Wherever a HyperWhatever appears in the list on the right-hand side means any number of elements can fill that space in the list being smartmatched.

Currying

When it comes to currying, the HyperWhatever follows the same rules as Whatever. The only difference is HyperWhatever produces a Callable with a *@ slurpy as a signature:

say (**²)(1, 2, 3, 4, 5); # OUTPUT: «(1 4 9 16 25)␤»

A HyperWhatever closure can be imagined as a Whatever closure with another sub wrapped around it that simply maps each element in the arguments over:

my &hyper-whatever = sub (*@args) { map *², @args }
say hyper-whatever(1, 2, 3, 4, 5); # OUTPUT: «(1 4 9 16 25)␤»

When currying, mixing HyperWhatever with Whatever is not permitted.

145 role IO

Input/output related routines

The role provides no methods, but exists so that IO() coercers, which coerce to IO::Path, correctly type-check the resultant value. The role is implemented by IO::Path and IO::Special.

See also the related classes IO::Handle and IO::Path.

146 class IO::ArgFiles

Iterate over contents of files specified on command line

class IO::ArgFiles is IO::CatHandle { }

This class exists for backwards compatibility reasons and provides no additional methods to IO::CatHandle, so it can be used in the same way as it, for instance, in this way:

my $argfiles = IO::ArgFiles.new(@*ARGS); 
 .say for $argfiles.lines; 

If invoked with perl6 io-argfiles.p6 *.p6 it will print the contents of all the files with that extension in the directory. However, that is totally equivalent to:

my $argfiles = IO::CatHandle.new(@*ARGS); 
 .say for $argfiles.lines; 

Variables

$*ARGFILES

This class is the magic behind the $*ARGFILES variable, which provides a way to iterate over files passed in to the program on the command line (i.e. elements of @*ARGS). Thus the examples above can be simplified like so:

.say for $*ARGFILES.lines;

# or
while ! $*ARGFILES.eof {
    say $*ARGFILES.get;
}

# or
say $*ARGFILES.slurp;

Save one of the variations above in a file, say argfiles.p6. Then create another file (named, say sonnet18.txt with the contents:

Shall I compare thee to a summer's day? 

Running the command

$ perl6 argfiles.p6 sonnet18.txt 

will then give the output

Shall I compare thee to a summer's day? 

As of 6.d language, $*ARGFILES inside sub MAIN is always set to $*IN, even when @*ARGS is not empty. That means that

sub MAIN () { 
     .say for $*ARGFILES.lines; 
 } 

which can be used as cat *.p6 | perl6 argfiles-main.p6, for instance, is totally equivalent to:

sub MAIN () { 
     .say for $*IN.lines; 
 } 

and, in fact, can't be used to process the arguments in the command line, since, in this case, it would result in an usage error.

Bear in mind that the object $*ARGFILES is going to contain a handle for every argument in a command line, even if that argument is not a valid file. You can retrieve them via the .handles method.

for $*ARGFILES.handles -> $fh { 
     say $fh; 
 } 

That code will fail if any of the arguments is not the valid name of a file. You will have to deal with that case at another level, checking that @*ARGS contains valid file names, for instance.

147 class IO::CatHandle

Use multiple IO handles as if they were one

class IO::CatHandle is IO::Handle { }

This class has been available in Rakudo since version 2017.06.

The IO::CatHandle|/type/IO::CatHandle class provides a means to create an IO::Handle that seamlessly gathers input from multiple IO::Handle and IO::Pipe sources.

All of the IO::Handle's methods are implemented, and while attempt to use write methods will (currently) throw and exception, an IO::CatHandle is usable anywhere a read-only IO::Handle can be used.

Methods

method new

Defined as:

method new(*@handles, :&on-switch, :$chomp = True, 
            :$nl-in = ["\n", "\r\n"], Str :$encoding, Bool :$bin) 

Creates a new IO::CatHandle object.

The @handles positional argument indicates a source of handles for the IO::CatHandle to read from and can deal with a mixed collection of Cool, IO::Path, and IO::Handle (including IO::Pipe) objects. As input from IO::CatHandle is processed (so operations won't happen during .new call, but only when @handles' data is needed), it will walk through the @handles list, processing each argument as follows:

In short, all the @handles end up as IO::Handle objects opened in the same mode and with the same attributes as the invocant IO::CatHandle.

See .on-switch method for details on the :&on-switch named argument, which by default is not set.

The :$encoding named argument specifies the handle's encoding and accepts the same values as IO::Handle.encoding. Set :$bin named argument to True if you wish the handle to be in binary mode. Attempting to specify both a defined :$encoding and a True :$bin is a fatal error resulting in X::IO::BinaryAndEncoding exception thrown. If neither :$encoding is set nor :$bin set to a true value, the handle will default to utf8 encoding.

The :$chomp and :$nl-in arguments have the same meaning as in IO::Handle and take and default to the same values.

method chomp

Defined as:

method chomp(IO::CatHandle:D:) is rw

Sets the invocant's $.chomp attribute to the assigned value. All source handles, including the active one will use the provided $.chomp value.

(my $f1 = 'foo'.IO).spurt: "A\nB\nC\n"; 
 (my $f2 = 'bar'.IO).spurt: "D\nE\n"; 
 with IO::CatHandle.new: $f1, $f2 { 
     # .chomp is True by default: 
     (.get xx 2).perl.say; # OUTPUT: «("A", "B").Seq␤» 
 
     .chomp = False; 
     (.get xx 3).perl.say; # OUTPUT: «("C\n", "D\n", "E\n").Seq␤» 
     .close 
 } 

method nl-in

Defined as:

method nl-in(IO::CatHandle:D:) is rw

Sets the invocant's $.nl-in attribute to the assigned value, which can be a Str or a List of Str, where each Str object represents the end-of-line string. All source handles, including the active one will use the provided $.nl-in value. Note that source handle boundary is always counted as a new line break.

(my $f1 = 'foo'.IO).spurt: "A\nB\nC"; 
 (my $f2 = 'bar'.IO).spurt: "DxEx"; 
 with IO::CatHandle.new: $f1, $f2 { 
     # .nl-in is ["\n", "\r\n"] by default: 
     (.get xx 2).perl.say; # OUTPUT: «("A", "B").Seq␤» 
 
     .nl-in = 'x'; 
     (.get xx 3).perl.say; # OUTPUT: «("C", "D", "E").Seq␤» 
     .close 
 } 

method close

Defined as:

method close(IO::CatHandle:D: --> True)

Closes the currently active source handle, as well as any already-open source handles, and empties the source handle queue. Unlike a regular IO::Handle, an explicit call to .close is often not necessary on a CatHandle, as merely exhausting all the input closes all the handles that need to be closed.

with IO::CatHandle.new: @bunch-of-handles { 
     say .readchars: 42; 
     .close; # we are done; close all the open handles 
 } 

method comb

Defined as:

method comb(IO::CatHandle:D: |args --> Seq:D)

Read the handle and processes its contents the same way Str.comb does, taking the same arguments. Implementations may slurp the contents of all the source handles in their entirety when this method is called.

(my $f1 = 'foo'.IO).spurt: 'foo'; 
 (my $f2 = 'bar'.IO).spurt: 'bar'; 
 IO::CatHandle.new($f1, $f2).comb(2).perl.say; 
 # OUTPUT: «("fo", "ob", "ar").Seq␤» 

method DESTROY

Defined as:

method DESTROY(IO::CatHandle:D:)

Calls .close. This method isn't to be used directly, but is something that's called during garbage collection.

method encoding

Defined as:

multi method encoding(IO::CatHandle:D:)
multi method encoding(IO::CatHandle:D: $new-encoding)

Sets the invocant's $.encoding attribute to the provided value. Valid values are the same as those accepted by IO::Handle.encoding (use value Nil to switch to binary mode). All source handles, including the active one will use the provided $.encoding value.

(my $f1 = 'foo'.IO).spurt: 'I ♥ Perl'; 
 (my $f2 = 'bar'.IO).spurt: 'meow'; 
 with IO::CatHandle.new: $f1, $f2 { 
     # .encoding is 'utf8' by default: 
     .readchars(5).say; # OUTPUT: «I ♥ P␤» 
 
     .encoding: Nil; # switch to binary mode 
     .slurp.say; # OUTPUT: «Buf[uint8]:0x<72 6c 6d 65 6f 77>␤» 
 } 

method eof

Defined as:

method eof(IO::CatHandle:D: --> Bool:D)

Returns True if the read operations have exhausted the source handle queue, including the contents of the last handle. Note: calling this method may cause one or more .on-switch calls, while the source handle queue is examined, and the source handle queue may get exhausted.

(my $f1 = 'foo'.IO).spurt: 'foo'; 
 (my $f2 = 'bar'.IO).spurt: 'bar'; 
 with IO::CatHandle.new: :on-switch{ print 'SWITCH! ' }, $f1, $f2 { 
                    # OUTPUT: «SWITCH! » 
     .eof.say;      # OUTPUT: «False␤» 
     .readchars(3); 
     .eof.say;      # OUTPUT: «SWITCH! False␤» 
 
     .slurp;        # OUTPUT: «SWITCH! » 
     .eof.say;      # OUTPUT: «True␤» 
 } 

The same caveats for non-seekable handles and empty files that apply to IO::Handle.eof apply here.

method get

Defined as:

method get(IO::CatHandle:D: --> Bool:D)

Returns a single line of input from the handle, with the new line string defined by the value(s) of $.nl-in attribute, which will be removed from the line if $.chomp attribute is set to True. Returns Nil when there is no more input. It is an error to call this method when the handle is in binary mode, resulting in X::IO::BinaryMode exception being thrown.

(my $f1 = 'foo'.IO).spurt: "a\nb\nc"; 
 (my $f2 = 'bar'.IO).spurt: "d\ne"; 
 my $cat = IO::CatHandle.new: $f1, $f2; 
 .say while $_ = $cat.get; # OUTPUT: «a␤b␤c␤d␤e␤» 

method getc

Defined as:

method getc(IO::CatHandle:D: --> Bool:D)

Returns a single character of input from the handle. All the caveats described in IO::Handle.getc apply. Returns Nil when there is no more input. It is an error to call this method when the handle is in binary mode, resulting in X::IO::BinaryMode exception being thrown.

(my $f1 = 'foo'.IO).spurt: 'I ♥ Perl'; 
 (my $f2 = 'bar'.IO).spurt: 'meow'; 
 my $cat = IO::CatHandle.new: $f1, $f2; 
 .say while $_ = $cat.getc; # OUTPUT: «I␤ ␤♥␤ ␤P␤e␤r␤l␤m␤e␤o␤w␤» 

method handles

Defines as:

method handles(IO::CatHandle:D: --> Seq:D)

Returns a Seq containing the currently-active handle, as well as all the remaining source handles produced by calling next-handle. If the invocant has already been fully-consumed, returns an empty Seq.

This method is especially handy when working with IO::ArgFiles, where you want to treat each filehandle separately:

# print at most the first 2 lines of each file in $*ARGFILES:
.say for flat $*ARGFILES.handles.map: *.lines: 2

It is acceptable to call this method multiple times; .handles.head is a valid idiom for obtaining the currently-active handle. If, between reification of the elements of the returned Seq the handles get switched by some other means, the next element produced by the Seq would be the next handle of the invocant, not the handle that would've been produced if no switching occurred:

(my $file1 := 'file1'.IO).spurt: "1a\n1b\n1c";
(my $file2 := 'file2'.IO).spurt: "2a\n2b\n2c";
(my $file3 := 'file3'.IO).spurt: "3a\n3b\n3c";
my $cat := IO::CatHandle.new: $file1, $file2, $file3;
for $cat.handles {
    say .lines: 2;
    $cat.next-handle;
}
# OUTPUT: «(1a 1b)␤(3a 3b)␤»

Likewise, reifying the returned Seq consumes the invocant's source handles and once it is fully reified the invocant becomes fully-consumed.

method IO

Defined as:

method IO(IO::CatHandle:D:)

Alias for .path

method lines

Defined as:

method lines(IO::CatHandle:D: $limit = Inf, :$close --> Seq:D)

Same as IO::Handle.lines. Note that a boundary between source handles is considered to be a newline break.

(my $f1 = 'foo'.IO).spurt: "foo\nbar"; 
 (my $f2 = 'bar'.IO).spurt: 'meow'; 
 IO::CatHandle.new($f1, $f2).lines.perl.say; 
 # OUTPUT: «("foo", "bar", "meow").Seq␤» 

Note: if :$close is False, fully-consumed handles are still going to be closed.

method lock

Defined as:

method lock(IO::CatHandle:D: Bool:D :$non-blocking = False, Bool:D :$shared = False --> True)

Same as IO::Handle.lock. Returns Nil if the source handle queue has been exhausted.

Locks only the currently active source handle. The .on-switch Callable can be used to conveniently lock/unlock the handles as they're being processed by the CatHandle.

method native-descriptor

Defined as:

method native-descriptor(IO::CatHandle:D: --> Int:D)

Returns the native-descriptor of the currently active source handle or Nil if the source handle queue has been exhausted.

Since the CatHandle closes a source handle, once it's done with it, it's possible for successive source handles to have the same native descriptor, if they were passed to .new as Cool or IO::Path objects.

(my $f1 = 'foo'.IO).spurt: 'foo'; 
 (my $f2 = 'bar'.IO).spurt: 'bar'; 
 with IO::CatHandle.new: $f1, $f2, $*IN { 
     repeat { .native-descriptor.say } while .next-handle; 
     # OUTPUT: «13␤13␤9␤» 
 } 

method next-handle

Defined as:

method next-handle(IO::CatHandle:D: --> IO::Handle:D)

Switches the active source handle to the next handle in the source handle queue, which is the sources given in @handles attribute to .new. The return value is the currently active source handle or Nil if the source handle queue has been exhausted.

Coerces Cool source "handles" to IO::Path; opens IO::Path and unopened IO::Handle source handles for reading using the invocant's $.nl-in, $.chomp, and $.encoding attributes; those same attributes of already-opened IO::Handle objects will be changed to the values of the invocant's attributes.

This method is called automatically whenever CatHandle's methods require a switch to the next source handle, triggers .on-switch Callable to be called, and is called once during .new call. The .on-switch will continue to be triggered each time this method is called, even after the source handle queue has been exhausted. Note that generally reaching the EOF of the currently active source handle does not trigger the .next-handle call, but rather further read operations that need more data do.

(my $f1 = 'foo'.IO).spurt: "a\nb"; 
 (my $f2 = 'bar'.IO).spurt: "c\nd"; 
 with IO::CatHandle.new: :on-switch{ say '▸ Switching' }, $f1, $f2 { 
     say 'one'; 
     .next-handle.^name.say; 
     say 'two'; 
     .next-handle.^name.say; 
     say 'three'; 
     .next-handle.^name.say; 
     # OUTPUT: 
     # ▸ Switching 
     # one 
     # ▸ Switching 
     # IO::Handle 
     # two 
     # ▸ Switching 
     # Nil 
     # three 
     # ▸ Switching 
     # Nil 
 } 

method on-switch

Defined as:

has &.on-switch is rw

One of the attributes that can be set during .new call and changed later by assigning to. By default is not specified. Takes a Callable with .count of 0, 1, 2, or Inf. Gets called every time .next-handle is, which happens once during .new call and then each time a source handle is switched to the next one in the queue, or when the .next-handle method is called manually.

If the .count of &.on-switch is 0, it receives no arguments; if it's 1, it receives the currently active handle, and if it's 2 or Inf, it receives the currently active handle, and the last active handle as positional arguments (in that order). On the very first &.on-switch execution, the "last active handle" argument is Nil. Upon source handle queue exhaustion the "currently active handle" argument is Nil, and all the executions made afterwards have both arguments as Nil.

(my $f1 = 'foo'.IO).spurt: "A\nB\nC"; 
 (my $f2 = 'bar'.IO).spurt: "D\nE"; 
 
 my $line; 
 my $cat = IO::CatHandle.new: :on-switch{ $line = 1 }, $f1, $f2; 
 say "{$cat.path}:{$line++} $_" for $cat.lines; 
 # OUTPUT: 
 # foo:1 A 
 # foo:2 B 
 # foo:3 C 
 # bar:1 D 
 # bar:2 E 
my @old-stuff; 
 sub on-switch ($new, $old) { 
     $new and $new.seek: 1, SeekFromBeginning; 
     $old and @old-stuff.push: $old.open.slurp: :close; 
 } 
 
 (my $f1 = 'foo'.IO).spurt: "A\nB\nC"; 
 (my $f2 = 'bar'.IO).spurt: "D\nE"; 
 my $cat = IO::CatHandle.new: :&on-switch, $f1, $f2; 
 $cat.lines.perl.say; # OUTPUT: «("", "B", "C", "", "E").Seq␤» 
 @old-stuff.perl.say; # OUTPUT: «["A\nB\nC", "D\nE"]␤» 

method open

Defined as:

method open(IO::CatHandle:D: --> IO::CatHandle:D)

Returns the invocant. The intent of this method is to merely make CatHandle workable with things that open IO::Handle. You never have to call this method intentionally.

method opened

Defined as:

method opened(IO::CatHandle:D: --> Bool:D)

Returns True if the invocant has any source handles, False otherwise.

say IO::CatHandle.new      .opened; # OUTPUT: «False␤» 
 say IO::CatHandle.new($*IN).opened; # OUTPUT: «True␤» 
 
 (my $f1 = 'foo'.IO).spurt: "A\nB\nC"; 
 with IO::CatHandle.new: $f1 { 
     .opened.say; # OUTPUT: «True␤» 
     .slurp; 
     .opened.say; # OUTPUT: «False␤» 
 } 

method path

Defined as:

method path(IO::CatHandle:D:)

Returns the value of .path attribute of the currently active source handle, or Nil if the source handle queue has been exhausted. Basically, if your CatHandle is based on files, this is the way to get the path of the file the CatHandle is currently reading from.

(my $f1 = 'foo'.IO).spurt: "A\nB\nC"; 
 (my $f2 = 'bar'.IO).spurt: "D\nE"; 
 
 my $line; 
 my $cat = IO::CatHandle.new: :on-switch{ $line = 1 }, $f1, $f2; 
 say "{$cat.path}:{$line++} $_" for $cat.lines; 
 # OUTPUT: 
 # foo:1 A 
 # foo:2 B 
 # foo:3 C 
 # bar:1 D 
 # bar:2 E 

method read

Defined as:

method read(IO::CatHandle:D: Int(Cool:D) $bytes = 65536 --> Buf:D)

Reads up to $bytes bytes from the handle and returns them in a Buf. $bytes defaults to an implementation-specific value (in Rakudo, the value of $*DEFAULT-READ-ELEMS, which by default is set to 65536). It is permitted to call this method on handles that are not in binary mode.

(my $f1 = 'foo'.IO).spurt: 'meow'; 
 (my $f2 = 'bar'.IO).spurt: Blob.new: 4, 5, 6; 
 with IO::CatHandle.new: :bin, $f1, $f2 { 
     say .read: 2;    # OUTPUT: «Buf[uint8]:0x<6d 65>␤» 
     say .read: 2000; # OUTPUT: «Buf[uint8]:0x<6f 77 04 05 06>␤» 
 } 
 
 # Non-binary mode is OK too: 
 with IO::CatHandle.new: $f1, $f2 { 
     say .get;        # OUTPUT: «meow␤» 
     say .read: 2000; # OUTPUT: «Buf[uint8]:0x<04 05 06>␤» 
 } 

method readchars

Defined as:

method readchars(IO::CatHandle:D: Int(Cool:D) $chars = 65536 --> Str:D)

Returns a Str of up to $chars characters read from the handle. $chars defaults to an implementation-specific value (in Rakudo, the value of $*DEFAULT-READ-ELEMS, which by default is set to 65536). It is NOT permitted to call this method on handles opened in binary mode and doing so will result in X::IO::BinaryMode exception being thrown.

(my $f1 = 'foo'.IO).spurt: 'Perl loves to'; 
 (my $f2 = 'bar'.IO).spurt: ' meow'; 
 
 with IO::CatHandle.new: $f1, $f2 { 
     say .readchars: 11;   # OUTPUT: «Perl loves ␤» 
     say .readchars: 1000; # OUTPUT: «to meow␤» 
 } 

method seek

Defined as:

method seek(IO::CatHandle:D: |c)

Calls .seek on the currently active source handle, forwarding it all the arguments, and returns the result. Returns Nil if the source handle queue has been exhausted. NOTE: this method does NOT perform any source handle switching, so seeking past the end of the current source handle will NOT seek to the next source handle in the queue and seeking past the beginning of the current source handle is a fatal error. Also see .next-handle, to learn the details on when source handles are switched.

(my $f1 = 'foo'.IO).spurt: 'foo'; 
 (my $f2 = 'bar'.IO).spurt: 'bar'; 
 
 with IO::CatHandle.new: $f1, $f2 { 
     .get.say;                     # OUTPUT: «foo␤» 
     .seek: -2, SeekFromCurrent; 
     .readchars(2).say;            # OUTPUT: «oo␤» 
     .seek: 1000, SeekFromCurrent; # this doesn't switch to second handle! 
     .readchars(3).say;            # OUTPUT: «bar␤» 
     try .seek: -4;                # this won't seek to previous handle! 
     say ~$!;                      # OUTPUT: «Failed to seek in filehandle: 22␤» 
 } 

method tell

Defined as:

method tell(IO::CatHandle:D: --> Int:D)

Calls .tell on the currently active source handle and returns the result. Returns Nil if the source handle queue has been exhausted.

(my $f1 = 'foo'.IO).spurt: 'foo'; 
 (my $f2 = 'bar'.IO).spurt: 'bar'; 
 
 with IO::CatHandle.new: $f1, $f2 { 
     .get.say;                   # OUTPUT: «foo␤» 
     .tell.say;                  # OUTPUT: «3␤» 
     .seek: -2, SeekFromCurrent; 
     .tell.say;                  # OUTPUT: «1␤» 
     say .readchars: 3;          # OUTPUT: «oob␤» 
     .tell.say;                  # OUTPUT: «2␤» 
     } 

method slurp

Defined as:

method slurp(IO::CatHandle:D:)

Reads all of the available input from all the source handles and returns it as a Buf if the handle is in binary mode or as a Str otherwise. Returns Nil if the source handle queue has been exhausted.

(my $f1 = 'foo'.IO).spurt: 'foo'; 
 (my $f2 = 'bar'.IO).spurt: 'bar'; 
 
 IO::CatHandle.new(      $f1, $f2).slurp.say; # OUTPUT: «foobar␤» 
 IO::CatHandle.new(:bin, $f1, $f2).slurp.say; # OUTPUT: «Buf[uint8]:0x<66 6f 6f 62 61 72>␤» 
 IO::CatHandle.new                .slurp.say; # OUTPUT: «Nil␤» 

method split

Defined as:

method split(IO::CatHandle:D: |args --> Seq:D)

Read the handle and processes its contents the same way Str.split does, taking the same arguments. Implementations may slurp the contents of all the source handles in their entirety when this method is called.

(my $f1 = 'foo'.IO).spurt: 'foo'; 
 (my $f2 = 'bar'.IO).spurt: 'bar'; 
 IO::CatHandle.new($f1, $f2).split(/o+/).perl.say; 
 # OUTPUT: «("f", "bar").Seq␤» 

method Str

Defined as:

method Str(IO::CatHandle:D: --> Str:D)

Calls .Str on the currently active source handle and returns the result. If the source handle queue has been exhausted, returns an implementation-defined string ('<closed IO::CatHandle>' in Rakudo).

method Supply

Defined as:

method Supply(IO::CatHandle:D: :$size = 65536 --> Supply:D)

Returns a Supply fed with either .read, if the handle is in binary mode, or with .readchars, if it isn't, with reads of :$size bytes or characters. :$size defaults to an implementation-specific value (in Rakudo, the value of $*DEFAULT-READ-ELEMS, which by default is set to 65536).

(my $f1 = 'foo'.IO).spurt: 'foo'; 
 (my $f2 = 'bar'.IO).spurt: 'bar'; 
 react whenever IO::CatHandle.new($f1, $f2).Supply: :2size {.say} 
 # OUTPUT: «fo␤ob␤ar␤» 
 
 react whenever IO::CatHandle.new(:bin, $f1, $f2).Supply: :2size {.say} 
 # OUTPUT: «Buf[uint8]:0x<66 6f>␤Buf[uint8]:0x<6f 62>␤Buf[uint8]:0x<61 72>␤» 

method t

Defined as:

method t(IO::CatHandle:D: --> Bool:D)

Calls .t, which tells if the handle is a TTY, on the currently active source handle and returns the result. If the source handle queue has been exhausted, returns False.

(my $f1 = 'foo'.IO).spurt: 'foo'; 
 with IO::CatHandle.new: $f1, $*IN { 
     repeat { .t.say } while .next-handle; # OUTPUT: «False␤True␤» 
 } 

method unlock

Defined as:

method unlock(IO::CatHandle:D:)

Same as IO::Handle.unlock. Returns Nil if the source handle queue has been exhausted.

Unlocks only the currently active source handle. The .on-switch Callable can be used to conveniently lock/unlock the handles as they're being processed by the CatHandle.

method words

Defined as:

method words(IO::CatHandle:D: $limit = Inf, :$close --> Seq:D)

Same as IO::Handle.words (including the caveat about more data read than needed to make some number of words). Note that a boundary between source handles is considered to be word boundary.

(my $f1 = 'foo'.IO).spurt: 'foo bar'; 
 (my $f2 = 'bar'.IO).spurt: 'meow'; 
 IO::CatHandle.new($f1, $f2).words.perl.say; 
 # OUTPUT: «("foo", "bar", "meow").Seq␤» 

Note: if :$close is False, fully-consumed handles are still going to be closed.

NYI Methods

The IO::CatHandle type overrides these methods to throw a X::NYI exception.

method flush

Defined as:

multi method flush(|)

The IO::CatHandle type overrides this method to throw a X::NYI exception. If you have a good idea for how this method should behave, tell Rakudo developers about it!

method nl-out

Defined as:

multi method nl-out(|)

The IO::CatHandle type overrides this method to throw a X::NYI exception. If you have a good idea for how this method should behave, tell Rakudo developers about it!

method out-buffer

Defined as:

multi method out-buffer(|)

The IO::CatHandle type overrides this method to throw a X::NYI exception. If you have a good idea for how this method should behave, tell Rakudo developers about it!

method print

Defined as:

multi method print(|)

The IO::CatHandle type overrides this method to throw a X::NYI exception. If you have a good idea for how this method should behave, tell Rakudo developers about it!

method printf

Defined as:

multi method printf(|)

The IO::CatHandle type overrides this method to throw a X::NYI exception. If you have a good idea for how this method should behave, tell Rakudo developers about it!

method print-nl

Defined as:

multi method print-nl(|)

The IO::CatHandle type overrides this method to throw a X::NYI exception. If you have a good idea for how this method should behave, tell Rakudo developers about it!

method put

Defined as:

multi method put(|)

The IO::CatHandle type overrides this method to throw a X::NYI exception. If you have a good idea for how this method should behave, tell Rakudo developers about it!

method say

Defined as:

multi method say(|)

The IO::CatHandle type overrides this method to throw a X::NYI exception. If you have a good idea for how this method should behave, tell Rakudo developers about it!

method write

Defined as:

multi method write(|)

The IO::CatHandle type overrides this method to throw a X::NYI exception. If you have a good idea for how this method should behave, tell Rakudo developers about it!

method WRITE

Defined as:

multi method WRITE(|)

The IO::CatHandle type overrides this method to throw a X::NYI exception. If you have a good idea for how this method should behave, tell Rakudo developers about it!

method READ

Defined as:

multi method EOF(|)

The IO::CatHandle type overrides this method to throw a X::NYI exception. If you have a good idea for how this method should behave, tell Rakudo developers about it!

method EOF

Defined as:

multi method EOF(|)

The IO::CatHandle type overrides this method to throw a X::NYI exception. If you have a good idea for how this method should behave, tell Rakudo developers about it!

148 class IO::Handle

Opened file or stream

class IO::Handle { }

Instances of IO::Handle encapsulate an handle to manipulate input/output resources. Usually there is no need to create directly an IO::Handle instance, since it will be done by other roles and methods. For instance, an IO::Path object provides an open method that returns an IO::Handle:

my $fh = '/tmp/log.txt'.IO.open;
say $fh.^name; # OUTPUT: IO::Handle

The first line is pretty much equivalent to the following piece of code:

my $fh = IO::Handle.new( :path( '/tmp/log.txt'.IO.path ) ).open;

Methods

method open

Defined as:

method open(IO::Handle:D: 
     :$bin, :$enc, :$chomp, :$nl-in, Str:D :$nl-out, 
     Str :$mode, 
     :$r, :$w, :$a, :$x, :$update, :$rw, :$rx, :$ra, 
     :$create, :$append, :$truncate, :$exclusive, 
     :$out-buffer, 
     --> IO::Handle:D 
 ) 

Opens the handle in one of the modes. Fails with appropriate exception if the open fails.

See description of individual methods for the accepted values and behavior of :$chomp, :$nl-in, :$nl-out, and :$enc. The values for parameters default to the invocant's attributes and if any of them are provided, the attributes will be updated to the new values. Specify :$bin set to True instead of :$enc to indicate the handle should be opened in binary mode. Specifying undefined value as :$enc is equivalent to not specifying :$enc at all. Specifying both a defined encoding as :$enc and :$bin set to true will cause X::IO::BinaryAndEncoding exception to be thrown.

The open mode defaults to non-exclusive, read only (same as specifying :r) and can be controlled by a mix of the following arguments:

:r      same as specifying   :mode<ro>  same as specifying nothing 
 
 :w      same as specifying   :mode<wo>, :create, :truncate 
 :a      same as specifying   :mode<wo>, :create, :append 
 :x      same as specifying   :mode<wo>, :create, :exclusive 
 
 :update same as specifying   :mode<rw> 
 :rw     same as specifying   :mode<rw>, :create 
 :ra     same as specifying   :mode<rw>, :create, :append 
 :rx     same as specifying   :mode<rw>, :create, :exclusive 

Support for combinations of modes other than what is listed above is implementation-dependent and should be assumed unsupported. That is, specifying, for example, .open(:r :create) or .open(:mode<wo> :append :truncate) might work or might cause the Universe to implode, depending on a particular implementation. This applies to reads/writes to a handle opened in such unsupported modes as well.

The mode details are:

:mode<ro>  means "read only" 
 :mode<wo>  means "write only" 
 :mode<rw>  means "read and write" 
 
 :create    means the file will be created, if it does not exist 
 :truncate  means the file will be emptied, if it exists 
 :exclusive means .open will fail if the file already exists 
 :append    means writes will be done at the end of file's current contents 

Attempts to open a directory, write to a handle opened in read-only mode or read from a handle opened in write-only mode, or using text-reading methods on a handle opened in binary mode will fail or throw.

In 6.c language, it's possible to open path '-', which will cause open to open (if closed) the $*IN handle if opening in read-only mode or to open the $*OUT handle if opening in write-only mode. All other modes in this case will result in exception being thrown.

As of 6.d language version, use path '-' is deprecated and it will be removed in future language versions entirely.

The :out-buffer controls output buffering and by default behaves as if it were Nil. See method out-buffer for details.

Note (Rakudo versions before 2017.09): Filehandles are NOT flushed or closed when they go out of scope. While they will get closed when garbage collected, garbage collection isn't guaranteed to get run. This means you should use an explicit close on handles opened for writing, to avoid data loss, and an explicit close is recommended on handles opened for reading as well, so that your program does not open too many files at the same time, triggering exceptions on further open calls.

Note (Rakudo versions 2017.09 and after): Open filehandles are automatically closed on program exit, but it is still highly recommended that you close opened handles explicitly.

method comb

Defined as:

method comb(IO::Handle:D: Bool :$close, |args --> Seq:D)

Read the handle and processes its contents the same way Str.comb does, taking the same arguments, closing the handle when done if $close is set to a true value. Implementations may slurp the file in its entirety when this method is called.

Attempting to call this method when the handle is in binary mode will result in X::IO::BinaryMode exception being thrown.

my $fh = 'path/to/file'.IO.open; 
 say "The file has {+$fh.comb: '♥', :close} ♥s in it"; 

method chomp

Defined as:

has $.chomp is rw = True

One of the attributes that can be set via .new or open. Defaults to True. Takes a Bool specifying whether the line separators (as defined by .nl-in) should be removed from content when using .get or .lines methods.

routine get

Defined as:

method get(IO::Handle:D: --> Str:D)
multi sub get (IO::Handle $fh = $*ARGFILES --> Str:D)

Reads a single line of input from the handle, removing the trailing newline characters (as set by .nl-in) if the handle's .chomp attribute is set to True. Returns Nil, if no more input is available. The subroutine form defaults to $*ARGFILES if no handle is given.

Attempting to call this method when the handle is in binary mode will result in X::IO::BinaryMode exception being thrown.

$*IN.get.say;              # Read one line from the standard input 
 
 my $fh = open 'filename'; 
 $fh.get.say;               # Read one line from a file 
 $fh.close; 
 
 say get;                   # Read one line from $*ARGFILES 

routine getc

Defined as:

method getc(IO::Handle:D: --> Str:D)
multi sub getc (IO::Handle $fh = $*ARGFILES --> Str:D)

Reads a single character from the input stream. Attempting to call this method when the handle is in binary mode will result in X::IO::BinaryMode exception being thrown. The subroutine form defaults to $*ARGFILES if no handle is given. Returns Nil, if no more input is available, otherwise operation will block, waiting for at least one character to be available; these caveats apply:

Buffering terminals

Using getc to get a single keypress from a terminal will only work properly if you've set the terminal to "unbuffered". Otherwise the terminal will wait for the return key to be struck or the buffer to be filled up before perl6 gets even a single byte of data.

Waiting for potential combiners

If your handle's encoding allows combining characters to be read, perl6 will wait for more data to be available before it provides a character. This means that inputting an "e" followed by a combining acute will give you an e with an acute rather than giving an "e" and letting the next reading function give you a dangling combiner. However, it also means that when the user inputs just an "e" and has no intention to also input a combining acute, your program will be waiting for another keypress before the initial "e" is returned.

submethod DESTROY

Defined as:

submethod DESTROY(IO::Handle:D:)

Closes the filehandle, unless its native-descriptor is 2 or lower. This ensures the standard filehandles do not get inadvertently closed.

Note that garbage collection is not guaranteed to happen, so you must NOT rely on DESTROY for closing the handles you write to and instead close them yourself. Programs that open a lot of files should close the handles explicitly as well, regardless of whether they were open for writing, since too many files might get opened before garbage collection happens and the no longer used handles get closed.

method gist

Defined as:

method gist(IO::Handle:D: --> Str:D)

Returns a string containing information which .path, if any, the handle is created for and whether it is .opened.

say IO::Handle.new; # IO::Handle<(Any)>(closed) 
 say "foo".IO.open;  # IO::Handle<"foo".IO>(opened) 

method eof

Defined as:

method eof(IO::Handle:D: --> Bool:D)

Non-blocking. Returns True if the read operations have exhausted the contents of the handle. For seekable handles, this means current position is at or beyond the end of file and seeking an exhausted handle back into the file's contents will result in eof returning False again.

On non-seekable handles and handles opened to zero-size files (including special files in /proc/), EOF won't be set until a read operation fails to read any bytes. For example, in this code, the first read consumes all of the data, but it's only until the second read that reads nothing would the EOF on a TTY handle be set:

$ echo "x" | perl6 -e 'with $*IN { .read: 10000; .eof.say; .read: 10; .eof.say }' 
 False 
 True 

method encoding

Defined as:

multi method encoding(IO::Handle:D: --> Str:D)
multi method encoding(IO::Handle:D: $enc --> Str:D)

Returns a Str representing the encoding currently used by the handle, defaulting to "utf8". Nil indicates the filehandle is currently in binary mode. Specifying an optional positional $enc argument switches the encoding used by the handle; specify Nil as encoding to put the handle into binary mode.

The accepted values for encoding are case-insensitive. The available encodings vary by implementation and backend. On Rakudo MoarVM the following are supported:

utf8 
 utf16 
 utf16le 
 utf16be 
 utf8-c8 
 iso-8859-1 
 windows-1251 
 windows-1252 
 windows-932 
 ascii 

The default encoding is utf8, which undergoes normalization into Unicode NFC (normalization form canonical). In some cases you may want to ensure no normalization is done; for this you can use utf8-c8. Before using utf8-c8 please read Unicode: Filehandles and I/O for more information on utf8-c8 and NFC.

As of Rakudo 2018.04 windows-932 is also supported which is a variant of ShiftJIS.

Implementation may choose to also provide support for aliases, e.g. Rakudo allows aliases latin-1 for iso-8859-1 encoding and dashed utf versions: utf-8 and utf-16.

utf16, utf16le and utf16be

Unlike utf8, utf16 has an endianness — either big endian or little endian. This relates to the ordering of bytes. Computer CPUs also have an endianness. Perl 6's utf16 format specifier will use the endianness of host system when encoding. When decoding it will look for a byte order mark and if it is there use that to set the endianness. If there is no byte order mark it will assume the file uses the same endianness as the host system. A byte order mark is the codepoint U+FEFF which is ZERO WIDTH NO-BREAK SPACE. On utf16 encoded files the standard states if it exists at the start of a file it shall be interpreted as a byte order mark, not a U+FEFF codepoint.

While writing will cause a different file to be written on different endian systems, at the release of 2018.10 the byte order mark will be written out when writing a file and files created with the utf16 encoding will be able to be read on either big or little endian systems.

When using utf16be or utf16le encodings a byte order mark is not used. The endianness used is not affected by the host cpu type and is either big endian for utf16be or little endian for utf16le.

In keeping with the standard, a 0xFEFF byte at the start of a file is interpreted as a ZERO WIDTH NO-BREAK SPACE and not as a byte order mark. No byte order mark is written to files that use the utf16be or utf16le encodings.

As of Rakudo 2018.09 on MoarVM, utf16, utf16le and utf16be are supported. In 2018.10, writing to a file with utf16 will properly add a byte order mark (BOM).

Examples

with 'foo'.IO { 
     .spurt: "First line is text, then:\nBinary"; 
     my $fh will leave {.close} = .open; 
     $fh.get.say;         # OUTPUT: «First line is text, then:␤» 
     $fh.encoding: Nil; 
     $fh.slurp.say;       # OUTPUT: «Buf[uint8]:0x<42 69 6e 61 72 79>␤» 
 } 

routine lines

Defined as:

sub lines(IO::Handle:D $fh = $*ARGFILES, $limit = Inf, :$close --> Seq:D)
method lines(IO::Handle:D:               $limit = Inf, :$close --> Seq:D)

Return a Seq each element of which is a line from the handle (that is chunks delineated by .nl-in). If the handle's .chomp attribute is set to True, then characters specified by .nl-in will be stripped from each line.

Reads up to $limit lines, where $limit can be a non-negative Int, Inf, or Whatever (which is interpreted to mean Inf). If :$close is set to True, will close the handle when the file ends or $limit is reached. Subroutine form defaults to $*ARGFILES, if no handle is provided.

Attempting to call this method when the handle is in binary mode will result in X::IO::BinaryMode exception being thrown.

NOTE: the lines are read lazily, so ensure the returned Seq is either fully reified or is no longer needed when you close the handle or attempt to use any other method that changes the file position.

say "The file contains ", 
   '50GB-file'.IO.open.lines.grep(*.contains: 'Perl').elems, 
   " lines that mention Perl"; 
 # OUTPUT: «The file contains 72 lines that mention Perl␤» 

method lock

Defined as:

method lock(IO::Handle:D: Bool:D :$non-blocking = False, Bool:D :$shared = False --> True)

Places an advisory lock on the filehandle. If :$non-blocking is True will fail with X::IO::Lock if lock could not be obtained, otherwise will block until the lock can be placed. If :$shared is True will place a shared (read) lock, otherwise will place an exclusive (write) lock. On success, returns True; fails with X::IO::Lock if lock cannot be placed (e.g. when trying to place a shared lock on a filehandle opened in write mode or trying to place an exclusive lock on a filehandle opened in read mode).

You can use lock again to replace an existing lock with another one. To remove a lock, close the filehandle or use unlock.

# One program writes, the other reads, and thanks to locks either 
 # will wait for the other to finish before proceeding to read/write 
 
 # Writer 
 given "foo".IO.open(:w) { 
     .lock; 
     .spurt: "I ♥ Perl 6!"; 
     .close; # closing the handle unlocks it; we could also use `unlock` method for that 
 } 
 
 # Reader 
 given "foo".IO.open { 
     .lock: :shared; 
     .slurp.say; # OUTPUT: «I ♥ Perl 6!␤» 
     .close; 
 } 

method unlock

Defined as:

method unlock(IO::Handle:D: --> True)

Removes a lock from the filehandle.

routine words

Defined as:

multi sub words(IO::Handle:D $fh = $*ARGFILES, $limit = Inf, :$close --> Seq:D)
multi method words(IO::Handle:D: $limit = Inf, :$close --> Seq:D)

Similar to Str.words, separates the handle's stream on contiguous chunks of whitespace (as defined by Unicode) and returns a Seq of the resultant "words." Takes an optional $limit argument that can be a non-negative Int, Inf, or Whatever (which is interpreted to mean Inf), to indicate only up-to $limit words must be returned. If Bool :$close named argument is set to True, will automatically close the handle when the returned Seq is exhausted. Subroutine form defaults to $*ARGFILES, if no handle is provided.

Attempting to call this method when the handle is in binary mode will result in X::IO::BinaryMode exception being thrown.

my %dict := bag $*IN.words; 
 say "Most common words: ", %dict.sort(-*.value).head: 5; 

NOTE: implementations may read more data than necessary when a call to .words is made. That is, $handle.words(2) may read more data than two "words" worth of data and subsequent calls to read methods might not read from the place right after the two fetched words. After a call to .words, the file position should be treated as undefined.

method split

Defined as:

method split(IO::Handle:D: :$close, |c)

Slurps the handle's content and calls Str.split on it, forwarding any of the given arguments. If :$close named parameter is set to True, will close the invocant after slurping.

Attempting to call this method when the handle is in binary mode will result in X::IO::BinaryMode exception being thrown.

my $fh = 'path/to/file'.IO.open; 
 $fh.split: '♥', :close; # Returns file content split on ♥ 

method spurt

Defined as:

multi method spurt(IO::Handle:D: Blob $data, :$close = False)
multi method spurt(IO::Handle:D: Cool $data, :$close = False)

Writes all of the $data into the filehandle, closing it when finished, if $close is True. For Cool $data, will use the encoding the handle is set to use (IO::Handle.open or IO::Handle.encoding).

Behavior for spurting a Cool when the handle is in binary mode or spurting a Blob when the handle is NOT in binary mode is undefined.

method print

Defined as:

multi method print(**@text --> True)
multi method print(Junction:D --> True)

Writes the given @text to the handle, coercing any non-Str objects to Str by calling .Str method on them. Junction arguments autothread and the order of printed strings is not guaranteed. See write to write bytes.

Attempting to call this method when the handle is in binary mode will result in X::IO::BinaryMode exception being thrown.

my $fh = 'path/to/file'.IO.open: :w; 
 $fh.print: 'some text'; 
 $fh.close; 

method print-nl

Defined as:

method print-nl(IO::Handle:D: --> True)

Writes the value of $.nl-out attribute into the handle. This attribute, by default, is , but see the page on newline for the rules it follows in different platforms and environments.

Attempting to call this method when the handle is in binary mode will result in X::IO::BinaryMode exception being thrown.

my $fh = 'path/to/file'.IO.open: :w, :nl-out("\r\n"); 
 $fh.print: "some text"; 
 $fh.print-nl; # prints \r\n 
 $fh.close; 

method printf

Defined as:

multi method printf(IO::Handle:D: Cool $format, *@args)

Formats a string based on the given format and arguments and .prints the result into the filehandle. See sub sprintf for details on acceptable format directives.

Attempting to call this method when the handle is in binary mode will result in X::IO::BinaryMode exception being thrown.

my $fh = open 'path/to/file', :w; 
 $fh.printf: "The value is %d\n", 32; 
 $fh.close; 

method out-buffer

Defined as:

method out-buffer(--> Int:D) is rw

Controls output buffering and can be set via an argument to open. Takes an int as the size of the buffer to use (zero is acceptable). Can take a Bool: True means to use default, implementation-defined buffer size; False means to disable buffering (equivalent to using 0 as buffer size).

Lastly, can take a Nil to enable TTY-based buffering control: if the handle is a TTY, the buffering is disabled, otherwise, default, implementation-defined buffer size is used.

See flush to write out data currently in the buffer. Changing buffer size flushes the filehandle.

given 'foo'.IO.open: :w, :1000out-buffer { 
     .say: 'Hello world!'; # buffered 
     .out-buffer = 42;       # buffer resized; previous print flushed 
     .say: 'And goodbye'; 
     .close; # closing the handle flushes the buffer 
 } 

method put

Defined as:

multi method put(**@text --> True)
multi method put(Junction:D --> True)

Writes the given @text to the handle, coercing any non-Str objects to Str by calling .Str method on them, and appending the value of .nl-out at the end. Junction arguments autothread and the order of printed strings is not guaranteed.

Attempting to call this method when the handle is in binary mode will result in X::IO::BinaryMode exception being thrown.

my $fh = 'path/to/file'.IO.open: :w; 
 $fh.put: 'some text'; 
 $fh.close; 

method say

Defined as:

multi method say(IO::Handle:D: **@text --> True)

This method is identical to put except that it stringifies its arguments by calling .gist instead of .Str.

Attempting to call this method when the handle is in binary mode will result in X::IO::BinaryMode exception being thrown.

my $fh = open 'path/to/file', :w; 
 $fh.say(Complex.new(3, 4));        # RESULT: «3+4i\n» 
 $fh.close; 

method read

Defined as:

method read(IO::Handle:D: Int(Cool:D) $bytes = 65536 --> Buf:D)

Binary reading; reads and returns up to $bytes bytes from the filehandle. $bytes defaults to an implementation-specific value (in Rakudo, the value of $*DEFAULT-READ-ELEMS, which by default is set to 65536). This method can be called even when the handle is not in binary mode.

(my $file = 'foo'.IO).spurt: 'I ♥ Perl'; 
 given $file.open { 
     say .read: 6; # OUTPUT: «Buf[uint8]:0x<49 20 e2 99 a5 20>␤» 
     .close; 
 } 

method readchars

Defined as:

method readchars(IO::Handle:D: Int(Cool:D) $chars = 65536 --> Str:D)

Reading chars; reads and returns up to $chars chars (graphemes) from the filehandle. $chars defaults to an implementation-specific value (in Rakudo, the value of $*DEFAULT-READ-ELEMS, which by default is set to 65536). Attempting to call this method when the handle is in binary mode will result in X::IO::BinaryMode exception being thrown.

(my $file = 'foo'.IO).spurt: 'I ♥ Perl'; 
 given $file.open { 
     say .readchars: 5; # OUTPUT: «I ♥ P␤» 
     .close; 
 } 

method write

Defined as:

method write(IO::Handle:D: Blob:D $buf --> True)

Writes $buf to the filehandle. This method can be called even when the handle is not in binary mode.

method seek

Defined as:

method seek(IO::Handle:D: Int:D $offset, SeekType:D $whence --> True)

Move the file pointer (that is, the position at which any subsequent read or write operations will begin) to the byte position specified by $offset relative to the location specified by $whence which may be one of:

method tell

Defined as:

method tell(IO::Handle:D: --> Int:D)

Return the current position of the file pointer in bytes.

method slurp-rest

Defined as:

multi method slurp-rest(IO::Handle:D: :$bin! --> Buf)
multi method slurp-rest(IO::Handle:D: :$enc --> Str)

DEPRECATION NOTICE: this method is deprecated in the 6.d version. Do not use it for new code, use .slurp method instead.

Returns the remaining content of the file from the current file position (which may have been set by previous reads or by seek.) If the adverb :bin is provided a Buf will be returned; otherwise the return will be a Str with the optional encoding :enc.

method slurp

Defined as:

method slurp(IO::Handle:D: :$close, :$bin)

Returns all the content from the current file pointer to the end. If the invocant is in binary mode or if $bin is set to True, will return a Buf, otherwise will decode the content using invocant's current .encoding and return a Str.

If :$close is set to True, will close the handle when finished reading.

Note: On Rakudo this method was introduced with release 2017.04; $bin arg was added in 2017.10.

method Supply

Defined as:

multi method Supply(IO::Handle:D: :$size = 65536)

Returns a Supply that will emit the contents of the handle in chunks. The chunks will be Buf if the handle is in binary mode or, if it isn't, Str decoded using same encoding as IO::Handle.encoding.

The size of the chunks is determined by the optional :size named parameter and 65536 bytes in binary mode or 65536 characters in non-binary mode.

"foo".IO.open(:bin).Supply(:size<10>).tap: *.perl.say; 
 # OUTPUT: 
 # Buf[uint8].new(73,32,226,153,165,32,80,101,114,108) 
 # Buf[uint8].new(32,54,33,10) 
 
 "foo".IO.open.Supply(:size<10>).tap: *.perl.say; 
 # OUTPUT: 
 # "I ♥ Perl" 
 # " 6!\n" 

method path

Defined as:

method path(IO::Handle:D:)

For a handle opened on a file this returns the IO::Path that represents the file. For the standard I/O handles $*IN, $*OUT, and $*ERR it returns an IO::Special object.

method IO

Defined as:

method IO(IO::Handle:D:)

Alias for .path

method Str

Returns the value of .path, coerced to Str.

say "foo".IO.open.path; # OUTPUT: «"foo".IO␤» 

routine close

Defined as:

method close(IO::Handle:D: --> Bool:D)
multi sub close(IO::Handle $fh)

Closes an open filehandle. It's not an error to call close on an already-closed filehandle. Returns True on success. If you close one of the standard filehandles (by default: $*IN, $*OUT, or $*ERR), that is any handle with native-descriptor 2 or lower, you won't be able to re-open such a handle.

It's a common idiom to use LEAVE phaser for closing the handles, which ensures the handle is closed regardless of how the block is left.

if $do-stuff-with-the-file { 
     my $fh = open "path-to-file"; 
     LEAVE close $fh; 
     # ... do stuff with the file 
 } 
 
 sub do-stuff-with-the-file (IO $path-to-file) 
   my $fh = $path-to-file.open; 
 
   # stick a `try` on it, since this will get run even when the sub is 
   # called with wrong arguments, in which case the `$fh` will be an `Any` 
   LEAVE try close $fh; 
 
   # ... do stuff with the file 
 } 
 
 given "foo/bar".IO.open(:w) { 
     .spurt: "I ♥ Perl 6!"; 
     .close; 
 } 

Note: unlike some other languages, Perl 6 does not use reference counting, and so the filehandles are NOT closed when they go out of scope. While they will get closed when garbage collected, garbage collection isn't guaranteed to get run. This means you must use an explicit close on handles opened for writing, to avoid data loss, and an explicit close is recommended on handles opened for reading as well, so that your program does not open too many files at the same time, triggering exceptions on further open calls.

Note several methods allow for providing :close argument, to close the handle after the operation invoked by the method completes. As a simpler alternative, the IO::Path type provides many reading and writing methods that let you work with files without dealing with filehandles directly.

method flush

Defined as:

method flush(IO::Handle:D: --> True)

Will flush the handle, writing any of the buffered data. Returns True on success; otherwise, fails with X::IO::Flush.

given "foo".IO.open: :w { 
     LEAVE .close; 
     .print: 'something'; 
     'foo'.IO.slurp.say; # (if the data got buffered) OUTPUT: «␤» 
     .flush;             # flush the handle 
     'foo'.IO.slurp.say; # OUTPUT: «something␤» 
 } 

method native-descriptor

Defined as:

method native-descriptor()

This returns a value that the operating system would understand as a "file descriptor" and is suitable for passing to a native function that requires a file descriptor as an argument such as fcntl or ioctl.

method nl-in

Defined as:

method nl-in(--> Str:D) is rw

One of the attributes that can be set via .new or open. Defaults to ["\x0A", "\r\n"]. Takes either a Str or Array of Str specifying input line ending(s) for this handle. If .chomp attribute is set to True, will strip these endings in routines that chomp, such as get and lines.

with 'test'.IO { 
     .spurt: '1foo2bar3foo'; # write some data into our test file 
     my $fh will leave {.close} = .open; # can also set .nl-in via .open arg 
     $fh.nl-in = [<foo bar>]; # set two possible line endings to use; 
     $fh.lines.say; # OUTPUT: ("1", "2", "3").Seq 
 } 

method nl-out

Defined as:

has Str:D $.nl-out is rw = "\n";

One of the attributes that can be set via .new or open. Defaults to "\n". Takes a Str specifying output line ending for this handle, to be used by methods .put and .say.

with 'test'.IO { 
     given .open: :w { 
         .put: 42; 
         .nl-out = 'foo'; 
         .put: 42; 
         .close; 
     } 
     .slurp.perl.say; # OUTPUT: «"42\n42foo"» 
 } 

method opened

Defined as:

method opened(IO::Handle:D: --> Bool:D)

Returns True if the handle is open, False otherwise.

method t

Defined as:

method t(IO::Handle:D: --> Bool:D)

Returns True if the handle is opened to a TTY, False otherwise.

Creating Custom Handles

As of 6.d language (early implementation available in Rakudo compiler version 2018.08), a few helper methods are available to simplify creation of custom IO::Handle objects. In your subclass you simply need to implement those methods to affect all of the related features. If your handle wants to work with textual read/write methods and doesn't use the standard .open method, be sure to call .encoding method in your custom handle to get decoder/encoder properly set up:

class IO::URL is IO::Handle { 
     has $.URL is required; 
     has Buf $!content; 
     submethod TWEAK { 
         use WWW; # ecosystem module that will let us `get` a web page 
         use DOM::Tiny; # ecosystem module that will parse out all text from HTML 
         $!content := Buf.new: DOM::Tiny.parse(get $!URL).all-text(:trim).encode; 
         self.encoding: 'utf8'; # set up encoder/decoder 
     } 
 
     method open(|)  { self }       # block out some IO::Handle methods 
     method close(|) { self }       # that work with normal low-level file 
     method opened   { ! self.EOF } # handles, since we don't. This isn't 
     method lock(| --> True) { }    # necessary, but will make our handle 
     method unlock( --> True) { }   # be more well-behaved if someone 
     # actually calls one of these methods. There are more of these you 
     # can handle, such as .tell, .seek, .flush, .native-descriptor, etc. 
 
     method WRITE(|) { 
         # For this handle we'll just die on write. If yours can handle writes. 
         # The data to write will be given as a Blob positional argument. 
         die "Cannot write into IO::URL"; 
     } 
     method READ(\bytes) { 
         # We splice off the requested number of bytes from the head of 
         # our content Buf. The handle's decoder will handle decoding them 
         # automatically, if textual read methods were called on the handle. 
         $!content.splice: 0, bytes 
     } 
     method EOF { 
         # For "end of file", we'll simply report whether we still have 
         # any bytes of the website we fetched on creation. 
         not $!content 
     } 
 } 
 
 my $fh := IO::URL.new: :URL<www.perl6.org>; 
 
 # .slurp and print all the content from the website. We can use all other 
 # read methods, such as .lines, or .get, or .readchars. All of them work 
 # correctly, even though we only defined .READ and .EOF 
 $fh.slurp.say; 

method WRITE

Defined as:

method WRITE(IO::Handle:D: Blob:D \data --> Bool:D)

Called whenever a write operation is performed on the handle. Always receives the data as a Blob, even if a textual writing method has been called.

class IO::Store is IO::Handle { 
     has @.lines = []; 
 
     submethod TWEAK { 
         self.encoding: 'utf8'; # set up encoder/decoder 
     } 
 
     method WRITE(IO::Handle:D: Blob:D \data --> Bool:D) { 
         @!lines.push: data.decode(); 
         True; 
     } 
 
     method gist() { 
         return @!lines.join("\n" ); 
     } 
 } 
 my $store = IO::Store.new(); 
 my $output = $PROCESS::OUT; 
 $PROCESS::OUT = $store; 
 .say for <one two three>; 
 $PROCESS::OUT = $output; 
 say $store.lines(); # OUTPUT «[one␤ two␤ three␤]» 

In this example we are creating a simple WRITE redirection which stores anything written to the filehandle to an array. Se need to save the standard output first, which we do in $output, and then everything that is printed or said (through say) gets stored in the defined IO::Store class. Two things should be taken into account in this class. By default, IO::Handles are in binary mode, so we need to TWEAK the objects if we want them to work with text. Second, a WRITE operation should return True if successful. It will fail if it does not.

method READ

Defined as:

method READ(IO::Handle:D: Int:D \bytes --> Buf:D)

Called whenever a read operation is performed on the handle. Receives the number of bytes requested to read. Returns a Buf with those bytes which can be used to either fill the decoder buffer or returned from reading methods directly. The result is allowed to have fewer than the requested number of bytes, including no bytes at all.

If you provide your own .READ, you very likely need to provide your own .EOF as well, for all the features to behave correctly.

The compiler may call .EOF method any number of times during a read operation to ascertain whether a call to .READ should be made. More bytes than necessary to satisfy a read operation may be requested from .READ, in which case the extra data may be buffered by the IO::Handle or the decoder it's using, to fulfill any subsequent reading operations, without necessarily having to make another .READ call.

class IO::Store is IO::Handle { 
     has @.lines = []; 
 
     submethod TWEAK { 
       self.encoding: 'utf8'; # set up encoder/decoder 
     } 
 
     method WRITE(IO::Handle:D: Blob:D \data --> Bool:D) { 
       @!lines.push: data; 
       True; 
     } 
 
     method whole() { 
       my Buf $everything = Buf.new(); 
       for @!lines -> $b { 
         $everything ~= $b; 
       } 
       return $everything; 
     } 
 
     method READ(IO::Handle:D: Int:D \bytes --> Buf:D) { 
       my Buf $everything := self.whole(); 
       return $everything; 
     } 
 
     method EOF { 
       my $everything = self.whole(); 
       !$everything; 
     } 
 } 
 
 my $store := IO::Store.new(); 
 
 $store.print( $_ ) for <one two three>; 
 say $store.read(3).decode; # OUTPUT «one␤» 
 say $store.read(3).decode; # OUTPUT «two␤» 

In this case, we have programmed the two READ and EOF methods, as well as WRITE, which stores every line in an element in an array. The read method actually calls READ, returning 3 bytes, which correspond to the three characters in the first two elements. Please note that it's the IO::Handle base class the one that is taking care of cursor, since READ just provides a handle into the whole content of the object; the base class will READ 1024 * 1024 bytes at a time. If your object is planned to hold an amount of bytes bigger than that, you will have to handle an internal cursor yourself. That is why in this example we don't actually use the bytes argument.

method EOF

Defined as:

method EOF(IO::Handle:D: --> Bool:D)

Indicates whether "end of file" has been reached for the data source of the handle; i.e. no more data can be obtained by calling .READ method. Note that this is not the same as eof method, which will return True only if .EOF returns True and all the decoder buffers, if any were used by the handle, are also empty. See .READ for an example implementation.

Related roles and classes

See also the related role IO and the related class IO::Path.

149 class IO::Notification

Asynchronous notification for file and directory changes

enum FileChangeEvent (:FileChanged(1), :FileRenamed(2)); 
class IO::Notification  { 
     class Change { 
         has $.path; 
         has $.event; 
     } 
     ... 
 } 

IO::Notification.watch-path($path) produces a Supply of IO::Notification::Change events for a file or directory.

Here is a small example that prints the first ten FileChanged-notifications for the current working directory:

my $finish = Promise.new; 
 my $count = 0; 
 IO::Notification.watch-path($*CWD).act( -> $change { 
     $count++ if $change.event ~~ FileChanged; 
     say "($count) $change.path(): $change.event()"; 
     $finish.keep if $count >= 10; 
 }); 
 await $finish; 

The type of the change is very much dependent both on the platform and on specific system calls that were used initiate the change. At this point in time you should not rely on the type of change in general, and test your particular situation.

Methods

method watch-path

method watch-path(IO::Notification: Str() $path, :$scheduler = $*SCHEDULER) 

Returns a Supply that emits IO::Notification::Change objects.

If $path is a file, only modifications of that file are reported. If $path is a directory, both modifications to the directory itself (for example permission changes) and to files in the directory (including new files in the directory) are reported.

:$scheduler allows you to specify which thread scheduler is responsible for the notification stream.

150 class IO::Path

File or directory path

class IO::Path is Cool does IO { } 

IO::Path is the workhorse of IO operations.

Conceptually, an IO::Path object consists of a volume, a directory, and a basename. It supports both purely textual operations, and operations that access the filesystem, e.g. to resolve a path, or to read all content of a file.

At creation, each IO::Path object is given information about the current working directory the path might be relative to using the $.CWD attribute (defaults to $*CWD), as well as what operating system semantics should be used for path manipulation using the special IO::Spec type given in the $.SPEC attribute.

The $.SPEC defaults to the value of $*SPEC, which uses the object suitable for the operating system the code is currently running on. This is the default most code will be comfortable with.

In certain situations, e.g. testing, you may wish to force $*SPEC to use one of the specific SPEC modules: IO::Spec::Unix, IO::Spec::Win32, IO::Spec::Cygwin, and IO::Spec::QNX, or to create IO::Path objects via shortcut subclasses IO::Path::Unix, IO::Path::Win32, IO::Path::Cygwin, and IO::Path::QNX that pre-set the $.SPEC attribute for you.

The rest of this document silently assumes Unix semantics in its examples, unless stated otherwise.

Methods

method new

Defined as:

multi method new(Str:D $path, IO::Spec :$SPEC = $*SPEC, Str() :$CWD = $*CWD) 
 multi method new( 
     :$basename!, :$dirname = '.', :$volume = '' 
     IO::Spec :$SPEC = $*SPEC, Str() :$CWD = $*CWD 
 ) 

Creates a new IO::Path object from a path string (which is being parsed for volume, directory name and basename), or from volume, directory name and basename passed as named arguments.

The path's operation will be performed using :$SPEC semantics (defaults to current $*SPEC) and will use :$CWD as the directory the path is relative to (defaults to $*CWD).

attribute CWD

IO::Path.new("foo", :CWD</home/camelia>)
    .IO.CWD.say; # OUTPUT: «/home/camelia␤»

Read-only. Contains implicit or explicit value of :$CWD argument to .new.

attribute SPEC

IO::Path.new("foo", :SPEC(IO::Spec::Unix.new))\
    .IO.SPEC.^name.say; # OUTPUT: «IO::Spec::Unix␤»

Read-only. Contains implicit or explicit value of :$SPEC argument to .new.

attribute path

IO::Path.new("foo").path.say; # OUTPUT: «foo␤»

Read-only. Returns the string the object was constructed from or the value of $SPEC.join($volume, $dirname, $basename) if multi-part version of .new was used. NOTE: this does not include the $.CWD; see IO::Path.absolute and IO::Path.relative for stringification options that include $.CWD.

NOTE: Implementations may cache operations done with this attribute, so modifying its value (via cloning or Proxy) is NOT recommended and may result in broken IO::Path objects. Create a new IO::Path object instead.

method ACCEPTS

Defined as:

multi method ACCEPTS(IO::Path:D: Cool:D $other --> Bool:D)

Coerces the argument to IO::Path, if necessary. Returns True if .absolute method on both paths returns the same string. NOTE: it's possible for two paths that superficially point to the same resource to NOT smartmatch as True, if they were constructed differently and were never fully resolved:

say "foo/../bar".IO ~~ "bar".IO # False

The reason is the two paths above may point to different resources when fully resolved (e.g. if foo is a symlink). Resolve the paths before smartmatching to check they point to same resource:

say "foo/../bar".IO.resolve(:completely) ~~ "bar".IO.resolve(:completely) # True

method basename

Defined as:

method basename(IO::Path:D:)

Returns the basename part of the path object, which is the name of the filesystem object itself that is referenced by the path.

"docs/README.pod".IO.basename.say; # OUTPUT: «README.pod␤»
"/tmp/".IO.basename.say;           # OUTPUT: «tmp␤»

Note that in IO::Spec::Win32 semantics, the basename of a Windows share is \, not the name of the share itself:

IO::Path::Win32.new('//server/share').basename.say; # OUTPUT: «\␤»

method add

Defined as:

method add(IO::Path:D: Str() $what --> IO::Path:D)

Concatenates a path fragment to the invocant and returns the resultant IO::Path. If adding ../ to paths that end with a file, you may need to call resolve for the resultant path to be accessible by other IO::Path methods like dir or open. See also sibling and parent.

"foo/bar".IO.mkdir;
"foo/bar".IO.add("meow")    .resolve.relative.say; # OUTPUT: «foo/bar/meow␤»
"foo/bar".IO.add("/meow")   .resolve.relative.say; # OUTPUT: «foo/bar/meow␤»
"foo/bar".IO.add("meow.txt").resolve.relative.say; # OUTPUT: «foo/bar/meow.txt␤»
"foo/bar".IO.add("../meow") .resolve.relative.say; # OUTPUT: «foo/meow␤»
"foo/bar".IO.add("../../")  .resolve.relative.say; # OUTPUT: «.␤»

method child

Defined as:

method child(IO::Path:D: Str() $childname --> IO::Path:D)

Alias for .add. NOTE: This method has been deprecated as of the 6.d version, and will be removed in the future. For any new code, please use .add

method cleanup

Defined as:

method cleanup(IO::Path:D: --> IO::Path:D)

Returns a new path that is a canonical representation of the invocant path, cleaning up any extraneous path parts:

"foo/./././..////bar".IO.cleanup.say;      # OUTPUT: «"foo/../bar".IO␤»
IO::Path::Win32.new("foo/./././..////bar")
    .cleanup.say; "foo\..\bar".IO;         # OUTPUT: «"foo\..\bar".IO␤»

Note that no filesystem access is made. See also resolve.

method comb

Defined as:

method comb(IO::Path:D: |args --> Seq:D)

Opens the file and processes its contents the same way Str.comb does, taking the same arguments. Implementations may slurp the file in its entirety when this method is called.

method split

Defined as:

method split(IO::Path:D: |args --> Seq:D)

Opens the file and processes its contents the same way Str.split does, taking the same arguments. Implementations may slurp the file in its entirety when this method is called.

method extension

Defined as:

multi method extension(IO::Path:D:                                         --> Str:D)
multi method extension(IO::Path:D:               Int :$parts               --> Str:D)
multi method extension(IO::Path:D:             Range :$parts               --> Str:D)
multi method extension(IO::Path:D: Str $subst,   Int :$parts, Str :$joiner --> IO::Path:D)
multi method extension(IO::Path:D: Str $subst, Range :$parts, Str :$joiner --> IO::Path:D)

Returns the extension consisting of $parts parts (defaults to 1), where a "part" is defined as a dot followed by possibly-empty string up to the end of the string, or previous part. That is "foo.tar.gz" has an extension of two parts: first part is "gz" and second part is "tar" and calling "foo.tar.gz".IO.extension: :2parts gives "tar.gz". If an extension with the specified number of $parts is not found, returns an empty string.

$parts can be a Range, specifying the minimum number of parts and maximum number of parts the extension should have. The routine will attempt to much the most parts it can. If $parts range's endpoints that are smaller than 0 they'll be treated as 0; implementations may treat endpoints larger than 2⁶³-1 as 2⁶³-1. Ranges with NaN or Str endpoints will cause an exception to be thrown.

If $subst is provided, the extension will be instead replaced with $subst and a new IO::Path object will be returned. It will be joined to the file's name with $joiner, which defaults to an empty string when $subst is an empty string and to "." when $subst is not empty. Note: if as the result of replacement the basename of the path ends up being empty, it will be assumed to be . (a single dot).

# Getting an extension:
say "foo.tar.gz".IO.extension;               # OUTPUT: «gz␤»
say "foo.tar.gz".IO.extension: :2parts;      # OUTPUT: «tar.gz␤»
say "foo.tar.gz".IO.extension: :parts(^5);   # OUTPUT: «tar.gz␤»
say "foo.tar.gz".IO.extension: :parts(0..1); # OUTPUT: «gz␤»

# Replacing an extension
say "foo.tar.gz".IO.extension: '';                # OUTPUT: «"foo.tar".IO␤»
say "foo.tar.gz".IO.extension: 'ZIP';             # OUTPUT: «"foo.tar.ZIP".IO␤»
say "foo.tar.gz".IO.extension: 'ZIP', :0parts;    # OUTPUT: «"foo.tar.gz.ZIP".IO␤»
say "foo.tar.gz".IO.extension: 'ZIP', :2parts;    # OUTPUT: «"foo.ZIP".IO␤»
say "foo.tar.gz".IO.extension: 'ZIP', :parts(^5); # OUTPUT: «"foo.ZIP".IO␤»

# Replacing an extension using non-standard joiner:
say "foo.tar.gz".IO.extension: '',    :joiner<_>;  # OUTPUT: «"foo.tar_".IO␤»
say "foo.tar.gz".IO.extension: 'ZIP', :joiner<_>;  # OUTPUT: «"foo.tar_ZIP".IO␤»
say "foo.tar.gz".IO.extension: 'ZIP', :joiner<_>,
                                       :2parts;     # OUTPUT: «"foo_ZIP".IO␤»
say "foo.tar.gz".IO.extension: 'ZIP', :joiner<_>,
                                       :parts(^5);  # OUTPUT: «"foo_ZIP".IO␤»

# EDGE CASES:

# There is no 5-part extension, so returned value is an empty string
say "foo.tar.gz".IO.extension: :5parts; # OUTPUT: «␤»

# There is no 5-part extension, so we replaced nothing:
say "foo.tar.gz".IO.extension: 'ZIP', :5parts; # OUTPUT: «"foo.tar.gz".IO␤»

# Replacing a 0-part extension is just appending:
say "foo.tar.gz".IO.extension: 'ZIP', :0parts; # OUTPUT: «"foo.tar.gz.ZIP".IO␤»

# Replace 1-part of the extension, using '.' joiner
say "...".IO.extension: 'tar'; # OUTPUT: «"...tar".IO␤»

# Replace 1-part of the extension, using empty string joiner
say "...".IO.extension: 'tar', :joiner(''); # OUTPUT: «"..tar".IO␤»

# Remove 1-part extension; results in empty basename, so result is ".".IO
say ".".IO.extension: ''; # OUTPUT: «".".IO␤»

method dirname

Defined as:

method dirname(IO::Path:D:)

Returns the directory name portion of the path object. That is, it returns the path excluding the volume and the base name. Unless the dirname consist of only the directory separator (i.e. it's the top directory), the trailing directory separator will not be included in the return value.

say IO::Path.new("/home/camelia/myfile.p6").dirname; # OUTPUT: «/home/camelia␤»
say IO::Path::Win32.new("C:/home/camelia").dirname;  # OUTPUT: «/home␤»
say IO::Path.new("/home").dirname;                   # OUTPUT: «/␤»

method volume

Defined as:

method volume(IO::Path:D:)

Returns the volume portion of the path object. On Unix system, this is always the empty string.

say IO::Path::Win32.new("C:\\Windows\\registry.ini").volume;    # OUTPUT: «C:␤»

method parts

Defined as:

method parts(IO::Path:D: --> Map:D)

Returns a Map with the keys volume, dirname, basename whose values are the same as available via methods .volume, .dirname, and .basename respectively.

say IO::Path::Win32.new("C:/rakudo/perl6.bat").parts.perl;
# OUTPUT: «Map.new((:basename("perl6.bat"),:dirname("/rakudo"),:volume("C:")))␤»

method perl

Defined as:

method perl(IO::Path:D: --> Str:D)

Returns a string that, when given passed through EVAL gives the original invocant back.

"foo/bar".IO.perl.say;
# OUTPUT: IO::Path.new("foo/bar", :SPEC(IO::Spec::Unix), :CWD("/home/camelia"))

Note that this string includes the value of the .CWD attribute that is set to $*CWD when the path object was created, by default.

method gist

Defined as:

method gist(IO::Path:D: --> Str:D)

Returns a string, part of which contains either the value of .absolute (if path is absolute) or .path. Note that no escaping of special characters is made, so e.g. "\b" means a path contains a backslash and letter "b", not a backspace.

say "foo/bar".IO;                       # OUTPUT: «"foo/bar".IO␤»
say IO::Path::Win32.new: 「C:\foo/bar\」; # OUTPUT: «"C:\foo/bar\".IO␤»

method Str

Defined as:

method Str(IO::Path:D: --> Str)

Alias for IO::Path.path. In particular, note that default stringification of an IO::Path does NOT use the value of $.CWD attribute. To stringify while retaining full path information use .absolute or .relative methods.

method succ

Defined as:

method succ(IO::Path:D: --> IO::Path:D)

Returns a new IO::Path constructed from the invocant, with .basename changed by calling Str.succ on it.

"foo/file02.txt".IO.succ.say; # OUTPUT: «"foo/file03.txt".IO␤»

method open

Defined as:

method open(IO::Path:D: *%opts)

Opens the path as a file; the named options control the mode, and are the same as the open function accepts.

method pred

Defined as:

method pred(IO::Path:D: --> IO::Path:D)

Returns a new IO::Path constructed from the invocant, with .basename changed by calling Str.pred on it.

"foo/file02.txt".IO.pred.say; # OUTPUT: «"foo/file01.txt".IO␤»

method watch

Defined as:

method watch(IO::Path:D: --> Supply:D)

Equivalent to calling IO::Notification.watch-path with the invocant as the argument.

method is-absolute

Defined as:

method is-absolute(IO::Path:D: --> Bool)

Returns True if the path is an absolute path, and False otherwise.

"/foo".IO.is-absolute.say; # OUTPUT: «True␤»
"bars".IO.is-absolute.say; # OUTPUT: «False␤»

Note that on Windows a path that starts with a slash or backslash is still considered absolute even if no volume was given, as it is absolute for that particular volume:

IO::Path::Win32.new("/foo"  ).is-absolute.say; # OUTPUT: «True␤»
IO::Path::Win32.new("C:/foo").is-absolute.say; # OUTPUT: «True␤»
IO::Path::Win32.new("C:foo" ).is-absolute.say; # OUTPUT: «False␤»

method is-relative

Defined as:

method is-relative(IO::Path:D: --> Bool)

Returns True if the path is a relative path, and False otherwise. Windows caveats for .is-absolute apply.

method absolute

Defined as:

multi method absolute(IO::Path:D: --> Str)
multi method absolute(IO::Path:D: $base --> Str)

Returns a new Str object that is an absolute path. If the invocant is not already an absolute path, it is first made absolute using $base as base, if it is provided, or the .CWD attribute the object was created with if it is not.

method relative

Defined as:

method relative(IO::Path:D: $base = $*CWD --> Str)

Returns a new Str object with the path relative to the $base. If $base is not provided, $*CWD is used in its place. If the invocant is not an absolute path, it's first made to be absolute using the .CWD attribute the object was created with, and then is made relative to $base.

method parent

Defined as:

multi method parent(IO::Path:D:)
multi method parent(IO::Path:D: UInt:D $level)

Returns the parent path of the invocant. Note that no actual filesystem access is made, so the returned parent is physical and not the logical parent of symlinked directories.

'/etc/foo'.IO.parent.say; # OUTPUT: «"/etc".IO␤»
'/etc/..' .IO.parent.say; # OUTPUT: «"/etc".IO␤»
'/etc/../'.IO.parent.say; # OUTPUT: «"/etc".IO␤»
'./'      .IO.parent.say; # OUTPUT: «"..".IO␤»
'foo'     .IO.parent.say; # OUTPUT: «".".IO␤»
'/'       .IO.parent.say; # OUTPUT: «"/".IO␤»
IO::Path::Win32.new('C:/').parent.say; # OUTPUT: «"C:/".IO␤»

If $level is specified, the call is equivalent to calling .parent() $level times:

say "/etc/foo".IO.parent(2) eqv "/etc/foo".IO.parent.parent; # OUTPUT: «True␤» 

method resolve

Defined as:

method resolve(IO::Path:D: :$completely --> IO::Path)

Returns a new IO::Path object with all symbolic links and references to the parent directory (..) resolved. This means that the filesystem is examined for each directory in the path, and any symlinks found are followed.

# bar is a symlink pointing to "/baz"
my $io = "foo/./bar/..".IO.resolve;      # now "/" (the parent of "/baz")

If :$completely, which defaults to False, is set to a true value, the method will fail with X::IO::Resolve if it cannot completely resolve the path, otherwise, it will resolve as much as possible, and will merely perform cleanup of the rest of the path. The last part of the path does NOT have to exist to :$completely resolve the path.

NOTE: Currently (April 2017) this method doesn't work correctly on all platforms, e.g. Windows, since it assumes POSIX semantics.

routine dir

Defined as:

sub    dir(Cool $path = '.', Mu :$test = none('.', '..'))
method dir(IO::Path:D: Mu :$test = none('.', '..'))

Returns the contents of a directory as a lazy list of IO::Path objects representing relative paths, filtered by smartmatching their names (as strings) against the :test parameter.

Since the tests are performed against Str arguments, not IO, the tests are executed in the $*CWD, instead of the target directory. When testing against file test operators, this won't work:

dir('mydir', test => { .IO.d })

while this will:

dir('mydir', test => { "mydir/$_".IO.d })

NOTE: a dir call opens a directory for reading, which counts towards maximum per-process open files for your program. Be sure to exhaust returned Seq before doing something like recursively performing more dir calls. You can exhaust it by assigning to a @-sigiled variable or simply looping over it. Note how examples below push further dirs to look through into an Array, rather than immediately calling dir on them. See also IO::Dir module that gives you finer control over closing dir handles.

Examples:

# To iterate over the contents of the current directory:
for dir() -> $file {
    say $file;
}

# As before, but include even '.' and '..' which are filtered out by
# the default :test matcher:
for dir(test => *) -> $file {
    say $file;
}

# To get the names of all .jpg and .jpeg files in ~/Downloads:
my @jpegs = $*HOME.dir: test => /:i '.' jpe?g $/;

An example program that lists all files and directories recursively:

sub MAIN($dir = '.') {
    my @todo = $dir.IO;
    while @todo {
        for @todo.pop.dir -> $path {
            say $path.Str;
            @todo.push: $path if $path.d;
        }
    }
}

A lazy way to find the first three files ending in ".p6" recursively starting from the current directory:

my @stack = '.'.IO; 
 my $perl-files = gather while @stack { 
     with @stack.pop { 
         when :d { @stack.append: .dir } 
         .take when .extension.lc eq 'p6' 
     } 
 } 
 .put for $perl-files[^3]; 

File test operators

For most file tests, you can do a smartmatch ~~ or you can call a method. You don't need to actually open a filehandle in the traditional way (although you can) to do a filetest. You can simply append .IO to the filename. For instance, here is how to check whether a file is readable using smartmatch:

'/path/to/file'.IO ~~ :r;

File tests include:

Smartmatching on Pairs can be used to perform multiple tests at once:

say :d & :x;                # OUTPUT: «all(d => True, x => True)␤»
say '/tmp'.IO ~~ :d & :x;   # OUTPUT: «True␤»
say '/'.IO    ~~ :d & :rw;  # OUTPUT: «False␤»

All of the above tests can be used as methods (without the colon), though method tests may throw X::IO::DoesNotExist as documented below. Three tests only exist as methods: accessed, changed and modified.

You can also perform file tests on an already opened filehandle by testing against its .path method. For example, given filehandle $fh:

$fh.path ~~ :r; 
 $fh.path.r;       # method form 

method e

Defined as:

method e(--> Bool:D)

Returns True if the invocant is a path that exists.

method d

Defined as:

method d(--> Bool:D)

Returns True if the invocant is a path that exists and is a directory. The method will fail with X::IO::DoesNotExist if the path points to a non-existent filesystem entity.

method f

Defined as:

method f(--> Bool:D)

Returns True if the invocant is a path that exists and is a file. The method will fail with X::IO::DoesNotExist if the path points to a non-existent filesystem entity.

method s

Defined as:

method s(--> Int:D)

Returns the file size in bytes. May be called on paths that are directories, in which case the reported size is dependent on the operating system. The method will fail with X::IO::DoesNotExist if the path points to a non-existent filesystem entity.

say $*EXECUTABLE.IO.s; # OUTPUT : «467␤»

method l

Defined as:

method l(--> Bool:D)

Returns True if the invocant is a path that exists and is a symlink. The method will fail with X::IO::DoesNotExist if the path points to a non-existent filesystem entity.

method r

Defined as:

method r(--> Bool:D)

Returns True if the invocant is a path that exists and is accessible. The method will fail with X::IO::DoesNotExist if the path points to a non-existent filesystem entity.

method w

Defined as:

method w(--> Bool:D)

Returns True if the invocant is a path that exists and is writable. The method will fail with X::IO::DoesNotExist if the path points to a non-existent filesystem entity.

method rw

Defined as:

method rw(--> Bool:D)

Returns True if the invocant is a path that exists and is readable and writable. The method will fail with X::IO::DoesNotExist if the path points to a non-existent filesystem entity.

method x

Defined as:

method x(--> Bool:D)

Returns True if the invocant is a path that exists and is executable. The method will fail with X::IO::DoesNotExist if the path points to a non-existent filesystem entity.

method rwx

Defined as:

method rwx(--> Bool:D)

Returns True if the invocant is a path that exists and is executable, readable, and writable. The method will fail with X::IO::DoesNotExist if the path points to a non-existent filesystem entity.

method z

Defined as:

method z(--> Bool:D)

Returns True if the invocant is a path that exists and has size of 0. May be called on paths that are directories, in which case the reported file size (and thus the result of this method) is dependent on the operating system. The method will fail with X::IO::DoesNotExist if the path points to a non-existent filesystem entity.

method sibling

Defined as:

method sibling(IO::Path:D: Str() $sibling --> IO::Path:D)

Allows to reference a sibling file or directory. Returns a new IO::Path based on the invocant, with the .basename changed to $sibling. The $sibling is allowed to be a multi-part path fragment; see also .add.

say '.bashrc'.IO.sibling: '.bash_aliases'; # OUTPUT: «.bash_aliases".IO␤»
say '/home/camelia/.bashrc'.IO.sibling: '.bash_aliases';
# OUTPUT: «/home/camelia/.bash_aliases".IO␤»

say '/foo/' .IO.sibling: 'bar';  # OUTPUT: «/bar".IO␤»
say '/foo/.'.IO.sibling: 'bar';  # OUTPUT: «/foo/bar".IO␤»

method words

Defined as:

method words(IO::Path:D: :$chomp = True, :$enc = 'utf8', :$nl-in = ["\x0A", "\r\n"], |c --> Seq:D)

Opens the invocant and returns its words.

The behavior is equivalent to opening the file specified by the invocant, forwarding the :$chomp, :$enc, and :$nl-in arguments to IO::Handle.open, then calling IO::Handle.words on that handle, forwarding any of the remaining arguments to that method, and returning the resultant Seq.

NOTE: words are lazily read. The handle used under the hood is not closed until the returned Seq is fully reified, and this could lead to leaking open filehandles. It is possible to avoid leaking open filehandles using the $limit argument to cut down the Seq of words to be generated.

my %dict := bag 'my-file.txt'.IO.words; 
 say "Most common words: ", %dict.sort(-*.value).head: 5; 

method lines

Defined as:

method lines(IO::Path:D: :$chomp = True, :$enc = 'utf8', :$nl-in = ["\x0A", "\r\n"], |c --> Seq:D)

Opens the invocant and returns its lines.

The behavior is equivalent to opening the file specified by the invocant, forwarding the :$chomp, :$enc, and :$nl-in arguments to IO::Handle.open, then calling IO::Handle.lines on that handle, forwarding any of the remaining arguments to that method, and returning the resultant Seq.

NOTE: the lines are ready lazily and the handle used under the hood won't get closed until the returned Seq is fully reified, so ensure it is, or you'll be leaking open filehandles. (TIP: use the $limit argument)

say "The file contains ", 
   '50GB-file'.IO.lines.grep(*.contains: 'Perl').elems, 
   " lines that mention Perl"; 
 # OUTPUT: «The file contains 72 lines that mention Perl␤» 

routine slurp

Defined as:

multi method slurp(IO::Path:D: :$bin, :$enc)

Read all of the file's content and return it as either Buf, if :$bin is True, or if not, as Str decoded with :$enc encoding, which defaults to utf8. File will be closed afterwards. See &open for valid values for :$enc.

method spurt

Defined as:

method spurt(IO::Path:D: $data, :$enc, :$append, :$createonly)

Opens the file path for writing, and writes all of the $data into it. File will be closed, afterwards. Will fail if it cannot succeed for any reason. The $data can be any Cool type or any Blob type. Arguments are as follows:

method chdir

Defined as:

multi method chdir(IO::Path:D: Str() $path, :$d = True, :$r, :$w, :$x)

DEPRECATION NOTICE: this method will be deprecated in 6.d language and removed in 6.e. Do not use it for new code. Instead, create a new path or use add method. For altering current working directory see &chdir and &*chdir subroutines.

Contrary to the name, the .chdir method does not change any directories, but merely concatenates the given $path to the invocant and returns the resultant IO::Path. Optional file tests can be performed by providing :d, :r, :w, or :x Bool named arguments; when set to True, they'll perform .d, .r, .w, and .x tests respectively. By default, only :d is set to True.

sub mkdir

Defined as:

method mkdir(IO::Path:D: Int() $mode = 0o777 --> IO::Path:D)

Creates a new directory, including its parent directories, as needed (similar to *nix utility mkdir with -p option). That is, mkdir "foo/bar/ber/meow" will create foo, foo/bar, and foo/bar/ber directories as well if they do not exist.

Returns the IO::Path object pointing to the newly created directory on success; fails with X::IO::Mkdir if directory cannot be created.

See also mode for explanation and valid values for $mode.

routine rmdir

Defined as:

sub    rmdir(*@dirs --> List:D)
method rmdir(IO::Path:D: --> True)

Remove the invocant, or in sub form, all of the provided directories in the given list, which can contain any Cool object. Only works on empty directories.

Method form returns True on success and throws an exception of type X::IO::Rmdir if the directory cannot be removed (e.g. the directory is not empty, or the path is not a directory). Subroutine form returns a list of directories that were successfully deleted.

To delete non-empty directory, see rmtree in File::Directory::Tree module.

method chmod

Defined as:

method chmod(IO::Path:D: Int() $mode --> Bool)

Changes the POSIX permissions of a file or directory to $mode. Returns True on success; on failure, fails with X::IO::Chmod.

The mode is expected as an integer following the standard numeric notation, and is best written as an octal number:

'myfile'.IO.chmod(0o444);          # make a file read-only 
 'somedir'.IO.chmod(0o777);         # set 0777 permissions on a directory 

Make sure you don't accidentally pass the intended octal digits as a decimal number (or string containing a decimal number):

'myfile'.IO.chmod:  '0444';        # BAD!!! (interpreted as mode 0o674) 
 'myfile'.IO.chmod: '0o444';        # OK (an octal in a string) 
 'myfile'.IO.chmod:  0o444;         # Also OK (an octal literal) 

routine rename

Defined as:

method rename(IO::Path:D: IO() $to, :$createonly = False --> Bool:D)
sub    rename(IO() $from, IO() $to, :$createonly = False --> Bool:D)

Renames a file or directory. Returns True on success; fails with X::IO::Rename if :$createonly is True and the $to path already exists or if the operation failed for some other reason.

Note: some renames will always fail, such as when the new name is on a different storage device. See also: move.

routine copy

Defined as:

method copy(IO::Path:D: IO() $to, :$createonly --> Bool:D)
sub    copy(IO() $from, IO() $to, :$createonly --> Bool:D)

Copies a file. Returns True on success; fails with X::IO::Copy if :$createonly is True and the $to path already exists or if the operation failed for some other reason, such as when $to and $from are the same file.

routine move

Defined as:

method move(IO::Path:D: IO() $to, :$createonly --> Bool:D)
sub    move(IO() $from, IO() $to, :$createonly --> Bool:D)

Copies a file and then removes the original. If removal fails, it's possible to end up with two copies of the file. Returns True on success; fails with X::IO::Move if :$createonly is True and the $to path already exists or if the operation failed for some other reason, such as when $to and $from are the same file.

To avoid copying, you can use rename, if the files are on the same storage device. It also works with directories, while move does not.

method Numeric

Defined as:

method Numeric(IO::Path:D: --> Numeric:D)

Coerces .basename to Numeric. Fails with X::Str::Numeric if base name is not numerical.

method Int

Defined as:

method Int(IO::Path:D: --> Int:D)

Coerces .basename to Int. Fails with X::Str::Numeric if base name is not numerical.

Defined as:

method symlink(IO::Path:D $target: IO() $link --> Bool:D)
sub    symlink(      IO() $target, IO() $link --> Bool:D)

Create a new symbolic link $link to existing $target. Returns True on success; fails with X::IO::Symlink if the symbolic link could not be created. If $target does not exist, creates a dangling symbolic link. To create a hard link, see link.

Note: on Windows, creation of symbolic links may require escalated privileges.

Defined as:

method link(IO::Path:D $target: IO() $link --> Bool:D)
sub    link(      IO() $target, IO() $link --> Bool:D)

Create a new hard link $link to existing $target. Returns True on success; fails with X::IO::Link if the hard link could not be created. To create a symbolic link, see symlink.

Defined as:

method unlink(IO::Path:D: --> True)
sub    unlink(*@filenames --> List:D)

Delete all specified ordinary files, links, or symbolic links for which there are privileges to do so. See rmdir to delete directories.

The subroutine form returns the names of all the files in the list, excluding those for which the filesystem raised some error; since trying to delete a file that does not exist does not raise any error at that level, this list will include the names of the files in the list that do not exist.

The method form returns True on success, or fails with X::IO::Unlink if the operation could not be completed. If the file to be deleted does not exist, the routine treats it as success.

'foo.txt'.IO.open(:w).close; 
 'bar'.IO.mkdir; 
 say unlink <foo.txt  bar  not-there.txt>; # OUTPUT: «[foo.txt not-there.txt]␤» 
 # `bar` is not in output because it failed to delete (it's a directory) 
 # `not-there.txt` is present. It never existed, so that's deemed a success. 
 
 # Method form `fail`s: 
 say .exception.message without 'bar'.IO.unlink; 
 # OUTPUT: «Failed to remove the file […] illegal operation on a directory␤» 

method IO

Defined as:

method IO(IO::Path:D: --> IO::Path)

Returns the invocant.

method SPEC

Defined as:

method SPEC(IO::Path:D: --> IO::Spec)

Returns the IO::Spec object that was (implicitly) specified at object creation time.

my $io = IO::Path.new("/bin/bash");
say $io.SPEC;                            # OUTPUT: «(Unix)␤»
say $io.SPEC.dir-sep;                    # OUTPUT: «/␤»

File timestamp retrieval

There are also 3 methods for fetching the 3 timestamps of a file (inode), on Operating Systems where these are available:

method modified

Returns an Instant object indicating when the content of the file was last modified. Compare with changed.

say "path/to/file".IO.modified;          # Instant:1424089165 
 say "path/to/file".IO.modified.DateTime; # 2015-02-16T12:18:50Z 

method accessed

Return an Instant object representing the timestamp when the file was last accessed. Note: depending on how the filesystem was mounted, the last accessed time may not update on each access to the file, but only on the first access after modifications.

say "path/to/file".IO.accessed;          # Instant:1424353577 
 say "path/to/file".IO.accessed.DateTime; # 2015-02-19T13:45:42Z 

method changed

Returns an Instant object indicating the metadata of the file or directory was last changed (e.g. permissions, or files created/deleted in directory). Compare with modified.

say "path/to/file".IO.changed;           # Instant:1424089165 
 say "path/to/file".IO.changed.DateTime;  # 2015-02-16T12:18:50Z 

File permissions retrieval

method mode

Return an IntStr object representing the POSIX permissions of a file. The Str part of the result is the octal representation of the file permission, like the form accepted by the chmod(1) utility.

say ~"path/to/file".IO.mode;  # e.g. '0644' 
 say +"path/to/file".IO.mode;  # e.g. 420, where sprintf('%04o', 420) eq '0644' 

The result of this can be used in the other methods that take a mode as an argument.

"path/to/file1".IO.chmod("path/to/file2".IO.mode);  # will change the 
                                                     # permissions of file1 
                                                     # to be the same as file2 

151 class IO::Path::Cygwin

IO::Path pre-loaded with IO::Spec::Cygwin

class IO::Path::Cygwin is IO::Path { }

This sub-class of IO::Path, pre-loaded with IO::Spec::Cygwin in the $.SPEC attribute.

Methods

method new

Same as IO::Path.new, except :$SPEC cannot be set and defaults to IO::Spec::Cygwin, regardless of the operating system the code is being run on.

method perl

Defined as:

method perl(IO::Path::Cygwin:D: --> Str:D)

Returns a string that, when given passed through EVAL gives the original invocant back.

IO::Path::Cygwin.new("foo/bar").perl.say;
# OUTPUT: IO::Path::Cygwin.new("foo/bar", :CWD("/home/camelia"))

Note that this string includes the value of the .CWD attribute that is set to $*CWD when the path object was created, by default.

152 class IO::Path::QNX

IO::Path pre-loaded with IO::Spec::QNX

class IO::Path::QNX is IO::Path { }

This sub-class of IO::Path, pre-loaded with IO::Spec::QNX in the $.SPEC attribute.

Methods

method new

Same as IO::Path.new, except :$SPEC cannot be set and defaults to IO::Spec::QNX, regardless of the operating system the code is being run on.

method perl

Defined as:

method perl(IO::Path::QNX:D: --> Str:D)

Returns a string that, when given passed through EVAL gives the original invocant back.

IO::Path::QNX.new("foo/bar").perl.say;
# OUTPUT: IO::Path::QNX.new("foo/bar", :CWD("/home/camelia"))

Note that this string includes the value of the .CWD attribute that is set to $*CWD when the path object was created, by default.

153 class IO::Path::Unix

IO::Path pre-loaded with IO::Spec::Unix

class IO::Path::Unix is IO::Path { }

This sub-class of IO::Path, pre-loaded with IO::Spec::Unix in the $.SPEC attribute.

Methods

method new

Same as IO::Path.new, except :$SPEC cannot be set and defaults to IO::Spec::Unix, regardless of the operating system the code is being run on.

method perl

Defined as:

method perl(IO::Path::Unix:D: --> Str:D)

Returns a string that, when given passed through EVAL gives the original invocant back.

IO::Path::Unix.new("foo/bar").perl.say;
# OUTPUT: IO::Path::Unix.new("foo/bar", :CWD("/home/camelia"))

Note that this string includes the value of the .CWD attribute that is set to $*CWD when the path object was created, by default.

154 class IO::Path::Win32

IO::Path pre-loaded with IO::Spec::Win32

class IO::Path::Win32 is IO::Path { }

This sub-class of IO::Path, pre-loaded with IO::Spec::Win32 in the $.SPEC attribute.

Methods

method new

Same as IO::Path.new, except :$SPEC cannot be set and defaults to IO::Spec::Win32, regardless of the operating system the code is being run on.

method perl

Defined as:

method perl(IO::Path::Win32:D: --> Str:D)

Returns a string that, when given passed through EVAL gives the original invocant back.

IO::Path::Win32.new("foo/bar").perl.say;
# OUTPUT: IO::Path::Win32.new("foo/bar", :CWD("C:\\Users\\camelia"))

Note that this string includes the value of the .CWD attribute that is set to $*CWD when the path object was created, by default.

155 class IO::Pipe

Buffered inter-process string or binary stream

class IO::Pipe is IO::Handle {}

An IO::Pipe object closely corresponds to a UNIX pipe. It has one end where it consumes string or binary data, and another where it reproduces the same data. It is buffered, so that a write without a read doesn't immediately block.

Pipes can be easily constructed with sub run and Proc::Async.new.

Methods

method close

Defined as:

method close(IO::Pipe: --> Proc:D)

Closes the pipe and returns Proc object from which the pipe originates.

method IO

Defined as:

method IO(IO::Pipe: --> IO::Path:U)

Returns an IO::Path type object.

method path

Defined as:

method path(IO::Pipe: --> IO::Path:U)

Returns an IO::Path type object.

method proc

Defined as:

method proc(IO::Pipe: --> Proc:D)

Returns the Proc object from which the pipe originates.

156 role IO::Socket

Network socket

role IO::Socket { ... }

IO::Socket contains read and write methods for sockets. It is usually used through IO::Socket::INET.

Methods

method recv

method recv(IO::Socket:D: Cool $elems = Inf, :$bin)

Receive a packet and return it, either as a Blob if :bin was passed, or a Str if not. Receives up to $elems or 65535 (whichever is smaller) bytes or characters.

Fails if the socket is not connected.

method read

method read(IO::Socket:D: Int(Cool) $bytes)

Reads $bytes bytes from the socket and returns them in a Blob.

Fails if the socket is not connected.

routine get

Defined as:

method get(IO::Socket:D: --> Str:D)

Reads a single line of input from the socket, removing the trailing newline characters (as set by .nl-in). Returns Nil, if no more input is available.

Fails if the socket is not connected.

method print

method print(IO::Socket:D: Str(Cool) $string)

Writes the supplied string to the socket, thus sending it to other end of the connection. The binary version is #method write.

Fails if the socket is not connected.

method write

method write(IO::Socket:D: Blob:D $buf)

Writes the supplied buffer to the socket, thus sending it to other end of the connection. The string version is #method print.

Fails if the socket is not connected.

method put

method put(IO::Socket:D: Str(Cool) $string)

Writes the supplied string, with a \n appended to it, to the socket, thus sending it to other end of the connection.

Fails if the socket is not connected.

method close

method close(IO::Socket:D)

Closes the socket.

Fails if the socket is not connected.

method native-descriptor

method native-descriptor()

This returns a value that the operating system would understand as a "socket descriptor" and is suitable for passing to a native function that requires a socket descriptor as an argument such as setsockopt.

157 class IO::Socket::Async

Asynchronous socket in TCP or UDP

class IO::Socket::Async {}

IO::Socket::Async|/type/IO::Socket::Async provides asynchronous sockets, for both the server and the client side.

Here is a simple example of a simple "hello world" HTTP server that listens on port 3333:

react { 
     whenever IO::Socket::Async.listen('0.0.0.0', 3333) -> $conn { 
         whenever $conn.Supply.lines -> $line { 
             $conn.print: qq:heredoc/END/; 
                 HTTP/1.1 200 OK 
                 Content-Type: text/html; charset=UTF-8 
                 Content-Encoding: UTF-8 
 
                 <html> 
                 <body> 
                     <h1>Hello World!</h1> 
                     <p>{ $line }</p> 
                 </body> 
                 </html> 
                 END 
             $conn.close; 
         } 
     } 
     CATCH { 
         default { 
             say .^name, ': ', .Str; 
             say "handled in $?LINE"; 
         } 
     } 
 } 

And a client that connects to it, and prints out what the server answers:

await IO::Socket::Async.connect('127.0.0.1', 3333).then( -> $promise { 
     given $promise.result { 
         .print("Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n"); 
         react { 
             whenever .Supply() -> $v { 
                 $v.print; 
                 done; 
             } 
         } 
         .close; 
     } 
 }); 

IO::Socket::Async can also send and receive UDP messages An example server that outputs all the data it receives would be:

my $socket = IO::Socket::Async.bind-udp('localhost', 3333); 
 
 react { 
     whenever $socket.Supply -> $v { 
         if $v.chars > 0 { 
             say $v; 
         } 
     } 
 } 

And an associated client might be:

my $socket = IO::Socket::Async.udp(); 
 await $socket.print-to('localhost', 3333, "Hello, Perl 6!"); 

The CATCH phaser can be included to deal specifically with problems that might occur in this kind of sockets, such as a port being already taken:

react { 
     whenever IO::Socket::Async.listen('0.0.0.0', 3000) -> $conn { 
         whenever $conn.Supply.lines -> $line { 
             $conn.print: qq:heredoc/END/; 
                 HTTP/1.1 200 OK 
                 Content-Type: text/html; charset=UTF-8 
                 Content-Encoding: UTF-8 
 
                 <html> 
                 <body> 
                     <h1>Hello World!</h1> 
                     <p>{ $line }</p> 
                 </body> 
                 </html> 
                 END 
             $conn.close; 
         } 
         QUIT { 
             default { 
                 say .^name, '→ ', .Str; 
                 say "handled in line $?LINE"; 
             } 
         } 
     } 
 
 } 
 # Will print this, if address 3000 is already in use: 
 # X::AdHoc→ address already in use 
 # handled in 23 

Main difference with using other phasers such as CATCH is that this kind of exception will be caught within the whenever block and will put exiting the program, or not, under your control.

Methods

The IO::Socket::Async cannot be constructed directly, either connect or listen (for TCP connections) or udp or bind-udp (for UDP data) should be used to create a client or a server respectively.

method connect

method connect(Str $host, Int $port --> Promise)

Attempts to connect to the TCP server specified by $host and $port, returning a Promise that will either be kept with a connected IO::Socket::Async or broken if the connection cannot be made.

method listen

method listen(Str $host, Int $port --> Supply)

Creates a listening socket on the specified $host and $port, returning a Supply to which the accepted client IO::Socket::Asyncs will be emitted. This Supply should be tapped start listening for client connections. You can use $port = 0 if you want the operating system to find one for you.

To close the underlying listening socket, the Tap returned by tapping the listener should be closed.

For example, when using tap:

my $listener = IO::Socket::Async.listen('127.0.0.1', 8080); 
 my $tap = $listener.tap({ ... }); 
 
 # When you want to close the listener 
 $tap.close; 

Or when using whenever:

my $listener = IO::Socket::Async.listen('127.0.0.1', 5000); 
 my $tap; 
 react { 
     $tap = do whenever $listener -> $conn { ... } 
 } 
 
 # When you want to close the listener, you can still use: 
 $tap.close; 

method udp

method udp(IO::Socket::Async:U: :$broadcast --> IO::Socket::Async)

Returns an initialized IO::Socket::Async client object that is configured to send UDP messages using print-to or write-to. The :broadcast adverb will set the SO_BROADCAST option which will allow the socket to send packets to a broadcast address.

method bind-udp

method bind-udp(IO::Socket::Async:U: Str() $host, Int() $port, :$broadcast --> IO::Socket::Async)

This returns an initialized IO::Socket::Async server object that is configured to receive UDP messages sent to the specified $host and $port and is equivalent to listen for a TCP socket. The :broadcast adverb can be specified to allow the receipt of messages sent to the broadcast address.

method print

method print(Str $str --> Promise)

Attempt to send $str on the IO::Socket::Async that will have been obtained indirectly via connect or listen, returning a Promise that will be kept with the number of bytes sent or broken if there was an error sending.

method print-to

method print-to(IO::Socket::Async:D: Str() $host, Int() $port, Str() $str --> Promise)

This is the equivalent of print for UDP sockets that have been created with the udp method, it will try send a UDP message of $str to the specified $host and $port returning a Promise that will be kept when the data is successfully sent or broken if it was unable to send the data. In order to send to a broadcast address the :broadcast flag must have been specified when the socket was created.

method write

method write(Blob $b --> Promise)

This method will attempt to send the bytes in $b on the IO::Socket::Async that will have been obtained indirectly via connect or listen, returning a Promise that will be kept with the number of bytes sent or broken if there was an error sending.

method write-to

method write-to(IO::Socket::Async:D: Str() $host, Int() $port, Blob $b --> Promise)

This is the equivalent of write for UDP sockets that have been created with the udp method. It will try send a UDP message comprised of the bytes in the Blob $b to the specified $host and $port returning a Promise that will be kept when the data is successfully sent or broken if it was unable to send the data. In order to send to a broadcast address the :broadcast flag must have been specified when the socket was created.

method Supply

method Supply(:$bin, :$buf = buf8.new --> Supply)

Returns a Supply which can be tapped to obtain the data read from the connected IO::Socket::Async as it arrives. By default the data will be emitted as characters, but if the :bin adverb is provided a Buf of bytes will be emitted instead, optionally in this case you can provide your own Buf with the :buf named parameter.

A UDP socket in character mode will treat each packet as a complete message and decode it. In the event of a decoding error, the Supply will quit.

On the other hand, a TCP socket treats the incoming packets as part of a stream, and feeds the incoming bytes into a streaming decoder. It then emits whatever characters the decoder considers ready. Since strings work at grapheme level in Perl 6, this means that only known complete graphemes will be emitted. For example, if the UTF-8 encoding were being used and the last byte in the packet decoded to a, this would not be emitted since the next packet may include a combining character that should form a single grapheme together with the a. Control characters (such as \n) always serve as grapheme boundaries, so any text-based protocols that use newlines or null bytes as terminators will not need special consideration. A TCP socket will also quit upon a decoding error.

method close

method close()

Close the connected client IO::Socket::Async which will have been obtained from the listen Supply or the connect Promise.

In order to close the underlying listening socket created by listen you can close the Tap. See listen for examples.

method socket-host

method socket-host(--> Str)

Returns the IP address of the local end of this socket.

method peer-host

method peer-host(--> Str)

Returns the IP address of the remote end of this socket.

method socket-port

method socket-port(--> Int)

Returns the port of the local end of this socket.

method peer-port

method peer-port(--> Int)

Returns the port of the remote end of this socket.

method native-descriptor

method native-descriptor(--> Int)

Returns the file descriptor of this socket.

158 class IO::Socket::INET

TCP Socket

class IO::Socket::INET does IO::Socket {} 

IO::Socket::INET provides TCP sockets, both the server and the client side.

For UDP support, please see IO::Socket::Async.

Here is an example of a very simplistic "echo" server that listens on localhost, port 3333:

my $listen = IO::Socket::INET.new( :listen, 
                                    :localhost<localhost>, 
                                    :localport(3333) ); 
 loop { 
     my $conn = $listen.accept; 
     try { 
         while my $buf = $conn.recv(:bin) { 
             $conn.write: $buf; 
         } 
     } 
     $conn.close; 
 
     CATCH { 
           default { .payload.say;      } 
     } 
 
 } 

And a client that connects to it, and prints out what the server answers:

my $conn = IO::Socket::INET.new( :host<localhost>, 
                                  :port(3333) ); 
 $conn.print: 'Hello, Perl 6'; 
 say $conn.recv; 
 $conn.close; 

Please bear in mind that this is a synchronous connection; an attempt by any of the nodes to write without the other reading will produce an Could not receive data from socket: Connection reset by peer error.

Methods

method new

multi method new( 
         :$host, 
         :$port, 
         :$family = PF_INET, 
         :$encoding = 'utf-8', 
         :$nl-in = "\r\n", 
     --> IO::Socket::INET:D) 
 multi method new( 
         :$localhost, 
         :$localport, 
         :$family = PF_INET, 
         :$listen, 
         :$encoding = 'utf-8', 
         :$nl-in = "\r\n", 
     --> IO::Socket::INET:D) 

Creates a new socket.

If :$listen is True, creates a new socket that listen on :$localhost (which can be an IP address or a domain name) on port :$localport; in other words the :$listen flag determines the server mode of the socket. Otherwise (i.e., :$listen is False), the new socket opens immediately a connection to :$host on port :$port.

:$family defaults to PF_INET constant for IPv4, and can be set to PF_INET6 constant for IPv6.

For text operations (such as #method lines and #method get), :$encoding specifies the encoding, and :$nl-in determines the character(s) that separate lines.

Methods

method get

method get()

Reads a line from the socket and returns it as of type Str. Return Nil on end-of-file (EOF).

method lines

method lines()

Returns a lazy list of lines read from the socket.

method accept

method accept()

In listen/server mode, waits for a new incoming connection. Once a new connection is established, an IO::Socket::INET instance (or a subclass instance) for consuming the connection is returned.

159 class IO::Spec

Platform specific operations on file and directory paths

class IO::Spec { }

Objects of this class are not used directly but as a sub-class specific to the platform perl is running on via the $*SPEC variable which will contain an object of the appropriate type.

The sub-classes are documented separately, with the platform-specific differences documented in IO::Spec::Cygwin, IO::Spec::QNX, IO::Spec::Unix and IO::Spec::Win32.

NOTE: the IO::Spec::* classes provide low-level path operations. Unless you're creating your own high-level path manipulation routines, you don't need to use IO::Spec::*. Use IO::Path instead.

NOTE2: no special validation is done by these classes (e.g. check whether path contains a null character). It is the job of higher-level classes, like IO::Path, to do that.

Methods

160 class IO::Spec::Cygwin

Platform specific operations on file and directory paths for Cygwin

class IO::Spec::QNX is IO::Spec { }

This sub-class of IO::Spec will be available from the $*SPEC variable for a perl running on Cygwin .

NOTE: the IO::Spec::* classes provide low-level path operations. Unless you're creating your own high-level path manipulation routines, you don't need to use IO::Spec::*. Use IO::Path instead.

NOTE2: no special validation is done by these classes (e.g. check whether path contains a null character). It is the job of higher-level classes, like IO::Path, to do that.

Methods

method abs2rel

Defined as:

method abs2rel(IO::Path:D $path, IO::Path:D $base = $*CWD --> Str:D)

Returns a string that represents $path, but relative to $base path. Both $path and $base may be relative paths. $base defaults to $*CWD. Uses IO::Spec::Win32's semantics.

method canonpath

Defined as:

method canonpath(Str() $path, :$parent --> Str:D)

Returns a string that is a canonical representation of $path. If :$parent is set to true, will also clean up references to parent directories. NOTE: the routine does not access the filesystem.

IO::Spec::Cygwin.canonpath(「C:\foo\\..\bar\..\ber」).say;
# OUTPUT: «C:/foo/../bar/../ber␤»

IO::Spec::Cygwin.canonpath("foo///./../bar/../ber").say;
# OUTPUT: «foo/../bar/../ber␤»

IO::Spec::Cygwin.canonpath("foo///./../bar/../ber", :parent).say;
# OUTPUT: «ber␤»

method catdir

Defined as:

method catdir (*@parts --> Str:D)

Concatenates multiple path fragments and returns the canonical representation of the resultant path as a string. The @parts are Str objects and are allowed to contain path separators.

IO::Spec::Cygwin.catdir(<foo/bar ber perl>).say;
# OUTPUT: «foo/bar/ber/perl␤»

method catpath

Defined as:

method catpath (Str:D $volume, Str:D $dir, Str:D $file --> Str:D)

Same as IO::Spec::Win32.catpath, except will also change all backslashes to slashes at the end:

IO::Spec::Cygwin.catpath('C:', '/some/dir', 'foo.txt').say;
# OUTPUT: «C:/some/dir/foo.txt␤»

IO::Spec::Cygwin.catpath('C:', '/some/dir', '').say;
# OUTPUT: «C:/some/dir␤»

IO::Spec::Cygwin.catpath('', '/some/dir', 'foo.txt').say;
# OUTPUT: «/some/dir/foo.txt␤»

IO::Spec::Cygwin.catpath('E:', '', 'foo.txt').say;
# OUTPUT: «E:foo.txt␤»

method is-absolute

Defined as:

method is-absolute(Str:D $path --> Bool:D)

Returns True if the $path starts with a slash ("/") or backslash ("\"), even if they have combining character on them, optionally preceded by a volume:

say IO::Spec::Cygwin.is-absolute: "/foo";        # OUTPUT: «True␤»
say IO::Spec::Cygwin.is-absolute: "/\x[308]foo"; # OUTPUT: «True␤»
say IO::Spec::Cygwin.is-absolute: 「C:\foo」;      # OUTPUT: «True␤»
say IO::Spec::Cygwin.is-absolute: "bar";         # OUTPUT: «False␤»

method join

Defined as:

method join(|c)

Same as IO::Spec::Win32.join, except replaces backslashes with slashes in the final result.

method rel2abs

Defined as:

method rel2abs(|c --> List:D)

Same as IO::Spec::Win32.rel2abs, except replaces backslashes with slashes in the final result.

method split

Defined as:

method split(|c --> List:D)

Same as IO::Spec::Win32.split, except replaces backslashes with slashes in all the values of the final result.

method splitpath

Defined as:

method splitpath(|c --> List:D)

Same as IO::Spec::Win32.splitpath, except replaces backslashes with slashes in all the values of the final result.

method tmpdir

Defined as:

method tmpdir(--> IO::Path:D)

Attempts to locate a system's temporary directory by checking several typical directories and environmental variables. Uses current directory if no suitable directories are found.

161 class IO::Spec::QNX

Platform specific operations on file and directory paths QNX

class IO::Spec::QNX is IO::Spec { }

This sub-class of IO::Spec specific to QNX will be available via $*SPEC if the perl is running on QNX.

NOTE: the IO::Spec::* classes provide low-level path operations. Unless you're creating your own high-level path manipulation routines, you don't need to use IO::Spec::*. Use IO::Path instead.

NOTE2: no special validation is done by these classes (e.g. check whether path contains a null character). It is the job of higher-level classes, like IO::Path, to do that.

Methods

method canonpath

Defined as:

method canonpath(Str() $path, :$parent --> Str:D)

Returns a string that is a canonical representation of $path. If :$parent is set to true, will also clean up references to parent directories. NOTE: the routine does not access the filesystem, so no symlinks are followed.

IO::Spec::QNX.canonpath("foo//../bar/../ber").say;
# OUTPUT: «foo/../bar/../ber␤»

IO::Spec::QNX.canonpath("foo///./../bar/../ber").say;
# OUTPUT: «foo/../bar/../ber␤»

IO::Spec::QNX.canonpath("foo///./../bar/../ber", :parent).say;
# OUTPUT: «ber␤»

162 class IO::Spec::Unix

Platform specific operations on file and directory paths for POSIX

class IO::Spec::Unix is IO::Spec  { }

On object of this type is available via the variable $*SPEC if the Perl 6 interpreter is running on a Unix-like platform.

The IO::Spec::* classes provide low-level path operations. Unless you're creating your own high-level path manipulation routines, you don't need to use IO::Spec::*. Use IO::Path instead.

Beware that no special validation is done by these classes (e.g. check whether path contains a null character). It is the job of higher-level classes, like IO::Path, to do that.

Methods

method abs2rel

Defined as:

method abs2rel(IO::Path:D $path, IO::Path:D $base = $*CWD --> Str:D)

Returns a string that represents $path, but relative to $base path. Both $path and $base may be relative paths. $base defaults to $*CWD.

method basename

Defined as:

method basename(Str:D $path --> Str:D)

Takes a path as a string and returns a possibly-empty portion after the last slash:

IO::Spec::Unix.basename("foo/bar/") .perl.say; # OUTPUT: «""␤»
IO::Spec::Unix.basename("foo/bar/.").perl.say; # OUTPUT: «"."␤»
IO::Spec::Unix.basename("foo/bar")  .perl.say; # OUTPUT: «"bar"␤»

method canonpath

Defined as:

method canonpath(Str() $path, :$parent --> Str:D)

Returns a string that is a canonical representation of $path. If :$parent is set to true, will also clean up references to parent directories. NOTE: the routine does not access the filesystem, so no symlinks are followed.

IO::Spec::Unix.canonpath("foo//../bar/../ber").say;
# OUTPUT: «foo/../bar/../ber␤»

IO::Spec::Unix.canonpath("foo///./../bar/../ber").say;
# OUTPUT: «foo/../bar/../ber␤»

IO::Spec::Unix.canonpath("foo///./../bar/../ber", :parent).say;
# OUTPUT: «ber␤»

method catdir

Defined as:

method catdir (*@parts --> Str:D)

Concatenates multiple path fragments and returns the canonical representation of the resultant path as a string. The @parts are Str objects and are allowed to contain path separators.

IO::Spec::Unix.catdir(<foo/bar ber perl>).say; # OUTPUT: «foo/bar/ber/perl␤»

method catfile

Alias for catdir.

method catpath

Defined as:

method catpath ($, Str:D $part1, Str:D $part2 --> Str:D)

Takes two path fragments and concatenates them, adding or removing a path separator, if necessary. The first argument is ignored (it exists to maintain consistent interface with other IO::Spec|/type/IO::Spec types for systems that have volumes).

IO::Spec::Unix.catpath($, 'some/dir', 'and/more').say;
# OUTPUT: «some/dir/and/more␤»

method curdir

Defined as:

method curdir()

Returns a string representing the current directory:

say '.' eq $*SPEC.curdir; # OUTPUT: «True␤»

method curupdir

Defined as:

method curupdir()

Returns a none Junction of strings representing the current directory and the "one directory up":

say $*SPEC.curupdir;                  # OUTPUT: «none(., ..)␤» 
 my @dirs = <. foo .. bar>; 
 say @dirs.grep(* eq $*SPEC.curupdir); # OUTPUT: «(foo bar)␤» 

Neither foo nor bar are equal to the representation of the current or parent directory, that is why they are returned by grep.

method devnull

Defined as:

method devnull(--> Str:D)

Returns the string "/dev/null" representing the "Null device":

$*SPEC.devnull.IO.spurt: "foo bar baz"; 

method dir-sep

Defined as:

method dir-sep(--> Str:D)

Returns the string "/" representing canonical directory separator character.

IO::Spec::Unix.dir-sep.say; # OUTPUT: «/␤» 

method extension

NOTE: Most users would want to use the higher-level routine IO::Path.extension instead of this lower-level version.

Defined as:

method extension(Str:D $path --> Str:D)

Takes a string representing a base name and returns the characters after the last dot ("."), or empty string if no dots are present. The routine makes no attempt to detect path separators and will return everything after the last dot.

$*SPEC.extension('foo.'      ).perl.say;  # OUTPUT: «""␤»
$*SPEC.extension('foo.txt'   ).perl.say;  # OUTPUT: «"txt"␤»
$*SPEC.extension('foo.tar.gz').perl.say;  # OUTPUT: «"gz"␤»
$*SPEC.extension('foo'       ).perl.say;  # OUTPUT: «""␤»
$*SPEC.extension('bar.foo/foo').perl.say; # OUTPUT: «"foo/foo"␤»

method is-absolute

Defined as:

method is-absolute(Str:D $path --> Bool:D)

Returns True if the $path starts with a slash ("/"), even if it has combining character on it:

say IO::Spec::Unix.is-absolute: "/foo";        # OUTPUT: «True␤»
say IO::Spec::Unix.is-absolute: "/\x[308]foo"; # OUTPUT: «True␤»
say IO::Spec::Unix.is-absolute: "bar";         # OUTPUT: «False␤»

method join

Defined as:

method join ($, Str:D $dir, Str:D $file --> Str:D)

Similar to catpath, takes two path fragments and concatenates them, adding or removing a path separator, if necessary, except it will return just $file if both $dir and $file are string '/' or if $dir is the string '.'. The first argument is ignored (it exists to maintain consistent interface with other IO::Spec types for systems that have volumes).

IO::Spec::Unix.join($, 'foo', 'bar').say; # OUTPUT: «foo/bar␤»
IO::Spec::Unix.join($, '/', '/').say;     # OUTPUT: «/␤»
IO::Spec::Unix.join($, '.', 'foo').say;   # OUTPUT: «foo␤»
say $*SPEC.join(True,".","/foo");         # OUTPUT: «/foo␤»

method path

Defined as:

method path(--> Seq:D)

Splits the value of %*ENV<PATH> on colons (":"), replaces empty parts with ".", and returns a Seq with each of the resultant parts. Returns an empty Seq if %*ENV<PATH> is not set or is an empty string.

%*ENV<PATH> = 'foo:bar/ber::foo:';
IO::Spec::Unix.path.perl.say;
# OUTPUT: «("foo", "bar/ber", ".", "foo", ".").Seq␤»

method rel2abs

Defined as:

method rel2abs(Str() $path, $base = $*CWD --> Str:D)

Returns a string representing $path converted to absolute path, based at $base, which defaults to $*CWD. If $base is not an absolute path, it will be made absolute relative to $*CWD, unless $*CWD and $base are the same.

say $*CWD;                                  # OUTPUT: «"/home/camelia".IO␤» 
 
 say IO::Spec::Unix.rel2abs: 'foo';          # OUTPUT: «/home/camelia/foo␤» 
 say IO::Spec::Unix.rel2abs: './';           # OUTPUT: «/home/camelia␤» 
 say IO::Spec::Unix.rel2abs: 'foo/../../';   # OUTPUT: «/home/camelia/foo/../..␤» 
 say IO::Spec::Unix.rel2abs: '/foo/';        # OUTPUT: «/foo␤» 
 
 say IO::Spec::Unix.rel2abs: 'foo', 'bar';   # OUTPUT: «/home/camelia/bar/foo␤» 
 say IO::Spec::Unix.rel2abs: './', '/bar';   # OUTPUT: «/bar␤» 
 say IO::Spec::Unix.rel2abs: '/foo/', 'bar'; # OUTPUT: «/foo␤» 
 
 say IO::Spec::Unix.rel2abs: 'foo/../../', 'bar'; 
 # OUTPUT: «/home/camelia/bar/foo/../..␤» 

method rootdir

Defined as:

method rootdir(--> Str:D)

Returns string '/', representing root directory.

method split

Defined as:

method split(Cool:D $path --> List:D)

Splits the given $path into "volume", "dirname", and "basename" and returns the result as a List of three Pairs, in that order. The "volume" is always an empty string and exists for consistency with other IO::Spec classes.

IO::Spec::Unix.split('C:/foo/bar.txt').perl.say; 
 # OUTPUT: «(:volume(""), :dirname("C:/foo"), :basename("bar.txt"))␤» 
 
 IO::Spec::Unix.split('/foo/').perl.say; 
 # OUTPUT: «(:volume(""), :dirname("/"), :basename("foo"))␤» 
 
 IO::Spec::Unix.split('///').perl.say; 
 # OUTPUT: «(:volume(""), :dirname("/"), :basename("/"))␤» 
 
 IO::Spec::Unix.split('./').perl.say; 
 # OUTPUT: «(:volume(""), :dirname("."), :basename("."))␤» 
 
 IO::Spec::Unix.split('.').perl.say; 
 # OUTPUT: «(:volume(""), :dirname("."), :basename("."))␤» 
 
 IO::Spec::Unix.split('').perl.say; 
 # OUTPUT: «(:volume(""), :dirname(""), :basename(""))␤» 

method splitdir

Defined as:

method splitdir(Cool:D $path --> List:D)

Splits the given $path on slashes.

IO::Spec::Unix.splitdir('C:\foo/bar.txt').perl.say; 
 # OUTPUT: «("C:\\foo", "bar.txt")␤» 
 
 IO::Spec::Unix.splitdir('/foo/').perl.say; 
 # OUTPUT: «("", "foo", "")␤» 
 
 IO::Spec::Unix.splitdir('///').perl.say; 
 # OUTPUT: «("", "", "", "")␤» 
 
 IO::Spec::Unix.splitdir('./').perl.say; 
 # OUTPUT: «(".", "")␤» 
 
 IO::Spec::Unix.splitdir('.').perl.say; 
 # OUTPUT: «(".",)␤» 
 
 IO::Spec::Unix.splitdir('').perl.say; 
 # OUTPUT: «("",)␤» 

method splitpath

Defined as:

method splitpath(Cool:D $path, :$nofile --> List:D)

Splits the given $path into a list of 3 strings: volume, dirname, and file. The volume is always an empty string, returned for API compatibility with other IO::Spec types. If :$nofile named argument is set to True, the content of the file string is undefined and should be ignored; this is a means to get a performance boost, as implementations may use faster code path when file is not needed.

IO::Spec::Unix.splitpath('C:\foo/bar.txt').perl.say; 
 # OUTPUT: «("", "C:\\foo/", "bar.txt")␤» 
 
 IO::Spec::Unix.splitpath('C:\foo/bar.txt', :nofile).perl.say; 
 # OUTPUT: «("", "C:\\foo/bar.txt", "")␤» 
 
 IO::Spec::Unix.splitpath('/foo/').perl.say; 
 # OUTPUT: «("", "/foo/", "")␤» 
 
 IO::Spec::Unix.splitpath('/foo/', :nofile).perl.say; 
 # OUTPUT: «("", "/foo/", "")␤» 
 
 IO::Spec::Unix.splitpath('///').perl.say; 
 # OUTPUT: «("", "///", "")␤» 
 
 IO::Spec::Unix.splitpath('./').perl.say; 
 # OUTPUT: «("", "./", "")␤» 
 
 IO::Spec::Unix.splitpath('.').perl.say; 
 # OUTPUT: «("", "", ".")␤» 
 
 IO::Spec::Unix.splitpath('').perl.say; 
 # OUTPUT: «("", "", "")␤» 

method tmpdir

Defined as:

method tmpdir(--> IO::Path:D)

Attempts to locate a system's temporary directory by checking several typical directories and environmental variables. Uses current directory if no suitable directories are found.

method updir

Defined as:

method updir()

Returns a string representing the directory one up from current:

say '..' eq $*SPEC.updir; # OUTPUT: «True␤»

163 class IO::Spec::Win32

Platform specific operations on file and directory paths for Windows

class IO::Spec::Win32 is IO::Spec { }

Objects of this class are used not directly but as a sub-class specific to the platform Perl 6 is running on via the $*SPEC variable, which will contain an object of the appropriate type.

NOTE: the IO::Spec::* classes provide low-level path operations. Unless you're creating your own high-level path manipulation routines, you don't need to use IO::Spec::*. Use IO::Path instead.

NOTE2: no special validation is done by these classes (e.g. check whether path contains a null character). It is the job of higher-level classes, like IO::Path, to do that.

Methods

method basename

Defined as:

method basename(Str:D $path --> Str:D)

Takes a path as a string and returns a possibly-empty portion after the last slash or backslash:

IO::Spec::Win32.basename("foo/bar/") .perl.say; # OUTPUT: «""␤»
IO::Spec::Win32.basename("foo/bar\\").perl.say; # OUTPUT: «""␤»
IO::Spec::Win32.basename("foo/bar/.").perl.say; # OUTPUT: «"."␤»
IO::Spec::Win32.basename("foo/bar")  .perl.say; # OUTPUT: «"bar"␤»

method canonpath

Defined as:

method canonpath(Str() $path, :$parent --> Str:D)

Returns a string that is a canonical representation of $path. If :$parent is set to true, will also clean up references to parent directories. NOTE: the routine does not access the filesystem.

IO::Spec::Win32.canonpath("C:/foo//../bar/../ber").say;
# OUTPUT: «C:\foo\..\bar\..\ber␤»

IO::Spec::Win32.canonpath("C:/foo///./../bar/../ber").say;
# OUTPUT: «C:\foo\..\bar\..\ber␤»

IO::Spec::Win32.canonpath("C:/foo///./../bar/../ber", :parent).say;
# OUTPUT: «C:\ber␤»

method catdir

Defined as:

method catdir (*@parts --> Str:D)

Concatenates multiple path fragments and returns the canonical representation of the resultant path as a string. The @parts are Str objects and are allowed to contain path separators.

IO::Spec::Win32.catdir(<foo/bar ber perl>).say;
# OUTPUT: «foo\bar\ber\perl␤»

method catfile

Alias for catdir.

method catpath

Defined as:

method catpath (Str:D $volume, Str:D $dir, Str:D $file --> Str:D)

Concatenates a path from given volume, a chain of directories, and file. An empty string can be given for any of the three arguments. No attempt to make the path canonical is made. Use canonpath for that purpose.

IO::Spec::Win32.catpath('C:', '/some/dir', 'foo.txt').say;
# OUTPUT: «C:/some/dir\foo.txt␤»

IO::Spec::Win32.catpath('C:', '/some/dir', '').say;
# OUTPUT: «C:/some/dir␤»

IO::Spec::Win32.catpath('', '/some/dir', 'foo.txt').say;
# OUTPUT: «/some/dir\foo.txt␤»

IO::Spec::Win32.catpath('E:', '', 'foo.txt').say;
# OUTPUT: «E:foo.txt␤»

method devnull

Defined as:

method devnull(--> Str:D)

Returns the string "nul" representing the "Null device":

$*SPEC.devnull.IO.spurt: "foo bar baz"; 

method dir-sep

Defined as:

method dir-sep(--> Str:D)

Returns the string 「\」 representing canonical directory separator character.

IO::Spec::Win32.dir-sep.say; # OUTPUT: «\␤» 

method is-absolute

Defined as:

method is-absolute(Str:D $path --> Bool:D)

Returns True if the $path starts with a slash ("/") or backslash ("\"), even if they have combining character on them, optionally preceded by a volume:

say IO::Spec::Win32.is-absolute: "/foo";        # OUTPUT: «True␤»
say IO::Spec::Win32.is-absolute: "/\x[308]foo"; # OUTPUT: «True␤»
say IO::Spec::Win32.is-absolute: 「C:\foo」;      # OUTPUT: «True␤»
say IO::Spec::Win32.is-absolute: "bar";         # OUTPUT: «False␤»

method join

Defined as:

method join (Str:D $volume, Str:D $dir, Str:D $file --> Str:D)

Similar to catpath, takes two path fragments and concatenates them, adding or removing a path separator, if necessary, except it will return just $file if both $dir and $file are string '/' or if $dir is the string '.'. The first argument is ignored (it exists to maintain consistent interface with other IO::Spec types for systems that have volumes).

IO::Spec::Win32.join('C:', '/some/dir', 'foo.txt').say;
# OUTPUT: «C:/some/dir\and/more␤»

IO::Spec::Win32.join('C:', '.', 'foo.txt').say;
# OUTPUT: «C:foo.txt␤»

IO::Spec::Win32.join('C:', 「\」, '/').say;
# OUTPUT: «C:\␤»

IO::Spec::Win32.join('//server/share', 「\」, '/').say;
# OUTPUT: «//server/share␤»

IO::Spec::Win32.join('E:', '', 'foo.txt').say;
# OUTPUT: «E:foo.txt␤»

method path

Defined as:

method path(--> Seq:D)

Splits the value of %*ENV<PATH> (or %*ENV<Path> if the former is not set) on semicolons (";") and returns a Seq with each of the resultant parts, always adding element "." to the head. Removes all double quotes (") it finds.

%*ENV<PATH> = 'foo;"bar"/"ber"';
IO::Spec::Win32.path.perl.say; # OUTPUT: «(".", "foo", "bar/ber").Seq␤»

method rel2abs

Defined as:

method rel2abs(Str() $path, $base = $*CWD --> Str:D)

Returns a string representing $path converted to absolute path, based at $base, which defaults to $*CWD. If $base is not an absolute path, it will be made absolute relative to $*CWD, unless $*CWD and $base are the same.

say $*CWD;                                   # OUTPUT: «"C:\Users\camelia".IO␤» 
 
 say IO::Spec::Win32.rel2abs: 'foo';          # OUTPUT: «C:\Users\camelia\foo␤» 
 say IO::Spec::Win32.rel2abs: './';           # OUTPUT: «C:\Users\camelia␤» 
 say IO::Spec::Win32.rel2abs: 'foo/../../';   # OUTPUT: «C:\Users\camelia\foo\..\..␤» 
 say IO::Spec::Win32.rel2abs: '/foo/';        # OUTPUT: «C:\foo␤» 
 
 say IO::Spec::Win32.rel2abs: 'foo', 'bar';   # OUTPUT: «C:\Users\camelia\bar\foo␤» 
 say IO::Spec::Win32.rel2abs: './', '/bar';   # OUTPUT: «\bar␤» 
 say IO::Spec::Win32.rel2abs: '/foo/', 'bar'; # OUTPUT: «C:\foo␤» 
 
 say IO::Spec::Win32.rel2abs: 'foo/../../', 'bar'; 
 # OUTPUT: «C:\Users\camelia\bar\foo\..\..␤» 

method rootdir

Defined as:

method rootdir(--> Str:D)

Returns string 「\」, representing root directory.

method split

Defined as:

method split(Cool:D $path --> List:D)

Splits the given $path into "volume", "dirname", and "basename" and returns the result as a List of three Pairs, in that order. The "volume" is always an empty string and exists for consistency with other IO::Spec classes.

IO::Spec::Win32.split('C:/foo/bar.txt').perl.say; 
 # OUTPUT: «(:volume("C:"), :dirname("/foo"), :basename("bar.txt"))␤» 
 
 IO::Spec::Win32.split('/foo/').perl.say; 
 # OUTPUT: «(:volume(""), :dirname("/"), :basename("foo"))␤» 
 
 IO::Spec::Win32.split('///').perl.say; 
 # OUTPUT: «(:volume(""), :dirname("/"), :basename("\\"))␤» 
 
 IO::Spec::Win32.split('./').perl.say; 
 # OUTPUT: «(:volume(""), :dirname("."), :basename("."))␤» 
 
 IO::Spec::Win32.split('.').perl.say; 
 # OUTPUT: «(:volume(""), :dirname("."), :basename("."))␤» 
 
 IO::Spec::Win32.split('').perl.say; 
 # OUTPUT: «(:volume(""), :dirname(""), :basename(""))␤» 

method splitdir

Defined as:

method splitdir(Cool:D $path --> List:D)

Splits the given $path on slashes and backslashes.

IO::Spec::Win32.splitdir('C:\foo/bar.txt').perl.say; 
 # OUTPUT: «("C:", "foo", "bar.txt")␤» 
 
 IO::Spec::Win32.splitdir('/foo/').perl.say; 
 # OUTPUT: «("", "foo", "")␤» 
 
 IO::Spec::Win32.splitdir('///').perl.say; 
 # OUTPUT: «("", "", "", "")␤» 
 
 IO::Spec::Win32.splitdir('./').perl.say; 
 # OUTPUT: «(".", "")␤» 
 
 IO::Spec::Win32.splitdir('.').perl.say; 
 # OUTPUT: «(".",)␤» 
 
 IO::Spec::Win32.splitdir('').perl.say; 
 # OUTPUT: «("",)␤» 

method splitpath

Defined as:

method splitpath(Cool:D $path, :$nofile --> List:D)

Splits the given $path into a list of 3 strings: volume, dirname, and file. The volume is always an empty string, returned for API compatibility with other IO::Spec types. If :$nofile named argument is set to True, the content of the file string is undefined and should be ignored; this is a means to get a performance boost, as implementations may use faster code path when file is not needed.

IO::Spec::Win32.splitpath('C:\foo/bar.txt').perl.say; 
 # OUTPUT: «("C:", "\\foo/", "bar.txt")␤» 
 
 IO::Spec::Win32.splitpath('C:\foo/bar.txt', :nofile).perl.say; 
 # OUTPUT: «("C:", "\\foo/bar.txt", "")␤» 
 
 IO::Spec::Win32.splitpath('/foo/').perl.say; 
 # OUTPUT: «("", "/foo/", "")␤» 
 
 IO::Spec::Win32.splitpath('/foo/', :nofile).perl.say; 
 # OUTPUT: «("", "/foo/", "")␤» 
 
 IO::Spec::Win32.splitpath('///').perl.say; 
 # OUTPUT: «("", "///", "")␤» 
 
 IO::Spec::Win32.splitpath('./').perl.say; 
 # OUTPUT: «("", "./", "")␤» 
 
 IO::Spec::Win32.splitpath('.').perl.say; 
 # OUTPUT: «("", "", ".")␤» 
 
 IO::Spec::Win32.splitpath('').perl.say; 
 # OUTPUT: «("", "", "")␤» 

method tmpdir

Defined as:

method tmpdir(--> IO::Path:D)

Attempts to locate a system's temporary directory by checking several typical directories and environmental variables. Uses current directory if no suitable directories are found.

164 class IO::Special

Path to special I/O device

class IO::Special does IO { } 

Used as a $.path attribute in filehandles for special standard input $*IN and output $*OUT and $*ERR. Provides a bridged interface of IO::Handle, mostly file tests and stringification.

Methods

method new

method new(:$!what!) 

Takes a single required attribute what. It is unlikely that you will ever need to construct one of these objects yourself.

method what

say $*IN.path.what;  # OUTPUT: «<STDIN>␤»
say $*OUT.path.what; # OUTPUT: «<STDOUT>␤»
say $*ERR.path.what; # OUTPUT: «<STDERR>␤»

Returns one of the strings '<STDIN>', '<STDOUT>', or '<STDERR>', specifying the type of the special IO device.

method WHICH

method WHICH(IO::Special:D: --> Str)

This returns a string that identifies the object. The string is composed by the type of the instance (IO::Special) and the what attribute:

$*IN.path.what;  # OUTPUT: «<STDIN>␤»
$*IN.path.WHICH; # OUTPUT: «IO::Special<STDIN>␤»

method Str

method Str(IO::Special:D:)

This returns '<STDIN>', '<STDOUT>', or '<STDERR>' as appropriate.

method IO

method IO(IO::Special:D: --> IO::Special)

Returns the invocant.

say $*IN.path.IO.what;  # OUTPUT: «<STDIN>␤»
say $*IN.path.what;     # OUTPUT: «<STDIN>␤»

method e

method e(IO::Special:D: --> True)

The 'exists' file test operator, always returns True.

method d

method d(IO::Special:D: --> False)

The 'directory' file test operator, always returns False.

method f

method f(IO::Special:D: --> False)

The 'file' file test operator, always returns False.

method s

method s(IO::Special:D: --> 0)

The 'size' file test operator, always returns 0.

method l

method l(IO::Special:D: --> False)

The 'symbolic links' file test operator, always returns False.

method r

method r(IO::Special:D: --> Bool)

The 'read access' file test operator, returns True if and only if this instance represents the standard input handle(<STDIN>).

method w

method w(IO::Special:D: --> Bool)

The 'write access' file test operator, returns True only if this instance represents either the standard output (<STOUT>) or the standard error (<STDERR>) handle.

method x

method x(IO::Special:D: --> False)

The 'execute access' file test operator, always returns False.

method modified

method modified(IO::Special:D: --> Instant)

The last modified time for the filehandle. It always returns an Instant type object.

method accessed

method accessed(IO::Special:D: --> Instant)

The last accessed time for the filehandle. It always returns an Instant type object.

method changed

method changed(IO::Special:D: --> Instant)

The last changed time for the filehandle. It always returns an Instant type object.

method mode

method mode(IO::Special:D: --> Nil)

The mode for the filehandle, it always returns Nil

165 class Instant

Specific moment in time

class Instant is Cool does Real { }

An Instant is a particular moment in time measured in atomic seconds, with fractions. It is not tied to or aware of any epoch.

An Instant can be used to create a DateTime object set to that Instant. The pseudo-constant now returns the current time as an Instant.

Basic math is defined for Instants (as well as Durations). Adding an Instant to a Duration returns another Instant. Subtracting two Instants will yield a Duration. Adding two Instants is explicitly disallowed. All other operations with Instants are undefined.

Future Leap Seconds

The methods that involve knowledge of leap seconds always assume that there will be no further leaps after the last leap second that the implementation knows about, which may not be the last leap second that has actually been scheduled. This means you can get different results, depending on the compiler version you're using. For example, the December 31, 2016 leap second was announced in July and shipped with Rakudo 2016.07, so 2016.06 and earlier releases won't know about it:

$ perl6-2016.06 -e 'say Instant.from-posix: 1485726595' 
 Instant:1485726631 
 
 $ perl6-2016.07 -e 'say Instant.from-posix: 1485726595' 
 Instant:1485726632 

Since a Rakudo compiler always returns 0 for future leap seconds it doesn't know about, you can patch your old code when new leap seconds are announced, so it will give correct results, regardless of what version of the compiler it runs on:

$ perl6-2016.06 -e 'say ($*VM.version before v2016.07 ?? 1 !! 0) + Instant.from-posix: 1485726595' 
 Instant:1485726632 
 
 $ perl6-2016.07 -e 'say ($*VM.version before v2016.07 ?? 1 !! 0) + Instant.from-posix: 1485726595' 
 Instant:1485726632 

Methods

method from-posix

method from-posix($posix, Bool $prefer-leap-second = False)

Converts the POSIX timestamp $posix to an Instant. If $prefer-leap-second is True, the return value will be the first of the two possible seconds in the case of a leap second.

say DateTime.new(Instant.from-posix(915148800, True));  # OUTPUT: «1998-12-31T23:59:60Z␤»
say DateTime.new(Instant.from-posix(915148800));        # OUTPUT: «1999-01-01T00:00:00Z␤»

method to-posix

method to-posix()

Converts the invocant to a POSIX timestamp and returns a two element list containing the POSIX timestamp and a Bool. It is the inverse of #method from-posix, except that the second return value is True if *and only if* this Instant is in a leap second.

say DateTime.new("1999-01-01T00:00:00Z").Instant.to-posix; # OUTPUT: «(915148800 False)␤»
say DateTime.new('1998-12-31T23:59:60Z').Instant.to-posix; # OUTPUT: «(915148800 True)␤»

method Date

Defined as:

method Date(Instant:D: --> Date:D)

Coerces the invocant to Date.

my $i = "/etc/passwd".IO.modified;
say $i;             # OUTPUT: «Instant:1451489025.878018␤»
say $i.Date;        # OUTPUT: «2015-12-30␤»

method DateTime

Defined as:

method DateTime(Instant:D: --> DateTime:D)

Coerces the invocant to DateTime.

say now.DateTime;  # OUTPUT: «2017-05-09T14:02:58.147165Z␤»

166 class Int

Integer (arbitrary-precision)

class Int is Cool does Real { } 

Int objects store integral numbers of arbitrary size. Ints are immutable.

There are two main syntax forms for Int literals

123;         # Int in decimal notation
:16<BEEF>;   # Int in radix notations

For your convenience common radix forms come with a prefix shortcut.

say so :2<11111111> == 0b11111111 == :8<377> == 0o377 == 255 == 0d255 == :16<ff> == 0xff;
# OUTPUT: «True␤»

All forms allow underscores between any two digits which can serve as visual separators, but don't carry any meaning:

5_00000;       # five Lakhs
500_000;       # five hundred thousand
0xBEEF_CAFE;   # a strange place
:2<1010_1010>; # 0d170

Radix notation also supports round and angle brackets which allow you to parse a string for a given base, and putting together digits into a whole number respectively:

:16("9F");         # 159
:100[99, 2, 3];    # 990203

These notations allow you to use variables, too:

my $two = "2";
my $ninety-nine = "99";
:16($ninety-nine); # 153
:100[99, $two, 3]; # 990203

Methods

method Capture

Defined as:

method Capture()

Throws X::Cannot::Capture.

routine chr

Defined as:

multi sub    chr(Int:D  --> Str:D)
multi method chr(Int:D: --> Str:D)

Returns a one-character string, by interpreting the integer as a Unicode codepoint number and converting it to the corresponding character.

Example:

65.chr;  # returns "A"
196.chr; # returns "Ä"

routine expmod

Defined as:

multi sub    expmod(      $x,     $y,     $mod --> Int:D)
multi sub    expmod(Int:D $x, Int $y, Int $mod --> Int:D)
multi method expmod(Int:D:    Int $y, Int $mod --> Int:D)

Returns the given Int raised to the $y power within modulus $mod, that is gives the result of ($x ** $y) mod $mod. The subroutine form can accept non-Int arguments, which will be coerced to Int.

say expmod(4, 2, 5);    # OUTPUT: «1␤»
say 7.expmod(2, 5);     # OUTPUT: «4␤»

$y argument can also be negative, in which case, the result is equivalent to ($x ** $y) mod $mod.

say 7.expmod(-2, 5);     # OUTPUT: «4␤»

method polymod

Defined as:

method polymod(Int:D: +@mods)

Returns a sequence of mod results corresponding to the divisors in @mods in the same order as they appear there. For the best effect, the divisors should be given from the smallest "unit" to the largest (e.g. 60 seconds per minute, 60 minutes per hour) and the results are returned in the same way: from smallest to the largest (5 seconds, 4 minutes). The last non-zero value will be the last remainder.

say 120.polymod(10);    # OUTPUT: «(0 12)␤»
say 120.polymod(10,10); # OUTPUT: «(0 2 1)␤»

In the first case, 120 is divided by 10 giving as a remainder 12, which is the last element. In the second, 120 is divided by 10, giving 12, whose remainder once divided by 10 is 2; the result of the integer division of 12 div 10 is the last remainder. The number of remainders will be always one more item than the number of given divisors. If the divisors are given as a lazy list, runs until the remainder is 0 or the list of divisors is exhausted. All divisors must be Ints, unless the method is called on a non-Int number.

my $seconds = 1 * 60*60*24 # days
            + 3 * 60*60    # hours
            + 4 * 60       # minutes
            + 5;           # seconds

say $seconds.polymod(60, 60);                # OUTPUT: «(5 4 27)␤»
say $seconds.polymod(60, 60, 24);            # OUTPUT: «(5 4 3 1)␤»

say 120.polymod:      1, 10, 10², 10³, 10⁴;  # OUTPUT: «(0 0 12 0 0 0)␤»
say 120.polymod: lazy 1, 10, 10², 10³, 10⁴;  # OUTPUT: «(0 0 12)␤»
say 120.polymod:      1, 10, 10² … ∞;        # OUTPUT: «(0 0 12)␤»

say ⅔.polymod(⅓);                            # OUTPUT: «(0 2)␤»
say 5.Rat.polymod(.3, .2);                   # OUTPUT: «(0.2 0 80)␤»

my @digits-in-base37 = 9123607.polymod(37 xx *); # Base conversion
say @digits-in-base37.reverse                    # OUTPUT: «[4 32 4 15 36]␤»

To illustrate how the Int, non-lazy version of polymod works, consider this code that implements it:

my $seconds = 2 * 60*60*24 # days
            + 3 * 60*60    # hours
            + 4 * 60       # minutes
            + 5;           # seconds

my @pieces;
for 60, 60, 24 -> $divisor {
    @pieces.push: $seconds mod $divisor;
    $seconds div= $divisor
}
@pieces.push: $seconds;

say @pieces; # OUTPUT: «[5 4 3 2]␤»

For a more detailed discussion, see this blog post

routine is-prime

Defined as:

multi sub    is-prime (Int:D $number --> Bool:D)
multi method is-prime (Int:D: --> Bool:D)

Returns True if this Int is known to be a prime, or is likely to be a prime based on a probabilistic Miller-Rabin test.

Returns False if this Int is known not to be a prime.

say 2.is-prime;         # OUTPUT: «True␤»
say is-prime(9);        # OUTPUT: «False␤»

routine lsb

Defined as:

multi method lsb(Int:D:)
multi sub    lsb(Int:D)

Short for "Least Significant Bit". Returns Nil if the number is 0. Otherwise returns the zero-based index from the right of the least significant (rightmost) 1 in the binary representation of the number.

say 0b01011.lsb;        # OUTPUT: «0␤»
say 0b01010.lsb;        # OUTPUT: «1␤»
say 0b10100.lsb;        # OUTPUT: «2␤»
say 0b01000.lsb;        # OUTPUT: «3␤»
say 0b10000.lsb;        # OUTPUT: «4␤»

routine msb

Defined as:

multi method msb(Int:D:)
multi sub    msb(Int:D)

Short for "Most Significant Bit". Returns Nil if the number is 0. Otherwise returns the zero-based index from the right of the most significant (leftmost) 1 in the binary representation of the number.

say 0b00001.msb;        # OUTPUT: «0␤»
say 0b00011.msb;        # OUTPUT: «1␤»
say 0b00101.msb;        # OUTPUT: «2␤»
say 0b01010.msb;        # OUTPUT: «3␤»
say 0b10011.msb;        # OUTPUT: «4␤»

routine unival

Defined as:

multi sub    unival(Int:D  --> Numeric)
multi method unival(Int:D: --> Numeric)

Returns the number represented by the Unicode codepoint with the given integer number, or NaN if it does not represent a number.

say ord("¾").unival;    # OUTPUT: «0.75␤»
say 190.unival;         # OUTPUT: «0.75␤»
say unival(65);         # OUTPUT: «NaN␤»

method Range

Returns a Range object that represents the range of values supported.

Operators

infix div

multi sub infix:<div>(Int:D, Int:D --> Int:D)

Does an integer division, rounded down.

167 class IntStr

Dual value integer and string

class IntStr is Int is Str { }

The dual value types (often referred to as allomorphs) allow for the representation of a value as both a string and a numeric type. Typically they will be created for you when the context is "stringy" but they can be determined to be numbers, such as in some quoting constructs:

my $f = <42>; say $f.^name; # OUTPUT: «IntStr␤»

As a subclass of both Int and Str, an IntStr will be accepted where either is expected. However, IntStr does not share object identity with Int- or Str-only variants:

my $int-str = <42>;
my Int $int = $int-str; # OK!
my Str $str = $int-str; # OK!
say 42 ∈ <42  55  1>;   # False; ∈ operator cares about object identity

Methods

method new

method new(Int $i, Str $s)

The constructor requires both the Int and the Str value, when constructing one directly the values can be whatever is required:

my $f = IntStr.new(42, "forty two");
say +$f; # OUTPUT: «42␤»
say ~$f; # OUTPUT: «"forty two"␤»

method Bool

Defined as:

multi method Bool(IntStr:D: --> Bool:D)

This method may be provided by the parent classes and not implemented in IntStr directly.

Returns False if the invocant is numerically 0, otherwise returns True. String portion is not considered.

method Int

method Int

Returns the integer value of the IntStr.

method Numeric

Defined as:

multi method Numeric(IntStr:D: --> Int:D)
multi method Numeric(IntStr:U: --> Int:D)

The :D variant returns the numeric portion of the invocant. The :U variant issues a warning about using an uninitialized value in numeric context and then returns value 0.

method Real

Defined as:

multi method Real(IntStr:D: --> Int:D)
multi method Real(IntStr:U: --> Int:D)

The :D variant returns the numeric portion of the invocant. The :U variant issues a warning about using an uninitialized value in numeric context and then returns value 0.

method Str

Returns the string value of the IntStr.

method ACCEPTS

Defined as:

multi method ACCEPTS(IntStr:D: Any:D $value)

If $value is Numeric (including another allomorph), checks if invocant's Numeric part ACCEPTS the $value. If $value is Str, checks if invocant's Str part ACCEPTS the $value. If value is anything else, checks if both Numeric and Str parts ACCEPTS the $value.

say <5> ~~ "5.0"; # OUTPUT: «False␤»
say <5> ~~  5.0 ; # OUTPUT: «True␤»
say <5> ~~ <5.0>; # OUTPUT: «True␤»

Operators

infix cmp

multi sub infix:<cmp>(IntStr:D $a, IntStr:D $b)

Compare two IntStr objects. The comparison is done on the Int value first and then on the Str value. If you want to compare in a different order then you would coerce to an Int or Str value first:

my $f = IntStr.new(42, "smaller");
my $g = IntStr.new(43, "larger");
say $f cmp $g;          # OUTPUT: «Less␤»
say $f.Str cmp $g.Str;  # OUTPUT: «More␤»

168 role Iterable

Interface for container objects that can be iterated over

role Iterable { }

Iterable serves as an API for objects that can be iterated with for and related iteration constructs, like assignment to a Positional variable.

Iterable objects nested in other Iterable objects (but not within scalar containers) flatten in certain contexts, for example when passed to a slurpy parameter (*@a), or on explicit calls to flat.

Its most important aspect is a method stub for iterator.

class DNA does Iterable { 
     has $.chain; 
     method new ($chain where { $chain ~~ /^^ <[ACGT]>+ $$ / } ) { 
         self.bless( :$chain ); 
     } 
 
     method iterator(DNA:D:) { 
         $!chain.comb.rotor(3).iterator; 
     } 
 } 
 
 my $a := DNA.new('GAATCC'); 
 .say for $a; # OUTPUT: «(G A A)␤(T C C)␤» 

This example mixes in the Iterable role to offer a new way of iterating over what is essentially a string (constrained by where to just the four DNA letters). In the last statement, for actually hooks to the iterator role printing the letters in groups of 3.

Methods

method iterator

Defined as:

method iterator(--> Iterator:D)

Method stub that ensures all classes doing the Iterable role have a method iterator.

It is supposed to return an Iterator.

say (1..10).iterator;

method flat

Defined as:

method flat(--> Iterable)

Returns another Iterable that flattens out all iterables that the first one returns.

For example

say (<a b>, 'c').elems;         # OUTPUT: «2␤»
say (<a b>, 'c').flat.elems;    # OUTPUT: «3␤»

because <a b> is a List and thus iterable, so (<a b>, 'c').flat returns ('a', 'b', 'c'), which has three elems.

Note that the flattening is recursive, so ((("a", "b"), "c"), "d").flat returns ("a", "b", "c", "d"), but it does not flatten itemized sublists:

say ($('a', 'b'), 'c').perl;    # OUTPUT: «($("a", "b"), "c")␤»

method lazy

Defined as:

method lazy(--> Iterable)

Returns a lazy iterable wrapping the invocant.

say (1 ... 1000).is-lazy;      # OUTPUT: «False␤»
say (1 ... 1000).lazy.is-lazy; # OUTPUT: «True␤»

method hyper

Defined as:

method hyper(Int(Cool) :$batch = 64, Int(Cool) :$degree = 4)

Returns another Iterable that is potentially iterated in parallel, with a given batch size and degree of parallelism.

The order of elements is preserved.

say ([1..100].hyper.map({ $_ +1 }).list);

Use hyper in situations where it is OK to do the processing of items in parallel, and the output order should be kept relative to the input order. See race for situations where items are processed in parallel and the output order does not matter.

Options degree and batch

The degree option (short for "degree of parallelism") configures how many parallel workers should be started. To start 4 workers (e.g. to use at most 4 cores), pass :4degree to the hyper or race method. Note that in some cases, choosing a degree higher than the available CPU cores can make sense, for example I/O bound work or latency-heavy tasks like web crawling. For CPU-bound work, however, it makes no sense to pick a number higher than the CPU core count.

The batch size option configures the number of items sent to a given parallel worker at once. It allows for making a throughput/latency trade-off. If, for example, an operation is long-running per item, and you need the first results as soon as possible, set it to 1. That means every parallel worker gets 1 item to process at a time, and reports the result as soon as possible. In consequence, the overhead for inter-thread communication is maximized. In the other extreme, if you have 1000 items to process and 10 workers, and you give every worker a batch of 100 items, you will incur minimal overhead for dispatching the items, but you will only get the first results when 100 items are processed by the fastest worker (or, for hyper, when the worker getting the first batch returns.) Also, if not all items take the same amount of time to process, you might run into the situation where some workers are already done and sit around without being able to help with the remaining work. In situations where not all items take the same time to process, and you don't want too much inter-thread communication overhead, picking a number somewhere in the middle makes sense. Your aim might be to keep all workers about evenly busy to make best use of the resources available.

You can also check out this blog post on the semantics of hyper and race

method race

Defined as:

method race(Int(Cool) :$batch = 64, Int(Cool) :$degree = 4 --> Iterable)

Returns another Iterable that is potentially iterated in parallel, with a given batch size and degree of parallelism (number of parallel workers).

Unlike hyper, race does not preserve the order of elements.

say ([1..100].race.map({ $_ +1 }).list);

Use race in situations where it is OK to do the processing of items in parallel, and the output order does not matter. See hyper for situations where you want items processed in parallel and the output order should be kept relative to the input order.

Blog post on the semantics of hyper and race

See hyper for an explanation of :$batch and :$degree.

169 role Iterator

Generic API for producing a sequence of values

constant IterationEnd 
 role Iterator { } 

A Iterator is an object that can generate or provide elements of a sequence. Users usually don't have to care about iterators, their usage is hidden behind iteration APIs such as for @list { }, map, grep, head, tail, skip and list indexing with .[$idx].

The main API is the pull-one method, which either returns the next value, or the sentinel value IterationEnd if no more elements are available. Each class implementing Iterator must provide a pull-one method. All other non-optional Iterator API methods are implemented in terms of pull-one, but can also be overridden by consuming classes for performance or other reasons. There are also optional Iterator API methods that will only be called if they are implemented by the consuming class: these are not implemented by the Iterator role.

IterationEnd

Iterators only allow one iteration over the entire sequence. It's forbidden to make attempts to fetch more data, once IterationEnd has been generated, and behavior for doing so is undefined. For example, the following Seq will not cause the die to be called under normal use, because pull-one will never be called after it returns IterationEnd:

class SkippingArray is Array { 
     # skip all undefined values while iterating 
     method iterator { 
         class :: does Iterator { 
             has $.index is rw = 0; 
             has $.array is required; 
             method pull-one { 
                 $.index++ while !$.array.AT-POS($.index).defined && $.array.elems > $.index; 
                 $.array.elems > $.index ?? $.array.AT-POS($.index++) !! IterationEnd 
             } 
         }.new(array => self) 
     } 
 } 
 
 my @a := SkippingArray.new; 
 
 @a.append: 1, Any, 3, Int, 5, Mu, 7; 
 
 for @a -> $a, $b { 
     say [$a, $b]; 
 } 
 
 # OUTPUT: «[1 3]␤[5 7]␤» 

The only valid use of the sentinel value IterationEnd in a program is identity comparison (using =:=) with the result of a method in the iterator API. Any other behavior is undefined and implementation dependent.

Please bear in mind that IterationEnd is a constant, so if you are going to compare it against the value of a variable, this variable will have to be bound, not assigned. Comparing directly to the output of pull-one will work.

my $it = (1,2).iterator; 
 $it.pull-one for ^2; 
 say $it.pull-one =:= IterationEnd; # OUTPUT: «True␤» 

However, if we use a variable we and we assign it, the result will be incorrect:

my $it = (1,2).iterator; 
 $it.pull-one for ^2; 
 my $is-it-the-end = $it.pull-one; 
 say $is-it-the-end =:= IterationEnd; # OUTPUT: «False␤» 

So we'll have to bind the variable to make it work:

my $is-it-the-end := $it.pull-one; 
 say $is-it-the-end =:= IterationEnd; # OUTPUT: «True␤» 

Methods

method pull-one

Defined as:

method pull-one(Iterator:D: --> Mu)

This method stub ensures that classes implementing the Iterator role provide a method named pull-one.

The pull-one method is supposed to produce and return the next value if possible, or return the sentinel value IterationEnd if no more values could be produced.

my $i = (1 .. 3).iterator;
say $i.pull-one;       # OUTPUT: «1␤»
say $i.pull-one;       # OUTPUT: «2␤»
say $i.pull-one;       # OUTPUT: «3␤»
say $i.pull-one.perl;  # OUTPUT: «IterationEnd␤»

As a more illustrative example of its use, here is a count down iterator along with a simplistic subroutine re-implementation of the for loop.

# works the same as (10 ... 1, 'lift off')
class CountDown does Iterator {
    has Int:D $!current = 10;

    method pull-one ( --> Mu ) {
        my $result = $!current--;
        if $result ==  0 { return 'lift off' }
        if $result == -1 { return IterationEnd }

        # calling .pull-one again after it returns IterationEnd is undefined
        if $result <= -2 {
            # so for fun we will give them nonsense data
            return (1..10).pick;
        }

        return $result;
    }
}

sub for( Iterable:D $sequence, &do --> Nil ) {
    my Iterator:D $iterator = $sequence.iterator;

    loop {
        # must bind the result so that =:= works
        my Mu $pulled := $iterator.pull-one;

        # always check the result and make sure that .pull-one
        # is not called again after it returns IterationEnd
        if $pulled =:= IterationEnd { last }

        do( $pulled );
    }
}

for( Seq.new(CountDown.new), &say );  # OUTPUT: «10␤9␤8␤7␤6␤5␤4␤3␤2␤1␤lift off␤»

It would be more idiomatic to use while or until, and a sigilless variable.

until IterationEnd =:= (my \pulled = $iterator.pull-one) { 
     do( pulled ); 
 } 

method push-exactly

Defined as:

method push-exactly(Iterator:D: $target, int $count --> Mu)

Should produce $count elements, and for each of them, call $target.push($value).

If fewer than $count elements are available from the iterator, it should return the sentinel value IterationEnd. Otherwise it should return $count.

my @array;
say (1 .. ∞).iterator.push-exactly(@array, 3); # OUTPUT: «3␤»
say @array; # OUTPUT: «[1 2 3]␤»

The Iterator role implements this method in terms of pull-one. In general, this is a method that is not intended to be called directly from the end user who, instead, should implement it in classes that mix the iterator role. For instance, this class implements that role:

class DNA does Iterable does Iterator { 
     has $.chain; 
     has Int $!index = 0; 
 
     method new ($chain where { 
                        $chain ~~ /^^ <[ACGT]>+ $$ / and 
                        $chain.chars %% 3 } ) { 
         self.bless( :$chain ); 
     } 
 
     method iterator( ){ self } 
 
     method pull-one( --> Mu){ 
       if $!index < $.chain.chars { 
          my $codon = $.chain.comb.rotor(3)[$!index div 3]; 
          $!index += 3; 
          return $codon; 
       } else { 
         return IterationEnd; 
       } 
     } 
 
     method push-exactly(Iterator:D: $target, int $count --> Mu) { 
         return IterationEnd if $.chain.elems / 3 < $count; 
         for ^($count) { 
             $target.push: $.chain.comb.rotor(3)[ $_ ]; 
         } 
     } 
 
 }; 
 
 my $b := DNA.new("AAGCCT"); 
 for $b -> $a, $b, $c { say "Never mind" }; # Does not enter the loop 
 my $þor := DNA.new("CAGCGGAAGCCT"); 
 for $þor -> $first, $second { 
     say "Coupled codons: $first, $second"; 
     # OUTPUT: «Coupled codons: C A G, C G G␤Coupled codons: A A G, C C T␤» 
 } 

This code, which groups DNA chains in triplets (usually called codons) returns those codons when requested in a loop; if too many are requested, like in the first case for $b -> $a, $b, $c, it simply does not enter the loop since push-exactly will return IterationEnd since it is not able to serve the request for exactly 3 codons. In the second case, however, it requests exactly two codons in each iteration of the loop; push-exactly is being called with the number of loop variables as the $count variable.

method push-at-least

Defined as:

method push-at-least(Iterator:D: $target, int $count --> Mu)

Should produce at least $count elements, and for each of them, call $target.push($value).

If fewer than $count elements are available from the iterator, it should return the sentinel value IterationEnd. Otherwise it should return $count.

Iterators with side effects should produce exactly $count elements; iterators without side effects (such as Range iterators) can produce more elements to achieve better performance.

my @array;
say (1 .. ∞).iterator.push-at-least(@array, 10); # OUTPUT: «10␤»
say @array; # OUTPUT: «[1 2 3 4 5 6 7 8 9 10]␤»

The Iterator role implements this method in terms of pull-one. In general, it is also not intended to be called directly as in the example above. It can be implemented, if unhappy with this default implementation, by those using this role. See the documentation for push-exactly for an example implementation.

method push-all

Defined as:

method push-all(Iterator:D: $target)

Should produce all elements from the iterator and push them to $target.

my @array;
say (1 .. 1000).iterator.push-all(@array); # All 1000 values are pushed

The Iterator role implements this method in terms of push-at-least. As in the case of the other push-* methods, it is mainly intended for developers implementing this role. push-all is called when assigning an object with this role to an array, for instance, like in this example:

class DNA does Iterable does Iterator { 
     has $.chain; 
     has Int $!index = 0; 
 
     method new ($chain where { 
                        $chain ~~ /^^ <[ACGT]>+ $$ / and 
                        $chain.chars %% 3 } ) { 
         self.bless( :$chain ); 
     } 
 
     method iterator( ){ self } 
     method pull-one( --> Mu){ 
       if $!index < $.chain.chars { 
          my $codon = $.chain.comb.rotor(3)[$!index div 3]; 
          $!index += 3; 
          return $codon; 
       } else { 
         return IterationEnd; 
       } 
     } 
 
     method push-all(Iterator:D: $target) { 
         for $.chain.comb.rotor(3) -> $codon { 
             $target.push: $codon; 
         } 
     } 
 
 }; 
 
 my $b := DNA.new("AAGCCT"); 
 my @dna-array = $b; 
 say @dna-array; # OUTPUT: «[(A A G) (C C T)]␤» 

The push-all method implemented pushes to the target iterator in lists of three aminoacid representations; this is called under the covers when we assign $b to @dna-array.

method push-until-lazy

Defined as:

method push-until-lazy(Iterator:D: $target --> Mu)

Should produce values until it considers itself to be lazy, and push them onto $target.

The Iterator role implements this method as a no-op if is-lazy returns a True value, or as a synonym of push-all if not.

This matters mostly for iterators that have other iterators embedded, some of which might be lazy, while others aren't.

method is-lazy

Defined as:

method is-lazy(Iterator:D: --> Bool:D)

Should return True for iterators that consider themselves lazy, and False otherwise.

Built-in operations that know that they can produce infinitely many values return True here, for example (1..6).roll(*).

say (1 .. 100).is-lazy; # OUTPUT: «False␤»
say (1 .. ∞).is-lazy; # OUTPUT: «True␤»

The Iterator role implements this method returning False, indicating a non-lazy iterator.

method sink-all

Defined as:

method sink-all(Iterator:D: --> IterationEnd)

Should exhaust the iterator purely for the side-effects of producing the values, without actually saving them in any way. Should always return IterationEnd. If there are no side-effects associated with producing a value, then it can be implemented by a consuming class to be a virtual no-op.

say (1 .. 1000).iterator.sink-all;  # OUTPUT: «IterationEnd␤»

The Iterator role implements this method as a loop that calls pull-one until it is exhausted.

method skip-one

Defined as:

method skip-one(Iterator:D: $target --> Mu)

Should skip producing one value. The return value should be truthy if the skip was successful and falsy if there were no values to be skipped:

my $i = <a b>.iterator;
say $i.skip-one; say $i.pull-one; say $i.skip-one
# OUTPUT: «1␤b␤0␤»

The Iterator role implements this method as a call pull-one and returning whether the value obtained was not IterationEnd.

method skip-at-least

Defined as:

method skip-at-least(Iterator:D: $target, int $to-skip --> Mu)

Should skip producing $to-skip values. The return value should be truthy if the skip was successful and falsy if there were not enough values to be skipped:

my $i = <a b c>.iterator;
say $i.skip-at-least(2); say $i.pull-one; say $i.skip-at-least(20);
# OUTPUT: «1␤c␤0␤»

The Iterator role implements this method as a loop calling skip-one and returning whether it returned a truthy value sufficient number of times.

method skip-at-least-pull-one

Defined as:

method skip-at-least-pull-one(Iterator:D: $target, int $to-skip --> Mu)

Should skip producing $to-skip values and if the iterator is still not exhausted, produce and return the next value. Should return IterationEnd if the iterator got exhausted at any point:

my $i = <a b c>.iterator;
say $i.skip-at-least-pull-one(2);
say $i.skip-at-least-pull-one(20) =:= IterationEnd;
# OUTPUT: «c␤True␤»

The Iterator role implements this method as calling skip-at-least and then calling pull-one if it was not exhausted yet.

Predictive iterators

Please see the PredictiveIterator role if your Iterator can know how many values it can still produce without actually producing them.

170 class Junction

Logical superposition of values

class Junction is Mu { }

A junction is an unordered composite value of zero or more values. Junctions autothread over many operations, which means that the operation is carried out for each junction element (also known as eigenstate), and the result is junction of the return values of all those operators.

Junctions collapse into a single value in boolean context, so when used in a conditional, a negation or an explicit coercion to Bool through the so or ? prefix operators. The semantics of this collapse depend on the junction type, which can be all, any, one or none.

type constructor operator True if ...
all all & no value evaluates to False
any any | at least one value evaluates to True
one one ^ exactly one value evaluates to True
none none no value evaluates to True

As the table shows, in order to create junctions, you use the string that represents the type followed by any object, or else call .all, .none or .one on the object.

say so 3 == (1..30).one;         # OUTPUT: «True␤»
say so ("a" ^ "b" ^ "c") eq "a"; # OUTPUT: «True␤»

Junctions are very special objects. They fall outside the Any hierarchy, being only, as any other object, subclasses of Mu. That enables a feature for most methods: autothreading. Autothreading happens when a junction is bound to a parameter of a code object that doesn't accept values of type Junction. Instead of producing an error, the signature binding is repeated for each value of the junction.

Example:

my $j = 1|2;
if 3 == $j + 1 {
    say 'yes';
}

First autothreads over the infix:<+> operator, producing the Junction 2|3. The next autothreading step is over infix:<==> , which produces False|True. The if conditional evaluates the junction in boolean context, which collapses it to True. So the code prints yes\n.

The type of a Junction does not affect the number of items in the resultant Junction after autothreading. For example, using a one Junction during Hash key lookup, still results in a Junction with several items. It is only in boolean context would the type of the Junction come into play:

my %h = :42foo, :70bar;
say    %h{one <foo meow>}:exists; # OUTPUT: «one(True, False)␤»
say so %h{one <foo meow>}:exists; # OUTPUT: «True␤»
say    %h{one <foo  bar>}:exists; # OUTPUT: «one(True, True)␤»
say so %h{one <foo  bar>}:exists; # OUTPUT: «False␤»

Note that the compiler is allowed, but not required, to parallelize autothreading (and Junction behavior in general), so it is usually an error to autothread junctions over code with side effects.

Autothreading implies that the function that's autothreaded will also return a Junction of the values that it would usually return.

(1..3).head( 2|3 ).say; # OUTPUT: «any((1 2), (1 2 3))␤»

Since .head returns a list, the autothreaded version returns a Junction of lists.

(1..3).contains( 2&3 ).say; # OUTPUT: «all(True, True)␤»

Likewise, .contains returns a Boolean; thus, the autothreaded version returns a Junction of Booleans. In general, all methods and routines that take an argument of type T and return type TT, will also accept junctions of T, returning junctions of TT.

Implementations are allowed to short-circuit Junctions. For example one or more routine calls (a(), b(), or c()) in the code below might not get executed at all, if the result of the conditional has been fully determined from routine calls already performed (only one truthy return value is enough to know the entire Junction is true):

if a() | b() | c() { 
     say "At least one of the routines was called and returned a truthy value" 
 } 

Junctions are meant to be used as matchers in boolean context; introspection of junctions is not supported. If you feel the urge to introspect a junction, use a Set or a related type instead.

Usage examples:

my @list = <1 2 "Great">;
@list.append(True).append(False);
my @bool_or_int = grep Bool|Int, @list;

sub is_prime(Int $x) returns Bool {
    # 'so' is for boolean context
    so $x %% none(2..$x.sqrt);
}
my @primes_ending_in_1 = grep &is_prime & / 1$ /, 2..100;
say @primes_ending_in_1;        # OUTPUT: «[11 31 41 61 71]␤»

my @exclude = <~ .git>;
for dir(".") { say .Str if .Str.ends-with(none @exclude) }

Special care should be taken when using all with arguments that may produce an empty list:

my @a = ();
say so all(@a) # True, because there are 0 False's

To express "all, but at least one", you can use @a && all(@a)

my @a = ();
say so @a && all(@a);   # OUTPUT: «False␤»

Negated operators are special-cased when it comes to autothreading. $a !op $b is rewritten internally as !($a op $b). The outer negation collapses any junctions, so the return value always a plain Bool.

my $word = 'yes';
my @negations = <no none never>;
if $word !eq any @negations {
    say '"yes" is not a negation';
}

Note that without this special-casing, an expression like $word ne any @words would always evaluate to True for non-trivial lists on one side.

For this purpose, infix:<ne> counts as a negation of infix:<eq> .

In general it is more readable to use a positive comparison operator and a negated junction:

my $word = 'yes';
my @negations = <no none never>;
if $word eq none @negations {
    say '"yes" is not a negation';
}

Failures and Exceptions

Failures are just values like any other, as far as Junctions are concerned:

my $j = +any "not a number", "42", "2.1";
(gather $j».take).grep(Numeric).say; # OUTPUT: «(42 2.1)␤»

Above, we've used prefix + operator on a Junction to coerce the strings inside of it to Numeric. Since the operator returns a Failure when Str that doesn't contain a number gets coerced to Numeric, one of the elements in the Junction is a Failure, but same Failure rules as normal apply and the Failure doesn't explode just because it's in a Junction, and we can .grep it out. The exception will be thrown, if you try to use the Failure as a value—just like were this Failure on its own and not part of the Junction:

my $j = +any "not a number", "42", "2.1"; 
 try say $j == 42; 
 $! and say "Got exception: $!.^name()"; 
 # OUTPUT: «Got exception: X::Str::Numeric␤» 

Note that if an exception gets thrown when any of the values in a Junction get computed, it will be thrown just as if the problematic value were computed on its own and not with a Junction; you can't just compute the values that work while ignoring exceptions:

sub calc ($_) { die when 13 }
my $j = any 1..42;
say try calc $j; # OUTPUT: «Nil␤»

Only one value above causes an exception, but the result of the try block is still a Nil. A possible way around it is to cheat and evaluate the values of the Junction individually and then re-create the Junction from the result:

sub calc ($_) { die when 13 }
my $j = any 1..42;
$j = any (gather $j».take).grep: {Nil !=== try calc $_};
say so $j == 42; # OUTPUT: «True␤»

Smartmatching

Note that using Junctions on the right-hand side of ~~ works slightly differently than using Junctions with other operators.

Consider this example:

say 25 == (25 | 42);    # OUTPUT: «any(True, False)␤» – Junction
say 25 ~~ (25 | 42);    # OUTPUT: «True␤»             – Bool

The reason is that == (and most other operators) are subject to auto-threading, and therefore you will get a Junction as a result. On the other hand, ~~ will call .ACCEPTS on the right-hand-side (in this case on a Junction) and the result will be a Bool.

Methods

method new

Defined as:

multi method new(Junction: \values, Str :$type!)
multi method new(Junction: Str:D \type, \values)

Constructor to define a new Junction from the type that defines de Junction and a set of values.

my $j = Junction.new(<Þor Oðinn Loki>, type => "all");
my $n = Junction.new( "one", 1..6 )

method defined

Defined as:

multi method defined(Junction:D:)

Checks for definedness instead of Boolean values.

say ( 3 | Str).defined ;   # OUTPUT: «True␤»
say (one 3, Str).defined;  # OUTPUT: «True␤»
say (none 3, Str).defined; # OUTPUT: «False␤»

Failures are also considered non-defined:

my $foo=Failure.new;
say (one 3, $foo).defined; # OUTPUT: «True␤»

Since 6.d, this method will autothread.

method Bool

Defined as:

multi method Bool(Junction:D:)

Collapses the Junction and returns a single Boolean value according to the type and the values it holds. Every element is transformed to Bool.

my $n = Junction.new( "one", 1..6 ); 
 say $n.Bool;                         # OUTPUT: «False␤» 

All elements in this case are converted to True, so it's false to assert that only one of them is.

my $n = Junction.new( "one", <0 1> ); 
 say $n.Bool;                         # OUTPUT: «True␤» 

Just one of them is truish in this case, 1, so the coercion to Bool returns True.

method Str

Defined as:

multi method Str(Junction:D:)

Autothreads the .Str method over its elements and returns results as a Junction. Output methods that use .Str method (print and put) are special-cased to autothread junctions, despite being able to accept a Mu type.

method gist

Defined as:

multi method gist(Junction:D:)

Collapses the Junction and returns a Str composed of the type of the junction and the gists of its components:

<a 42 c>.all.say; # OUTPUT: «all(a, 42, c)␤»

method perl

Defined as:

multi method perl(Junction:D:)

Collapses the Junction and returns a Str composed of perls of its components that evaluates to the equivalent Junction with equivalent components:

<a 42 c>.all.perl.put; # OUTPUT: «all("a", IntStr.new(42, "42"), "c")␤»

infix ~

Defined as:

multi sub infix:<~>(Str:D $a, Junction:D $b)
multi sub infix:<~>(Junction:D $a, Str:D $b)
multi sub infix:<~>(Junction:D \a, Junction:D \b)

The infix ~ concatenation can be used to merge junctions into a single one or merge Junctions with strings. The resulting junction will have all elements merged as if they were joined into a nested loop:

my $odd  = 1|3|5; 
 my $even = 2|4|6; 
 
 my $merged = $odd ~ $even; 
 say $merged; #OUTPUT: «any(12, 14, 16, 32, 34, 36, 52, 54, 56)␤» 
 
 say "Found 34!" if 34 == $merged; #OUTPUT: «Found 34!␤» 
 my $prefixed = "0" ~ $odd; 
 say "Found 03" if "03" == $prefixed; #OUTPUT: «Found 03!␤» 
 
 my $postfixed = $odd ~ "1"; 
 say "Found 11" if 11 == $postfixed; #OUTPUT: «Found 11!␤» 

On the other hand, the versions of ~ that use a string as one argument will just concatenate the string to every member of the Junction, creating another Junction with the same number of elements.

See Also

171 class Kernel

Kernel related information

class Kernel does Systemic { }

Built-in class for providing kernel related information. Usually accessed through the $*KERNEL dynamic variable.

Methods

method arch

method arch

Instance method returning the "arch" (as in "architecture") information of the Kernel object. Dies if the "arch" could not be established.

method archname

method archname

Instance method returning the concatenation of hardware and name.

method bits

method bits

Instance method returning the number of bits used in the architecture of the processor. Usually 32 or 64.

method cpu-cores

method cpu-cores(--> Int)

Instance / Class method returning the number of CPU cores that are available.

say $*KERNEL.cpu-cores; # OUTPUT: «8␤»

method cpu-usage

method cpu-usage(--> Int)

Instance / Class method returning the amount of CPU uses since the start of the program (in microseconds).

method free-memory

method free-memory(--> Int)

Instance / Class method returning the available memory on the system. When using the JVM, this returns the available memory to the JVM instead. This method is only available in release v2019.06 and later.

method total-memory

method total-memory(--> Int)

Instance / Class method returning the total memory available to the system. When using the JVM, this returns the total memory available to the JVM instead. This method is only available in release v2019.06 and later.

method endian

method endian(--> Endian:D)

Class method that returns the Endian object associated with the kernel architecture (either LittleEndian or BigEndian).

method hardware

Defined as

method hardware

Instance method returning the hardware information of the Kernel object. Dies if the hardware information could not be established.

say $*KERNEL.hardware; # OUTPUT: «x86_64␤»

method hostname

method hostname

Instance method returning the hostname of the Kernel object.

method release

method release

Instance method returning the release information of the Kernel object. Dies if the release information could not be established.

method signal

Defined as:

multi method signal(Kernel:D: Str:D $signal --> Int:D)
multi method signal(Kernel:D: Signal:D \signal --> Int:D)
multi method signal(Kernel:D: Int:D \signal --> Int:D)

Instance method returning the Signal numeric code for a given name for the Kernel object.

say $*KERNEL.signal("INT"); # OUTPUT: «2␤»

method signals

Instance method returning a list of Signals that are supported by the kernel represented by the Kernel object.

172 class Label

Tagged location in the source code

class Label {}

Labels are used in Perl 6 to tag loops so that you can specify the one you want to jump to with statements such as last. You can use it to jump out of loops and get to outer ones, instead of just exiting the current loop or going to the statement before.

USERS:          # the label 
 for @users -> $u { 
     for $u.pets -> $pet { 
         # usage of a label 
         next USERS if $pet.barks; 
     } 
     say "None of {$u}'s pets barks"; 
 } 
 say USERS.^name;        # OUTPUT: «Label␤» 

Those label are objects of type Label, as shown in the last statement. Labels can be used in any loop construct, as long as they appear right before the loop statement.

my $x = 0; 
 my $y = 0; 
 my $t = ''; 
 A: while $x++ < 2 { 
     $t ~= "A$x"; 
     B: while $y++ < 2 { 
         $t ~= "B$y"; 
         redo A if $y++ == 1; 
         last A 
     } 
 } 
 say $t; # OUTPUT: «A1B1A1A2» 

Putting them on the line before the loop or the same line is optional. Labels must follow the syntax of ordinary identifiers, although traditionally we will use the latin alphabet in uppercase so that they stand out in the source. You can use, however, other alphabets like here:

駱駝道: while True {
  say 駱駝道.name;
  last 駱駝道;
}

Methods

method name

Defined as:

method name()

Not terribly useful, returns the name of the defined label:

A: while True {
  say A.name; # OUTPUT: «A»
  last A;
}

method next

Defined as:

method next(Label:)

Begin the next iteration of the loop associated with the label.

MY-LABEL:
for 1..10 {
    next MY-LABEL if $_ < 5;
    print "$_ ";
}

# OUTPUT: «5 6 7 8 9 10 »

method redo

Defined as:

method redo(Label:)

Repeat the same iteration of the loop associated with the label.

my $has-repeated = False;

MY-LABEL:
for 1..10 {
    print "$_ ";
    if $_ == 5 {
        LEAVE $has-repeated = True;
        redo MY-LABEL unless $has-repeated;
    }
}

# OUTPUT: «1 2 3 4 5 5 6 7 8 9 10 »

method last

Defined as:

method last(Label:)

Terminate the execution of the loop associated with the label.

MY-LABEL:
for 1..10 {
    last MY-LABEL if $_ > 5;
    print "$_ ";
}

# OUTPUT: «1 2 3 4 5 »

173 class List

Sequence of values

my class List does Iterable does Positional { } 

List stores items sequentially and potentially lazily.

Indexes into lists and arrays start at 0 by default.

You can assign to list elements if they are containers. Use Arrays to have every value of the list stored in a container.

List implements Positional and as such provides support for subscripts.

Items, flattening and sigils

In Perl 6, assigning a List to a scalar variable does not lose information. The difference is that iteration generally treats a list (or any other list-like object, like a Seq or an Array) inside a scalar as a single element.

my $s = (1, 2, 3);
for $s { }      # one iteration
for $s.list { } # three iterations

my $t = [1, 2, 3];
for $t { }      # one iteration
for $t.list { } # three iterations

my @a = 1, 2, 3;
for @a { }      # three iterations
for @a.item { } # one iteration

This operation is called itemization or putting in an item context. .item does the job for objects, as well as $( ... ) and, on array variables, $@a.

Lists generally don't interpolate (flatten) into other lists, except when they are in list context and the single argument to an operation such as append:

my $a = (1, 2, 3);
my $nested = ($a, $a);  # two elements

my $flat = $nested.map({ .Slip });  # six elements, with explicit Slip

my @b = <a b>;
@b.append: $a.list;     # The array variable @b has 5 elements, because
                        # the list $a is the sole argument to append

say @b.elems;           # OUTPUT: «5␤»

my @c = <a b>;
@c.append: $a.list, 7;  # The array variable @c has 4 elements, because
                        # the list $a wasn't the only argument and thus
                        # wasn't flatten by the append operation

say @c.elems;           # OUTPUT: «4␤»

my @d = <a b>;
@d.append: $a;          # The array variable @d has 3 elements, because
                        # $a is in  and as far as append is
                        # concerned a single element

say @d.elems;           # OUTPUT: «3␤»

The same flattening behavior applies all objects that do the Iterable role, notable hashes:

my %h = a => 1, b => 2;
my @b = %h;   say @b.elems;     # OUTPUT: «2␤»
my @c = %h, ; say @c.elems;     # OUTPUT: «1␤»
my @d = $%h;  say @d.elems;     # OUTPUT: «1␤»

Slurpy parameters (*@a) flatten non-itemized sublists:

sub fe(*@flat) { @flat.elems }
say fe(<a b>, <d e>);           # OUTPUT: «4␤»
say fe(<a b>, <d e>.item);      # OUTPUT: «3␤»

The empty list is created with (). Smartmatching against the empty list will check for the absence of elements.

my @a;
for @a, @a.list, @a.Seq -> \listoid {
    say listoid ~~ ()
}
# OUTPUT: «True␤True␤True␤»

Coercion to Bool also indicates if the List got any elements.

my @a;
say [@a.elems, @a.Bool, ?@a]; # OUTPUT: «[0 False False]␤»
@a.push: 42;
say [@a.elems, @a.Bool, ?@a]; # OUTPUT: «[1 True True]␤»
say 'empty' unless @a;        # no output

Methods

method ACCEPTS

Defined as:

multi method ACCEPTS(List:D: $topic)

If $topic is an Iterable, returns True or False based on whether the contents of the two Iterables match. A Whatever element in the invocant matches anything in the corresponding position of the $topic Iterable. A HyperWhatever matches any number of any elements, including no elements:

say (1, 2, 3)       ~~ (1,  *, 3);  # OUTPUT: «True␤»
say (1, 2, 3)       ~~ (9,  *, 5);  # OUTPUT: «False␤»
say (1, 2, 3)       ~~ (   **, 3);  # OUTPUT: «True␤»
say (1, 2, 3)       ~~ (   **, 5);  # OUTPUT: «False␤»
say (1, 3)          ~~ (1, **, 3); # OUTPUT: «True␤»
say (1, 2, 4, 5, 3) ~~ (1, **, 3); # OUTPUT: «True␤»
say (1, 2, 4, 5, 6) ~~ (1, **, 5); # OUTPUT: «False␤»
say (1, 2, 4, 5, 6) ~~ (   **   ); # OUTPUT: «True␤»
say ()              ~~ (   **   ); # OUTPUT: «True␤»

In addition, returns False if either the invocant or $topic is a lazy Iterable, unless $topic is the same object as the invocant, in which case True is returned.

If $topic is not an Iterable, returns the invocant if the invocant has no elements or its first element is a Match object (this behavior powers m:g// smartmatch), or False otherwise.

routine elems

Defined as:

sub    elems($list --> Int:D)
method elems(List:D: --> Int:D)

Returns the number of elements in the list.

say (1,2,3,4).elems; # OUTPUT: «4␤»

routine end

Defined as:

sub    end($list --> Int:D)
method end(List:D: --> Int:D)

Returns the index of the last element.

say (1,2,3,4).end; # OUTPUT: «3␤»

routine keys

Defined as:

sub    keys($list --> Seq:D)
method keys(List:D: --> Seq:D)

Returns a sequence of indexes into the list (e.g., 0..(@list.elems-1)).

say (1,2,3,4).keys; # OUTPUT: «0..3␤»

routine values

Defined as:

sub    values($list --> Seq:D)
method values(List:D: --> Seq:D)

Returns a sequence of the list elements, in order.

say (1,2,3,4).^name;        # OUTPUT: «List␤»
say (1,2,3,4).values.^name; # OUTPUT: «Seq␤»

routine kv

Defined as:

sub    kv($list --> Seq:D)
method kv(List:D: --> Seq:D)

Returns an interleaved sequence of indexes and values. For example

<a b c>.kv; # (0 a 1 b 2 c)

routine pairs

Defined as:

sub    pairs($list --> Seq:D)
method pairs(List:D: --> Seq:D)

Returns a sequence of pairs, with the indexes as keys and the list values as values.

<a b c>.pairs   # (0 => a 1 => b 2 => c)

routine antipairs

Defined as:

method antipairs(List:D: --> Seq:D)

Returns a Seq of pairs, with the values as keys and the indexes as values, i.e. the direct opposite to pairs.

say <a b c>.antipairs;  # OUTPUT: «(a => 0 b => 1 c => 2)␤»

routine invert

Defined as:

method invert(List:D: --> Seq:D)

Assumes every element of the List is a Pair. Returns all elements as a Seq of Pairs where the keys and values have been exchanged. If the value of a Pair is an Iterable, then it will expand the values of that Iterable into separate pairs.

my $l = List.new('a' => (2, 3), 'b' => 17);
say $l.invert;   # OUTPUT: «(2 => a 3 => a 17 => b)␤»

routine join

Defined as:

sub    join($separator, *@list)
method join(List:D: $separator = "")

Treats the elements of the list as strings by calling .Str on each of them, interleaves them with $separator and concatenates everything into a single string. Note that you can omit the $separator if you use the method syntax.

Example:

join ', ', <a b c>;             # RESULT: «a, b, c»

Note that the method form does not flatten sublists:

say (1, <a b c>).join('|');     # OUTPUT: «1|a b c␤»

The method form also allows you to omit the separator:

say <a b c>.join;               # OUTPUT: «abc␤»

But it behaves slurpily, flattening all arguments after the first into a single list:

say join('|', 3, 'þ', 1+4i);    # OUTPUT: «3|þ|1+4i␤»
say join ', ', <a b c>, 'd', 'e' , 'f'; # OUTPUT: «a, b, c, d, e, f␤»

In this case, the first list <a b c is slurped and flattened, unlike what happens when join is invoked as a method.

If one of the elements of the list happens to be a Junction, then join will also return a Junction with concatenation done as much as possible:

say ("a"|"b","c","d").join;     # OUTPUT: «any(acd,bcd)␤»

routine map

Defined as:

multi method map(Hash:D \hash)
multi method map(Iterable:D \iterable)
multi method map(|c)
multi method map(\SELF: &block;; :$label, :$item)
multi sub map(&code, +values)

Examples applied to lists are included here for the purpose of illustration.

For a list, it invokes &code for each element and gathers the return values in a sequence and returns it. This happens lazily, i.e. &code is only invoked when the return values are accessed.Examples:

say ('hello', 1, 22/7, 42, 'world').map: { .^name } # OUTPUT: «(Str Int Rat Int Str)␤» 
 say map *.Str.chars, 'hello', 1, 22/7, 42, 'world'; # OUTPUT: «(5 1 8 2 5)␤» 

map inspects the arity of the code object, and tries to pass as many arguments to it as expected:

sub b($a, $b) { "$a before $b" };
say <a b x y>.map(&b).join(', ');   # OUTPUT: «a before b, x before y␤»

iterates the list two items at a time.

Note that map does not flatten embedded lists and arrays, so

((1, 2), <a b>).map({ .join(',')})

passes (1, 2) and <a b> in turn to the block, leading to a total of two iterations and the result sequence "1,2", "a,b". See method flatmap for an alternative that flattens.

If &code is a Block loop phasers will be executed and loop control statements will be treated as in loop control flow. Please note that return is executed in the context of its definition. It is not the return statement of the block but the surrounding Routine. Using a Routine will also handle loop control statements and loop phasers. Any Routine specific control statement or phaser will be handled in the context of that Routine.

sub s {
    my &loop-block = {
        return # return from sub s
    };
    say 'hi';
    (1..3).map: &loop-block;
    say 'oi‽' # dead code
};
s
# RESULT: «hi»

method flatmap

Defined as:

method flatmap(List:D: &code --> Seq:D)

Like map iterates over the elements of the invocant list, feeding each element in turn to the code reference, and assembling the return values from these invocations in a result list.

The use of flatmap is strongly discouraged. Instead of .flatmap( ), please use .map( ).flat as it is clear when the .flat is called and is not confusing like .flatmap.

Unlike map it flattens non-itemized lists and arrays, so

## flatmap
my @list = ('first1', ('second2', ('third3', 'third4'), 'second5'), 'first6');
say @list.flatmap({.reverse}).perl;
# OUTPUT «("first1", "second5", "third3", "third4", "second2", "first6").Seq␤»
## map
say @list.map({"$_ was a {.^name}"}).perl;
# OUTPUT «("first1 was a Str", "second2 third3 third4 second5 was a List", "first6 was a Str").Seq␤»
## .map .flat has the same output as .flatmap
say @list.map({.reverse}).flat.perl
# OUTPUT «("first1", "second5", "third3", "third4", "second2", "first6").Seq␤»

method gist

Defined as:

multi method gist(List:D: --> Str:D)

Returns the string containing the parenthesized "gist" of the List, listing up to the first 100 elements, separated by space, appending an ellipsis if the List has more than 100 elements. If List is-lazy, returns string '(...)'

put (1, 2, 3).gist;   # OUTPUT «(1 2 3)␤» 
 put (1..∞).List.gist; # OUTPUT «(...)␤» 
 
 put (1..200).List.gist; 
 # OUTPUT: 
 # (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 
 # 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 
 # 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 
 # 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 
 # 96 97 98 99 100 ...) 

routine grep

Defined as:

sub    grep(Mu $matcher, *@elems, :$k, :$kv, :$p, :$v --> Seq:D)
method grep(List:D:  Mu $matcher, :$k, :$kv, :$p, :$v --> Seq:D)

Returns a sequence of elements against which $matcher smartmatches. The elements are returned in the order in which they appear in the original list.

Examples:

say ('hello', 1, 22/7, 42, 'world').grep: Int;              # OUTPUT: «(1 42)␤»
say grep { .Str.chars > 3 }, 'hello', 1, 22/7, 42, 'world'; # OUTPUT: «(hello 3.142857 world)␤»

Note that if you want to grep for elements that do not match, you can use a none-Junction:

say <a b 6 d 8 0>.grep(none Int);           # OUTPUT: «(a b d)␤»
say <a b c d e f>.grep(none /<[aeiou]>/);   # OUTPUT: «(b c d f)␤»

Another option to grep for elements that do not match a regex is to use a block:

say <a b c d e f>.grep({! /<[aeiou]>/})     # OUTPUT: «(b c d f)␤»

The reason the example above works is because a regex in boolean context applies itself to $_. In this case, ! boolifies the /<[aeiou]>/ regex and negates the result. Smartmatching against a Callable (in this case a Block) returns the value returned from that callable, so the boolified result of a regex is then used to decide whether the current value should be kept in the result of a grep.

The optional named parameters :k, :kv, :p, :v provide the same functionality as on slices:

Only return the index values of the matching elements in order.

Return both the index and matched elements in order.

Return the index and the matched element as a Pair, in order.

Only return the matched elements (same as not specifying any named parameter at all).

Examples:

say ('hello', 1, 22/7, 42, 'world').grep: Int, :k;
# OUTPUT: «(1 3)␤»
say grep { .Str.chars > 3 }, :kv, 'hello', 1, 22/7, 42, 'world';
# OUTPUT: «(0 hello 2 3.142857 4 world)␤»
say grep { .Str.chars > 3 }, :p, 'hello', 1, 22/7, 42, 'world';
# OUTPUT: «(0 => hello 2 => 3.142857 4 => world)␤»

routine first

Defined as:

sub    first(Mu $matcher, *@elems, :$k, :$kv, :$p, :$end)
method first(List:D:  Mu $matcher?, :$k, :$kv, :$p, :$end)

Returns the first item of the list which smartmatches against $matcher, returns Nil when no values match. The optional named parameter :end indicates that the search should be from the end of the list, rather than from the start.

Examples:

say (1, 22/7, 42, 300).first: * > 5;                  # OUTPUT: «42␤»
say (1, 22/7, 42, 300).first: * > 5, :end;            # OUTPUT: «300␤»
say ('hello', 1, 22/7, 42, 'world').first: Complex;   # OUTPUT: «Nil␤»

The optional named parameters :k, :kv, :p provide the same functionality as on slices:

Return the index value of the matching element. Index is always counted from the beginning of the list, regardless of whether the :end named parameter is specified or not.

Return both the index and matched element.

Return the index and the matched element as a Pair.

Examples:

say (1, 22/7, 42, 300).first: * > 5, :k;        # OUTPUT: «2␤»
say (1, 22/7, 42, 300).first: * > 5, :p;        # OUTPUT: «2 => 42␤»
say (1, 22/7, 42, 300).first: * > 5, :kv, :end; # OUTPUT: «(3 300)␤»

In method form, the $matcher can be omitted, in which case the first available item (or last if :end is set) will be returned. See also head and tail methods.

method head

Defined as:

multi method head(Any:D:) is raw
multi method head(Any:D: Callable:D $w)
multi method head(Any:D: $n)

This method is directly inherited from Any, and it returns the first $n items of the list, an empty list if $n <= 0, or the first element with no argument. The version that takes a Callable uses a WhateverCode to specify all elements, starting from the first, but the last ones.

Examples:

say <a b c d e>.head ;     # OUTPUT: «a␤»
say <a b c d e>.head(2);   # OUTPUT: «(a b)␤»
say <a b c d e>.head(*-3); # OUTPUT: «(a b)␤»

method tail

Defined as:

multi method tail(List:D:)
multi method tail(List:D: $n --> Seq:D)

Returns a Seq containing the last $n items of the list. Returns an empty Seq if $n <= 0. Defaults to the last element if no argument is specified. Throws an exception if the list is lazy.

Examples:

say <a b c d e>.tail(*-3);# OUTPUT: «(d e)␤» 
 say <a b c d e>.tail(2);  # OUTPUT: «(d e)␤» 
 say <a b c d e>.tail;     # OUTPUT: «e␤» 

In the first case, $n is taking the shape of a WhateverCode to indicate the number of elements from the beginning that will be excluded. $n can be either a Callable, in which case it will be called with the value 0, or anything else that can be converted to a number, in which case it will use that as the number of elements in the output Seq.

say <a b c d e>.tail( { $_ - 2 } ); # OUTPUT: «(c d e)␤»

routine categorize

Defined as:

multi method categorize()
multi method categorize(Whatever)
multi method categorize($test, :$into!, :&as)
multi method categorize($test, :&as)
multi sub categorize($test, +items, :$into!, *%named )
multi sub categorize($test, +items, *%named )

These methods are directly inherited from Any; see Any.list for more examples.

This routine transforms a list of values into a hash representing the categorizations of those values according to $test, which is called once for every element in the list; each hash key represents one possible categorization for one or more of the incoming list values, and the corresponding hash value contains an array of those list values categorized by the $test, acting like a mapper, into the category of the associated key.

Note that, unlike classify, which assumes that the return value of the mapper is a single value, categorize always assumes that the return value of the mapper is a list of categories that are appropriate to the current value.

Example:

sub mapper(Int $i) returns List {
    $i %% 2 ?? 'even' !! 'odd',
    $i.is-prime ?? 'prime' !! 'not prime'
}
say categorize &mapper, (1, 7, 6, 3, 2);  # OUTPUT: «{even => [6 2], not prime => [1 6],
                                          #          odd => [1 7 3], prime => [7 3 2]}␤»

routine classify

Defined as:

multi method classify($test, :$into!, :&as)
multi method classify($test, :&as)
multi sub classify($test, +items, :$into!, *%named )
multi sub classify($test, +items, *%named )

Transforms a list of values into a hash representing the classification of those values; each hash key represents the classification for one or more of the incoming list values, and the corresponding hash value contains an array of those list values classified into the category of the associated key. $test will be an expression that will produce the hash keys according to which the elements are going to be classified.

Example:

say classify { $_ %% 2 ?? 'even' !! 'odd' }, (1, 7, 6, 3, 2);
# OUTPUT: «{even => [6 2], odd => [1 7 3]}␤»
say ('hello', 1, 22/7, 42, 'world').classify: { .Str.chars };
# OUTPUT: «{1 => [1], 2 => [42], 5 => [hello world], 8 => [3.142857]}␤»

It can also take :as as a named parameter, transforming the value before classifying it:

say <Innie Minnie Moe>.classify( { $_.chars }, :as{ lc $_ });
# OUTPUT: «{3 => [moe], 5 => [innie], 6 => [minnie]}␤»

This code is classifying by number of characters, which is the expression that has been passed as $test parameter, but the :as block lowercases it before doing the transformation. The named parameter :into can also be used to classify into a newly defined variable:

<Innie Minnie Moe>.classify( { $_.chars }, :as{ lc $_ }, :into( my %words{Int} ) );
say %words; # OUTPUT: «{3 => [moe], 5 => [innie], 6 => [minnie]}␤»

We are declaring the scope of %words{Int} on the fly, with keys that are actually integers; it gets created with the result of the classification.

method Bool

Defined as:

method Bool(List:D: --> Bool:D)

Returns True if the list has at least one element, and False for the empty list.

say ().Bool;  # OUTPUT: «False␤»
say (1).Bool; # OUTPUT: «True␤»

method Str

Defined as:

method Str(List:D: --> Str:D)

Stringifies the elements of the list and joins them with spaces (same as .join(' ')).

say (1,2,3,4,5).Str; # OUTPUT: «1 2 3 4 5␤»

method Int

Defined as:

method Int(List:D: --> Int:D)

Returns the number of elements in the list (same as .elems).

say (1,2,3,4,5).Int; # OUTPUT: «5␤»

method Numeric

Defined as:

method Numeric(List:D: --> Int:D)

Returns the number of elements in the list (same as .elems).

say (1,2,3,4,5).Numeric; # OUTPUT: «5␤»

method Capture

Defined as:

method Capture(--> Capture:D)

Returns a Capture where each Pair, if any, in the List has been converted to a named argument (with the key of the Pair stringified). All other elements in the List are converted to positional arguments in the order they are found, i.e. the first non pair item in the list becomes the first positional argument, which gets index 0, the second non pair item becomes the second positional argument, getting index 1 etc.

my $list = (7, 5, a => 2, b => 17);
my $capture = $list.Capture;
say $capture.keys;                                # OUTPUT: «(0 1 a b)␤»
my-sub(|$capture);                                # RESULT: «7, 5, 2, 17»

sub my-sub($first, $second, :$a, :$b) {
    say "$first, $second, $a, $b"
}

A more advanced example demonstrating the returned Capture being matched against a Signature.

my $list = (7, 5, a => 2, b => 17);
say so $list.Capture ~~ :($ where * == 7,$,:$a,:$b); # OUTPUT: «True␤»

$list = (8, 5, a => 2, b => 17);
say so $list.Capture ~~ :($ where * == 7,$,:$a,:$b); # OUTPUT: «False␤»

routine pick

Defined as:

multi sub    pick($count, *@list --> Seq:D)
multi method pick(List:D: $count --> Seq:D)
multi method pick(List:D: --> Mu)

If $count is supplied: Returns $count elements chosen at random and without repetition from the invocant. If * is passed as $count, or $count is greater than or equal to the size of the list, then all elements from the invocant list are returned in a random sequence; i.e. they are returned shuffled.

In method form, if $count is omitted: Returns a single random item from the list, or Nil if the list is empty

Examples:

say <a b c d e>.pick;           # OUTPUT: «b␤»
say <a b c d e>.pick: 3;        # OUTPUT: «(c a e)␤»
say <a b c d e>.pick: *;        # OUTPUT: «(e d a b c)␤»

routine roll

Defined as:

multi sub    roll($count, *@list --> Seq:D)
multi method roll(List:D: $count --> Seq:D)
multi method roll(List:D: --> Mu)

If $count is supplied: Returns a sequence of $count elements, each randomly selected from the list. Each random choice is made independently, like a separate die roll where each die face is a list element. If * is passed as $count returns a lazy, infinite sequence of randomly chosen elements from the original list.

If $count is omitted: Returns a single random item from the list, or Nil if the list is empty

Examples:

say <a b c d e>.roll;       # 1 random letter
say <a b c d e>.roll: 3;    # 3 random letters
say roll 8, <a b c d e>;    # 8 random letters

my $random-digits := (^10).roll(*);
say $random-digits[^15];    # 15 random digits

routine eager

Defined as:

multi method eager(List:D: --> List:D)
multi sub eager(*@elems --> List:D)

Evaluates all elements in the List eagerly, and returns them as a List.

my  \ll = (lazy 1..5).cache;

say ll[];     # OUTPUT: «(...)␤»
say ll.eager  # OUTPUT: «(1 2 3 4 5)␤»

routine reverse

Defined as:

multi sub    reverse(*@list  --> Seq:D)
multi method reverse(List:D: --> Seq:D)

Returns a Seq with the same elements in reverse order.

Note that reverse always refers to reversing elements of a list; to reverse the characters in a string, use flip.

Examples:

say <hello world!>.reverse;     # OUTPUT: «(world! hello)␤»
say reverse ^10;                # OUTPUT: «(9 8 7 6 5 4 3 2 1 0)␤»

routine rotate

Defined as:

multi sub    rotate(@list,  Int:D $n = 1 --> List:D)
multi method rotate(List:D: Int:D $n = 1 --> List:D)

Returns the list rotated by $n elements.

Examples:

<a b c d e>.rotate(2);   # <c d e a b>
<a b c d e>.rotate(-1);  # <e a b c d>

routine sort

Defined as:

multi sub    sort(*@elems      --> Seq:D)
multi sub    sort(&custom-routine-to-use, *@elems --> Seq:D)
multi method sort(List:D:      --> Seq:D)
multi method sort(List:D: &custom-routine-to-use  --> Seq:D)

Sorts the list, smallest element first. By default infix:<cmp> is used for comparing list elements.

If &custom-routine-to-use is provided, and it accepts two arguments, it is invoked for pairs of list elements, and should return Order::Less, Order::Same or Order::More.

If &custom-routine-to-use accepts only one argument, the list elements are sorted according to custom-routine-to-use($a) cmp custom-routine-to-use($b) . The return values of &custom-routine-to-use are cached, so that &custom-routine-to-use is only called once per list element.

Examples:

say (3, -4, 7, -1, 2, 0).sort;                  # OUTPUT: «(-4 -1 0 2 3 7)␤»
say (3, -4, 7, -1, 2, 0).sort: *.abs;           # OUTPUT: «(0 -1 2 3 -4 7)␤»
say (3, -4, 7, -1, 2, 0).sort: { $^b leg $^a }; # OUTPUT: «(7 3 2 0 -4 -1)␤»

Additionally, if &custom-routine-to-use returns a List, elements will be sorted based upon multiple values with subsequent values in the List being used to break the tie if the comparison between the prior elements evaluate to Order::Same.

my @resistance = (
    %( first-name => 'Kyle',  last-name => 'Reese'  ),
    %( first-name => 'Sarah', last-name => 'Connor' ),
    %( first-name => 'John',  last-name => 'Connor' ),
);
.say for @resistance.sort: { .<last-name>, .<first-name> };

#`(
OUTPUT:
  {first-name => John, last-name => Connor}
  {first-name => Sarah, last-name => Connor}
  {first-name => Kyle, last-name => Reese}
)

This sorting can be based on characteristics of a single element:

say <ddd aaa bbb bb ccc c>.sort( {.chars, .Str} ); 
 # OUTPUT: «(c bb aaa bbb ccc ddd)␤» 

In this case, elements of the array are sorted in ascending order according first to the string length (.chars) and second to the actual alphabetical order .Str) if the length is exactly the same.

Any number of criteria can be used in this:

say <01 11 111 2 20 02>.sort( { .Int, .comb.sum, .Str } ); 
 # OUTPUT: «(01 02 2 11 20 111)␤» 

routine reduce

Defined as:

multi method reduce(Any:U: & --> Nil)
multi method reduce(Any:D: &with)
multi sub reduce (&with, +list)

The first form is obviously a no-op. The second form generates a single "combined" value from a list of arbitrarily many values, by iteratively applying a function which knows how to combine two values.

If @values contains just a single element, the operator is applied to that single element if possible; if not, it returns the element itself.

say [-] <10 5 3>; #OUTPUT: 2␤
say [-] 10;       #OUTPUT: 10␤

If it contains no elements, an exception is thrown, unless &with is an operator with a known identity value. For this reason, you may want to prefix the input list with an explicit identity value:

my @strings = ("One good string!", "And one another good string!");
say reduce { $^a ~ $^b }, '', |@strings;               # like @strings.join
my @numbers = (1,2,3,4,5);
say reduce { $^a > $^b ?? $^a !! $^b }, 0, |@numbers;  # like @numbers.max

If &with is the function object of an operator, its inherent identity value and associativity is respected - in other words, (VAL1, VAL2, VAL3).reduce(&[OP]) is the same as VAL1 OP VAL2 OP VAL3 even for operators which aren't left-associative:

# Raise 2 to the 81st power, because 3 to the 4th power is 81
[2,3,4].reduce(&[**]).lsb.say;        # OUTPUT: «81␤»
(2**(3**4)).lsb.say;                  # OUTPUT: «81␤»
(2**3**4).lsb.say;                    # OUTPUT: «81␤»

# Subtract 4 from -1, because 2 minus 3 is -1
[2,3,4].reduce(&[-]).say;             # OUTPUT: «-5␤»
((2-3)-4).say;                        # OUTPUT: «-5␤»
(2-3-4).say;                          # OUTPUT: «-5␤»

Since reducing with an infix operator is a common thing to do, the [ ] metaoperator provides a syntactic shortcut:

# The following all do the same thing...
my @numbers = (1,2,3,4,5);
say reduce { $^a + $^b }, 0, |@numbers;
say reduce * + *, 0, |@numbers;
say reduce &[+], @numbers; # operator does not need explicit identity
say [+] @numbers;          # most people write it this way

Please note also the use of reduce in sub form. Since reduce is an implicit loop, it responds to next, last and redo statements inside &with:

say (2,3,4,5).reduce: { last if $^a > 7; $^a + $^b }; # says 9

Practical example:

# Generate a random-ish math formula like "(4 + ((3 * x) + 11) / 6))"

my @ops = [Z] (<+ - * />, 1..20)».roll(4);

say ('x', |@ops).reduce: -> $formula, [$op, $number] {
    Bool.pick ?? "($formula $op $number)"
              !! "($number $op $formula)"
}

Note: In the functional programming world, this operation is generally called a fold. With a right-associative operator it is a right fold, otherwise (and usually) it is a left fold:

sub infix:<foo>($a, $b) is assoc<right> { "($a, $b)" }
say [foo] 1, 2, 3, 4; # OUTPUT: «(1, (2, (3, 4)))␤»

sub infix:<bar>($a, $b) is assoc<left> { "($a, $b)" }
say [bar] 1, 2, 3, 4; # OUTPUT: «(((1, 2), 3), 4)␤»

routine produce

Defined as:

multi sub    produce(&with, *@values)
multi method produce(List:D: &with)

Generates a list of all intermediate "combined" values along with the final result by iteratively applying a function which knows how to combine two values.

If @values contains just a single element, a list containing that element is returned immediately. If it contains no elements, an exception is thrown, unless &with is an operator with a known identity value.

If &with is the function object of an operator, its inherent identity value and associativity is respected - in other words, (VAL1, VAL2, VAL3).produce(&[OP]) is the same as VAL1 OP VAL2 OP VAL3 even for operators which aren't left-associative:

# Raise 2 to the 81st power, because 3 to the 4th power is 81
[2,3,4].produce(&[**]).say;        # OUTPUT: «(4 81 2417851639229258349412352)␤»
say produce &[**], (2,3,4);        # OUTPUT: «(4 81 2417851639229258349412352)␤»
say [\**] (2,3,4);                 # OUTPUT: «(4 81 2417851639229258349412352)␤»

# Subtract 4 from -1, because 2 minus 3 is -1
[2,3,4].produce(&[-]).say;         # OUTPUT: «(2 -1 -5)␤»
say produce &[-], (2,3,4);         # OUTPUT: «(2 -1 -5)␤»
say [\-] (2,3,4);                  # OUTPUT: «(2 -1 -5)␤»

A triangle metaoperator [\ ] provides a syntactic shortcut for producing with an infix operator:

# The following all do the same thing...
my @numbers = (1,2,3,4,5);
say produce { $^a + $^b }, @numbers;
say produce * + *, @numbers;
say produce &[+], @numbers; # operator does not need explicit identity
say [\+] @numbers;          # most people write it this way

The visual picture of a triangle [\ is not accidental. To produce a triangular list of lists, you can use a "triangular comma":

[\,] 1..5;
# (
# (1)
# (1 2)
# (1 2 3)
# (1 2 3 4)
# (1 2 3 4 5)
# )

Since produce is an implicit loop, it responds to next, last and redo statements inside &with:

say (2,3,4,5).produce: { last if $^a > 7; $^a + $^b }; # OUTPUT: «(2 5 9)␤»

routine combinations

Defined as:

multi sub    combinations($from, $of = 0..*             --> Seq:D)
multi method combinations(List:D: Int() $of             --> Seq:D)
multi method combinations(List:D: Iterable:D $of = 0..* --> Seq:D)

Returns a Seq with all $of-combinations of the invocant list. $of can be a numeric Range, in which case combinations of the range of item numbers it represents will be returned (i.e. 2.6 .. 4 will return 2-, 3-, and 4-item combinations>). Otherwise, $of is coerced to an Int.

.say for <a b c>.combinations: 2;
# OUTPUT:
# (a b)
# (a c)
# (b c)

Above, there are three possible ways to combine the 2-items lists from the original list, which is what we receive in the output. See permutations if you want permutations instead of combinations.

With Range argument, we get both three 2-item combinations and one 3-item combination:

.say for <a b c>.combinations: 2..3;
# OUTPUT:
# (a b)
# (a c)
# (b c)
# (a b c)

If $of is negative or is larger than there are items in the given list, an empty list will be returned. If $of is zero, a 1-item list containing an empty list will be returned (there's exactly 1 way to pick no items).

The subroutine form is equivalent to the method form called on the first argument ($from), with the exception that if $from is not an Iterable, it gets coerced to an Int and combinations are made from a Range constructed with 0..^$from instead:

.say for combinations 3, 2
# OUTPUT:
# (0 1)
# (0 2)
# (1 2)

Note: some implementations may limit the maximum value of non-Iterable $from. On Rakudo, 64-bit systems have a limit of 2³¹-1 and 32-bit systems have a limit of 2²⁸-1.

routine permutations

Defined as:

multi sub    permutations(Int()    $from --> Seq:D)
multi sub    permutations(Iterable $from --> Seq:D)
multi method permutations(List:D:        --> Seq:D)

Returns all possible permutations of a list as a Seq of lists:

.say for <a b c>.permutations;
# OUTPUT:
# (a b c)
# (a c b)
# (b a c)
# (b c a)
# (c a b)
# (c b a)

permutations treats all elements as unique, thus (1, 1, 2).permutations returns a list of 6 elements, even though there are only three distinct permutations, due to first two elements being the same.

The subroutine form behaves the same as the method form, computing permutations from its first argument $from. If $from is not an Iterable, coerces $from to an Int and picks from a Range constructed with 0..^$from:

.say for permutations 3;
# OUTPUT:
# (0 1 2)
# (0 2 1)
# (1 0 2)
# (1 2 0)
# (2 0 1)
# (2 1 0)

method rotor

Defined as:

method rotor(*@cycle, Bool() :$partial --> Seq:D)

Returns a sequence of lists, where each sublist is made up of elements of the invocant.

In the simplest case, @cycle contains just one integer, in which case the invocant list is split into sublists with as many elements as the integer specifies. If :$partial is True, the final chunk is included even if it doesn't satisfy the length requirement:

say ('a'..'h').rotor(3).join('|');              # OUTPUT: «a b c|d e f␤»
say ('a'..'h').rotor(3, :partial).join('|');    # OUTPUT: «a b c|d e f|g h␤»

If the element of @cycle is a Pair instead, the key of the pair specifies the length of the return sublist, and the value the gap between sublists; negative gaps produce overlap:

say ('a'..'h').rotor(2 => 1).join('|');         # OUTPUT: «a b|d e|g h␤»
say ('a'..'h').rotor(3 => -1).join('|');        # OUTPUT: «a b c|c d e|e f g␤»

If @cycle contains more than element, rotor cycles through it to find the number of elements for each sublist:

say ('a'..'h').rotor(2, 3).join('|');           # OUTPUT: «a b|c d e|f g␤»
say ('a'..'h').rotor(1 => 1, 3).join('|');      # OUTPUT: «a|c d e|f␤»

Combining multiple cycles and :partial also works:

say ('a'..'h').rotor(1 => 1, 3 => -1, :partial).join('|');
# OUTPUT: «a|c d e|e|g h␤»

See this blog post for more elaboration on rotor.

method batch

Defined As:

multi method batch(Int:D $batch --> Seq)
multi method batch(Int:D :$elems --> Seq)

Returns a Seq of the elements in batches of :$elems or $batch, respectively. If the number of elements is not a multiple of $batch, the last batch may have less than $batch elements, similar to .rotor($batch, :partial).

routine cross

sub cross(+@e, :&with --> Seq:D)

Computes the cross-product of two or more lists or iterables. This returns a sequence of lists where the first item in each list is an item from the first iterable, the second is from the second given iterable, etc. Every item will be paired with every other item in all the other lists.

say cross(<a b c>, <d e f>).map(*.join).join(",")
# OUTPUT: «ad,ae,af,bd,be,bf,cd,ce,cf␤»

The cross routine has an infix synonym as well, named X.

say (<a b c> X <d e f>).map(*.join).join(",")
# output is the same as the previous example

If the optional with parameter is passed, it is used as a reduction operation to apply to each of the cross product items.

say cross([1, 2, 3], [4, 5, 6], :with(&infix:<*>)).join(",");
# OUTPUT: «4,5,6,8,10,12,12,15,18␤»

The X operator can be combined with another operator as a metaoperator to perform a reduction as well:

say ([1, 2, 3] X* [4, 5, 6]).join(",")
# same output as the previous example

routine zip

Defined as:

sub zip(+@e, :&with --> Seq:D)

Builds a 'list of lists', returned as a sequence, from multiple input lists or other iterables.

zip iterates through each of the input lists synchronously, 'Zipping' them together, so that elements are grouped according to their input list index, in the order that the lists are provided.

say zip(<a b c>, <d e f>, <g h i>);
# OUTPUT: «((a d g) (b e h) (c f i))␤»

zip has an infix synonym, the Z operator.

say <a b c> Z <d e f> Z <g h i>;                   # same output

zip can provide input to a for loop :

for <a b c> Z <d e f> Z <g h i> -> [$x,$y,$z] {say ($x,$y,$z).join(",")}
# OUTPUT: «a,d,g␤
# b,e,h␤
# c,f,i␤»

, or more succinctly:

say .join(",") for zip <a b c>, <d e f>, <g h i>;  # same output

Note, that if the input lists have an unequal number of elements, then zip terminates once the shortest input list is exhausted, and trailing elements from longer input lists are discarded.

say <a b c> Z <d e f m n o p> Z <g h i>;
# ((a d g) (b e h) (c f i))

In cases where data clipping is possible, but undesired, then consider using roundrobin instead of zip.

The optional with parameter will additionally reduce the zipped lists. For example, the following multiplies corresponding elements together to return a single list of products.

.say for zip <1 2 3>, [1, 2, 3], (1, 2, 3), :with(&infix:<*>);
# OUTPUT: «1␤
# 8␤
# 27␤»

The Z form can also be used to perform reduction by implicitly setting the with parameter with a metaoperator :

.say for <1 2 3> Z* [1, 2, 3] Z* (1, 2, 3);        # same output

routine roundrobin

Defined as:

sub roundrobin(+list-of-lists --> Seq)

Builds a 'list of lists', returned as a sequence, from multiple input lists or other iterables. roundrobin returns an identical result to that of zip, except when the input lists are allowed to have an unequal number of elements.

say roundrobin <a b c>, <d e f>, <g h i>;
# OUTPUT: «((a d g) (b e h) (c f i))␤»

say .join(",") for roundrobin([1, 2], [2, 3], [3, 4]);
# OUTPUT: «1,2,3␤
# 2,3,4␤»

roundrobin does not terminate once one or more of the input lists become exhausted, but proceeds until all elements from all lists have been processed.

say roundrobin <a b c>, <d e f m n o p>, <g h i j>;
# OUTPUT: «((a d g) (b e h) (c f i) (m j) (n) (o) (p))␤»

say .join(",") for roundrobin([1, 2], [2, 3, 57, 77], [3, 4, 102]);
# OUTPUT: «1,2,3␤
# 2,3,4␤
# 57,102␤
# 77␤»

Therefore no data values are lost due in the 'zipping' operation. A record of which input list provided which element cannot be gleaned from the resulting sequence, however.

roundrobin can be useful in combining messy data to the point where a manual post-processing step can then be undertaken.

routine sum

Defined as:

sub    sum($list   --> Numeric:D)
method sum(List:D: --> Numeric:D)

Returns the sum of all elements in the list or 0 if the list is empty. Throws an exception if an element can not be coerced into Numeric.

say (1, 3, pi).sum;       # OUTPUT: «7.14159265358979␤»
say (1, "0xff").sum;      # OUTPUT: «256␤»
say sum(0b1111, 5);       # OUTPUT: «20␤»

When being called on native integer arrays, it is also possible to specify a :wrap named parameter. This will add the values as native integers, wrapping around if they exceed the size of a native integer. If you are sure you will not exceed that value, or if you don't mind, using :wrap will make the calculation about 20x as fast.

my int @values = ^1_000_000; 
 say @a.sum(:wrap);        # OUTPUT: «499999500000␤» 

method fmt

Defined as:

method fmt($format = '%s', $separator = ' ' --> Str:D)

Returns a string where each element in the list has been formatted according to $format and where each element is separated by $separator.

For more information about formats strings, see sprintf.

my @a = 8..11;
say @a.fmt('%03d', ',');  # OUTPUT: «008,009,010,011␤»

method from

Assumes the list contains Match objects and returns the value of .from called on the first element of the list.

'abcdefg' ~~ /(c)(d)/;
say $/.list.from;         # OUTPUT: «2␤»

"abc123def" ~~ m:g/\d/;
say $/.list.from;         # OUTPUT: «3␤»

method to

"abc123def" ~~ m:g/\d/;
say $/.to; # OUTPUT: «6␤»

Assumes the List contains Match objects, such as the $/ variable being a List, when using :g modifier in regexes. Returns the value of .to called on the last element of the list.

method sink

Defined as:

method sink(--> Nil) { }

It does nothing, and returns Nil, as the definition clearly shows.

sink [1,2,Failure.new("boo!"),"still here"]; # OUTPUT: «»

method Set

In general, creates a set which has as members elements of the list.

say <æ ß þ €>.Set;  # OUTPUT: «set(ß æ þ €)␤»

However, there might be some unexpected changes in case the list includes non-scalar data structures. For instance, with Pairs:

my @a = (:42a, :33b);
say @a;                # OUTPUT: «[a => 42 b => 33]␤»
say @a.Set;            # OUTPUT: «set(a b)␤»

The set will be composed of the keys of the Pair whose corresponding value is not 0, eliminating all the values. Please check the Set documentation for more examples and a more thorough explanation.

Operators

infix cmp

multi sub infix:<cmp>(List @a, List @b)

Evaluates Lists by comparing element @a[$i] with @b[$i] (for some Int $i, beginning at 0) and returning Order::Less, Order::Same, or Order::More depending on if and how the values differ. If the operation evaluates to Order::Same, @a[$i + 1] is compared with @b[$i + 1]. This is repeated until one is greater than the other or all elements are exhausted.

If the Lists are of different lengths, at most only $n comparisons will be made (where $n = @a.elems min @b.elems). If all of those comparisons evaluate to Order::Same, the final value is selected based upon which List is longer.

say (1, 2, 3) cmp (1, 2, 3);   # OUTPUT: «Same␤»
say (4, 5, 6) cmp (4, 5, 7);   # OUTPUT: «Less␤»
say (7, 8, 9) cmp (7, 8, 8);   # OUTPUT: «More␤»

say (1, 2)    cmp (1, 2, 3);   # OUTPUT: «Less␤»
say (1, 2, 3) cmp (1, 2);      # OUTPUT: «More␤»
say (9).List  cmp (^10).List;  # OUTPUT: «More␤»

174 class Lock

A low-level, re-entrant, mutual exclusion lock

class Lock {}

A Lock is a low-level concurrency control construct. It provides mutual exclusion, meaning that only one thread may hold the lock at a time. Once the lock is unlocked, another thread may then lock it.

A Lock is typically used to protect access to one or more pieces of state. For example, in this program:

my $x = 0;
my $l = Lock.new;
await (^10).map: {
    start {
        $l.protect({ $x++ });
    }
}
say $x;         # OUTPUT: «10␤»

The Lock is used to protect operations on $x. An increment is not an atomic operation; without the lock, it would be possible for two threads to both read the number 5 and then both store back the number 6, thus losing an update. With the use of the Lock, only one thread may be running the increment at a time.

A Lock is re-entrant, meaning that a thread that holds the lock can lock it again without blocking. That thread must unlock the same number of times before the lock can be obtained by another thread (it works by keeping a recursion count).

It's important to understand that there is no direct connection between a Lock and any particular piece of data; it is up to the programmer to ensure that the Lock is held during all operations that involve the data in question. The OO::Monitors module, while not a complete solution to this problem, does provide a way to avoid dealing with the lock explicitly and encourage a more structured approach.

The Lock class is backed by operating-system provided constructs, and so a thread that is waiting to acquire a lock is, from the point of view of the operating system, blocked.

Code using high-level Perl 6 concurrency constructs should avoid using Lock. Waiting to acquire a Lock blocks a real Thread, meaning that the thread pool (used by numerous higher-level Perl 6 concurrency mechanisms) cannot use that thread in the meantime for anything else.

Any await performed while a Lock is held will behave in a blocking manner; the standard non-blocking behavior of await relies on the code following the `await` resuming on a different Thread from the pool, which is incompatible with the requirement that a Lock be unlocked by the same thread that locked it. See Lock::Async for an alternative mechanism that does not have this shortcoming.

By their nature, Locks are not composable, and it is possible to end up with hangs should circular dependencies on locks occur. Prefer to structure concurrent programs such that they communicate results rather than modify shared data structures, using mechanisms like Promise, Channel and Supply.

Methods

method protect

Defined as:

method protect(Lock:D: &code)

Obtains the lock, runs &code, and releases the lock afterwards. Care is taken to make sure the lock is released even if the code is left through an exception.

Note that the Lock itself needs to be created outside the portion of the code that gets threaded and it needs to protect. In the first example below, Lock is first created and assigned to $lock, which is then used inside the Promises to protect the sensitive code. In the second example, a mistake is made: the Lock is created right inside the Promise, so the code ends up with a bunch of separate locks, created in a bunch of threads, and thus they don't actually protect the code we want to protect.

# Right: $lock is instantiated outside the portion of the
# code that will get threaded and be in need of protection
my $lock = Lock.new;
await ^20 .map: {
    start {
        $lock.protect: {
            print "Foo";
            sleep rand;
            say "Bar";
        }
    }
}

# !!! WRONG !!! Lock is created inside threaded area!
await ^20 .map: {
    start {
        Lock.new.protect: {
            print "Foo"; sleep rand; say "Bar";
        }
    }
}

method lock

Defined as:

method lock(Lock:D:)

Acquires the lock. If it is currently not available, waits for it.

my $l = Lock.new;
$l.lock;

Since a Lock is implemented using OS-provided facilities, a thread waiting for the lock will not be scheduled until the lock is available for it. Since Lock is re-entrant, if the current thread already holds the lock, calling lock will simply bump a recursion count.

While it's easy enough to use the lock method, it's more difficult to correctly use unlock. Instead, prefer to use the protect method instead, which takes care of making sure the lock/unlock calls always both occur.

method unlock

Defined as:

method unlock(Lock:D:)

Releases the lock.

my $l = Lock.new;
$l.lock;
$l.unlock;

It is important to make sure the Lock is always released, even if an exception is thrown. The safest way to ensure this is to use the protect method, instead of explicitly calling lock and unlock. Failing that, use a LEAVE phaser.

my $l = Lock.new;
{
    $l.lock;
    LEAVE $l.unlock;
}

method condition

Defined as:

my class ConditionVariable { 
     method wait(); 
     method signal(); 
     method signal_all(); 
 } 
 
 method condition(Lock:D: --> ConditionVariable:D) 

Returns a condition variable. Compare https://web.stanford.edu/~ouster/cgi-bin/cs140-spring14/lecture.php?topic=locks or https://en.wikipedia.org/wiki/Monitor_%28synchronization%29 for background.

my $l = Lock.new;
$l.condition;

175 class Lock::Async

A non-blocking, non-re-entrant, mutual exclusion lock

class Lock::Async {}

A Lock::Async instance provides a mutual exclusion mechanism: when the lock is held, any other code wishing to lock must wait until the holder calls unlock.

Unlike Lock, which provides a traditional OS-backed mutual exclusion mechanism, Lock::Async works with the high-level concurrency features of Perl 6. The lock method returns a Promise, which will be kept when the lock is available. This Promise can be used with non-blocking await. This means that a thread from the thread pool need not be consumed while waiting for the Lock::Async to be available, and the code trying to obtain the lock will be resumed once it is available.

The result is that it's quite possible to have many thousands of outstanding Lock::Async lock requests, but just a small number of threads in the pool. Attempting that with a traditional Lock would not go so well!

There is no requirement that a Lock::Async is locked and unlocked by the same physical thread, meaning it is possible to do a non-blocking await while holding the lock. The flip side of this is Lock::Async is not re-entrant.

While Lock::Async works in terms of higher-level Perl 6 concurrency mechanisms, it should be considered a building block. Indeed, it lies at the heart of the Supply concurrency model. Prefer to structure programs so that they communicate results rather than mutate shared data structures, using mechanisms like Promise, Channel and Supply.

Methods

method lock

Defined as:

method lock(Lock::Async:D: --> Promise:D)

Returns a Promise that will be kept when the lock is available. In the case that the lock is already available, an already kept Promise will be returned. Use await to wait for the lock to be available in a non-blocking manner.

my $l = Lock::Async.new;
await $l.lock;

Prefer to use protect instead of explicit calls to lock and unlock.

method unlock

Defined as:

method unlock(Lock::Async:D: --> Nil)

Releases the lock. If there are any outstanding lock Promises, the one at the head of the queue will then be kept, and potentially code scheduled on the thread pool (so the cost of calling unlock is limited to the work needed to schedule another piece of code that wants to obtain the lock, but not to execute that code).

my $l = Lock::Async.new;
await $l.lock;
$l.unlock;

Prefer to use protect instead of explicit calls to lock and unlock. However, if wishing to use the methods separately, it is wise to use a LEAVE block to ensure that unlock is reliably called. Failing to unlock will mean that nobody can ever lock this particular Lock::Async instance again.

my $l = Lock::Async.new;
{
    await $l.lock;
    LEAVE $l.unlock;
}

method protect

Defined as:

method protect(Lock::Async:D: &code)

Calls lock, does an await to wait for the lock to be available, and reliably calls unlock afterwards, even if the code throws an exception.

Note that the Lock::Async itself needs to be created outside the portion of the code that gets threaded and it needs to protect. In the first example below, Lock::Async is first created and assigned to $lock, which is then used inside the Promises to protect the sensitive code. In the second example, a mistake is made, the Lock::Async is created right inside the Promise, so the code ends up with a bunch of separate locks, created in a bunch of threads, and thus they don't actually protect the code we want to protect.

# Right: $lock is instantiated outside the portion of the
# code that will get threaded and be in need of protection
my $lock = Lock::Async.new;
await ^20 .map: {
    start {
        $lock.protect: {
            print "Foo";
            sleep rand;
            say "Bar";
        }
    }
}

# !!! WRONG !!! Lock::Async is instantiated inside threaded area!
await ^20 .map: {
    start {
        my $lock = Lock::Async.new;
        $lock.protect: {
            print "Foo"; sleep rand; say "Bar";
        }
    }
}

method protect-or-queue-on-recursion

Defined as:

method protect-or-queue-on-recursion(Lock::Async:D: &code)

When calling protect on a Lock::Async instance that is already locked, the method is forced to block until the lock gets unlocked. protect-or-queue-on-recursion avoids this issue by either behaving the same as protect if the lock is unlocked or the lock was locked by something outside the caller chain, returning Nil, or queueing the call to &code and returning a Promise if the lock had already been locked at another point in the caller chain.

my Lock::Async $lock .= new;
my Int         $count = 0;

# The lock is unlocked, so the code runs instantly.
$lock.protect-or-queue-on-recursion({
    $count++
});

# Here, we have caller recursion. The outer call only returns a Promise
# because the inner one does. If we try to await the inner call's Promise
# from the outer call, the two calls will block forever since the inner
# caller's Promise return value is just the outer's with a then block.
$lock.protect-or-queue-on-recursion({
    $lock.protect-or-queue-on-recursion({
        $count++
    }).then({
        $count++
    })
});

# Here, the lock is locked, but not by anything else on the caller chain.
# This behaves just like calling protect would in this scenario.
for 0..^2 {
    $lock.protect-or-queue-on-recursion({
        $count++;
    });
}

say $count; # OUTPUT: 5

method with-lock-hidden-from-recursion-check

Defined as:

method with-lock-hidden-from-recursion-check(&code)

Temporarily resets the Lock::Async recursion list so that it no longer includes the lock this method is called on and runs the given &code immediately if the call to the method occurred in a caller chain where protect-or-queue-on-recursion has already been called and the lock has been placed on the recursion list.

my Lock::Async $lock .= new;
my Int         $count = 0;

$lock.protect-or-queue-on-recursion({
    my Int $count = 0;

    # Runs instantly.
    $lock.with-lock-hidden-from-recursion-check({
        $count++;
    });

    # Runs after the outer caller's protect-or-queue-on-recursion call has
    # finished running.
    $lock.protect-or-queue-on-recursion({
        $count++;
    }).then({
        say $count; # OUTPUT: 2
    });

    say $count; # OUTPUT: 1
});

176 class Macro

Compile-time routine

class Macro is Routine { }

A macro is a Routine whose invocation typically happens during parsing. By returning an AST, a macro can inject code into the calling location.

177 class Map

Immutable mapping from strings to values

class Map does Associative does Iterable { }

A Map is an immutable mapping from string keys to values of arbitrary types. It serves as a base class for Hash, which is mutable.

In list context a Map behaves as a list of Pair objects.

Note that the order in which keys, values and pairs are retrieved is generally arbitrary, but the keys, values and pairs methods return them always in the same order when called on the same object.

my %e := Map.new('a', 1, 'b', 2);
say %e.keys;    # can print "a b\n" or "b a\n";
say %e.values;  # prints "1 2\n" if the previous line
                # printed "a b\n", "b a\n" otherwise

To retrieve a value from the Map by key, use the { } postcircumfix operator:

my $map = Map.new('a', 1, 'b', 2);
say $map{'a'};      # OUTPUT: «1␤»
say $map{ 'a', 'b' }; # OUTPUT: «(1 2)␤»

To check whether a given key is stored in a Map, modify the access with the :exists adverb:

my $map = Map.new('a', 1, 'b', 2);
my $key = 'a';
if $map{$key}:exists {
    say "$map{} has key $key";
}

Being an immutable instance, it is not possible to add keys after a Map has been initialized:

my $m = Map.new( 'a', 1, 'b', 2 );
$m{ 'c' } = 'foo'; # WRONG!
                   # Cannot modify an immutable Str

Methods

method new

Defined as:

method new(*@args)

Creates a new Map from a list of alternating keys and values, with the same semantics as described for hash assigning in the Hash documentation, except, for literal pair handling. To ensure pairs correctly get passed, add extra parentheses around all the arguments.

my %h = Map.new('a', 1, 'b', 2);

# WRONG: :b(2) interpreted as named argument
say Map.new('a', 1, :b(2) ).keys; # OUTPUT: «(a)␤»

# RIGHT: :b(2) interpreted as part of Map's contents
say Map.new( ('a', 1, :b(2)) ).keys; # OUTPUT: «(a b)␤»

method elems

Defined as:

method elems(Map:D: --> Int:D)

Returns the number of pairs stored in the Map.

my %map = Map.new('a', 1, 'b', 2);
say %map.elems; # OUTPUT: «2␤»

method ACCEPTS

Defined as:

multi method ACCEPTS(Map:D: Positional $topic)
multi method ACCEPTS(Map:D: Cool:D     $topic)
multi method ACCEPTS(Map:D: Regex      $topic)
multi method ACCEPTS(Map:D: Any        $topic)

Used in smartmatching if the right-hand side is an Map.

If the topic is list-like (Positional), returns True if any of the list elements exist as a key in the Map.

If the topic is of type Cool (strings, integers etc.), returns True if the topic exists as a key.

If the topic is a regex, returns True if any of the keys match the regex.

As a fallback, the topic is coerced to a list, and the Positional behavior is applied.

method gist

Defined as:

method gist(Map:D: --> Str:D)

Returns the string containing the "gist" of the Map, sorts the pairs and lists up to the first 100, appending an ellipsis if the Map has more than 100 pairs.

method keys

Defined as:

method keys(Map:D: --> Seq:D)

Returns a Seq of all keys in the Map.

my $m = Map.new('a' => (2, 3), 'b' => 17);
say $m.keys; # OUTPUT: «(a b)␤»

method values

Defined as:

method values(Map:D: --> Seq:D)

Returns a Seq of all values in the Map.

my $m = Map.new('a' => (2, 3), 'b' => 17);
say $m.values; # OUTPUT: «((2 3) 17)␤»

method pairs

Defined as:

method pairs(Map:D: --> Seq:D)

Returns a Seq of all pairs in the Map.

my $m = Map.new('a' => (2, 3), 'b' => 17);
say $m.pairs; # OUTPUT: «(a => (2 3) b => 17)␤»

method antipairs

Defined as:

method antipairs(Map:D: --> Seq:D)

Returns all keys and their respective values as a Seq of Pairs where the keys and values have been exchanged, i.e. the opposite of method pairs. Unlike the invert method, there is no attempt to expand list values into multiple pairs.

my $m = Map.new('a' => (2, 3), 'b' => 17);
say $m.antipairs;                                  # OUTPUT: «((2 3) => a 17 => b)␤»

method invert

Defined as:

method invert(Map:D: --> Seq:D)

Returns all keys and their respective values as a Seq of Pairs where the keys and values have been exchanged. The difference between invert and antipairs is that invert expands list values into multiple pairs.

my $m = Map.new('a' => (2, 3), 'b' => 17);
say $m.invert;                                    # OUTPUT: «(2 => a 3 => a 17 => b)␤»

method kv

Defined as:

method kv(Map:D: --> Seq:D)

Returns a Seq of keys and values interleaved.

Map.new('a', 1, 'b', 2).kv  # (a 1 b 2)

method list

Defined as:

method list(Map:D: --> List:D)

Returns a List of all keys and values in the Map.

my $m = Map.new('a' => (2, 3), 'b' => 17);
say $m.list;                                      # OUTPUT: «(b => 17 a => (2 3))␤»

method sort

Defined as:

multi method sort(Map:D: --> Seq:D)

Returns a Seq of Pair objects, which are the pairs of the hash, sorted by key. Equivalent to %hash.sort: *.key

# These are equivalent:
say Map.new(<c 3 a 1 b 2>).sort;        # OUTPUT: «(a => 1 b => 2 c => 3)␤»
say Map.new(<c 3 a 1 b 2>).sort: *.key; # OUTPUT: «(a => 1 b => 2 c => 3)␤»

See Any.sort for additional available candidates.

method Int

Defined as:

method Int(Map:D: --> Int:D)

Returns the number of pairs stored in the Map (same as .elems).

my $m = Map.new('a' => 2, 'b' => 17);
say $m.Int;                                       # OUTPUT: «2␤»

method Numeric

Defined as:

method Numeric(Map:D: --> Int:D)

Returns the number of pairs stored in the Map (same as .elems).

my $m = Map.new('a' => 2, 'b' => 17);
say $m.Numeric;                                   # OUTPUT: «2␤»

method Bool

Defined as:

method Bool(Map:D: --> Bool:D)

Returns True if the invocant contains at least one key/value pair.

my $m = Map.new('a' => 2, 'b' => 17);
say $m.Bool;                                      # OUTPUT: «True␤»

method Capture

Defined as:

method Capture(Map:D:)

Returns a Capture where each key, if any, has been converted to a named argument with the same value as it had in the original Map. The returned Capture will not contain any positional arguments.

my $map = Map.new('a' => 2, 'b' => 17);
my $capture = $map.Capture;
my-sub(|$capture);                                # RESULT: «2, 17»

sub my-sub(:$a, :$b) {
    say "$a, $b"
}

178 class Match

Result of a successful regex match

class Match is Capture is Cool does NQPMatchRole {}

Match objects are the result of a successful regex match, this does include any zero-width match. They store a reference to the original string (.orig), positional and named captures, the positions of the start and end of the match in the original string, and a payload referred to as AST (abstract syntax tree), which can be used to build data structures from complex regexes and grammars.

The last match is also stored in the Match object, which is lexically scoped to the regex, that is, only available from within the regular expression, as shown here:

my $c;
'abc' ~~ /.$${ $c = $¢ }/;
say $c; # OUTPUT: «「c」␤»

In this case, we are running the code among curly braces when the match occurs, in this case the last letter in the string (actually, the last, indicated by the double $, character); $c gets the value of the cursor , which contains the Match; when used with say, the Match is stringified by calling .Str on it. This offers a way of capturing the Match inside a regular expression; outside, you need to use $/

my $c; 'camelia' ~~ /<[ l m ]> {$c = $¢}/;
say $c; # OUTPUT: «「m」␤»
say $/; # OUTPUT: «「m」␤»

Note: This feature works only from Perl 6 version 2018.02. It would have returned Nil with any previous version. Alternatively and prior to that version, you could use $/ which, inside the regex, has the same value:

'123' ~~ / (\d) { say $0; say $/; } \d+ /; # OUTPUT: «「1」␤「1」␤ 0 => 「1」␤»

The main difference between $/ and is scope: the latter only has a value inside the regex:

'123' ~~ / (\d) { say $/; say $¢; } \d+ /; # OUTPUT: «「1」␤ 0 => 「1」␤「1」␤ 0 => 「1」␤» 
 say "¢ → ", $¢, "/ is $/"; ; # OUTPUT: «¢ → Nil/ is 123␤» 

Submatches are also Match objects (or lists of Match objects, if the corresponding regex was quantified), so each match object can be seen as the root of a tree of match objects.

A Match object can also hold the result of a match in progress (while the grammar engine is running), in which case the pos method returns the current position. This view on Match objects is only visible if you call code from within a regex.

Methods

method pos

method pos()

Returns the current position as a string index into Match.target for a regex match in progress:

my $a = 'abcdef';
$a ~~ /b. {say $/.pos }../; say $/.pos;     # OUTPUT: «3␤»

You should not use this method on finished Match, as the output can be implementation specific.

method target

method target()

Returns a string representation of the object against which the regex matches. This is the value that the regex engine works with internally.

my $a = "þor" ~~ /o/;
say $a.target # OUTPUT: «þor␤»

method chars

Returns the numbers of characters in the matched string.

Returns the same as .Str.chars.

method clone

Defined as:

method clone()

Clones the Match object.

method orig

Returns the original input to the regex engine, which is usually a string, but doesn't need to be (could be anything that can be coerced to a string):

42 ~~ /.+/;
say $/.orig;            # OUTPUT: «42»
say $/.orig.^name;      # OUTPUT: «Int»

See #method target for a close equivalent that always returns a string.

method from

Returns the index of the starting position of the match.

method to

Returns the index of the end position of the match.

method made

Returns the payload that was set with make.

method make

Defined as

method make(Match:D: Mu $payload)
sub make(Mu $payload)

Sets the .ast attribute, which will be retrieved using .made.

$/.make("your payload here");

That is, it stores an arbitrary payload into the Match object that can later be retrieved via .made method.

This is typically used in a grammar's actions class methods, where a piece of data is stored by one method and then later retrieved by another. It's up to you what data you store. It could be a tree node, result of a calculation, or a list of values.

The sub form operates on the current Match $/, which can be a convenient shortcut:

method my-action ($/) {
    make "foo: $/";
}

method actions

method actions(Match:D: --> Mu)

Returns the actions object (if any was set; else Mu) that the grammar used from which this Match object was created.

method ast

Alias for #method made.

method Bool

Defined as:

method Bool(Capture:D: --> Bool:D)

Returns True on successful and False on unsuccessful matches. Please note that any zero-width match can also be successful.

say 'abc' ~~ /^/;                   # OUTPUT: «「」␤»
say $/.from, ' ',  $/.to, ' ', ?$/; # OUTPUT: «0 0 True␤»

method Str

Defined as:

method Str(Match:D: --> Str:D)

Returns the matched text.

"abc123def" ~~ /\d+/;
say $/.Str;               # OUTPUT: «123␤»

method Int

Defined as:

method Int(Match:D: --> Int:D)

Tries to convert stringified result of the matched text into Int.

say ('12345' ~~ /234/).Int;       # OUTPUT: «234␤»
say ('12345' ~~ /234/).Int.^name; # OUTPUT: «Int␤»
# the next line produces a warning about using Nil (result of a no match) in numeric context
say ('one-two' ~~ /234/).Int;     # OUTPUT: «0␤» # because Nil.Int returns 0

method caps

Returns a list of pairs, with the index or submatch name as key and the submatches as values. The list is ordered by starting position of the submatches.

method chunks

Returns a list of pairs, with the index or submatch name as key and the submatches as values. The list is ordered by starting position of the submatches.

Those parts of the string that were not matched by submatches are interleaved with the other pairs, with the string ~ as key.

method list

Returns a list of positional submatches.

method hash

Returns a hash of named submatches.

method prematch

Defined as:

method prematch(Match:D: --> Str:D)

Returns the part of the original string leading up to the match.

'abcdefg' ~~ /cd/;
say $/.prematch;          # OUTPUT: «ab␤»

# will return a list of three match objects
"abc123def" ~~ m:g/\d/;
say $/.[1].prematch;      # OUTPUT: «abc1␤»

method postmatch

Defined as:

method postmatch(Match:D: --> Str:D)

Returns the part of the original string following the match.

'abcdefg' ~~ /cd/;
say $/.postmatch;         # OUTPUT: «efg␤»

# will return a list of three match objects
"abc123def" ~~ m:g/\d/;
say $/.[1].postmatch;     # OUTPUT: «3def␤»

method infix:<eqv>

Defined as:

multi sub infix:<eqv>(Match:D \a, Match:D \b)

Returns True if the attributes pos, from and orig are equal, and if made, Capture::list and Capture::hash are either the same or both undefined.

179 role Metamodel::AttributeContainer

Metaobject that can hold attributes

role Metamodel::AttributeContainer {}

Classes, roles and grammars can have attributes. Storage and introspection of attributes is implemented by this role.

Methods

method add_attribute

method add_attribute(Metamodel::AttributeContainer: $obj, $attribute)

Adds an attribute. $attribute must be an object that supports the methods name, type and package, which are called without arguments. It can for example be of type Attribute.

method attributes

method attributes(Metamodel::AttributeContainer: $obj)

Returns a list of attributes. For most Perl 6 types, these will be objects of type Attribute.

method set_rw

method set_rw(Metamodel::AttributeContainer: $obj)

Marks a type whose attributes default to having a write accessor. For example in

class Point is rw {
    has $.x;
    has $.y;
}

The is rw trait on the class calls the set_rw method on the meta class, making all the attributes implicitly writable, so that you can write;

my $p = Point.new(x => 1, y => 2); 
 $p.x = 42; 

method rw

method rw(Metamodel::AttributeContainer: $obj)

Returns a true value if method set_rw has been called on this object, that is, if new public attributes are writable by default.

TODO: compose_attributes, get_attribute_for_usage Also TODO: describe :local, :excl, :all options of method attributes

180 role Metamodel::C3MRO

Metaobject that supports the C3 method resolution order

role Metamodel::C3MRO { }

Meta model role for the C3 method resolution order (MRO). Note: this method, along with almost the whole metamodel, is part of the Rakudo implementation.

The method resolution order for a type is a flat list of types including the type itself, and (recursively) all super classes. It determines in which order the types will be visited for determining which method to call with a given name, or for finding the next method in a chain with nextsame, callsame, nextwith or callwith.

class CommonAncestor { };   # implicitly inherits from Any 
 class Child1 is CommonAncestor { } 
 class Child2 is CommonAncestor { } 
 class GrandChild2 is Child2 { } 
 class Weird is Child1 is GrandChild2 { }; 
 
 say Weird.^mro; # OUTPUT: «(Weird) (Child1) (GrandChild2) (Child2) (CommonAncestor) (Any) (Mu)␤» 

C3 is the default resolution order for classes and grammars in Perl 6. Note that roles generally do not appear in the method resolution order (unless they are punned into a class, from which another type inherits), because methods are copied into classes at role application time.

Methods

method compute_mro

method compute_mro($type)

Computes the method resolution order.

method mro

method mro($type)

Returns a list of types in the method resolution order, even those that are marked is hidden.

say Int.^mro;   # OUTPUT: «((Int) (Cool) (Any) (Mu))␤»

method mro_unhidden

method mro_unhidden($type)

Returns a list of types in method resolution order, excluding those that are marked with is hidden.

181 class Metamodel::ClassHOW

Metaobject representing a Perl 6 class.

class Metamodel::ClassHOW
    does Metamodel::Naming
    does Metamodel::Documenting
    does Metamodel::Versioning
    does Metamodel::Stashing
    does Metamodel::AttributeContainer
    does Metamodel::MethodContainer
    does Metamodel::PrivateMethodContainer
    does Metamodel::MultiMethodContainer
    does Metamodel::RoleContainer
    does Metamodel::MultipleInheritance
    does Metamodel::DefaultParent
    does Metamodel::C3MRO
    does Metamodel::MROBasedMethodDispatch
    does Metamodel::MROBasedTypeChecking
    does Metamodel::Trusting
    does Metamodel::BUILDPLAN
    does Metamodel::Mixins
    does Metamodel::ArrayType
    does Metamodel::BoolificationProtocol
    does Metamodel::REPRComposeProtocol
    does Metamodel::InvocationProtocol
    does Metamodel::Finalization
        { }

Metamodel::ClassHOW is the meta class behind the class keyword.

say so Int.HOW ~~ Metamodel::ClassHOW;    # OUTPUT: «True␤»
say Int.^methods(:all).pick.name;         # OUTPUT: «random Int method name␤»

Warning: This class is part of the Rakudo implementation, not a part of the language itself.

Methods

method add_fallback

method add_fallback(Metamodel::ClassHOW:D: $obj, $condition, $calculator)

Installs a method fallback, that is, add a way to call methods that weren't statically added.

Both $condition and $calculator must be callables that receive the invocant and the method name once a method is called that can't be found in the method cache.

If $condition returns a true value, $calculator is called with the same arguments, and must return the code object to be invoked as the method, and is added to the method cache.

If $condition returns a false value, the next fallback (if any) is tried, and if none matches, an exception of type X::Method::NotFound is thrown.

User-facing code (that is, code not dabbling with meta classes) should use method FALLBACK instead.

method can

method can(Metamodel::ClassHOW:D: $obj, $method-name)

Given a method name, it returns a List of methods that are available with this name.

class A      { method x($a) {} };
class B is A { method x()   {} };
say B.^can('x').elems;              # OUTPUT: «2␤»
for B.^can('x') {
    say .arity;                     # OUTPUT: «1, 2␤»
}

In this example, class B has two possible methods available with name x (though a normal method call would only invoke the one installed in B directly). The one in B has arity 1 (i.e. it expects one argument, the invocant (self)), and the one in A expects 2 arguments (self and $a).

method lookup

method lookup(Metamodel::ClassHOW:D: $obj, $method-name --> Method:D)

Returns the first matching Method with the provided name. If no method was found, returns a VM-specific sentinel value (typically a low-level NULL value) that can be tested for with a test for definedness. It is potentially faster than .^can but does not provide a full list of all candidates.

say Str.^lookup('Int').perl; # OUTPUT: «method Int (Str:D $: *%_) { #`(Method|39910024) ... }␤»

for <upper-case  uc> {
    Str.^lookup: $^meth andthen .("foo").say
        orelse "method `$meth` not found".say
}
# OUTPUT:
# method `upper-case` not found
# FOO

method compose

method compose(Metamodel::ClassHOW:D: $obj)

A call to compose brings the meta object and thus the class it represents into a fully functional state, so if you construct or modify a class, you must call the compose method before working with the class.

It updates the method cache, checks that all methods that are required by roles are implemented, does the actual role composition work, and sets up the class to work well with language interoperability.

method new_type

method (:$name, :$repr = 'P6opaque', :$ver, :$auth)

Creates a new type from the metamodel, which we can proceed to build

my $type = Metamodel::ClassHOW.new_type(name => "NewType",
                                        ver => v0.0.1,
                                        auth => 'github:perl6' );
$type.HOW.add_method($type,"hey", method { say "Hey" });
$type.hey;     # OUTPUT: «Hey␤»
$type.HOW.compose($type);
my $instance = $type.new;
$instance.hey; # OUTPUT: «Hey␤»

We add a single method by using Higher Order Workings methods, and then we can use that method directly as class method; we can then compose the type, following which we can create already an instance, which will behave in the exact same way.

182 role Metamodel::ConcreteRoleHOW

Provides an implementation of a concrete instance of a role

class Metamodel::ConcreteRoleHOW
    does Metamodel::Naming
    does Metamodel::Versioning
    does Metamodel::PrivateMethodContainer
    does Metamodel::MethodContainer
    does Metamodel::MultiMethodContainer
    does Metamodel::AttributeContainer
    does Metamodel::RoleContainer
    does Metamodel::MultipleInheritance
    does Metamodel::ArrayType
    does Metamodel::Concretization {}

You can use this to build roles, in the same way that ClassHOW can be used to build classes:

my $a = Metamodel::ConcreteRoleHOW.new_type(name => "Bar"); 
 $a.^compose; 
 say $a.^roles; # OUTPUT: «(Mu)␤» 

The main difference with ClassHOW.new_type is that you can mix-in roles in this newly created one.

This class is Rakudo specific, and provided only for completeness. Not really intended to be used by the final user.

183 role Metamodel::CurriedRoleHOW

Support for parameterized roles that have not been instantiated

class Metamodel::CurriedRoleHOW
    does Metamodel::Naming
    does Metamodel::TypePretense
    does Metamodel::RolePunning {}

Sometimes, we see references to roles that provide parameters but do not fully resolve them. For example, in:

class C does R[Type] { } 

We need to represent R[T], but we cannot yet fully specialize the role because we don't have the first parameter at hand. We may also run into the issue where we have things like:

sub foo(R[T] $x) { ... } 
 if $x ~~ R[T] { ... } 

Where we clearly want to talk about a partial parameterization of a role and actually want to do so in a way distinct from a particular instantiation of it. This meta-object represents those "partial types" as both a way to curry on your way to a full specialization, but also as a way to do type-checking or punning.

This class will show up in parameterized roles. For instance:

role Zipi[::T] { 
     method zape { "Uses " ~ T.^name }; 
 } 
 role Zipi[::T, ::Y] { 
     method zape { "Uses " ~ T.^name ~ " and " ~ Y.^name }; 
 } 
 for Zipi[Int], Zipi[Int,Str] -> $role { 
     say $role.HOW; 
     say $role.new().zape; 
 } 
 # OUTPUT: 
 # Perl6::Metamodel::CurriedRoleHOW.new 
 # Uses Int 
 # Perl6::Metamodel::CurriedRoleHOW.new 
 # Uses Int and Str 

Since there are several variants of Zipi, providing a parameter curries it, but it's still up to the compiler to find out the actual realization taking into account the ParametricRoleGroup, so these (partially instantiated) roles show up as Metamodel::CurriedRoleHOW as shown in the example; even if there's a single parameter an instantiated role will also be of the same type:

role Zape[::T] {};
say Zape[Int].HOW; #: «Perl6::Metamodel::CurriedRoleHOW.new␤»

Note: As most of the Metamodel classes, this class is here mainly for illustration purposes and it's not intended for the final user to instantiate.

184 class Metamodel::EnumHOW

Metaobject representing a Perl 6 enum.

class Metamodel::EnumHOW
    does Metamodel::Naming
    does Metamodel::Documenting
    does Metamodel::Stashing
    does Metamodel::AttributeContainer
    does Metamodel::MethodContainer
    does Metamodel::MultiMethodContainer
    does Metamodel::RoleContainer
    does Metamodel::BaseType
    does Metamodel::MROBasedMethodDispatch
    does Metamodel::MROBasedTypeChecking
    does Metamodel::BUILDPLAN
    does Metamodel::BoolificationProtocol
    does Metamodel::REPRComposeProtocol
    does Metamodel::InvocationProtocol
    does Metamodel::Mixins
        { }

Metamodel::EnumHOW is the meta-class behind the enum keyword.

enum Numbers <1 2>;
say Numbers.HOW ~~ Metamodel::EnumHOW; # OUTPUT: «True␤»

The following enum declaration:

our Int enum Error <Warning Failure Exception Sorrow Panic>;

Is roughly equivalent to this code using Metamodel::EnumHOW's methods:

BEGIN {
    my constant Error = Metamodel::EnumHOW.new_type: :name<Error>, :base_type(Int);
    Error.^add_role: Enumeration;
    Error.^add_role: NumericEnumeration;
    Error.^compose;
    for <Warning Failure Exception Sorrow Panic>.kv -> Int $v, Str $k {
        # Note: Enumeration.pred and .succ will not work when adding enum
        # values as pairs. They should be instances of the enum itself, but
        # this isn't possible to do without nqp.
        Error.^add_enum_value: $k => $v;
        OUR::{$k} := Error.^enum_from_value: $v;
    }
    Error.^compose_values;
    OUR::<Error> := Error;
}

Warning: This class is part of the Rakudo implementation, and is not a part of the language specification.

Methods

method new_type

method new_type(:$name!, :$base_type?, :$repr = 'P6opaque', :$is_mixin)

Creates a new type object for an enum. $name is the enum name, $base_type is the type given when the enum is declared using a scoped declaration (if any), and $repr is the type representation passed to the enum using the repr trait. $is_mixin is unused.

method add_parent

method add_parent($obj, $parent)

Sets the base type of an enum. This can only be used if no base type was passed to .new_type.

method set_export_callback

method set_export_callback($obj, $callback)

Sets the enum's export callback, which is invoked when calling .compose_values. This is called when applying the export trait to an enum. $callback should be a routine of some sort, taking no arguments, that handles exporting the enum's values.

method export_callback

method export_callback($obj)

Returns the export callback set by .set_export_callback.

method compose

method compose($obj, :$compiler_services)

Completes a type object for an enum. This is when any roles done by the enum are mixed in. This needs to be called before any enum values can be added using .add_enum_value.

method is_composed

method is_composed($obj)

Returns 1 if the enum is composed, otherwise returns 0.

method compose_values

method compose_values($obj)

Calls the export callback set by .set_export_callback and removes it from state. This should be called after adding the enum's values using .add_enum_value.

method set_composalizer

method set_composalizer($c)

Sets the composalizer for an enum, which produces a type that can be mixed in with another. $c should be a routine of some that has the following signature:

:($type, $name, @enum_values)

method composalizer

method composalizer($obj)

Returns the composalizer set by .set_composalizer.

method add_enum_value

method add_enum_value($obj, $value)

Adds a value to this enum. $value should be an instance of the enum itself, as type Enumeration.

method enum_values

method enum_values($obj)

Returns the values for the enum.

enum Numbers <10 20>;
say Numbers.^enum_values;                   # OUTPUT: {10 => 0, 20 => 1}

method elems

method elems($obj)

Returns the number of values.

enum Numbers <10 20>;
say Numbers.^elems;                         # OUTPUT: 2

method enum_from_value

method enum_from_value($obj, $value)

Given a value of the enum's base type, return the corresponding enum.

enum Numbers <10 20>;
say Numbers.^enum_from_value(0);            # OUTPUT: 10

method enum_value_list

method enum_value_list($obj)

Returns a list of the enum values.

enum Numbers <10 20>;
say Numbers.^enum_value_list;               # OUTPUT: (10 20)

185 role Metamodel::Finalization

Metaobject supporting object finalization

role Metamodel::Finalization { ... }

This role takes care that DESTROY submethods are called (if they exist) when an object is garbage-collected.

Methods

method setup_finalization

method setup_finalization(Metamodel::Finalization:D: $obj)

Collects the DESTROY submethods from this class and all its superclasses, and marks the class as needing action on garbage collection.

A metamodel for a kind that implements finalization semantics must call this method at type composition time.

method destroyers

method destroyers(Metamodel::Finalization:D: $obj --> List:D)

Returns a list of all finalization methods.

186 role Metamodel::MROBasedMethodDispatch

Metaobject that supports resolving inherited methods

role Metamodel::MROBasedMethodDispatch { }

This role implements locating methods based on the method resolution order of related (usually "super"/"parent") types.

Methods

method find_method

method find_method($obj, $name, $no_fallback, *%adverbs)

Given a method name, it returns the method object of that name which is closest in the method resolution order (MRO). If no method can be found, it returns a VM-specific sentinel value (typically a low-level NULL value) that can be tested for with a test for definedness:

for <upper-case  uc> {
    Str.^find_method: $^meth andthen .("foo").say
        orelse "method `$meth` not found".say
}
# OUTPUT:
# method `upper-case` not found
# FOO

If :no_fallback is supplied, fallback methods are not considered.

method find_method_qualified

method find_method_qualified($obj, $type, $name)

Given a method name and a type, returns the method from that type. This is used in calls like

self.SomeParentClass::the_method(); 

method can

method can($obj, $name)

Returns the list of methods of that name the object can do.

method publish_method_cache

Defined as:

method publish_method_cache($obj)

Walk MRO and add methods to cache, unless another method lower in the class hierarchy "shadowed" it.

187 role Metamodel::MethodContainer

Metaobject that supports storing and introspecting methods

role Metamodel::MethodContainer {}

roles, classes, grammars and enums can contain methods. This role implements the API around storing and introspecting them.

say .name for Int.^methods(:all);

# don't do that, because it changes type Int globally.
# just for demonstration purposes.
Int.^add_method('double', method ($x:) { 2 * $x });
say 21.double; # OUTPUT: «42␤»

Methods

method add_method

method add_method(Metamodel::MethodContainer: $obj, $name, $code)

Adds a method to the meta class, to be called with name $name. This should only be done before a type is composed.

method methods

method methods(Metamodel::MethodContainer: $obj, :$all, :$local)

Returns a list of public methods available on the class (which includes methods from superclasses and roles). By default this stops at the classes Cool, Any or Mu; to really get all methods, use the :all adverb. If :local is set, only methods declared directly in the class are returned.

class A {
    method x() { };
}

say A.^methods();                   # x
say A.^methods(:all);               # x infinite defined ...

The returned list contains objects of type Method, which you can use to introspect their signatures and call them.

Some introspection method-look-alikes like WHAT will not show up, although they are present in any Perl 6 object. They are handled at the grammar level and will likely remain so for bootstrap reasons.

method method_table

method method_table(Metamodel::MethodContainer:D: $obj --> Hash:D)

Returns a hash where the keys are method names, and the values are methods. Note that the keys are the names by which the methods can be called, not necessarily the names by which the methods know themselves.

method lookup

method lookup(Metamodel::MethodContainer: $obj, $name --> Method)

Returns the first matching method object of the provided $name or (Mu) if no method object was found. The search for a matching method object is done by following the mro of $obj. Note that lookup is supposed to be used for introspection, if you're after something which can be invoked you probably want to use find_method instead.

say 2.5.^lookup("sqrt").perl:      # OUTPUT: «method sqrt (Rat $: *%_) ...␤»
say Str.^lookup("BUILD").perl;     # OUTPUT: «submethod BUILD (Str $: :$value = "", *%_ --> Nil) ...␤»
say Int.^lookup("does-not-exist"); # OUTPUT: «(Mu)␤»

The difference between find_method and lookup are that find_method will use a default candidate for parametric roles, whereas lookup throws an exception in this case, and that find_method honors FALLBACK methods, which lookup does not.

TODO: submethod_table, declares_method, cache, cache_get, cache_add

188 role Metamodel::MultipleInheritance

Metaobject that supports multiple inheritance

role Metamodel::MultipleInheritance {}

Classes, roles and grammars can have parent classes, that is, classes to which method lookups fall back to, and to whose type the child class conforms to.

This role implements the capability of having zero, one or more parent (or super) classes.

In addition, it supports the notion of hidden classes, whose methods are excluded from the normal dispatching chain, so that for example nextsame ignores it.

This can come in two flavors: methods from a class marked as is hidden are generally excluded from dispatching chains, and class A hides B adds B as a parent class to A, but hides it from the method resolution order, so that mro_unhidden skips it.

Methods

method add_parent

method add_parent(Metamodel::MultipleInheritance:D: $Obj, $parent, :$hides)

Adds $parent as a parent type. If $hides is set to a true value, the parent type is added as a hidden parent.

$parent must be a fully composed typed. Otherwise an exception of type X::Inheritance::NotComposed is thrown.

method parents

method parents(Metamodel::MultipleInheritance:D: $obj, :$all, :$tree)

Returns the list of parent classes. By default it stops at Cool, Any or Mu, which you can suppress by supplying the :all adverb. With :tree, a nested list is returned.

class D { };
class C1 is D { };
class C2 is D { };
class B is C1 is C2 { };
class A is B { };

say A.^parents(:all).perl;
# OUTPUT: «(B, C1, C2, D, Any, Mu)␤»
say A.^parents(:all, :tree).perl;
# OUTPUT: «[B, ([C1, [D, [Any, [Mu]]]], [C2, [D, [Any, [Mu]]]])]␤»

method hides

method hides(Metamodel::MultipleInheritance:D: $obj)

Returns a list of all hidden parent classes.

method hidden

method hidden(Metamodel::MultipleInheritance:D: $obj)

Returns a true value if (and only if) the class is marked is hidden.

method set_hidden

method set_hidden(Metamodel::MultipleInheritance:D: $obj)

Marks the type as hidden.

189 role Metamodel::Naming

Metaobject that supports named types

role Metamodel::Naming { }

Meta model role for (optionally) named things, like classes, roles and enums.

Methods

method name

method name($type)

Returns the name of the meta object, if any.

say 42.^name;       # OUTPUT: «Int␤»

method set_name

method set_name($type, $new_name)

Sets the new name of the meta object.

190 class Metamodel::PackageHOW

Metaobject representing a Perl 6 package.

class Metamodel::PackageHOW
  does Metamodel::Naming
  does Metamodel::Documenting
  does Metamodel::Stashing
  does Metamodel::TypePretense
  does Metamodel::MethodDelegation { }

Metamodel::ClassHOW is the meta class behind the package keyword.

package P {};
say P.HOW; # OUTPUT: «Perl6::Metamodel::PackageHOW.new␤»

Warning: This class is part of the Rakudo implementation, not a part of the language itself.

Methods

method archetypes

Defined as:

method archetypes()

Returns the archetypes for this model, that is, the properties a meta-type can implement.

method new

Defined as:

method new(*%named)

Creates a new PackageHOW.

method new_type

Defined as:

method new_type(:$name = '<anon>', :$repr, :$ver, :$auth)

Creates a new package, with optional representation, version and auth field.

compose

Defined as:

method compose($obj, :$compiler_services)

Sets the meta-package as composed.

is_composed

Defined as:

method is_composed($obj)

Returns the composed status of the meta-package.

191 role Metamodel::ParametricRoleGroupHOW

Represents a group of roles with different parameterizations

class Metamodel::ParametricRoleGroupHOW
    does Metamodel::Naming
    does Metamodel::Documenting
    does Metamodel::Stashing
    does Metamodel::TypePretense
    does Metamodel::RolePunning
    does Metamodel::BoolificationProtocol {}

A ParametricRoleGroupHOW groups a set of ParametricRoleHOW, every one of them representing a single role declaration with their own parameter sets.

(role Zape[::T] {}).HOW.say; # OUTPUT: «Perl6::Metamodel::ParametricRoleHOW.new␤» 
 Zape.HOW.say ; # OUTPUT: «Perl6::Metamodel::ParametricRoleGroupHOW.new␤» 

ParametricRoleHOWs need to be added to this kind of group:

my \zape := Metamodel::ParametricRoleGroupHOW.new_type( name => "zape"); 
 my \zipi := Metamodel::ParametricRoleHOW.new_type( name => "zipi", group => zape); 
 say zipi.HOW; # OUTPUT: «Perl6::Metamodel::ParametricRoleHOW.new␤» 

Note: As most of the Metamodel classes, this class is here mainly for illustration purposes and it's not intended for the final user to instantiate.

192 role Metamodel::ParametricRoleHOW

Represents a non-instantiated, parameterized, role.

class Metamodel::ParametricRoleHOW
    does Metamodel::Naming
    does Metamodel::Documenting
    does Metamodel::Versioning
    does Metamodel::MethodContainer
    does Metamodel::PrivateMethodContainer
    does Metamodel::MultiMethodContainer
    does Metamodel::AttributeContainer
    does Metamodel::RoleContainer
    does Metamodel::MultipleInheritance
    does Metamodel::Stashing
    does Metamodel::TypePretense
    does Metamodel::RolePunning
    does Metamodel::ArrayType {}

A Metamodel::ParametricRoleHOW represents a non-instantiated, possibly parameterized, role:

(role Zape[::T] {}).HOW.say;# OUTPUT: «Perl6::Metamodel::ParametricRoleHOW.new␤» 
 (role Zape {}).HOW.say; # OUTPUT: «Perl6::Metamodel::ParametricRoleHOW.new␤» 

As usual, .new_type will create a new object of this class.

my \zipi := Metamodel::ParametricRoleHOW.new_type( name => "zape", group => "Zape"); 
 say zipi.HOW; # OUTPUT: «Perl6::Metamodel::ParametricRoleHOW.new␤» 

The extra group argument will need to be used to integrate it in a parametric role group, which will need to be defined in advance.

Note: As most of the Metamodel classes, this one is here mainly for illustration purposes and it's not intended for the final user to instantiate, unless their intention is really to create a parametric role group.

193 class Metamodel::Primitives

Metaobject that supports low-level type operations

class Metamodel::Primitives {}

Metamodel::Primitives provides low-level operations for working with types, which are otherwise only available as implementation-dependent directives. These primitives are available as class methods.

Here is an example that steals the meta model instance from the Int class to create a custom type (usually you would create your own meta class if you mess with something as low-level), which allows calling of just one method called why:

my Mu $type := Metamodel::Primitives.create_type(Int.HOW, 'P6opaque');
$type.^set_name('why oh why?');
my %methods =  why => sub ($) { say 42 };
Metamodel::Primitives.install_method_cache($type, %methods, :authoritative);
$type.why;      # 42
$type.list;
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Method::NotFound: Method 'list' not found for invocant of class 'why oh why?'␤»

Methods

method create_type

method create_type(Mu $how, $repr = 'P6opaque')

Creates and returns a new type from a meta object $how and a representation name.

method set_package

method set_package(Mu $type, $package)

Sets the package associated with the type.

method install_method_cache

method install_method_cache( Mu $type, %cache, :$authoritative = True)

Installs a method cache, that is, a mapping from method names to code objects. If :authoritative is missing, or set to True, then calls of methods that do not exist in the cache will throw an exception of type X::Method::NotFound. If :authoritative is set to False, the usual fallback mechanism are tried.

method configure_type_checking

method configure_type_checking( Mu $type, @cache, :$authoritative = True,   :$call_accepts = False )

Configures the type checking for $type. @cache is a list of known types against which $type checks positively (so in a classical class-based system, the type itself and all recursive superclasses). If :authoritative is missing or True, this type will fail checks against all types not in @cache. If :call_accepts is True, the method ACCEPTS will be called for type checks against this type.

method configure_destroy

method configure_destroy(Mu $type, $destroy)

Configures whether DESTROY methods are called (if present) when the garbage collector collects an object of this type (if $destroy is set to a true value). This comes with a performance overhead, so should only be set to a true value if necessary.

method compose_type

method compose_type(Mu $type, $configuration)

Composes $type (that is, finalizes it to be ready for instantiation). See https://github.com/perl6/nqp/blob/master/docs/6model/repr-compose-protocol.markdown for what $configuration can contain (until we have better docs, sorry).

method rebless

method rebless(Mu $object, Mu $type)

Changes $obj to be of type $type. This only works if $type type-checks against the current type of $obj, and if the storage of $object is a subset of that of $type.

method is_type

method is_type(Mu \obj, Mu \type --> Bool:D)

Type-checks obj against type

194 role Metamodel::PrivateMethodContainer

Metaobject that supports private methods

role Metamodel::PrivateMethodContainer { ... }

In Perl 6, classes, roles and grammars can have private methods, that is, methods that are only callable from within the class, and are not inherited by types derived by inheritance.

class A {
    # the ! declares a private method
    method !double($x) {
        say 2 * $x;
    }
    method call-double($y) {
        # call with ! instead of .
        self!double($y);
    }
}

For the purposes of dispatching and scoping, private methods are closer to subroutines than to methods. However they share access to self and attributes with methods.

Methods

method add_private_method

method add_private_method(Metamodel::PrivateMethodContainer: $obj, $name, $code)

Adds a private method $code with name $name.

method private_method_table

method private_method_table(Metamodel::PrivateMethodContainer: $obj)

Returns a hash of name => &method_object

TODO: document find_private_method, once we've figured out how to represent or catch nqp::null in Perl 6 land

195 role Metamodel::RoleContainer

Metaobject that supports holding/containing roles

role Metamodel::RoleContainer {}

Implements the ability to hold roles to be held for composition.

class A does SomeRole {} 

roughly corresponds to

class A { 
     BEGIN A.^add_role(SomeRole); 
 } 

Methods

method add_role

method add_role(Metamodel::RoleContainer:D: $obj, Mu $role)

Adds the $role to the list of roles to be composed.

method roles_to_compose

method roles_to_compose(Metamodel::RoleContainer:D: $obj --> List:D)

returns a list of roles added with add_role, which are to be composed at type composition time.

196 role Metamodel::RolePunning

Metaobject that supports

role Perl6::Metamodel::RolePunning {}

Implements the ability to create objects from Roles without the intermediate need to use a class. Not intended to be used directly (will in fact error if it's used), but via punning of roles, as below. This is also Rakudo specific and not part of the spec.

role A { 
     method b { 
       return "punned" 
     } 
 }; 
 my $a = A.new; 
 say $a.b; # OUTPUT: «punned␤» 

197 role Metamodel::Trusting

Metaobject that supports trust relations between types

role Metamodel::Trusting is SuperClass { ... } 

Normally, code in a class or role can only access its own private methods. If another type declares that it trusts that first class, then access to private methods of that second type is possible. Metamodel::Trusting implements that aspect of the Perl 6 object system.

class A {
    my class B {
        trusts A;   # that's where Metamodel::Trusting comes in
        method !private_method() {
            say "Private method in B";
        }
    }
    method build-and-poke {
        # call a private method from B
        # disallowed if A doesn't trust B
        B.new()!B::private_method();
    }
};

A.build-and-poke;   # Private method in A

Methods

method add_trustee

method add_trustee(Metamodel::Trusting:D: $type, Mu $trustee)

Trust $trustee.

class A { 
     BEGIN A.^add_trustee(B); 
     # same as 'trusts B'; 
 } 

method trusts

method trusts(Metamodel::Trusting:D: $type --> List)

Returns a list of types that the invocant trusts.

class A { trusts Int; };
say .^name for A.^trusts;       # Int

method is_trusted

method is_trusted(Metamodel::Trusting:D: $type, $claimant)

Returns 1 if $type trusts $claimant, and 0 otherwise. Types always trust themselves.

198 role Metamodel::Versioning

Metaobjects that support versioning

role Metamodel::Versioning { ... }

Metamodel role for (optionally) versioning metaobjects.

When you declare a type, you can pass it a version, author, and/or API and get them, like so:

class Versioned:ver<0.0.1>:auth<github:Kaiepi>:api<1> { } 
 
 say Versioned.^ver;  # OUTPUT: «v0.0.1␤» 
 say Versioned.^auth; # OUTPUT: «github:Kaiepi␤» 
 say Versioned.^api;  # OUTPUT: «1␤» 

This is roughly equivalent to the following, which also sets them explicitly:

BEGIN { 
     class Versioned { } 
     Versioned.^set_ver:  v0.0.1; 
     Versioned.^set_auth: 'github:Kaiepi'; 
     Versioned.^set_api:  <1>; 
 } 
 
 say Versioned.^ver;  # OUTPUT: «v0.0.1␤» 
 say Versioned.^auth; # OUTPUT: «github:Kaiepi␤» 
 say Versioned.^api;  # OUTPUT: «1␤» 

Methods

method ver

method ver($obj)

Returns the version of the metaobject, if any, otherwise returns Mu.

method auth

method auth($obj)

Returns the author of the metaobject, if any, otherwise returns an empty string.

method api

method api($obj)

Returns the API of the metaobject, if any, otherwise returns an empty string.

method set_ver

method set_ver($obj, $ver)

Sets the version of the metaobject.

method set_auth

method set_auth($obj, $auth)

Sets the author of the metaobject.

method set_api

method set_api($obj, $api)

Sets the API of the metaobject.

199 class Method

Member function

class Method is Routine { }

A type for methods that behave the same way then Routine with some exceptions listed in the following. For details of a method's parameter list see Signature.

To create a method outside a class definition, use the declarators my and method. If an identifier is provided the methods name will be injected into the scope specified by the declarator.

my $m = method ($invocant: $param) {
    say "$invocant: '$param'";
}
"greeting".$m("hello");  # OUTPUT: «greeting: 'hello'␤»

<a b c>.&(my method (List:D:) { say self.perl; self }).say;
# OUTPUT: «("a", "b", "c")␤(a b c)␤»

The invocant of a method defaults to self. A type constraint including a type-smiley can be used and is honored both for methods defined in a class and for free floating methods. Call the latter with .& on an object.

my method m(Int:D: $b){
    say self.^name
}
my $i = 1;
$i.&m(<a>);
# OUTPUT: «Int␤»

Methods will ignore extra named arguments where other types of Routine will throw at runtime. Extra arguments will be forwarded by nextsame and friends.

class A {
    multi method m(:$a, :$b) { say "2 named" }
}

class B is A {
    method m(:$a) { say "1 named"; nextsame }
}
B.m( :1a, :2b );
# OUTPUT: «1 named␤2 named␤»

sub lastcall

sub lastcall(--> True)

Truncates the current dispatch chain, which means any calls to nextsame, callsame, nextwith, and callwith will not find any of the next candidates. Note that since samewith restarts the dispatch from the start, it's not affected by the truncation of current chain with lastcall.

Consider example below. foo(6) uses nextsame when lastcall hasn't been called, and so it reaches the Any candidate. foo(2) calls nextsame as well, but since lastcall was called first, the dispatch chain was truncated and the Any candidate was not reached. The last call, foo(1), calls lastcall too, however, it then uses samewith, which isn't affected by it, and so the dispatch re-starts from scratch, hits the Int candidate with the new argument 6, and then proceeds to the Any candidate via nextsame (which isn't affected by the lastcall that was used before the samewith was called):

multi foo (Int $_) {
    say "Int: $_";
    lastcall   when *.is-prime;
    nextsame   when *  %% 2;
    samewith 6 when * !%% 2;
}
multi foo (Any $x) { say "Any $x" }

foo 6; say '----';
foo 2; say '----';
foo 1;

# OUTPUT:
# Int: 6
# Any 6
# ----
# Int: 2
# ----
# Int: 1
# Int: 6
# Any 6

200 class Mix

Immutable collection of distinct objects with Real weights

class Mix does Mixy { }

A Mix is an immutable collection of distinct elements in no particular order that each have a real-number weight assigned to them. (For mutable mixes, see MixHash instead.)

Mixes are often used for performing weighted random selections - see .roll.

Objects/values of any type are allowed as mix elements. Within a Mix, items that would compare positively with the === operator are considered the same element, with a combined weight.

my $recipe = (butter => 0.22, sugar => 0.1, 
               flour => 0.275, sugar => 0.02).Mix; 
 
 say $recipe.elems;      # OUTPUT: «3␤» 
 say $recipe.keys.sort;  # OUTPUT: «butter flour sugar␤» 
 say $recipe.pairs.sort; # OUTPUT: «"butter" => 0.22 "flour" => 0.275 "sugar" => 0.12␤» 
 say $recipe.total;      # OUTPUT: «0.615␤» 

Mixes can be treated as object hashes using the { } postcircumfix operator, which returns the corresponding numeric weight for keys that are elements of the mix, and 0 for keys that aren't:

my $recipe = (butter => 0.22, sugar => 0.1,
              flour => 0.275, sugar => 0.02).Mix;
say $recipe<butter>;     # OUTPUT: «0.22␤»
say $recipe<sugar>;      # OUTPUT: «0.12␤»
say $recipe<chocolate>;  # OUTPUT: «0␤»

Creating Mix objects

Mixes can be composed using the mix subroutine (or Mix.new, for which it is a shorthand). Any positional parameters, regardless of their type, become elements of the mix - with a weight of 1 for each time the parameter occurred:

my $n = mix "a", "a", "b" => 0, 3.14, π, π; # The Pair is a single element
say $n.keys.map: *.^name; # OUTPUT: «(Rat Pair Num Str)␤»
say $n.pairs;
# OUTPUT: «(3.14 => 1 (b => 0) => 1 3.141592653589793 => 2 a => 2)␤»

Alternatively, the .Mix coercer (or its functional form, Mix()) can be called on an existing object to coerce it to a Mix. Its semantics depend on the type and contents of the object. In general it evaluates the object in list context and creates a mix with the resulting items as elements, although for Hash-like objects or Pair items, only the keys become elements of the mix, and the (cumulative) values become the associated numeric weights:

my $n = ("a", "a", "b" => 0, "c" => 3.14).Mix;
say $n.keys.map(&WHAT);  # OUTPUT: «((Str) (Str))␤»
say $n.pairs;            # OUTPUT: «(a => 2 c => 3.14)␤»

Elements with a 0 value, as b above, are simply eliminated from the Mix.

Alternatively, since Mixes are Associative, we can use the % sigil to declare them; in that case, we can employ is to declare their type:

my %n is Mix = ("a", "a", "b" => 0, "c" => 3.14);
say %n.^name; # OUTPUT: «Mix␤»
say %n;       # OUTPUT: «Mix(a(2), c(3.14))␤»

Since 6.d (2019.03 and later) it is also possible to specify the type of values you would like to allow in a Mix. This can either be done when calling .new:

# only allow strings
my $n = Mix[Str].new: <a b b c c c>;

or using the masquerading syntax:

# only allow strings
my %m is Mix[Str] = <a b b c c c>;
say %m<b>;  # 2
say %m<d>;  # 0

# only allow whole numbers
my %m is Mix[Int] = <a b b c c c>;
# Type check failed in binding; expected Int but got Str ("a")

Operators

Mixes can use all kind of set operators returning either Bool or other Mixes:

my $this-mix = (sugar => ⅓, spice => ¼, all-things-nice => ¾); 
 my $that-mix = ( sugar => 1, spice => 2); 
 
 say $that-mix (<) $this-mix;     # OUTPUT: «True␤» 
 say $that-mix (^) $this-mix;     # OUTPUT: «set(all-things-nice)␤» 
 say $that-mix (+) $this-mix;     # OUTPUT: «Bag(spice(2), sugar)␤» 

With their equivalent Unicode operators:

say $that-mix ⊂ $this-mix;     # OUTPUT: «True␤» 
 say $that-mix ⊖ $this-mix;     # OUTPUT: «set(all-things-nice)␤» 
 say $that-mix ⊎ $this-mix;     # OUTPUT: «Bag(spice(2), sugar)␤» 

See Set/Bag Operators for a complete list of set and bag operators with detailed explanations.

sub mix

sub mix(*@args --> Mix)

Creates a new Mix from @args.

Methods

method Bag

Defined as:

method Bag (--> Bag:D)

Coerces the Mix to a Bag. The weights are convert to Int, which means the number of keys in the resulting Bag can be fewer than in the original Mix, if any of the weights are negative or truncate to zero.

method BagHash

Defined as:

method BagHash (--> BagHash:D)

Coerces the Mix to a BagHash. The weights are convert to Int, which means the number of keys in the resulting BagHash can be fewer than in the original Mix, if any of the weights are negative or truncate to zero.

method reverse

Note: This method is inherited from Any, however, Mixes do not have an inherent order and you should not trust it returning a consistent output.

Note on order

Same as the other elements in the Bag/Mix suite, order is not guaranteed or consistent and you shouldn't rely on methods like reverse above returning always the same result.

See Also

Sets, Bags, and Mixes

201 class MixHash

Mutable collection of distinct objects with Real weights

class MixHash does Mixy { }

A MixHash is a mutable mix, meaning a collection of distinct elements in no particular order that each have a real-number weight assigned to them. (For immutable mixes, see Mix instead.)

Objects/values of any type are allowed as mix elements. Within a MixHash, items that would compare positively with the === operator are considered the same element, with a combined weight.

my $recipe = (butter => 0.22, sugar => 0.1, 
               flour => 0.275, sugar => 0.02).MixHash; 
 
 say $recipe.elems;      # OUTPUT: «3␤» 
 say $recipe.keys.sort;  # OUTPUT: «butter flour sugar␤» 
 say $recipe.pairs.sort; # OUTPUT: «"butter" => 0.22 "flour" => 0.275 "sugar" => 0.12␤» 
 say $recipe.total;      # OUTPUT: «0.615␤» 

MixHashes can be treated as object hashes using the { } postcircumfix operator, which returns the corresponding numeric weight for keys that are elements of the mix, and 0 for keys that aren't. It can also be used to modify weights; Setting a weight to 0 automatically removes that element from the mix, and setting a weight to a non-zero number adds that element if it didn't already exist:

my $recipe = (butter => 0.22, sugar => 0.1, 
               flour => 0.275, sugar => 0.02).MixHash; 
 
 say $recipe<butter>;     # OUTPUT: «0.22␤» 
 say $recipe<sugar>;      # OUTPUT: «0.12␤» 
 say $recipe<chocolate>;  # OUTPUT: «0␤» 
 
 $recipe<butter> = 0; 
 $recipe<chocolate> = 0.30; 
 say $recipe.pairs;       # OUTPUT: «"sugar" => 0.12 "flour" => 0.275 "chocolate" => 0.3␤» 

Creating MixHash objects

MixHashes can be composed using MixHash.new. Any positional parameters, regardless of their type, become elements of the mix - with a weight of 1 for each time the parameter occurred:

my $n = MixHash.new: "a", "a", "b" => 0, "c" => 3.14;
say $n.keys.map(&WHAT);  # OUTPUT: «((Str) (Pair) (Pair))␤»
say $n.pairs;            # OUTPUT: «(a => 2 (c => 3.14) => 1 (b => 0) => 1)␤»

Alternatively, the .MixHash coercer (or its functional form, MixHash()) can be called on an existing object to coerce it to a MixHash. Its semantics depend on the type and contents of the object. In general it evaluates the object in list context and creates a mix with the resulting items as elements, although for Hash-like objects or Pair items, only the keys become elements of the mix, and the (cumulative) values become the associated numeric weights:

my $n = ("a", "a", "b" => 0, "c" => 3.14).MixHash;
say $n.keys.map(&WHAT);  # OUTPUT: «((Str) (Str))␤»
say $n.pairs;            # OUTPUT: «(a => 2 c => 3.14)␤»

Since 6.d (2019.03 and later) it is also possible to specify the type of values you would like to allow in a MixHash. This can either be done when calling .new:

# only allow strings
my $n = MixHash[Str].new: <a b b c c c>;

or using the masquerading syntax:

# only allow strings
my %mh is MixHash[Str] = <a b b c c c>;
say %mh<b>;  # 2
say %mh<d>;  # 0

# only allow whole numbers
my %mh is MixHash[Int] = <a b b c c c>;
# Type check failed in binding; expected Int but got Str ("a")

Operators

my ($a, $b) = MixHash(2 => 2, 4), MixHash(2 => 1.5, 3 => 2, 4); 
 
 say $a (<) $b;   # OUTPUT: «False␤» 
 say $a (<+) $b;  # OUTPUT: «False␤» 
 say $a (^) $b;   # OUTPUT: «Mix(2(0.5), 3(2))␤» 
 say $a (+) $b;   # OUTPUT: «Mix(2(3.5), 4(2), 3(2))␤» 
 
 # Unicode versions: 
 say $a ⊂ $b;  # OUTPUT: «False␤» 
 say $a ≼ $b;  # OUTPUT: «False␤» 
 say $a ⊖ $b;  # OUTPUT: «Mix(2(0.5), 3(2))␤» 
 say $a ⊎ $b;  # OUTPUT: «Mix(2(3.5), 4(2), 3(2))␤» 

See Set/Bag Operators for a complete list of set and bag operators with detailed explanations.

Note on reverse and ordering.

MixHash inherits reverse from Any, however, Mixes do not have an inherent order and you should not trust it returning a consistent output.

If you sort a MixHash, the result is a list of pairs, at which point reverse makes perfect sense:

my $a = MixHash.new(2, 2, 18, 3, 4); 
 say $a;  # OUTPUT: «MixHash(18, 2(2), 3, 4)␤» 
 
 say $a.sort;  # OUTPUT: «(2 => 2 3 => 1 4 => 1 18 => 1)␤» 
 say $a.sort.reverse;  # OUTPUT: «(18 => 1 4 => 1 3 => 1 2 => 2)␤» 

Methods

method Bag

Defined as:

method Bag (--> Bag:D)

Coerces the MixHash to a Bag. The weights are converted to Int, which means the number of keys in the resulting Bag can be fewer than in the original MixHash, if any of the weights are negative or truncate to zero.

method BagHash

Defined as:

method BagHash (--> BagHash:D)

Coerces the MixHash to a BagHash. The weights are converted to Int, which means the number of keys in the resulting BagHash can be fewer than in the original MixHash, if any of the weights are negative or truncate to zero.

Note on reverse and ordering

This method is inherited from Any, however, Mixes do not have an inherent order and you should not trust it returning a consistent output.

See Also

Sets, Bags, and Mixes

202 role Mixy

Collection of distinct objects with Real weights

role Mixy does Baggy { }

A role for collections of weighted values. See Mix and MixHash. Mixy objects differ from Baggy objects in that the weights of Mixy are Reals rather than Ints.

Methods

method total

method total(--> Real)

Returns the sum of all the weights

say mix('a', 'b', 'c', 'a', 'a', 'd').total == 6;  # OUTPUT: «True␤»
say %(a => 5.6, b => 2.4).Mix.total == 8;          # OUTPUT: «True␤»

method roll

method roll($count = 1)

Similar to a Bag.roll, but with Real weights rather than integral ones.

See Also

Sets, Bags, and Mixes

203 class Mu

The root of the Perl 6 type hierarchy.

class Mu { }

The root of the Perl 6 type hierarchy. For the origin of the name, see https://en.wikipedia.org/wiki/Mu_%28negative%29. One can also say that there are many undefined values in Perl 6, and Mu is the most undefined value.

Note that most classes do not derive from Mu directly, but rather from Any.

Methods

method iterator

Defined as:

method iterator(--> Iterator)

Coerces the invocant to a list by applying its .list method and uses iterator on it.

my $it = Mu.iterator;
say $it.pull-one; # OUTPUT: «(Mu)␤»
say $it.pull-one; # OUTPUT: «IterationEnd␤»

method defined

Declared as

multi method defined(   --> Bool:D)

Returns False on a type object, and True otherwise.

say Int.defined;                # OUTPUT: «False␤»
say 42.defined;                 # OUTPUT: «True␤»

A few types (like Failure) override defined to return False even for instances:

sub fails() { fail 'oh noe' };
say fails().defined;            # OUTPUT: «False␤»

routine defined

Declared as

multi sub defined(Mu --> Bool:D)

invokes the .defined method on the object and returns its result.

routine isa

multi method isa(Mu $type     --> Bool:D)
multi method isa(Str:D $type  --> Bool:D)

Returns True if the invocant is an instance of class $type, a subset type or a derived class (through inheritance) of $type. does is similar, but includes roles.

my $i = 17;
say $i.isa("Int");   # OUTPUT: «True␤»
say $i.isa(Any);     # OUTPUT: «True␤»
role Truish {};
my $but-true = 0 but Truish;
say $but-true.^name;        # OUTPUT: «Int+{Truish}␤»
say $but-true.does(Truish); # OUTPUT: «True␤»
say $but-true.isa(Truish);  # OUTPUT: «False␤»

routine does

method does(Mu $type --> Bool:D)

Returns True if and only if the invocant conforms to type $type.

my $d = Date.new('2016-06-03'); 
 say $d.does(Dateish);             # True    (Date does role Dateish) 
 say $d.does(Any);                 # True    (Date is a subclass of Any) 
 say $d.does(DateTime);            # False   (Date is not a subclass of DateTime) 

Unlike isa, which returns True only for superclasses, does includes both superclasses and roles.

say $d.isa(Dateish); # OUTPUT: «False␤» 

Using the smartmatch operator ~~ is a more idiomatic alternative.

my $d = Date.new('2016-06-03');
say $d ~~ Dateish;                # OUTPUT: «True␤»
say $d ~~ Any;                    # OUTPUT: «True␤»
say $d ~~ DateTime;               # OUTPUT: «False␤»

routine Bool

multi sub    Bool(Mu --> Bool:D)
multi method Bool(   --> Bool:D)

Returns False on the type object, and True otherwise.

Many built-in types override this to be False for empty collections, the empty string or numerical zeros

say Mu.Bool;                    # OUTPUT: «False␤»
say Mu.new.Bool;                # OUTPUT: «True␤»
say [1, 2, 3].Bool;             # OUTPUT: «True␤»
say [].Bool;                    # OUTPUT: «False␤»
say %( hash => 'full' ).Bool;   # OUTPUT: «True␤»
say {}.Bool;                    # OUTPUT: «False␤»
say "".Bool;                    # OUTPUT: «False␤»
say 0.Bool;                     # OUTPUT: «False␤»
say 1.Bool;                     # OUTPUT: «True␤»
say "0".Bool;                   # OUTPUT: «True␤»

method Capture

Declared as:

method Capture(Mu:D: --> Capture:D)

Returns a Capture with named arguments corresponding to invocant's public attributes:

class Foo {
    has $.foo = 42;
    has $.bar = 70;
    method bar { 'something else' }
}.new.Capture.say; # OUTPUT: «\(:bar("something else"), :foo(42))␤»

method Str

multi method Str(--> Str)

Returns a string representation of the invocant, intended to be machine readable. Method Str warns on type objects, and produces the empty string.

say Mu.Str;   # Use of uninitialized value of type Mu in string context.
my @foo = [2,3,1];
say @foo.Str  # OUTPUT: «2 3 1␤»

routine gist

multi sub    gist(+args --> Str)
multi method gist(   --> Str)

Returns a string representation of the invocant, optimized for fast recognition by humans. As such lists will be truncated at 100 elements. Use .perl to get all elements.

The default gist method in Mu re-dispatches to the perl method for defined invocants, and returns the type name in parenthesis for type object invocants. Many built-in classes override the case of instances to something more specific that may truncate output.

gist is the method that say calls implicitly, so say $something and say $something.gist generally produce the same output.

say Mu.gist;        # OUTPUT: «(Mu)␤»
say Mu.new.gist;    # OUTPUT: «Mu.new␤»

routine perl

multi method perl(--> Str)

Returns a Perlish representation of the object (i.e., can usually be re-evaluated with EVAL to regenerate the object). The exact output of perl is implementation specific, since there are generally many ways to write a Perl expression that produces a particular value.

method item

method item(Mu \item:) is raw

Forces the invocant to be evaluated in item context and returns the value of it.

say [1,2,3].item.perl;          # OUTPUT: «$[1, 2, 3]␤»
say %( apple => 10 ).item.perl; # OUTPUT: «${:apple(10)}␤»
say "abc".item.perl;            # OUTPUT: «"abc"␤»

method self

method self(--> Mu)

Returns the object it is called on.

method clone

multi method clone(Mu:U: *%twiddles)
multi method clone(Mu:D: *%twiddles)

This method will clone type objects, or die if it's invoked with any argument.

say Num.clone( :yes ) 
 # OUTPUT: «(exit code 1) Cannot set attribute values when cloning a type object␤  in block <unit>␤␤» 

If invoked with value objects, it creates a shallow clone of the invocant, including shallow cloning of private attributes. Alternative values for public attributes can be provided via named arguments with names matching the attributes' names.

class Point2D { 
     has ($.x, $.y); 
     multi method gist(Point2D:D:) { 
         "Point($.x, $.y)"; 
     } 
 } 
 
 my $p = Point2D.new(x => 2, y => 3); 
 
 say $p;                     # OUTPUT: «Point(2, 3)␤» 
 say $p.clone(y => -5);      # OUTPUT: «Point(2, -5)␤» 

Note that .clone does not go the extra mile to shallow-copy @. and %. sigiled attributes and, if modified, the modifications will still be available in the original object:

class Foo { 
     has $.foo is rw = 42; 
     has &.boo is rw = { say "Hi" }; 
     has @.bar       = <a b>; 
     has %.baz       = <a b c d>; 
 } 
 
 my $o1 = Foo.new; 
 with my $o2 = $o1.clone { 
     .foo = 70; 
     .bar = <Z Y>; 
     .baz = <Z Y X W>; 
     .boo = { say "Bye" }; 
 } 
 
 # Hash and Array attribute modifications in clone appear in original as well: 
 say $o1; 
 # OUTPUT: «Foo.new(foo => 42, bar => ["Z", "Y"], baz => {:X("W"), :Z("Y")}, …␤» 
 say $o2; 
 # OUTPUT: «Foo.new(foo => 70, bar => ["Z", "Y"], baz => {:X("W"), :Z("Y")}, …␤» 
 $o1.boo.(); # OUTPUT: «Hi␤» 
 $o2.boo.(); # OUTPUT: «Bye␤» 

To clone those, you could implement your own .clone that clones the appropriate attributes and passes the new values to Mu.clone, for example, via nextwith.

class Bar { 
     has $.quux; 
     has @.foo = <a b>; 
     has %.bar = <a b c d>; 
     method clone { nextwith :foo(@!foo.clone), :bar(%!bar.clone), |%_  } 
 } 
 
 my $o1 = Bar.new( :42quux ); 
 with my $o2 = $o1.clone { 
     .foo = <Z Y>; 
     .bar = <Z Y X W>; 
 } 
 
 # Hash and Array attribute modifications in clone do not affect original: 
 say $o1; 
 # OUTPUT: «Bar.new(quux => 42, foo => ["a", "b"], bar => {:a("b"), :c("d")})␤» 
 say $o2; 
 # OUTPUT: «Bar.new(quux => 42, foo => ["Z", "Y"], bar => {:X("W"), :Z("Y")})␤» 

The |%_ is needed to slurp the rest of the attributes that would have been copied via shallow copy.

method new

multi method new(*%attrinit)
multi method new($, *@)

Default method for constructing (create + initialize) new objects of a class. This method expects only named arguments which are then used to initialize attributes with accessors of the same name.

Classes may provide their own new method to override this default.

new triggers an object construction mechanism that calls submethods named BUILD in each class of an inheritance hierarchy, if they exist. See the documentation on object construction for more information.

method bless

method bless(*%attrinit --> Mu:D)

Low-level object construction method, usually called from within new, implicitly from the default constructor, or explicitly if you create your own constructor. bless creates a new object of the same type as the invocant, using the named arguments to initialize attributes and returns the created object.

It is usually invoked within custom new method implementations:

class Point { 
     has $.x; 
     has $.y; 
     multi method new($x, $y) { 
         self.bless(:$x, :$y); 
     } 
 } 
 my $p = Point.new(-1, 1); 

In this case we are declaring new as a multi method so that we can still use the default constructor like this: Point.new( x => 3, y => 8 ). In this case we are declaring this new method simply to avoid the extra syntax of using pairs when creating the object. self.bless returns the object, which is in turn returned by new.

However, in general, implementing a customized new method might not be the best way of initializing a class, even more so if the default constructor is disabled, since it can make it harder to correctly initialize the class from a subclass. For instance, in the above example, the new implementation takes two positional arguments that must be passed from the subclass to the superclass in the exact order. That is not a real problem if it's documented, but take into account bless will eventually be calling BUILD in the class that is being instantiated. This might result in some unwanted problems, like having to create a BUILD submethod to serve it correctly:

class Point { 
     has Int $.x; 
     has Int $.y; 
     multi method new($x, $y) { 
         self.bless(:$x, :$y); 
     } 
 } 
 
 class Point-with-ID is Point { 
     has Int $.ID  is rw = 0; 
 
     submethod BUILD( *%args ) { 
         say %args;                # OUTPUT: «{x => 1, y => 2}␤» 
         for self.^attributes -> $attr { 
             if $attr.Str ~~ /ID/ { 
                 $attr.set_value( self, "*" ~ %args<x> ~ "-" ~ %args<y> ) ; 
             } 
         } 
     } 
 } 
 
 my $p = Point-with-ID.new(1,2); 
 say $p.perl; 
 # OUTPUT: «Point-with-ID.new(ID => "*1-2", x => 1, y => 2)␤» 

In this code, bless, called within Point.new, is eventually calling BUILD with the same parameters. We have to create a convoluted way of using the $.ID attribute using the meta-object protocol so that we can instantiate it and thus serve that new constructor, which can be called on Point-with-ID since it is a subclass.

We might have to use something similar if we want to instantiate superclasses. bless will help us with that, since it is calling across all the hierarchy:

class Str-with-ID is Str { 
     my $.counter = 0; 
     has Int $.ID  is rw = 0; 
 
     multi method new( $str ) { 
         self.bless( value => $str, ID => $.counter++ ); 
     } 
 
     submethod BUILD( *%args ) { 
         for self.^attributes -> $attr { 
             if $attr.Str ~~ /ID/ { 
                 $attr.set_value( self, %args<ID> ) ; 
             } 
         } 
     } 
 } 
 
 say Str-with-ID.new("1.1,2e2").ID;                  # OUTPUT: «0␤» 
 my $enriched-str = Str-with-ID.new("3,4"); 
 say "$enriched-str, {$enriched-str.^name}, {$enriched-str.ID}"; 
 # OUTPUT: «3,4, Str-with-ID, 1␤» 

We are enriching Str with an auto-incrementing ID. We create a new since we want to initialize it with a string and, besides, we need to instantiate the superclass. We do so using bless from within new. bless is going to call Str.BUILD. It will *capture* the value it's looking for, the pair value = $str> and initialize itself. But we have to initialize also the properties of the subclass, which is why within BUILD we use the previously explained method to initialize $.ID with the value that is in the %args variable. As shown in the output, the objects will be correctly initialized with its ID, and will correctly behave as Str, converting themselves in just the string in the say statement, and including the ID property as required.

For more details see the documentation on object construction.

method CREATE

method CREATE(--> Mu:D)

Allocates a new object of the same type as the invocant, without initializing any attributes.

say Mu.CREATE.defined;  # OUTPUT: «True␤»

method print

multi method print(--> Bool:D)

Prints value to $*OUT after stringification using .Str method without adding a newline at end.

"abc\n".print;          # RESULT: «abc␤»

method put

multi method put(--> Bool:D)

Prints value to $*OUT, adding a newline at end, and if necessary, stringifying non-Str object using the .Str method.

"abc".put;              # RESULT: «abc␤»

method say

multi method say()

Will say to standard output.

say 42;                 # OUTPUT: «42␤»

What say actually does is, thus, deferred to the actual subclass. In most cases it calls .gist on the object, returning a compact string representation.

In non-sink context, say will always return True.

say (1,[1,2],"foo",Mu).map: so *.say ;
# OUTPUT: «1␤[1 2]␤foo␤(Mu)␤(True True True True)␤»

However, this behavior is just conventional and you shouldn't trust it for your code. It's useful, however, to explain certain behaviors.

say is first printing out in *.say, but the outermost say is printing the True values returned by the so operation.

method ACCEPTS

multi method ACCEPTS(Mu:U: $other)

ACCEPTS is the method that smartmatching with the infix ~~ operator and given/when invokes on the right-hand side (the matcher).

The Mu:U multi performs a type check. Returns True if $other conforms to the invocant (which is always a type object or failure).

say 42 ~~ Mu;           # OUTPUT: «True␤»
say 42 ~~ Int;          # OUTPUT: «True␤»
say 42 ~~ Str;          # OUTPUT: «False␤»

Note that there is no multi for defined invocants; this is to allow autothreading of junctions, which happens as a fallback mechanism when no direct candidate is available to dispatch to.

method WHICH

multi method WHICH(--> ObjAt:D)

Returns an object of type ObjAt which uniquely identifies the object. Value types override this method which makes sure that two equivalent objects return the same return value from WHICH.

say 42.WHICH eq 42.WHICH;       # OUTPUT: «True␤»

method WHERE

method WHERE(--> Int)

Returns an Int representing the memory address of the object.

method WHY

multi method WHY(--> Pod::Block::Declarator)

Returns the attached Pod::Block::Declarator.

For instance:

#| Initiate a specified spell normally 
 sub cast(Spell $s) { 
   do-raw-magic($s); 
 } 
 #= (do not use for class 7 spells) 
 say &cast.WHY; 
 # OUTPUT: «Initiate a specified spell normally␤(do not use for class 7 spells)␤» 

See Pod declarator blocks for details about attaching Pod to variables, classes, functions, methods, etc.

trait is export

multi sub trait_mod:<is>(Mu:U \type, :$export!)

Marks a type as being exported, that is, available to external users.

my class SomeClass is export { }

A user of a module or class automatically gets all the symbols imported that are marked as is export.

See Exporting and Selective Importing Modules for more details.

method return

method return()

The method return will stop execution of a subroutine or method, run all relevant phasers and provide invocant as a return value to the caller. If a return type constraint is provided it will be checked unless the return value is Nil. A control exception is raised and can be caught with CONTROL.

sub f { (1|2|3).return };
say f(); # OUTPUT: «any(1, 2, 3)␤»

method return-rw

Same as method return except that return-rw returns a writable container to the invocant (see more details here: return-rw).

method emit

method emit()

Emits the invocant into the enclosing supply or react block.

react { whenever supply { .emit for "foo", 42, .5 } {
    say "received {.^name} ($_)";
}}

# OUTPUT:
# received Str (foo)
# received Int (42)
# received Rat (0.5)

method take

method take()

Returns the invocant in the enclosing gather block.

sub insert($sep, +@list) {
    gather for @list {
        FIRST .take, next;
        take slip $sep, .item
    }
}

say insert ':', <a b c>;
# OUTPUT: «(a : b : c)␤»

routine take

sub take(\item)

Takes the given item and passes it to the enclosing gather block.

#| randomly select numbers for lotto
my $num-selected-numbers = 6;
my $max-lotto-numbers = 49;
gather for ^$num-selected-numbers {
    take (1 .. $max-lotto-numbers).pick(1);
}.say;    # six random values

routine take-rw

sub take-rw(\item)

Returns the given item to the enclosing gather block, without introducing a new container.

my @a = 1...3;
sub f(@list){ gather for @list { take-rw $_ } };
for f(@a) { $_++ };
say @a;
# OUTPUT: «[2 3 4]␤»

method so

method so()

Evaluates the item in boolean context (and thus, for instance, collapses Junctions), and returns the result. It is the opposite of not, and equivalent to the ? operator.

One can use this method similarly to the English sentence: "If that is so, then do this thing". For instance,

my @args = <-a -e -b -v>;
my $verbose-selected = any(@args) eq '-v' | '-V';
if $verbose-selected.so {
    say "Verbose option detected in arguments";
} # OUTPUT: «Verbose option detected in arguments␤»

The $verbose-selected variable in this case contains a Junction, whose value is any(any(False, False), any(False, False), any(False, False), any(True, False)). That is actually a truish value; thus, negating it will yield False. The negation of that result will be True. so is performing all those operations under the hood.

method not

method not()

Evaluates the item in boolean context (leading to final evaluation of Junctions, for instance), and negates the result. It is the opposite of so and its behavior is equivalent to the ! operator.

my @args = <-a -e -b>;
my $verbose-selected = any(@args) eq '-v' | '-V';
if $verbose-selected.not {
    say "Verbose option not present in arguments";
} # OUTPUT: «Verbose option not present in arguments␤»

Since there is also a prefix version of not, this example reads better as:

my @args = <-a -e -b>;
my $verbose-selected = any(@args) eq '-v' | '-V';
if not $verbose-selected {
    say "Verbose option not present in arguments";
} # OUTPUT: «Verbose option not present in arguments␤»

204 class NFC

Codepoint string in Normal Form C (composed)

class NFC is Uni {}

A Codepoint string in Unicode Normalization Form C. It is created by Canonical Decomposition, followed by Canonical Composition. For more information on what this means, see Unicode TR15.

205 class NFD

Codepoint string in Normal Form D (decomposed)

class NFD is Uni {}

A Codepoint string in the "D" Unicode Normalization Form

206 class NFKC

Codepoint string in Normal Form KC (compatibility composed)

class NFKC is Uni {}

A Codepoint string in Unicode Normalization Form KC. It is created by Compatibility Decomposition, followed by Canonical Composition. For more information on what this means, see Unicode TR15.

207 class NFKD

Codepoint string in Normal Form KD (compatibility decomposed)

class NFKD is Uni {}

A Codepoint string in Unicode Normalization Form KD. It is created by Compatibility Decomposition. For more information on what this means, see Unicode TR15.

208 class Nil

Absence of a value or a benign failure

class Nil is Cool { }

The value Nil may be used to fill a spot where a value would normally go, and in so doing, explicitly indicate that no value is present. It may also be used as a cheaper and less explosive alternative to a Failure. (In fact, class Failure is derived from Nil, so smartmatching Nil will also match Failure.)

The class Nil is the same exact thing as its only possible value, Nil.

say Nil === Nil.new;        # OUTPUT: «True␤»

Along with Failure, Nil and its sub classes may always be returned from a routine even when the routine specifies a particular return type. It may also be returned regardless of the definedness of the return type, however, Nil is considered undefined for all other purposes.

sub a( --> Int:D ) { return Nil }
a().say;                    # OUTPUT: «Nil␤»

Nil is what is returned from empty routines or closure, or routines that use a bare return statement.

sub a { }; a().say;         # OUTPUT: «Nil␤»
sub b { return }; b().say;  # OUTPUT: «Nil␤»
say (if 1 { });             # OUTPUT: «Nil␤»
{ ; }().say;                # OUTPUT: «Nil␤»
say EVAL "";                # OUTPUT: «Nil␤»

In a list, Nil takes the space of one value. Iterating a Nil behaves like iteration of any non-iterable value, producing a sequence of one Nil. (When you need the other meaning, the special value Empty is available to take no spaces when inserted into list, and to return no values when iterated.)

(1, Nil, 3).elems.say;      # OUTPUT: «3␤»
(for Nil { $_ }).perl.say;  # OUTPUT: «(Nil,)␤»

Any method call on Nil of a method that does not exist, and consequently, any subscripting operation, will succeed and return Nil.

say Nil.ITotallyJustMadeThisUp;  # OUTPUT: «Nil␤»
say (Nil)[100];                  # OUTPUT: «Nil␤»
say (Nil){100};                  # OUTPUT: «Nil␤»

When assigned to a container, the Nil value (but not any subclass of Nil) will attempt to revert the container to its default value; if no such default is declared, Perl 6 assumes Any.

Since a hash assignment expects two elements, use Empty not Nil, e.g.

my %h = 'a'..'b' Z=> 1..*;
# stuff happens
%h = Empty; # %h = Nil will generate an error

However, if the container type is constrained with :D, assigning Nil to it will immediately throw an exception. (In contrast, an instantiated Failure matches :D because it's a definite value, but will fail to match the actual nominal type unless it happens to be a parent class of Failure.) Native types can not have default values nor hold a type object. Assigning Nil to a native type container will fail with a runtime error.

my Int $x = 42;
$x = Nil;
$x.say;                     # OUTPUT: «(Int)␤»

sub f( --> Int:D ){ Nil };  # this definedness constraint is ignored
my Int:D $i = f;            # this definedness constraint is not ignored, so throws
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::TypeCheck::Assignment: Type check failed in assignment to $y; expected Int but got Any (Any)»

sub g( --> Int:D ){ fail "oops" }; # this definedness constraint is ignored
my Any:D $h = g;                   # failure object matches Any:D, so is assigned

but

my Int:D $j = g; 
 # It will throw both exceptions: 
 # Earlier failure: 
 #  oops 
 #   in sub g at <unknown file> line 1 
 #   in block <unit> at <unknown file> line 1 
 # 
 # Final error: 
 #  Type check failed in assignment to $j; expected Int:D but got Failure (Failure.new(exception...) 
 #   in block <unit> at <unknown file> line 1 

Because an untyped variable is type Any, assigning a Nil to one will result in an (Any) type object.

my $x = Nil;
$x.say;          # OUTPUT: «(Any)␤»
my Int $y = $x;  # will throw an exception
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::TypeCheck::Assignment: Type check failed in assignment to $y; expected Int but got Any (Any)␤»

If you are looking for a variable which transforms objects into type objects when said variable appears on the right-hand side, you can type the container as Nil.

my Nil $x;
my Str $s = $x;
$s.say;          # OUTPUT: «(Str)␤»

There is an important exception to this transforms-into-type-object rule: assigning Nil to a variable which has a default will restore that default.

my Int $x is default(42) = -1;
my $y = 1;
for $x, $y -> $val is rw { $val = Nil unless $val > 0 }
$x.say;          # OUTPUT: «42␤»

Methods

method append

method append(*@)

Warns the user that they tried to append onto a Nil.

method gist

method gist(--> Str:D)

Returns "Nil".

method Str

method Str()

Warns the user that they tried to stringify a Nil.

method new

method new(*@)

Returns Nil

method prepend

method prepend(*@)

Warns the user that they tried to prepend onto a Nil.

method push

method push(*@)

Warns the user that they tried to push onto a Nil.

method unshift

method unshift(*@)

Warns the user that they tried to unshift onto a Nil.

method FALLBACK

method FALLBACK(| --> Nil) {}

The fallback method takes any arguments and always returns a Nil.

method Numeric

method Numeric()

Warns the user that they tried to numify a Nil.

209 class Num

Floating-point number

class Num is Cool does Real { }

A Num object stores a floating-point number. It is immutable. On most platforms, it's an IEEE 754 64-bit floating point numbers, aka "double precision".

Inf

The value Inf is an instance of Num and represents value that's too large to represent in 64-bit double-precision floating point number (roughly, above 1.7976931348623158e308 for positive Inf and below -1.7976931348623157e308 for negative Inf) as well as returned from certain operations as defined by the IEEE 754-2008 standard.

say 2e300 ** 2e300; # OUTPUT: «Inf␤»
say (-1/0).Num;     # OUTPUT: «-Inf␤»

The U+221E Unicode character can be used instead of the word Inf and can be handy when Inf would otherwise require an unspace, such as when writing Complex numbers:

say Inf+Inf\i; # Backslash (unspace) before `i` required
say ∞+∞i;      # No backslash is needed

Note that there are just two infinities (positive and negative), so even if an operation that would instinctively give a "larger" infinity is performed, the result in still an infinity of the original magnitude. The infinities can be compared, operated and used as an argument as if they were simply a number that's too big to represent or to signify "without bounds" or limits:

say ∞²;                       # OUTPUT: «Inf␤»
say 42 + Inf === ∞;           # OUTPUT: «True␤»
say atan ∞;                   # OUTPUT: «1.5707963267949␤»
say -∞ < 42 < ∞;              # OUTPUT: «True␤»
my  $l := 1, 2, 4, 8 ... Inf; # Infinite sequence (no limits)

In some cases, it's used as an implicit value to represent "all of them"

say "House of M".comb(3,Inf).join("←X→");
# OUTPUT: «Hou←X→se ←X→of ←X→M␤»

In the example above, Inf can be eliminated, since it's the default value for the second argument of .comb, used to indicate how many parts should be returned.

Division of an infinity by another infinity results in a NaN:

say ∞/∞;             # OUTPUT: «NaN␤»

NaN

The value NaN is an instance of Num and represents a floating point not-a-number value, which is returned from some routines where a concrete number as the answer is not defined, but a Numeric value is still acceptable. NaN is defined and boolifies to True, but is not numerically equal to any value (including itself).

say cos ∞;     # OUTPUT: «NaN␤»
say (0/0).Num; # OUTPUT: «NaN␤»

To test for NaN, use isNaN method or === operator:

say (0/0).isNaN;       # OUTPUT: «True␤»
say (0/0).Num === NaN; # OUTPUT: «True␤»

method rand

method rand(Num:D: --> Num)

Returns a pseudo random number between 0 and the invocant.

sub srand

sub srand(Int $seed --> Int:D)

Seeds the pseudo random number generator used by Num.rand with the provided value. Note that srand is called with a platform dependent value when a Perl 6 program is started.

method Capture

Defined as:

method Capture()

Throws X::Cannot::Capture.

Int

method Int(Num:D:)

Converts the number to an Int. Fails with X::Numeric::CannotConvert if the invocant is a NaN or Inf/-Inf. No rounding is performed.

Rat

method Rat(Num:D: Real $epsilon = 1e-6)

Converts the number to a Rat with $epsilon precision. If the invocant is a Inf, -Inf, or a NaN, converts them to a Rat with 0 denominator and 1, -1, or 0 numerator, respectively.

FatRat

method FatRat(Num:D: Real $epsilon = 1e-6)

Converts the number to a FatRat with the precision $epsilon. If invocant is a Inf, -Inf, or a NaN, converts them to a FatRat with 0 denominator and 1, -1, or 0 numerator, respectively.

210 class NumStr

Dual value floating-point number and string

class NumStr is Num is Str { }

The dual value types (often referred to as allomorphs) allow for the representation of a value as both a string and a numeric type. Typically they will be created for you when the context is "stringy" but they can be determined to be numbers, such as in some quoting constructs:

my $f = <42.1e0>; say $f.^name; # OUTPUT: «NumStr␤»

As a subclass of both Num and Str, a NumStr will be accepted where either is expected. However, NumStr does not share object identity with Num- or Str-only variants:

my $num-str = <42e10>;
my Num $num = $num-str; # OK!
my Str $str = $num-str; # OK!
say 42e10 ∈ <42e10  55  1>; # False; ∈ operator cares about object identity

Methods

method new

method new(Num $i, Str $s)

The constructor requires both the Num and the Str value, when constructing one directly the values can be whatever is required:

my $f = NumStr.new(42.1e0, "forty two and a bit");
say +$f; # OUTPUT: «42.1␤»
say ~$f; # OUTPUT: «"forty two and a bit"␤»

method Bool

Defined as:

multi method Bool(NumStr:D: --> Bool:D)

This method may be provided by the parent classes and not implemented in NumStr directly.

Returns False if the invocant is numerically ±0e0, otherwise returns True. String portion is not considered.

method Num

method Num

Returns the Num value of the NumStr.

method Numeric

Defined as:

multi method Numeric(NumStr:D: --> Num:D)
multi method Numeric(NumStr:U: --> Num:D)

The :D variant returns the numeric portion of the invocant. The :U variant issues a warning about using an uninitialized value in numeric context and then returns value 0e0.

method Real

Defined as:

multi method Real(NumStr:D: --> Num:D)
multi method Real(NumStr:U: --> Num:D)

The :D variant returns the numeric portion of the invocant. The :U variant issues a warning about using an uninitialized value in numeric context and then returns value 0e0.

method Str

Returns the string value of the NumStr.

method ACCEPTS

Defined as:

multi method ACCEPTS(NumStr:D: Any:D $value)

If $value is Numeric (including another allomorph), checks if invocant's Numeric part ACCEPTS the $value. If $value is Str, checks if invocant's Str part ACCEPTS the $value. If value is anything else, checks if both Numeric and Str parts ACCEPTS the $value.

say <5e0> ~~ "5.0"; # OUTPUT: «False␤»
say <5e0> ~~  5.0 ; # OUTPUT: «True␤»
say <5e0> ~~ <5.0>; # OUTPUT: «True␤»

Operators

infix cmp

multi sub infix:<cmp>(NumStr:D $a, NumStr:D $b)

Compare two NumStr objects. The comparison is done on the Num value first and then on the Str value. If you want to compare in a different order then you would coerce to a Num or Str value first:

my $f = NumStr.new(42.1e0, "smaller");
my $g = NumStr.new(43.1e0, "larger");
say $f cmp $g;          # OUTPUT: «Less␤»
say $f.Str cmp $g.Str;  # OUTPUT: «More␤»

211 role Numeric

Number or object that can act as a number

role Numeric { ... }

Common role for numbers and types that can act as numbers.

Binary numeric operations return an object of the "wider" type:

Int         narrowest 
 Rat 
 FatRat 
 Num 
 Complex     widest 

So for example the product of a Rat and an Int is a Rat.

Unary operations that in pure math usually return an irrational number generally return Num in Perl 6.

Methods

method Numeric

Defined as:

multi method Numeric(Numeric:D: --> Numeric:D)
multi method Numeric(Numeric:U: --> Numeric:D)

The :D variant simply returns the invocant. The :U variant issues a warning about using an uninitialized value in numeric context and then returns self.new.

method Int

method Int(Numeric:D: --> Int:D)

If this Numeric is equivalent to a Real, return the equivalent of calling truncate on that Real to get an Int. Fail with X::Numeric::Real otherwise.

method Rat

method Rat(Numeric:D: Real $epsilon = 1.0e-6 --> Rat:D)

If this Numeric is equivalent to a Real, return a Rat which is within $epsilon of that Real's value. Fail with X::Numeric::Real otherwise.

method Num

method Num(Numeric:D: --> Num:D)

If this Numeric is equivalent to a Real, return that Real as a Num as accurately as is possible. Fail with X::Numeric::Real otherwise.

method narrow

method narrow(Numeric:D --> Numeric:D)

Returns the number converted to the narrowest type that can hold it without loss of precision.

say (4.0 + 0i).narrow.perl;     # OUTPUT: «4␤»
say (4.0 + 0i).narrow.^name;    # OUTPUT: «Int␤»

method ACCEPTS

multi method ACCEPTS(Numeric:D: $other)

Returns True if $other can be coerced to Numeric and is numerically equal to the invocant (or both evaluate to NaN).

routine log

multi sub    log(Numeric:D, Numeric $base = e --> Numeric:D)
multi method log(Numeric:D: Numeric $base = e --> Numeric:D)

Calculates the logarithm to base $base. Defaults to the natural logarithm. Returns NaN if $base is negative. Throws an exception if $base is 1.

routine log10

multi sub    log10(Numeric:D  --> Numeric:D)
multi method log10(Numeric:D: --> Numeric:D)

Calculates the logarithm to base 10. Returns NaN for negative arguments and -Inf for 0.

routine exp

multi sub    exp(Numeric:D, Numeric:D $base = e --> Numeric:D)
multi method exp(Numeric:D: Numeric:D $base = e --> Numeric:D)

Returns $base to the power of the number, or e to the power of the number if called without a second argument.

method roots

multi method roots(Numeric:D: Int:D $n --> Positional)

Returns a list of the $n complex roots, which evaluate to the original number when raised to the $nth power.

routine abs

multi sub    abs(Numeric:D  --> Real:D)
multi method abs(Numeric:D: --> Real:D)

Returns the absolute value of the number.

routine sqrt

multi sub    sqrt(Numeric:D --> Numeric:D)
multi method sqrt(Numeric:D --> Numeric:D)

Returns a square root of the number. For real numbers the positive square root is returned.

On negative real numbers, sqrt returns NaN rather than a complex number, in order to not confuse people who are not familiar with complex arithmetic. If you want to calculate complex square roots, coerce to Complex first, or use the roots method.

method conj

multi method conj(Numeric:D --> Numeric:D)

Returns the complex conjugate of the number. Returns the number itself for real numbers.

method Bool

multi method Bool(Numeric:D:)

Returns False if the number is equivalent to zero, and True otherwise.

method succ

method succ(Numeric:D:)

Returns the number incremented by one (successor).

method pred

method pred(Numeric:D:)

Returns the number decremented by one (predecessor).

212 class ObjAt

Unique identification for an object

class ObjAt is Any {}

Objects of type ObjAt are the return value of .WHICH calls on other objects, and identify an object uniquely.

If two objects compare equally via ===, their .WHICH methods return the same ObjAt object.

See also ValueObjAt for value types.

Methods

infix eqv

Defined as:

multi sub infix:<eqv>(ObjAt:D $a, ObjAt:D $b)

Returns True if the two ObjAt are the same, that is, if the object they identify is the same.

my @foo = [2,3,1];
my @bar := @foo;
say @foo.WHICH eqv @bar.WHICH; # OUTPUT: «True␤»

213 enum Order

Human readable form for comparison operators.

enum Order (:Less(-1), :Same(0), :More(1));

Operators

infix cmp

multi sub infix:<cmp>(\a, \b --> Order:D)

cmp will first try to compare operands as strings (via coercion to Stringy), and, failing that, will try to compare numerically via the <=> operator or any other type-appropriate comparison operator. See also the documentation for the cmp operator.

infix <=>

multi sub infix:«<=>»(Int:D \a, Int:D \b --> Order:D)

Specialized form for Int.

214 class Pair

Key/value pair

class Pair does Associative {}

Consists of two parts, a key and a value. Pairs can be seen as the atomic units in Hashes, and they are also used in conjunction with named arguments and parameters.

There are many syntaxes for creating Pairs:

Pair.new('key', 'value'); # The canonical way
'key' => 'value';         # this...
:key<value>;              # ...means the same as this
:key<value1 value2>;      # But this is  key => <value1 value2>
:foo(127);                # short for  foo => 127
:127foo;                  # the same   foo => 127

Note that last form supports Non-ASCII numerics as well:

# use MATHEMATICAL DOUBLE-STRUCK DIGIT THREE
say (:𝟛math-three);         # OUTPUT: «math-three => 3␤»

You can also use an identifier-like literal as key; this will not need the quotes as long as it follows the syntax of ordinary identifiers:

(foo => 127)              # the same   foo => 127

Variants of this are

:key;                     # same as   key => True
:!key;                    # same as   key => False

And this other variant, to be used in routine invocation

sub colon-pair( :$key-value ) { 
     say $key-value; 
 } 
 my $key-value = 'value'; 
 colon-pair( :$key-value );               # OUTPUT: «value␤» 
 colon-pair( key-value => $key-value );   # OUTPUT: «value␤» 

Colon pairs can be chained without a comma to create a List of Pairs. Depending on context you may have to be explicit when assigning colon lists.

sub s(*%h){ say %h.perl };
s :a1:b2;
# OUTPUT: «{:a1, :b2}␤»

my $manna = :a1:b2:c3;
say $manna.^name;
# OUTPUT: «Pair␤»

$manna = (:a1:b2:c3);
say $manna.^name;
# OUTPUT: «List␤»

Any variable can be turned into a Pair of its name and its value.

my $bar = 10;
my $p   = :$bar;
say $p; # OUTPUT: «bar => 10␤»

It is worth noting that when assigning a Scalar as value of a Pair the value holds the container of the value itself. This means that it is possible to change the value from outside of the Pair itself:

my $v = 'value A'; 
 my $pair = a => $v; 
 $pair.say;  # OUTPUT: «a => value A␤» 
 
 $v = 'value B'; 
 $pair.say;  # OUTPUT: «a => value B␤» 

Please also note that this behavior is totally unrelated to the way used to build the Pair itself (i.e., explicit usage of new, use of colon, fat arrow), as well as if the Pair is bound to a variable.

It is possible to change the above behavior forcing the Pair to remove the scalar container and to hold the effective value itself via the method freeze:

my $v = 'value B'; 
 my $pair = a => $v; 
 $pair.freeze; 
 $v = 'value C'; 
 $pair.say; # OUTPUT: «a => value B␤» 

As Pair implements Associative role, its value can be accessed using Associative subscription operator, however, due to Pair's singular nature, the pair's value will be only returned for the pair's key. Nil object will be returned for any other key. Subscript adverbs such as :exists can be used on Pair.

my $pair = a => 5; 
 say $pair<a>;           # OUTPUT: «5␤» 
 say $pair<a>:exists;    # OUTPUT: «True␤» 
 say $pair<no-such-key>; # OUTPUT: «Nil␤» 

Methods

method new

Defined as:

multi method new(Pair: Mu  $key, Mu  $value)
multi method new(Pair: Mu :$key, Mu :$value)

Constructs a new Pair object.

method ACCEPTS

Defined as:

multi method ACCEPTS(Pair:D $: %topic)
multi method ACCEPTS(Pair:D $: Pair:D $topic)
multi method ACCEPTS(Pair:D $: Mu $topic)

If %topic is an Associative, looks up the value using invocant's key in it and checks invocant's value .ACCEPTS that value:

say %(:42a) ~~ :42a; # OUTPUT: «True␤»
say %(:42a) ~~ :10a; # OUTPUT: «False␤»

If $topic is another Pair, checks the invocant's value .ACCEPTS the $topic's value. Note that the keys are not considered and can be different:

say :42a ~~ :42a; # OUTPUT: «True␤»
say :42z ~~ :42a; # OUTPUT: «True␤»
say :10z ~~ :42a; # OUTPUT: «False␤»

If $topic is any other value, the invocant Pair's key is treated as a method name. This method is called on $topic, the boolean result of which is compared against the invocant Pair's boolean value. For example, primality can be tested using smartmatch:

say 3 ~~ :is-prime;             # OUTPUT: «True␤»
say 3 ~~  is-prime => 'truthy'; # OUTPUT: «True␤»
say 4 ~~ :is-prime;             # OUTPUT: «False␤»

This form can also be used to check Bool values of multiple methods on the same object, such as IO::Path, by using Junctions:

say "foo" .IO ~~ :f & :rw; # OUTPUT: «False␤»
say "/tmp".IO ~~ :!f;      # OUTPUT: «True␤»
say "."   .IO ~~ :f | :d;  # OUTPUT: «True␤»

method antipair

Defined as:

method antipair(--> Pair:D)

Returns a new Pair object with key and value exchanged.

my $p = (6 => 'Perl').antipair;
say $p.key;         # OUTPUT: «Perl␤»
say $p.value;       # OUTPUT: «6␤»

method key

Defined as:

multi method key(Pair:D:)

Returns the key part of the Pair.

my $p = (Perl => 6);
say $p.key; # OUTPUT: «Perl␤»

method value

Defined as:

multi method value(Pair:D:) is rw

Returns the value part of the Pair.

my $p = (Perl => 6);
say $p.value; # OUTPUT: «6␤»

infix cmp

Defined as:

multi sub infix:<cmp>(Pair:D, Pair:D)

The type-agnostic comparator; compares two Pairs. Compares first their key parts, and then compares the value parts if the keys are equal.

my $a = (Apple => 1);
my $b = (Apple => 2);
say $a cmp $b; # OUTPUT: «Less␤»

method fmt

Defined as:

multi method fmt(Pair:D: Str:D $format --> Str:D)

Takes a format string, and returns a string the key and value parts of the Pair formatted. Here's an example:

my $pair = :Earth(1);
say $pair.fmt("%s is %.3f AU away from the sun")
# OUTPUT: «Earth is 1.000 AU away from the sun␤»

For more about format strings, see sprintf.

method kv

Defined as:

multi method kv(Pair:D: --> List:D)

Returns a two-element List with the key and value parts of Pair, in that order. This method is a special case of the same-named method on Hash, which returns all its entries as a list of keys and values.

my $p = (Perl => 6);
say $p.kv[0]; # OUTPUT: «Perl␤»
say $p.kv[1]; # OUTPUT: «6␤»

method pairs

Defined as:

multi method pairs(Pair:D:)

Returns a list of one Pair, namely this one.

my $p = (Perl => 6);
say $p.pairs.^name; # OUTPUT: «List␤»
say $p.pairs[0];    # OUTPUT: «Perl => 6␤»

method antipairs

Defined as:

multi method antipairs(Pair:D:)

Returns a List containing the antipair of the invocant.

my $p = (6 => 'Perl').antipairs;
say $p.^name;                                     # OUTPUT: «List␤»
say $p.first;                                     # OUTPUT: «Perl => 6␤»
say $p.first.^name;                               # OUTPUT: «Pair␤»

method invert

Defined as:

method invert(Pair:D: --> Seq:D)

Returns a Seq. If the .value of the invocant is NOT an Iterable, the Seq will contain a single Pair whose .key is the .value of the invocant and whose .value is the .key of the invocant:

:foo<bar>.invert.perl.say; # OUTPUT: «(:bar("foo"),).Seq»

If invocant's .value is an Iterable, the returned Seq will contain the same number of Pairs as items in the .value, with each of those items a .key of a pair and the .key of the invocant the .value of that pair:

:foo<Perl is great>.invert.perl.say;
# OUTPUT: «(:Perl("foo"), :is("foo"), :great("foo")).Seq»

:foo{ :42a, :72b }.invert.perl.say;
# OUTPUT: «((:a(42)) => "foo", (:b(72)) => "foo").Seq»

To perform the exact .key and .value swap, use .antipair method.

method keys

Defined as:

multi method keys(Pair:D: --> List:D)

Returns a List containing the key of the invocant.

say ('Perl' => 6).keys;                           # OUTPUT: «(Perl)␤»

method values

Defined as:

multi method values(Pair:D: --> List:D)

Returns a List containing the value of the invocant.

say ('Perl' => 6).values;                         # OUTPUT: «(6)␤»

method freeze

Defined as:

method freeze(Pair:D:)

Makes the value of the Pair read-only, by removing it from its Scalar container, and returns it.

my $str = "apple";
my $p = Pair.new('key', $str);
$p.value = "orange";              # this works as expected
$p.say;                           # OUTPUT: «key => orange␤»
$p.freeze.say;                    # OUTPUT: «orange␤»
$p.value = "a new apple";         # Fails
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Assignment::RO: Cannot modify an immutable Str (apple)␤»

NOTE: this method is deprecated as of 6.d language version. Instead, create a new Pair, with a decontainerized key/value.

$p.=Map.=head.say;                                    # OUTPUT: «orange␤» 

method Str

Defined as:

multi method Str(Pair:D: --> Str:D)

Returns a string representation of the invocant formatted as key ~ \t ~ value.

my $b = eggs => 3;
say $b.Str;                                       # OUTPUT: «eggs  3␤»

method Pair

Defined as:

method Pair()

Returns the invocant Pair object.

my $pair = eggs => 3;
say $pair.Pair === $pair;                         # OUTPUT: «True␤»

215 class Parameter

Element of a Signature

class Parameter { }

Represents a parameter, for purpose of introspection.

The usual way to obtain a Parameter object is to create a signature, and call .params on it to obtain a list of the Parameters.

my $sig   = :(Str $x);
my $param = $sig.params[0];
say $param.type;              # OUTPUT: «Str()␤»

See Signature for more information, and also for an explanation on what most of the concepts related to parameters mean.

Methods

method name

Returns the variable name, which includes all sigils and twigils. This name is used internally when applied to code, or in a declaration determines the name declared. This name is not necessarily usable by a caller – if it is, it will also appear as an alias. Often, the name will chosen descriptively as a form of self-documentation.

If the parameter is anonymous, Nil will be returned.

method sigil

Defined as:

method sigil(Parameter:D: --> Str:D)

Returns a string containing the parameter's sigil, for a looser definition of "sigil" than what is considered part of the variable's name|method name. Still returns a sigil even if the parameter is anonymous.

This "sigil" is actually an introspection used to help determine the normal binding style of a parameter, if it has not been altered through a trait.

Sigil Will bind to Default behavior
$ Scalar Generate new Scalar, use instead of Scalar in argument, if any
@ Positional Bind directly to the argument
@ PositionalBindFailover If binding failed, call argument's .cache method, bind to result
% Associative Bind directly to the argument
& Callable Bind directly to the argument
\ (anything) Bind directly to the argument, keep existing Scalar, if any

Also, | will bind to all remaining arguments and make new Capture if needed.

method type

Returns the nominal type constraint of the parameter.

method coerce_type

Returns the coercion type of the parameter.

method constraints

Returns additional constraints on the parameter (usually as an all-Junction).

method named

Defined as:

method named(Parameter:D: --> Bool:D)

Returns True if it's a named parameter.

my Signature $sig = :(Str $x, Bool :$is-named);
say $sig.params[0].named;                          # OUTPUT: «False␤»
say $sig.params[1].named;                          # OUTPUT: «True␤»

method named_names

Defined as:

method named_names(Parameter:D: --> List:D)

Returns the list of externally usable names/aliases for a named parameter.

method positional

Defined as:

method positional(Parameter:D: --> Bool:D)

Returns True if the parameter is positional.

my Signature $sig = :(Str $x, Bool :$is-named);
say $sig.params[0].positional;                     # OUTPUT: «True␤»
say $sig.params[1].positional;                     # OUTPUT: «False␤»

method slurpy

Defined as:

method slurpy(Parameter:D: --> Bool:D)

Returns True for slurpy parameters.

method twigil

Defined as:

method twigil(Parameter:D: --> Str:D)

Returns a string containing the twigil part of the parameter's name.

method optional

Defined as:

method optional(Parameter:D: --> Bool:D)

Returns True for optional parameters.

method raw

Defined as:

method raw(Parameter:D: --> Bool:D)

Returns True for raw parameters.

sub f($a, $b is raw, \c) {
    my $sig = &?ROUTINE.signature;
    for ^$sig.params.elems {
        say $sig.params[$_].raw;
    }
}
f(17, "4711", 42); OUTPUT: «False␤True␤True␤»

Raw parameters bind either a variable or a value passed to it, with no decontainerization taking place. That means that if a variable was passed to it, you can assign to the parameter. This is different from rw-parameter which can only bind to variables, never to values.

This is the normal behavior for parameters declared with a sigil of '\', which is not really a sigil insofar as it is only used on the parameter.

sub f(\x) {
    x = 5;
}
f(my $x);   # works
f(42);      # dies
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Assignment::RO: Cannot modify an immutable Int␤»

Other parameters may become raw through use of the 'is raw' trait. These still use their sigil in code.

sub f($x is raw) {
    $x = 5;
}

method capture

Defined as:

method capture(Parameter:D: --> Bool:D)

Returns True for parameters that capture the rest of the argument list into a single Capture object.

sub how_many_extra_positionals($!, |capture) { capture.elems.say }
how_many_extra_positionals(0, 1, 2, 3);                        # RESULT: «3»
say &how_many_extra_positionals.signature.params[1].capture;   # OUTPUT: «True␤»

Like raw parameters, Capture parameters do not force any context on the values bound to them, which is why their sigils are only used in declarations.

method rw

Defined as:

method rw(Parameter:D: --> Bool:D)

Returns True for is rw parameters.

my Signature $sig = :(Str $x is rw, Bool :$is-named);
say $sig.params[0].rw;                             # OUTPUT: «True␤»
say $sig.params[1].rw;                             # OUTPUT: «False␤»

method copy

Defined as:

method copy(Parameter:D: --> Bool:D)

Returns True for is copy parameters.

my Signature $sig = :(Str $x, Bool :$is-named is copy);
say $sig.params[0].copy;                           # OUTPUT: «False␤»
say $sig.params[1].copy;                           # OUTPUT: «True␤»

method readonly

Defined as:

method readonly(Parameter:D: --> Bool:D)

Returns True for read-only parameters (the default).

my Signature $sig = :(Str $x is rw, Bool :$is-named);
say $sig.params[0].readonly;                       # OUTPUT: «False␤»
say $sig.params[1].readonly;                       # OUTPUT: «True␤»

method invocant

Defined as:

method invocant(Parameter:D: --> Bool:D)

Returns True if the parameter is the invocant parameter.

method default

Returns a closure that upon invocation returns the default value for this parameter, or Any if no default was provided.

method type_captures

Defined as:

method type_captures(Parameter:D: --> List:D)

Returns a list of variable names of type captures associated with this parameter. Type captures define a type name within the attached code, which is an alias to the type gleaned from the argument during a call.

sub a(::T ::U $x) { T.say }
a(8);                                       # OUTPUT: «(Int)␤»
say &a.signature.params[0].type_captures;   # OUTPUT: «(T U)␤»
sub b($x) { $x.^name.say }
a(8);                                       # OUTPUT: «Int␤»

The type used may change from call to call. Once they are defined, type captures can be used wherever you would use a type, even later in same the signature:

sub c(::T $x, T $y, $z) { my T $zz = $z }; 
 c(4, 5, 6);          # OK 
 c(4, 5, "six");      # Fails when assigning to $zz, wants Int not Str 
 c("four", 5, "six"); # Fails when binding $y, wants Str, not Int 

Type captures may be used at the same time as type constraints.

sub d(::T Numeric $x, T $y) {}; 
 d(4, 5);            # OK 
 d(4e0, 5e0);        # OK 
 d(4e0, 5);          # Fails when binding $y 
 d("four", "five");  # Fails when binding $x 

method sub_signature

If the parameter has a sub-signature, returns a Signature object for it. Otherwise returns Any.

Runtime creation of Parameter objects (6.d, 2019.03 and later)

Parameter.new( ... )

In some situations, specifically when working with the MetaObject Protocol, it makes sense to create Parameter objects programmatically. For this purpose, you can call the new method with the following named parameters:

Optional. The name of the variable, if any. Can be specified in the same way as in a Signature. So it may contain specific additional information, such as a sigil ($, @, % or &), a : prefix to indicate a named parameter, a twigil (. or !) to indicate public / private attribute binding, a postfix ! or ? to indicate an optional / mandatory parameter, and the various combinations of +, *, ** prefixes to indicate slurpiness types and | to indicate a Capture.

Optional. The type of the parameter. Assumes Any if not specified.

Optional. The value of the parameter if the parameter is optional and no argument has been given for that parameter. Assumes not initialization if no argument has been given, which would fall back to the (implicit) type of the parameter.

Optional. Additional constraints to be applied to any argument to match with this parameter. Does not set any additional constraints by default.

Optional. Allows one to set the "is copy" flag on the parameter. Does not set the flag by default.

Optional. Allows one to set the "is raw" flag on the parameter. Does not set the flag by default.

Optional. Allows one to set the "is rw" flag on the parameter. Does not set the flag by default.

Optional. Indicates whether the parameter is a named parameter or not. Should only be specified if the : prefix is not specified in the name and a named parameter is required.

Optional. Indicates whether the parameter is optional or not. Should only be specified if the ? postfix is not specified in the name and an optional parameter is required.

Optional. Indicates whether the parameter is mandatory or not. Should only be specified if the ! postfix is not specified in the name and a mandatory parameter is required.

Optional. Indicates whether the parameter should be considered in multi-dispatch or not. Defaults to True, so one would need to do :!multi-invocant to make the parameter not be considered in multi-dispatch.

Optional. Specifies any Signature that should be applied to the parameter to deconstruct it. By default, no signature is to be applied.

216 class Perl

Perl related information

class Perl does Systemic { }

Built-in class for providing perl related information. Usually accessed through the $*PERL dynamic variable.

Methods

method compiler

Instance method returning the compiler object, of type Compiler, associated with the Perl object.

method DISTROnames

Instance / Class method returning the names of the Distro objects that are supported by this version of Perl.

method KERNELnames

Instance / Class method returning the names of the Kernel objects that are supported by this version of Perl.

method VMnames

Instance / Class method returning the names of the VM objects that are supported by this version of Perl.

See Also

Systemic, Compiler.

217 class Pod::Block

Block in a Pod document

class Pod::Block { }

Class for a Pod block, and base class for most other Pod classes.

A Pod block has contents (more pod blocks or strings) and a config hash.

Useful subclasses:

Class Used for
Pod::Block::Para paragraphs
Pod::Block::Named named blocks
Pod::Block::Declarator declarator blocks
Pod::Block::Code code blocks
Pod::Block::Comment comments
Pod::Block::Table =begin/end table
tabular data
Pod::Heading =head1 etc. headings
Pod::Item list items
Pod::Defn definition lists
Pod::FormattingCode formatting codes

Methods

method contents

method contents(--> Positional:D)

Returns a list of contents of this block.

method config

method config(--> Map:D)

Returns a hash of configs.

218 class Pod::Block::Code

Verbatim code block in a Pod document

class Pod::Block::Code is Pod::Block { }

Class for a code (verbatim) Pod block.

Methods

method allowed

method allowed(--> Positional:D)

Returns a list of formatting codes that are allowed inside the code block.

219 class Pod::Block::Comment

Comment in a Pod document

class Pod::Block::Comment is Pod::Block { }

Class for a Pod comment.

220 class Pod::Block::Declarator

Declarator block in a Pod document

class Pod::Block::Declarator is Pod::Block { }

Class for a declarator Pod block

Methods

method leading

method leading(--> Str)

Returns the leading Pod comment attached to the declarator

method trailing

method trailing(--> Str)

Returns the trailing Pod comment attached to the declarator

method WHEREFORE

method WHEREFORE(--> Mu)

Returns the code object or metaobject to which the Pod block is attached to

221 class Pod::Block::Named

Named block in a Pod document

class Pod::Block::Named is Pod::Block { }

Class for a named Pod block. For example

=begin MySection 
 ... 
 =end MySection 

creates a Pod::Block::Named with name MySection.

Methods

method name

method name(--> Str:D)

Returns the name of the block.

222 class Pod::Block::Para

Paragraph in a Pod document

class Pod::Block::Para is Pod::Block { }

Class for a Pod paragraph.

223 class Pod::Block::Table

Table in a Pod document

class Pod::Block::Table is Pod::Block { }

Class for a table in a Pod document.

Methods

method caption

method caption(--> Str:D)

Returns the associated caption of the table.

method headers

method headers(--> Positional:D)

Returns a list of table headers. If no headers have been defined the list is empty.

224 class Pod::Defn

Pod definition list

class Pod::Defn is Pod::Block { }

Class for definition lists in a Pod document.

Methods

method term

method term(--> Mu)

225 class Pod::FormattingCode

Pod formatting code

class Pod::FormattingCode is Pod::Block { }

Class for formatting codes in a Pod document.

Methods

method type

method type(--> Mu)

method meta

method meta(--> Positional)

226 class Pod::Heading

Heading in a Pod document

class Pod::Heading is Pod::Block { }

Class for headings in a Pod document.

Methods

method level

method level(--> Int)

Returns the level of the heading, starting at 1.

227 class Pod::Item

Item in a Pod enumeration list

class Pod::Item is Pod::Block { }

Class for items in Pod enumeration lists.

Methods

method level

method level(--> Int)

Returns the level of the enumeration list, starting at 1.

228 role Positional

Object that supports looking up values by index

role Positional { ... }

Role for objects which support indexing them using postcircumfix:«[ ]» (usually list-like objects). Example types with Positional role include List, Array, Range, and Buf.

Methods

method of

method of()

Returns the type constraint for elements of the positional container. Defaults to Mu.

Methods that should be provided

method elems

method elems()

Should return the number of available elements in the instantiated object.

method AT-POS

method AT-POS(\position)

Should return the value / container at the given position.

method EXISTS-POS

method EXISTS-POS(\position)

Should return a Bool indicating whether the given position actually has a value.

method STORE

method STORE(\values, :$initialize)

This method should only be supplied if you want to support the:

my @a is Foo = 1,2,3; 

syntax for binding your implementation of the Positional role.

Should accept the values to (re-)initialize the object with. The optional named parameter will contain a True value when the method is called on the object for the first time. Should return the invocant.

See also

See Methods to implement for positional subscripting for information about additional methods that can be implemented for the Positional role.

229 role PositionalBindFailover

Failover for binding to a Positional

role PositionalBindFailover { ... }

This role provides an interface by which an object can be coerced into a Positional when binding to Positional parameters.

For example, Seq type is not Positional, but you can still write the following, because it does PositionalBindFailover role:

sub fifths(@a) {        # @a is constraint to Positional
    @a[4];
}
my $seq := gather {     # a Seq, which is not Positional
    take $_ for 1..*;
}
say fifths($seq);       # OUTPUT: «5␤»

The invocation of fifths in the example above would ordinarily give a type error, because $seq is of type Seq, which doesn't do the Positional interface that the @-sigil implies.

But the signature binder recognizes that Seq does the PositionalBindFailover role, and calls its cache method to coerce it to a List, which does the Positional role.

The same happens with custom classes that do the role; they simply need to provide an iterator method that produces an Iterator:

class Foo does PositionalBindFailover {
    method iterator {
        class :: does Iterator {
            method pull-one {
                return 42 unless $++;
                IterationEnd
            }
        }.new
    }
}

sub first-five (@a) { @a[^5].say }
first-five Foo.new; # OUTPUT: # OUTPUT: «(42 Nil Nil Nil Nil)␤»

Methods

method cache

method cache(PositionalBindFailover:D: --> List:D)

Returns a List based on the iterator method, and caches it. Subsequent calls to cache always return the same List object.

method list

method list(PositionalBindFailover:D: --> List:D)

Returns a List based on the iterator method without caching it.

method iterator

method iterator(PositionalBindFailover:D:) { ... }

This method stub ensure that a class implementing role PositionalBindFailover provides an iterator method.

230 role PredictiveIterator

Iterators that can predict number of values

A PredictiveIterator is a special kind of Iterator that can know how many values it will (still) generate without actually needing to generate those values.

The main addition to the API of the Iterator role, is the count-only method, which should return the number of values the Iterator is still able to generate.

The other addition is the bool-only method, that should return a Bool indicating whether the Iterator is still capable of producing values (aka, is not exhausted yet). By default, this is the Booleanification of the result of the call to the count-only method.

Methods

method count-only

Defined as:

method count-only(--> Int:D) { ... }

It is expected to return the number of values the iterator can still produce without actually producing them. The returned number must adjust itself for items already pulled, so that the method can be called on a partially consumed Iterator.

It will be used in situations where only the number of values of an iterator is needed, e.g. when the .elems method is called.

Important: it's expected the Iterators that implement this method can return that number without producing any values. In other words, it's expected the user of the class will be able to still pull-one after calling this method, and eventually receive as many values as the return value of this method indicated.

method bool-only

Defaults to the Booleanification of the result of calling the count-only method. If it is possible to have a faster way of finding out whether the iterator is capable of producing any value, it should be implemented.

Defined as:

method bool-only(--> Bool:D) { self.count-only.Bool }

231 class Proc

Running process (filehandle-based interface)

class Proc {}

Proc is a representation of an invocation of an external process. It provides access to the input, output and error stream as well as the exit code. It is typically created through the run subroutine:

my $proc = run 'echo', 'Hallo world', :out; 
 my $captured-output = $proc.out.slurp: :close; 
 say "Output was $captured-output.perl()";# OUTPUT: «Output was "Hallo world\n"␤» 

Piping several commands is easy too. To achieve the equivalent of the pipe echo "Hello, world" | cat -n in Perl 6, and capture the output from the second command, you can do

my $p1 = run 'echo', 'Hello, world', :out; 
 my $p2 = run 'cat', '-n', :in($p1.out), :out; 
 say $p2.out.get; 

You can also feed the :in (standard input) pipe directly from your program, by setting it to True, which will make the pipe available via .in method on the Proc:

my $p = run "cat", "-n", :in, :out; 
 $p.in.say: "Hello,\nworld!"; 
 $p.in.close; 
 say $p.out.slurp: :close; 
 # OUTPUT: «1  Hello,␤ 
 #          2  world!␤» 

In order to capture the standard error, :err can be supplied:

my $p = run "ls", "-l", ".", "qqrq", :out, :err; 
 my $captured-output = $p.out.slurp: :close; 
 my $captured-error  = $p.err.slurp: :close; 
 my $exit-code       = $p.exitcode; 

In sink context, a Proc will call its sink method, throwing an exception if the process has exited with an exit code different from zero:

shell 'exit 1' 
 # OUTPUT: «(exit code 1) The spawned command 'exit 1' exited unsuccessfully (exit code: 1)␤» 

Note: Versions of Rakudo older than 2017.04 do not have .slurp available on IO::Pipe objects; use .slurp-rest instead.

Use Proc::Async for non-blocking operations.

Methods

method new

method new(Proc:U: 
         :$in = '-', 
         :$out = '-', 
         :$err = '-', 
         Bool :$bin = False, 
         Bool :$chomp = True, 
         Bool :$merge = False, 
         Str:D :$enc = 'UTF-8', 
         Str:D :$nl = "\n", 
     --> Proc:D) 
 
 sub shell( 
         $cmd, 
         :$in = '-', 
         :$out = '-', 
         :$err = '-', 
         Bool :$bin = False, 
         Bool :$chomp = True, 
         Bool :$merge = False, 
         Str:D :$enc = 'UTF-8', 
         Str:D :$nl = "\n", 
         :$cwd = $*CWD, 
         Hash() :$env = %*ENV 
     --> Proc:D) 

new creates a new Proc object, whereas run or shell create one and spawn it with the command and arguments provided in @args or $cmd, respectively.

$in, $out and $err are the three standard streams of the to-be-launched program, and default to "-" meaning they inherit the stream from the parent process. Setting one (or more) of them to True makes the stream available as an IO::Pipe object of the same name, like for example $proc.out. You can set them to False to discard them. Or you can pass an existing IO::Handle object (for example IO::Pipe) in, in which case this handle is used for the stream.

Please bear in mind that the process streams reside in process variables, not in the dynamic variables that make them available to our programs. Thus, modifying the dynamic filehandle variables (such as $*OUT ) inside the host process will have no effect in the spawned process, unlike $*CWD and $*ENV, whose changes will be actually reflected in it.

my $p-name = "/tmp/program.p6"; 
 my $program = Q:to/END/; 
     #!/usr/bin/env perl6 
 
     $*OUT.say( qq/\t$*PROGRAM: This goes to standard output/ ); 
 END 
 
 spurt $p-name, $program; 
 
 $*OUT.put: "1. standard output before doing anything weird"; 
 
 { 
     temp $*OUT = open '/tmp/out.txt', :w; 
     $*OUT.put: "2. temp redefine standard output before this message"; 
     shell( "perl6 $p-name" ).so; 
 } 
 
 $*OUT.put: "3. everything should be back to normal"; 
 # OUTPUT 
 # 1. standard output before doing anything weird 
 #     /tmp/program.p6: This goes to standard output 
 # 3. everything should be back to normal 
 
 # /tmp/out.txt will contain: 
 # 2. temp redefine standard output before this message 

This program shows that the program spawned with shell is not using the temporary $*OUT value defined in the host process (redirected to /tmp/out.txt), but the initial STDOUT defined in the process.

$bin controls whether the streams are handled as binary (i.e. Blob object) or text (i.e. Str objects). If $bin is False, $enc holds the character encoding to encode strings sent to the input stream and decode binary data from the output and error streams.

With $chomp set to True, newlines are stripped from the output and err streams when reading with lines or get. $nl controls what your idea of a newline is.

If $merge is set to True, the standard output and error stream end up merged in $proc.out.

method sink

Defined as:

method sink(--> Nil)

When sunk, the Proc object will throw X::Proc::Unsuccessful if the process it ran exited unsuccessfully.

shell 'ls /qqq'; 
 # OUTPUT: «(exit code 1) ls: cannot access '/qqq': No such file or directory␤The spawned command 'ls /qqq' exited unsuccessfully (exit code: 2)␤ 
 n block <unit> at /tmp/3169qXElwq line 1␤␤» 

method spawn

method spawn(*@args ($, *@), :$cwd = $*CWD, Hash() :$env = %*ENV --> Bool:D)

Runs the Proc object with the given command, argument list, working directory, and environment.

method shell

method shell($cmd, :$cwd = $*CWD, :$env --> Bool:D)

Runs the Proc object with the given command and environment which are passed through to the shell for parsing and execution. See shell for an explanation of which shells are used by default in the most common operating systems.

method command

method command(Proc:D: --> List:D)

The command method is an accessor to a list containing the arguments that were passed when the Proc object was executed via spawn or shell or run.

method pid

method pid()

Returns the PID value of the process if available, or Nil.

method exitcode

method exitcode(Proc:D: --> Int:D)

Returns the exit code of the external process, or -1 if it has not exited yet.

method signal

method signal(Proc:D:)

Returns the signal number with which the external process was killed, or 0 or an undefined value otherwise.

232 class Proc::Async

Running process (asynchronous interface)

class Proc::Async {} 

Proc::Async allows you to run external commands asynchronously, capturing standard output and error handles, and optionally write to its standard input.

my $file = ‘foo’.IO; 
 spurt $file, “and\nCamelia\n♡\nme\n”; 
 
 my $proc = Proc::Async.new: :w, ‘tac’, ‘--’, $file, ‘-’; 
 # my $proc = Proc::Async.new: :w, ‘sleep’, 15; # uncomment to try timeouts 
 
 react { 
     whenever $proc.stdout.lines { # split input on \r\n, \n, and \r 
         say ‘line: ’, $_ 
     } 
     whenever $proc.stderr { # chunks 
         say ‘stderr: ’, $_ 
     } 
     whenever $proc.ready { 
         say ‘PID: ’, $_ # Only in Rakudo 2018.04 and newer, otherwise Nil 
     } 
     whenever $proc.start { 
         say ‘Proc finished: exitcode=’, .exitcode, ‘ signal=’, .signal; 
         done # gracefully jump from the react block 
     } 
     whenever $proc.print: “I\n♥\nCamelia\n” { 
         $proc.close-stdin 
     } 
     whenever signal(SIGTERM).merge: signal(SIGINT) { 
         once { 
             say ‘Signal received, asking the process to stop’; 
             $proc.kill; # sends SIGHUP, change appropriately 
             whenever signal($_).zip: Promise.in(2).Supply { 
                 say ‘Kill it!’; 
                 $proc.kill: SIGKILL 
             } 
         } 
     } 
     whenever Promise.in(5) { 
         say ‘Timeout. Asking the process to stop’; 
         $proc.kill; # sends SIGHUP, change appropriately 
         whenever Promise.in(2) { 
             say ‘Timeout. Forcing the process to stop’; 
             $proc.kill: SIGKILL 
         } 
     } 
 } 
 
 say ‘Program finished’; 

Example above produces the following output:

line: me 
 line: ♡ 
 line: Camelia 
 line: and 
 line: Camelia 
 line: ♥ 
 line: I 
 Proc finished. Exit code: 0 
 Program finished 

Alternatively, you can use Proc::Async without using a react block:

# command with arguments
my $proc = Proc::Async.new('echo', 'foo', 'bar');

# subscribe to new output from out and err handles:
$proc.stdout.tap(-> $v { print "Output: $v" }, quit => { say 'caught exception ' ~ .^name });
$proc.stderr.tap(-> $v { print "Error:  $v" });

say "Starting...";
my $promise = $proc.start;

# wait for the external program to terminate
await $promise;
say "Done.";

This produces the following output:

Starting... 
 Output: foo bar 
 Done. 

An example that opens an external program for writing:

my $prog = Proc::Async.new(:w, 'hexdump', '-C');
my $promise = $prog.start;
await $prog.write(Buf.new(12, 42));
$prog.close-stdin;
await $promise;

An example of piping several commands like echo "Hello, world" | cat -n:

my $proc-echo = Proc::Async.new: 'echo', 'Hello, world';
my $proc-cat = Proc::Async.new: 'cat', '-n';
$proc-cat.bind-stdin: $proc-echo.stdout;
await $proc-echo.start, $proc-cat.start;

Methods

method new

multi method new(*@ ($path, *@args), :$w, :$enc, :$translate-nl --> Proc::Async:D)
multi method new(   :$path, :@args,  :$w, :$enc, :$translate-nl --> Proc::Async:D)

Creates a new Proc::Async object with external program name or path $path and the command line arguments @args.

If :w is passed to new, then a pipe to the external program's standard input stream (stdin) is opened, to which you can write with write and say.

The :enc specifies the encoding for streams (can still be overridden in individual methods) and defaults to utf8.

If :translate-nl is set to True (default value), OS-specific newline terminators (e.g. \r\n on Windows) will be automatically translated to \n.

method stdout

method stdout(Proc::Async:D: :$bin --> Supply:D)

Returns the Supply for the external program's standard output stream. If :bin is passed, the standard output is passed along in binary as Blob, otherwise it is interpreted as UTF-8, decoded, and passed along as Str.

my $proc = Proc::Async.new(:r, 'echo', 'Perl 6');
$proc.stdout.tap( -> $str {
    say "Got output '$str' from the external program";
});
my $promise = $proc.start;
await $promise;

You must call stdout before you call #method start. Otherwise an exception of class X::Proc::Async::TapBeforeSpawn is thrown.

If stdout is not called, the external program's standard output is not captured at all.

Note that you cannot call stdout both with and without :bin on the same object; it will throw an exception of type X::Proc::Async::CharsOrBytes if you try.

Use .Supply for merged STDOUT and STDERR.

method stderr

method stderr(Proc::Async:D: :$bin --> Supply:D)

Returns the Supply for the external program's standard error stream. If :bin is passed, the standard error is passed along in binary as Blob, otherwise it is interpreted as UTF-8, decoded, and passed along as Str.

my $proc = Proc::Async.new(:r, 'echo', 'Perl 6');
$proc.stderr.tap( -> $str {
    say "Got error '$str' from the external program";
});
my $promise = $proc.start;
await $promise;

You must call stderr before you call #method start. Otherwise an exception of class X::Proc::Async::TapBeforeSpawn is thrown.

If stderr is not called, the external program's standard error stream is not captured at all.

Note that you cannot call stderr both with and without :bin on the same object; it will throw an exception of type X::Proc::Async::CharsOrBytes if you try.

Use .Supply for merged STDOUT and STDERR.

method bind-stdin

multi method bind-stdin(IO::Handle:D $handle)
multi method bind-stdin(Proc::Async::Pipe:D $pipe)

Sets a handle (which must be opened) or a Pipe as a source of STDIN. The STDIN of the target process must be writable or X::Proc::Async::BindOrUse will be thrown.

my $p = Proc::Async.new("cat", :in);
my $h = "/etc/profile".IO.open;
$p.bind-stdin($h);
$p.start;

This is equivalent to

cat < /etc/profile 

and will print the content of /etc/profile to standard output.

method bind-stdout

method bind-stdout(IO::Handle:D $handle)

Redirects STDOUT of the target process to a handle (which must be opened). If STDOUT is closed X::Proc::Async::BindOrUse will be thrown.

my $p = Proc::Async.new("ls", :out);
my $h = "ls.out".IO.open(:w);
$p.bind-stdout($h);
$p.start;

This program will pipe the output of the ls shell command to a file called ls.out, which we are opened for reading.

method bind-stderr

method bind-stderr(IO::Handle:D $handle)

Redirects STDERR of the target process to a handle (which must be opened). If STDERR is closed X::Proc::Async::BindOrUse will be thrown.

my $p = Proc::Async.new("ls", "--foo", :err);
my $h = "ls.err".IO.open(:w);
$p.bind-stderr($h);
$p.start;

method w

method w(Proc::Async:D:)

Returns a true value if :w was passed to the constructor, that is, if the external program is started with its input stream made available to output to the program through the .print, .say and .write methods.

method start

method start(Proc::Async:D: :$scheduler = $*SCHEDULER, :$ENV, :$cwd = $*CWD)

Initiates spawning of the external program. Returns a Promise that will be kept with a Proc object once the external program exits or broken if the program cannot be started. Optionally, you can use a scheduler instead of the default $*SCHEDULER, or change the environment the process is going to run in via the named argument :$ENV or the directory via the named argument :$cwd.

If start is called on a Proc::Async object on which it has already been called before, an exception of type X::Proc::Async::AlreadyStarted is thrown.

Note: If you wish to await the Promise and discard its result, using

try await $p.start; 

will throw if the program exited with non-zero status, as the Proc returned as the result of the Promise throws when sunk and in this case it will get sunk outside the try. To avoid that, sink it yourself inside the try:

try sink await $p.start; 

method started

method started(Proc::Async:D: --> Bool:D)

Returns False before .start has been called, and True afterwards.

method ready

method ready(Proc::Async:D: --> Promise:D)

Returns a Promise that will be kept once the process has successfully started. Promise will be broken if the program fails to start.

Implementation-specific note: Starting from Rakudo 2018.04, the returned promise will hold the process id (PID).

method pid

method pid(Proc::Async:D: --> Promise:D)

Equivalent to ready.

Returns a Promise that will be kept once the process has successfully started. Promise will be broken if the program fails to start. Returned promise will hold the process id (PID).

Implementation-specific note: Available starting from Rakudo 2018.04.

method path

method path(Proc::Async:D:)

Deprecated as of v6.d. Use command instead.

Returns the name and/or path of the external program that was passed to the new method as first argument.

method args

method args(Proc::Async:D: --> Positional:D)

Deprecated as of v6.d. Use command instead.

Returns the command line arguments for the external programs, as passed to the new method.

method command

method command(Proc::Async:D: --> List:D)

Available as of v6.d.

Returns the command and arguments used for this Proc::Async object:

my $p := Proc::Async.new: 'cat', 'some', 'files';
$p.command.say; # OUTPUT: «(cat some files)␤»

method write

method write(Proc::Async:D: Blob:D $b, :$scheduler = $*SCHEDULER --> Promise:D)

Write the binary data in $b to the standard input stream of the external program.

Returns a Promise that will be kept once the data has fully landed in the input buffer of the external program.

The Proc::Async object must be created for writing (with Proc::Async.new(:w, $path, @args)). Otherwise an X::Proc::Async::OpenForWriting exception will the thrown.

start must have been called before calling method write, otherwise an X::Proc::Async::MustBeStarted exception is thrown.

method print

method print(Proc::Async:D: Str(Any) $str, :$scheduler = $*SCHEDULER)

Write the text data in $str to the standard input stream of the external program, encoding it as UTF-8.

Returns a Promise that will be kept once the data has fully landed in the input buffer of the external program.

The Proc::Async object must be created for writing (with Proc::Async.new(:w, $path, @args)). Otherwise an X::Proc::Async::OpenForWriting exception will the thrown.

start must have been called before calling method print, otherwise an X::Proc::Async::MustBeStarted exception is thrown.

method say

method say(Proc::Async:D: $output, :$scheduler = $*SCHEDULER)

Calls method gist on the $output, adds a newline, encodes it as UTF-8, and sends it to the standard input stream of the external program, encoding it as UTF-8.

Returns a Promise that will be kept once the data has fully landed in the input buffer of the external program.

The Proc::Async object must be created for writing (with Proc::Async.new(:w, $path, @args)). Otherwise an X::Proc::Async::OpenForWriting exception will the thrown.

start must have been called before calling method say, otherwise an X::Proc::Async::MustBeStarted exception is thrown.

method Supply

multi method Supply(Proc::Async:D: :$bin!)
multi method Supply(Proc::Async:D: :$enc, :$translate-nl)

Returns a Supply of merged stdout and stderr streams. If :$bin named argument is provided, the Supply will be binary, producing Buf objects, otherwise, it will be in character mode, producing Str objects and :$enc named argument can specify encoding to use. The :$translate-nl option specifies whether new line endings should be translated for to match those used by the current operating system (e.g. \r\n on Windows).

react { 
     with Proc::Async.new: «"$*EXECUTABLE" -e 'say 42; note 100'» { 
         whenever .Supply { .print }  # OUTPUT: «42␤100␤» 
         whenever .start {} 
     } 
 } 

It is an error to create both binary and non-binary .Supply. It is also an error to use both .Supply and either stderr or stdout supplies.

method close-stdin

method close-stdin(Proc::Async:D: --> True)

Closes the standard input stream of the external program. Programs that read from STDIN often only terminate when their input stream is closed. So if waiting for the promise from #method start hangs (for a program opened for writing), it might be a forgotten close-stdin.

The Proc::Async object must be created for writing (with Proc::Async.new(:w, $path, @args)). Otherwise an X::Proc::Async::OpenForWriting exception will the thrown.

start must have been called before calling method close-stdin, otherwise an X::Proc::Async::MustBeStarted exception is thrown.

method kill

method kill(Proc::Async:D: $signal = "HUP")

Sends a signal to the running program. The signal can be a signal name ("KILL" or "SIGKILL"), an integer (9) or an element of the Signal enum (Signal::SIGKILL).

233 class Promise

Status/result of an asynchronous computation

my enum PromiseStatus (:Planned(0), :Kept(1), :Broken(2));
class Promise {}

A Promise is used to handle the result of a computation that might not have finished. It allows the user to execute code once the computation is done (with the then method), execution after a time delay (with in), combining promises, and waiting for results.

my $p = Promise.start({ sleep 2; 42});
$p.then({ say .result });   # will print 42 once the block finished
say $p.status;              # OUTPUT: «Planned␤»
$p.result;                  # waits for the computation to finish
say $p.status;              # OUTPUT: «Kept␤»

There are two typical scenarios for using promises. The first is to use a factory method (start, in, at, anyof, allof, kept, broken) on the type object; those will make sure that the promise is automatically kept or broken for you, and you can't call break or keep on these promises yourself.

The second is to create your promises yourself with Promise.new. If you want to ensure that only your code can keep or break the promise, you can use the vow method to get a unique handle, and call keep or break on it:

sub async-get-with-promise($user-agent, $url) { 
     my $p = Promise.new; 
     my $v = $p.vow; 
 
     # do an asynchronous call on a fictive user agent, 
     # and return the promise: 
     $user-agent.async-get($url, 
             on-error => -> $error { 
                 $v.break($error); 
             }, 
             on-success => -> $response { 
                 $v.keep($response); 
             } 
     ); 
     return $p; 
 } 

Further examples can be found in the concurrency page.

Methods

method start

method start(Promise:U: &code, :$scheduler = $*SCHEDULER --> Promise:D)

Creates a new Promise that runs the given code object. The promise will be kept when the code terminates normally, or broken if it throws an exception. The return value or exception can be inspected with the result method.

The scheduler that handles this promise can be passed as a named argument.

There is also a statement prefix start that provides syntactic sugar for this method:

# these two are equivalent:
my $p1 = Promise.start({ ;#`( do something here ) });
my $p2 = start { ;#`( do something here ) };

As of the 6.d version of the language, start statement prefix used in sink context will automatically attach an exceptions handler. If an exception occurs in the given code, it will be printed and the program will then exit, like if it were thrown without any start statement prefixes involved.

use v6.c; 
 start { die }; sleep ⅓; say "hello"; # OUTPUT: «hello␤» 
use v6.d; 
 start { die }; sleep ⅓; say "hello"; 
 # OUTPUT: 
 # Unhandled exception in code scheduled on thread 4 
 # Died 
 #     in block  at -e line 1 

If you wish to avoid this behavior, use start in non-sink context or catch the exception yourself:

# Don't sink it: 
 my $ = start { die }; sleep ⅓; say "hello"; # OUTPUT: «hello␤» 
 
 # Catch yourself: 
 start { die; CATCH { default { say "caught" } } }; 
 sleep ⅓; 
 say "hello"; 
 # OUTPUT: «caught␤hello␤» 

This behavior exists only syntactically, by using an alternate .sink method for Promise objects created by start blocks in sink context, thus simply sinking a Promise object that was created by other means won't trigger this behavior.

method in

method in(Promise:U: $seconds, :$scheduler = $*SCHEDULER --> Promise:D)

Creates a new Promise that will be kept in $seconds seconds, or later.

my $proc = Proc::Async.new('perl6', '-e', 'sleep 10; warn "end"');

my $result = await Promise.anyof(
    my $promise = $proc.start,  # may or may not work in time
    Promise.in(5).then: {       # fires after 5 seconds no matter what
        unless $promise {       # don't do anything if we were successful
            note 'timeout';
            $proc.kill;
        }
    }
).then: { $promise.result }
# OUTPUT: «timeout␤»

$seconds can be fractional or negative. Negative values are treated as 0 (i.e. keeping the returned Promise right away).

Please note that situations like these are often more clearly handled with a react and whenever block.

method at

method at(Promise:U: $at, :$scheduler = $*SCHEDULER --> Promise:D)

Creates a new Promise that will be kept $at the given time—which is given as an Instant or equivalent Numeric—or as soon as possible after it.

my $p = Promise.at(now + 2).then({ say "2 seconds later" });
# do other stuff here

await $p;   # wait here until the 2 seconds are over

If the given time is in the past, it will be treated as now (i.e. keeping the returned Promise right away).

Please note that situations like these are often more clearly handled with a react and whenever block.

method kept

multi method kept(Promise:U: \result = True --> Promise:D)

Returns a new promise that is already kept, either with the given value, or with the default value True.

method broken

multi method broken(Promise:U: --> Promise:D)
multi method broken(Promise:U: \exception --> Promise:D)

Returns a new promise that is already broken, either with the given value, or with the default value X::AdHoc.new(payload => "Died")

method allof

method allof(Promise:U: *@promises --> Promise:D)

Returns a new promise that will be kept when all the promises passed as arguments are kept or broken. The result of the individual Promises is not reflected in the result of the returned promise: it simply indicates that all the promises have been completed in some way. If the results of the individual promises are important then they should be inspected after the allof promise is kept.

In the following requesting the result of a broken promise will cause the original Exception to be thrown. (You may need to run it several times to see the exception.)

my @promises;
for 1..5 -> $t {
    push @promises, start {
        sleep $t;
    };
}
my $all-done = Promise.allof(@promises);
await $all-done;
@promises>>.result;
say "Promises kept so we get to live another day!";

method anyof

method anyof(Promise:U: *@promises --> Promise:D)

Returns a new promise that will be kept as soon as any of the promises passed as arguments is kept or broken. The result of the completed Promise is not reflected in the result of the returned promise which will always be Kept.

You can use this to wait at most a number of seconds for a promise:

my $timeout = 5;
await Promise.anyof(
    Promise.in($timeout),
    start {
        # do a potentially long-running calculation here
    },
);

method then

method then(Promise:D: &code)

Schedules a piece of code to be run after the invocant has been kept or broken, and returns a new promise for this computation. In other words, creates a chained promise.

my $timer = Promise.in(2);
my $after = $timer.then({ say "2 seconds are over!"; 'result' });
say $after.result;  # 2 seconds are over
                    # result

method keep

multi method keep(Promise:D: \result = True)

Keeps a promise, optionally setting the result. If no result is passed, the result will be True.

Throws an exception of type X::Promise::Vowed if a vow has already been taken. See method vow for more information.

my $p = Promise.new;

if Bool.pick {
    $p.keep;
}
else {
     $p.break;
}

method break

multi method break(Promise:D: \cause = False)

Breaks a promise, optionally setting the cause. If no cause is passed, the cause will be False.

Throws an exception of type X::Promise::Vowed if a vow has already been taken. See method vow for more information.

my $p = Promise.new;

$p.break('sorry');
say $p.status;          # OUTPUT: «Broken␤»
say $p.cause;           # OUTPUT: «sorry␤»

method result

method result(Promise:D)

Waits for the promise to be kept or broken. If it is kept, returns the result; otherwise throws the result as an exception.

method cause

method cause(Promise:D)

If the promise was broken, returns the result (or exception). Otherwise, throws an exception of type X::Promise::CauseOnlyValidOnBroken.

method Bool

multi method Bool(Promise:D:)

Returns True for a kept or broken promise, and False for one in state Planned.

method status

method status(Promise:D --> PromiseStatus)

Returns the current state of the promise: Kept, Broken or Planned:

say "promise got Kept" if $promise.status ~~ Kept; 

method scheduler

method scheduler(Promise:D:)

Returns the scheduler that manages the promise.

method vow

my class Vow { 
     has Promise $.promise; 
     method keep() { ... } 
     method break() { ... } 
 } 
 method vow(Promise:D: --> Vow:D) 

Returns an object that holds the sole authority over keeping or breaking a promise. Calling keep or break on a promise that has vow taken throws an exception of type X::Promise::Vowed.

my $p   = Promise.new;
my $vow = $p.vow;
$vow.keep($p);
say $p.status;          # OUTPUT: «Kept␤»

method Supply

method Supply(Promise:D:)

Returns a Supply that will emit the result of the Promise being Kept or quit with the cause if the Promise is Broken.

sub await

multi sub await(Promise:D --> Promise)
multi sub await(*@ --> Array)

Waits until one or more promises are all fulfilled, and then returns their values. Also works on channels. Any broken promises will rethrow their exceptions. If a list is passed it will return a list containing the results of awaiting each item in turn.

234 class Proxy

Item container with custom storage and retrieval

class Proxy {}

A Proxy is an object that allows you to set a hook that executes whenever a value is retrieved from a container (FETCH) or when it is set (STORE). Please note that Proxy can introduce mutability at places where it would break behavior, e.g. in Hash keys.

To create a container that returns twice what was stored in it, you do something like this:

sub double() is rw {
    my $storage = 0;
    Proxy.new(
        FETCH => method ()     { $storage * 2    },
        STORE => method ($new) { $storage = $new },
    )
 }
 my $doubled := double();
 $doubled = 4;
 say $doubled;       # OUTPUT: «8␤»

Methods

method new

method new(:&FETCH!, :&STORE! --> Proxy:D)

Creates a new Proxy object. &FETCH is called with one argument (the proxy object) when the value is accessed, and must return the value that the fetch produces. &STORE is called with two arguments (the proxy object, and the new value) when a new value is stored in the container.

235 class PseudoStash

Stash type for pseudo-packages

class PseudoStash is Map { }

PseudoStash is the stash type (hanging off .WHO) that backs various pseudo-packages. So, when you do MY:: or CALLER::, that gives back a PseudoStash. In most cases, Package:: gives back a Stash. Neither of these are objects the user is expected to create by themselves, but in case you have one, you can just use it like a hash.

my $a = 42; 
 my $b = q/$a/; 
 say MY::{$b}; 
 #OUTPUT: «42␤» 

This shows how you can use a PseudoStash to look up variables, by name, at runtime.

236 role QuantHash

Object hashes with limitation on type of value

role QuantHash does Associative { }

The QuantHash role provides the basic functionality shared by the Setty, Baggy and Mixy roles. These provide object hashes of which the values are limited in some way.

QuantHashes are what set operators use internally.

Methods

method hash

method hash()

Coerces the QuantHash object to a Hash (by stringifying the objects for the keys) with the values of the hash limited to the same limitation as QuantHash, and returns that.

method Hash

method Hash()

Coerces the QuantHash object to a Hash (by stringifying the objects for the keys) without any limitations on the values, and returns that.

method of

method of()

Returns the type of value a value of this QuantHash may have. This is typically Bool for Setty, UInt for Baggy or Real for Mixy roles.

method keyof

method keyof()

Returns the type of value a key of this QuantHash may have. This is typically Mu.

method Setty

method Setty(--> Setty:D)

Coerce the QuantHash object to the equivalent object that uses the Setty role. Note that for Mixy type coercion items with negative values will be skipped.

my %b is Bag = one => 1, two => 2;
say %b.Setty; # OUTPUT: «set(one two)␤»
my %m is Mix = one => 1, minus => -1;
say %m.Setty; # OUTPUT: «set(one)␤»

method Baggy

method Baggy(--> Baggy:D)

Coerce the QuantHash object to the equivalent object that uses the Baggy role. Note that for Mixy type coercion items with negative values will be skipped.

my %s is Set = <one two>;
say %s.Baggy; # OUTPUT: «Bag(one, two)␤»
my %m is Mix = one => 1, minus => -1;
say %m.Baggy; # OUTPUT: «Bag(one)␤»

method Mixy

method Mixy(--> Mixy:D)

Coerce the QuantHash object to the equivalent object that uses the Mixy role.

my %s is Set = <one two>;
say %s.Mixy; # OUTPUT: «Mix(one, two)␤»
my %b is Bag = one => 1, two => 2;
say %b.Mixy; # OUTPUT: «Mix(one, two)␤»

237 class RaceSeq

Performs batches of work in parallel without respecting original order.

class RaceSeq does Iterable does Sequence { }

An RaceSeq is the intermediate object used when the operator race is invoked on a Seq. In general, it's not intended for direct consumption by the developer.

Methods

method iterator

method iterator(RaceSeq:D: --> Iterator:D)

Returns the underlying iterator.

method grep

method grep(RaceSeq:D: $matcher, *%options)

Applies grep to the RaceSeq similarly to how it would do it on a Seq.

my @raced = (^10000).map(*²).race; 
 @raced.grep( * %% 3 ).say; 
 # OUTPUT: «(0 9 36 81 144 …» 

When you use race on a Seq, this is the method that is actually called.

method map

method map(RaceSeq:D: $matcher, *%options)

Uses maps on the RaceSeq, generally created by application of .race to a preexisting Seq.

method invert

method invert(RaceSeq:D:)

Inverts the RaceSeq created from a Seq by .race.

method race

method race(RaceSeq:D:)

Returns the object.

method hyper

method hyper(RaceSeq:D:)

Creates a HyperSeq object out of the current one.

method serial

multi method serial(RaceSeq:D:)

Converts the object to a Seq and returns it.

method is-lazy

method is-lazy(--> False )

Returns False.

method sink

Defined as:

method sink(--> Nil)

Sinks the underlying data structure, producing any side effects.

238 class Range

Interval of ordered values

class Range is Cool does Iterable does Positional {}

Ranges serve two main purposes: to generate lists of consecutive numbers or strings, and to act as a matcher to check if a number or string is within a certain range.

Ranges are constructed using one of the four possible range operators, which consist of two dots, and optionally a caret which indicates that the endpoint marked with it is excluded from the range.

1 .. 5;  # 1 <= $x <= 5
1^.. 5;  # 1 <  $x <= 5
1 ..^5;  # 1 <= $x <  5
1^..^5;  # 1 <  $x <  5

The caret is also a prefix operator for constructing numeric ranges starting from zero:

my $x = 10;
say ^$x;     # same as 0 ..^ $x.Numeric

Iterating a range (or calling the list method) uses the same semantics as the ++ prefix and postfix operators, i.e., it calls the succ method on the start point, and then the generated elements.

Ranges always go from small to larger elements; if the start point is bigger than the end point, the range is considered empty.

for 1..5 { .say };       # OUTPUT: «1␤2␤3␤4␤5␤»
('a' ^..^ 'f').list;     # RESULT: «'b', 'c', 'd', 'e'»
5 ~~ ^5;                 # RESULT: «False»
4.5 ~~ 0..^5;            # RESULT: «True»
(1.1..5).list;           # RESULT: «(1.1, 2.1, 3.1, 4.1)»

Use the ... sequence operator to produce lists of elements that go from larger to smaller values, or to use offsets other than increment-by-1 and other complex cases.

Use or * (Whatever) to indicate an end point to be open-ended.

for 1..* { .say };       # start from 1, continue until stopped 
 for 1..∞ { .say };       # the same 

Beware that a WhateverCode end point, instead of a plain Whatever, will go through the range operator and create another WhateverCode which returns a Range:

# A Whatever produces the 1..Inf range 
 say (1..*).^name;        # OUTPUT: «Range␤» 
 say (1..*);              # OUTPUT: «1..Inf␤» 
 # Upper end point is now a WhateverCode 
 say (1..*+20).^name;     # OUTPUT: «{ ... }␤» 
 say (1..*+20).WHAT;      # OUTPUT: «(WhateverCode)␤» 
 say (1..*+20).(22);      # OUTPUT: «1..42␤» 

Ranges implement Positional interface, so its elements can be accessed using an index. In a case when the index given is bigger than the Range object's size, Nil object will be returned. The access works for lazy Range objects as well.

say (1..5)[1];  # OUTPUT: «2␤» 
 say (1..5)[10]; # OUTPUT: «Nil␤» 
 say (1..*)[10]; # OUTPUT: «11␤» 

Ranges in subscripts

A Range can be used in a subscript to get a range of values. Please note that assigning a Range to a scalar container turns the Range into an item. Use binding, @-sigiled containers or a slip to get what you mean.

my @numbers =  <4 8 15 16 23 42>;
my $range := 0..2;
.say for @numbers[$range]; # OUTPUT: «4␤8␤15␤»
my @range = 0..2;
.say for @numbers[@range]; # OUTPUT: «4␤8␤15␤»

Shifting and scaling intervals

It is possible to shift or scale the interval of a range:

say (1..10) + 1;       # OUTPUT: «2..11␤»
say (1..10) - 1;       # OUTPUT: «0..9␤»
say (1..10) * 2;       # OUTPUT: «2..20␤»
say (1..10) / 2;       # OUTPUT: «0.5..5.0␤»

Matching against Ranges

You can use smartmatch to match against Ranges.

say 3 ~~ 1..12;          # OUTPUT: «True␤»
say 2..3 ~~ 1..12;       # OUTPUT: «True␤»

In Rakudo only, you can use the in-range method for matching against a range, which in fact is equivalent to smartmatch except it will throw an exception when out of range, instead of returning False:

say ('א'..'ת').in-range('ע');  # OUTPUT: «True␤»

However, if it is not included in the range:

say ('א'..'ת').in-range('p', "Letter 'p'"); 
 # OUTPUT: «(exit code 1) Letter 'p' out of range. Is: "p", should be in "א".."ת"␤ 

The second parameter to in-range is the optional message that will be printed with the exception. It will print Value by default.

Methods

method ACCEPTS

Defined as

multi method ACCEPTS(Range:D: Mu \topic)
multi method ACCEPTS(Range:D: Range \topic)
multi method ACCEPTS(Range:D: Cool:D \got)
multi method ACCEPTS(Range:D: Complex:D \got)

Indicates if the Range contains (overlaps with) another Range. As an example:

my $p = Range.new( 3, 5  );
my $r = Range.new( 1, 10 );

say $p.ACCEPTS( $r );    # OUTPUT: «False␤»
say $r.ACCEPTS( $p );    # OUTPUT: «True␤»
say $r ~~ $p;            # OUTPUT: «False␤»  (same as $p.ACCEPTS( $r )
say $p ~~ $r;            # OUTPUT: «True␤»   (same as $r.ACCEPTS( $p )

Of course, an infinite Range always contains another Range, therefore:

say 1..10 ~~ -∞..∞;    # OUTPUT: «True␤»
say 1..10 ~~ -∞^..^∞;  # OUTPUT: «True␤»

Similarly, a Range with open boundaries often includes other ranges:

say 1..2 ~~ *..10;  # OUTPUT: «True␤»
say 2..5 ~~ 1..*;   # OUTPUT: «True␤»

It is also possible to use non-numeric ranges, for instance string based ones:

say 'a'..'j' ~~ 'b'..'c';  # OUTPUT: «False␤»
say 'b'..'c' ~~ 'a'..'j';  # OUTPUT: «True␤»
say 'perl' ~~ -∞^..^∞;     # OUTPUT: «True␤»
say 'perl' ~~ -∞..∞;       # OUTPUT: «True␤»
say 'perl' ~~ 1..*;        # OUTPUT: «True␤»

When smartmatching a Range of integers with a Cool (string) the ACCEPTS methods exploits the before and after operators in order to check that the Cool value is overlapping the range:

say 1.10 ~~ '5';   # OUTPUT: «False␤»
say '5' before 1;  # OUTPUT: «False␤»
say '5' after 10;  # OUTPUT: «True␤»
say '5' ~~ *..10;  # OUTPUT: «False␤»

In the above example, since the '5' string is after the 10 integer value, the Range does not overlap with the specified value.

When matching with a Mu instance (i.e., a generic instance), the cmp operator is used.

method min

method min(Range:D:)

Returns the start point of the range.

say (1..5).min;                                   # OUTPUT: «1␤»
say (1^..^5).min;                                 # OUTPUT: «1␤»

method excludes-min

method excludes-min(Range:D: --> Bool:D)

Returns True if the start point is excluded from the range, and False otherwise.

say (1..5).excludes-min;                          # OUTPUT: «False␤»
say (1^..^5).excludes-min;                        # OUTPUT: «True␤»

method max

method max(Range:D:)

Returns the end point of the range.

say (1..5).max;                                   # OUTPUT: «5␤»
say (1^..^5).max;                                 # OUTPUT: «5␤»

method excludes-max

method excludes-max(Range:D: --> Bool:D)

Returns True if the end point is excluded from the range, and False otherwise.

say (1..5).excludes-max;                          # OUTPUT: «False␤»
say (1^..^5).excludes-max;                        # OUTPUT: «True␤»

method bounds

method bounds()

Returns a list consisting of the start and end point.

say (1..5).bounds;                                # OUTPUT: «(1 5)␤»
say (1^..^5).bounds;                              # OUTPUT: «(1 5)␤»

method infinite

method infinite(Range:D: --> Bool:D)

Returns True if either end point was declared with or *.

say (1..5).infinite;                              # OUTPUT: «False␤»
say (1..*).infinite;                              # OUTPUT: «True␤»

method is-int

method is-int(Range:D: --> Bool:D)

Returns True if both end points are Int values.

say ('a'..'d').is-int;                            # OUTPUT: «False␤»
say (1..^5).is-int;                               # OUTPUT: «True␤»
say (1.1..5.5).is-int;                            # OUTPUT: «False␤»

method int-bounds

method int-bounds(Range:D: --> Positional)

If the Range is an integer range (as indicated by is-int), then this method returns a list with the first and last value it will iterate over (taking into account excludes-min and excludes-max). Returns a Failure if it is not an integer range.

say (2..5).int-bounds;                            # OUTPUT: «(2 5)␤»
say (2..^5).int-bounds;                           # OUTPUT: «(2 4)␤»

method minmax

Defined as:

multi method minmax(Range:D: --> List:D)

If the Range is an integer range (as indicated by is-int), then this method returns a list with the first and last value it will iterate over (taking into account excludes-min and excludes-max). If the range is not an integer range, the method will return a two element list containing the start and end point of the range unless either of excludes-min or excludes-max are True in which case a Failure is returned.

my $r1 = (1..5); my $r2 = (1^..5);
say $r1.is-int, ', ', $r2.is-int;                 # OUTPUT: «True, True␤»
say $r1.excludes-min, ', ', $r2.excludes-min;     # OUTPUT: «False, True␤»
say $r1.minmax, ', ', $r2.minmax;                 # OUTPUT: «(1 5), (2 5)␤»

my $r3 = (1.1..5.2); my $r4 = (1.1..^5.2);
say $r3.is-int, ', ', $r4.is-int;                 # OUTPUT: «False, False␤»
say $r3.excludes-max, ', ', $r4.excludes-max;     # OUTPUT: «False, True␤»
say $r3.minmax;                                   # OUTPUT: «(1.1 5.2)␤»
say $r4.minmax;
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::AdHoc: Cannot return minmax on Range with excluded ends␤»

method elems

method elems(Range:D: --> Numeric:D)

Returns the number of elements in the range, e.g. when being iterated over, or when used as a List. Returns Inf if either end point was specified as Inf or *.

say (1..5).elems;                                 # OUTPUT: «5␤»
say (1^..^5).elems;                               # OUTPUT: «3␤»

method list

method list(Range:D: --> List:D)

Generates the list of elements that the range represents.

say (1..5).list;                                  # OUTPUT: «(1 2 3 4 5)␤»
say (1^..^5).list;                                # OUTPUT: «(2 3 4)␤»

method flat

method flat(Range:D: --> List:D)

Generates the list of elements that the range represents.

method pick

multi method pick(Range:D:         --> Any:D)
multi method pick(Range:D: $number --> Seq:D)

Performs the same function as Range.list.pick, but attempts to optimize by not actually generating the list if it is not necessary.

method roll

multi method roll(Range:D:         --> Any:D)
multi method roll(Range:D: $number --> Seq:D)

Performs the same function as Range.list.roll, but attempts to optimize by not actually generating the list if it is not necessary.

method sum

multi method sum(--> Numeric:D)

Returns the sum of all elements in the Range. Throws X::Str::Numeric if an element can not be coerced into Numeric.

(1..10).sum                                       # 55

method reverse

method reverse(Range:D: --> Seq:D)

Returns a Seq where all elements that the Range represents have been reversed. Note that reversing an infinite Range won't produce any meaningful results.

say (1^..5).reverse;                            # OUTPUT: «(5 4 3 2)␤» 
 say ('a'..'d').reverse;                         # OUTPUT: «(d c b a)␤» 
 say (1..∞).reverse;                             # OUTPUT: «(Inf Inf Inf ...)␤» 

method Capture

Defined as:

method Capture(Range --> Capture:D)

Returns a Capture with values of .min .max, .excludes-min, .excludes-max, .infinite, and .is-int as named arguments.

method rand

Defined as:

method rand(Range:D --> Num:D)

Returns a pseudo-random value belonging to the range.

say (1^..5).rand;                              # OUTPUT: «1.02405550417031␤»
say (0.1..0.3).rand;                           # OUTPUT: «0.2130353370062␤»

method EXISTS-POS

Defined as

multi method EXISTS-POS(Range:D: int \pos)
multi method EXISTS-POS(Range:D: Int \pos)

Returns True if pos is greater or equal than zero and lower than self.elems. Returns False otherwise.

say (6..10).EXISTS-POS(2); # OUTPUT: «True␤»
say (6..10).EXISTS-POS(7); # OUTPUT: «False␤»

method AT-POS

Defined as

multi method AT-POS(Range:D: int \pos)
multi method AT-POS(Range:D: int:D \pos)

Checks if the Int position exists and in that case returns the element in that position.

say (1..4).AT-POS(2) # OUTPUT: «3␤»

method perl

Defined as

multi method perl(Range:D:)

Returns an implementation-specific string that produces an equivalent object when given to EVAL.

say (1..2).perl # OUTPUT: «1..2␤»

method fmt

Defined as

method fmt(|c)

Returns a string where min and max in the Range have been formatted according to |c.

For more information about formats strings, see sprintf.

say (1..2).fmt("Element: %d", ",") # OUTPUT: «Element: 1,Element: 2␤»

method WHICH

Defined as

multi method WHICH (Range:D:)

This returns a string that identifies the object. The string is composed by the type of the instance (Range) and the min and max attributes:

say (1..2).WHICH # OUTPUT: «Range|1..2␤»

sub infix:<+>

multi sub infix:<+>(Range:D \r, Real:D \v)
multi sub infix:<+>(Real:D \v, Range:D \r)

Takes an Real and adds that number to both boundaries of the Range object. Be careful with the use of parenthesis.

say (1..2) + 2; # OUTPUT: «3..4␤»
say 1..2 + 2;   # OUTPUT: «1..4␤»

sub infix:<->

multi sub infix:<->(Range:D \r, Real:D \v)

Takes an Real and subtract that number to both boundaries of the Range object. Be careful with the use of parenthesis.

say (1..2) - 1; # OUTPUT: «0..1␤»
say 1..2 - 1;   # OUTPUT: «1..1␤»

sub infix:<*>

multi sub infix:<*>(Range:D \r, Real:D \v)
multi sub infix:<*>(Real:D \v, Range:D \r)

Takes an Real and multiply both boundaries of the Range object by that number.

say (1..2) * 2; # OUTPUT: «2..4␤»

sub infix:</>

multi sub infix:</>(Range:D \r, Real:D \v)

Takes an Real and divide both boundaries of the Range object by that number.

say (2..4) / 2; # OUTPUT: «1..2␤»

sub infix:<cmp>

multi sub infix:<cmp>(Range:D \a, Range:D \b --> Order:D)
multi sub infix:<cmp>(Num(Real) \a, Range:D \b --> Order:D)
multi sub infix:<cmp>(Range:D \a, Num(Real) \b --> Order:D)
multi sub infix:<cmp>(Positional \a, Range:D \b --> Order:D)
multi sub infix:<cmp>(Range:D \a, Positional \b --> Order:D)

Compares two Range objects. If you use a Real, it will be compared to the Range b..b. If you use a Positional.

say (1..2) cmp (1..2); # OUTPUT: «Same␤»
say (1..2) cmp (1..3); # OUTPUT: «Less␤»
say (1..4) cmp (1..3); # OUTPUT: «More␤»
say (1..2) cmp 3;      # OUTPUT: «Less␤»
say (1..2) cmp [1,2];  # OUTPUT: «Same␤»

239 class Rat

Rational number (limited-precision)

class Rat is Cool does Rational[Int, uint64] { }

Rat objects store rational numbers as a pair of a numerator and denominator. Number literals with a dot but without exponent produce Rats.

say 3.1;          # OUTPUT: «3.1␤»      (same as: Rat.new(31, 10))
say 3.1.^name;    # OUTPUT: «Rat␤»
say 3.1.nude;     # OUTPUT: «(31 10)␤»

say <1/2>;        # OUTPUT: «0.5␤»      (same as: Rat.new(1, 2))
say <1/2>.^name;  # OUTPUT: «Rat␤»
say <1/2>.nude;   # OUTPUT: «(1 2)␤»

Thus arithmetic with short dotted-decimal numbers does not suffer from floating point errors.

To prevent the numerator and denominator from becoming pathologically large, the denominator is limited to 64 bit storage. On overflow of the denominator a Num (floating-point number) is returned instead.

For example this function crudely approximates a square root, and overflows the denominator quickly:

sub approx-sqrt($n, $iterations) {
    my $x = $n;
    $x = ($x + $n / $x) / 2 for ^$iterations;
    return $x;
}
say approx-sqrt(2, 5).^name;     # OUTPUT: «Rat␤»
say approx-sqrt(2, 10).^name;    # OUTPUT: «Num␤»

If you want arbitrary precision arithmetic with rational numbers, use the FatRat type instead.

Rat objects are immutable.

Methods

method perl

multi method perl(Rat:D: --> Str:D)

Returns an implementation-specific string that produces an equivalent object when given to EVAL.

say (1/3).perl;                # OUTPUT: «<1/3>␤»
say (2/4).perl;                # OUTPUT: «0.5␤»

240 class RatStr

Dual value rational number and string

class RatStr is Rat is Str {}

The dual value types (often referred to as allomorphs) allow for the representation of a value as both a string and a numeric type. Typically they will be created for you when the context is "stringy" but they can be determined to be numbers, such as in some quoting constructs:

my $f = <42.1>; say $f.^name; # OUTPUT: «RatStr␤»

As a subclass of both Rat and Str, a RatStr will be accepted where either is expected. However, RatStr does not share object identity with Rat- or Str-only variants:

my $rat-str = <42.1>;
my Rat $rat = $rat-str; # OK!
my Str $str = $rat-str; # OK!
say 42.1 ∈ <42.1  55  1>; # False; ∈ operator cares about object identity

Methods

method new

method new(Rat $i, Str $s)

The constructor requires both the Rat and the Str value, when constructing one directly the values can be whatever is required:

my $f = RatStr.new(42.1, "forty two and a bit");
say +$f; # OUTPUT: «42.1␤»
say ~$f; # OUTPUT: «"forty two and a bit"␤»

method Bool

Defined as:

multi method Bool(RatStr:D: --> Bool:D)

This method may be provided by the parent classes and not implemented in RatStr directly.

Returns False if the numerator of the numeric portion is 0, otherwise returns True. This applies for < 0/0 > zero-denominator RatStr as well, despite ?< 0/0 >.Num being True. String portion is not considered.

method Capture

Defined as:

method Capture(RatStr:D --> Capture:D)

Equivalent to Mu.Capture.

method Numeric

Defined as:

multi method Numeric(RatStr:D: --> Rat:D)
multi method Numeric(RatStr:U: --> Rat:D)

The :D variant returns the numeric portion of the invocant. The :U variant issues a warning about using an uninitialized value in numeric context and then returns value 0.0.

method Rat

method Rat

Returns the Rat value of the RatStr.

method Real

Defined as:

multi method Real(Real:D: --> Rat:D)
multi method Real(Real:U: --> Rat:D)

The :D variant returns the numeric portion of the invocant. The :U variant issues a warning about using an uninitialized value in numeric context and then returns value 0.0.

method Str

Returns the string value of the RatStr.

method ACCEPTS

Defined as:

multi method ACCEPTS(RatStr:D: Any:D $value)

If $value is Numeric (including another allomorph), checks if invocant's Numeric part ACCEPTS the $value. If $value is Str, checks if invocant's Str part ACCEPTS the $value. If value is anything else, checks if both Numeric and Str parts ACCEPTS the $value.

say <5.0> ~~ "5"; # OUTPUT: «False␤»
say <5.0> ~~  5 ; # OUTPUT: «True␤»
say <5.0> ~~ <5>; # OUTPUT: «True␤»

Operators

infix cmp

multi sub infix:<cmp>(RatStr:D $a, RatStr:D $b)

Compare two RatStr objects. The comparison is done on the Rat value first and then on the Str value. If you want to compare in a different order then you would coerce to the Rat or Str values first:

my $f = RatStr.new(42.1, "smaller");
my $g = RatStr.new(43.1, "larger");
say $f cmp $g;          # OUTPUT: «Less␤»
say $f.Str cmp $g.Str;  # OUTPUT: «More␤»

241 role Rational

Number stored as numerator and denominator

role Rational[::NuT, ::DeT] does Real { ... }

Rational is the common role for numbers that are stored as pairs of numerator and denominator. It is parameterized by the types of the numerator (NuT) and denominator (DeT). By default, these are Int, but other types of Rational are possible by using a different parameterization. In addition, Rational objects are immutable throughout their life.

class Positive does Rational[UInt] {};
my Positive $one-third = Positive.new(1,3);
say $one-third;                         # OUTPUT: «0.333333␤»
my Positive $fail =Positive.new(-2,3);  # OUTPUT: «Type check failed in binding to parameter 'nu'; expected UInt but got Int (-2)␤»

Please note that, since DeT is by default equal to NuT, in this case both are instantiated to UInt. Built into Perl 6 are Rat and FatRat, which both do the Rational role.

Methods

method new

    method new(NuT:D $numerator, DeT:D $denominator --> Rational:D) 

Creates a new rational object from numerator and denominator, which it normalizes to the lowest terms. The $denominator can be zero, in which case the numerator is normalized to -1, 0, or 1 depending on whether the original is negative, zero, or positive, respectively.

method Bool

Defined as:

multi method Bool(Rational:D: --> Bool:D)

Returns False if numerator is 0, otherwise returns True. This applies for <0/0> zero-denominator Rational as well, despite ?<0/0>.Num being True.

method Int

Defined as:

method Int(Rational:D: --> Int:D)

Coerces the invocant to Int by truncating non-whole portion of the represented number, if any. If the denominator is zero, will fail with X::Numeric::DivideByZero.

method Num

Defined as:

method Num(Rational:D: --> Num:D)

Coerces the invocant to Num by dividing numerator by denominator. If denominator is 0, returns Inf, -Inf, or NaN, based on whether numerator is a positive number, negative number, or 0, respectively.

method ceiling

Defined as:

method ceiling(Rational:D: --> Int:D)

Return the smallest integer not less than the invocant. If denominator is zero, fails with X::Numeric::DivideByZero.

method floor

Defined as:

method floor(Rational:D: --> Int:D)

Return the largest integer not greater than the invocant. If denominator is zero, fails with X::Numeric::DivideByZero.

method isNaN

method isNaN(Rational:D: --> Bool:D)

Tests whether the invocant's Num value is a NaN, an acronym for Not available Number. That is both its numerator and denominator are zero.

method numerator

    method numerator(Rational:D: --> NuT:D) 

Returns the numerator.

method denominator

    method denominator(Rational:D: --> DeT:D) 

Returns the denominator.

method nude

method nude(Rational:D: --> Positional)

Returns a list of the numerator and denominator.

method norm

method norm(Rational:D: --> Rational:D)

DEPRECATED as of 6.d. The method is no longer needed, because as of 6.d language version, it's required for Rational type to be normalized on creation.

Returns a normalized Rational object, i.e. with positive denominator, and numerator and denominator coprime. The denominator can also by zero, but using it in any operation or a conversion to string will result in an exception.

use v6.c; 
 my Rational $by-zero = 3/0; 
 say $by-zero.norm.perl; # OUTPUT: «<1/0>␤» 
say $by-zero; # OUTPUT: «Attempt to divide by zero when coercing Rational to Str␤ 

method base-repeating

method base-repeating(Rational:D: Int:D() $base = 10)

Returns a list of two strings that, when concatenated, represent the number in base $base. The second element is the one that repeats. For example:

my ($non-rep, $repeating) = (19/3).base-repeating(10);
say $non-rep;                               # OUTPUT: «6.␤»
say $repeating;                             # OUTPUT: «3␤»
printf '%s(%s)', $non-rep, $repeating;      # OUTPUT: «6.(3)»

19/3 is 6.333333... with the 3 repeating indefinitely.

If no repetition occurs, the second string is empty:

say (5/2).base-repeating(10).perl;          # OUTPUT: «("2.5", "")␤»

The precision for determining the repeating group is limited to 1000 characters, above that, the second string is ???.

$base defaults to 10.

method Range

Returns a Range object that represents the range of values supported.

242 role Real

Non-complex number

role Real does Numeric { ... }

Common role for non-Complex numbers.

Methods

method Bridge

Defined as:

method Bridge(Real:D:)

Default implementation coerces the invocant to Num and that's the behavior of this method in core Real types. This method primarily exist to make it easy to implement custom Real types by users, with the Bridge method returning one of the core Real types (NOT necessarily a Num) that best represent the custom Real type. In turn, this lets all the core operators and methods obtain a usable value they can work with.

As an example, we can implement a custom Temperature type. It has a unit of measure and the value, which are given during instantiation. We can implement custom operators or conversion methods that work with this type. When it comes to regular mathematical operators, however, we can simply use the .Bridge method to convert the Temperature to Kelvin expressed in one of the core numeric types:

class Temperature is Real {
    has Str:D  $.unit  is required where any <K F C>;
    has Real:D $.value is required;
    method new ($value, :$unit = 'K') { self.bless :$value :$unit }
    # Note: implementing .new() that handles $value of type Temperature is left as an exercise

    method Bridge {
        when $!unit eq 'F' { ($!value + 459.67) × 5/9 }
        when $!unit eq 'C' {  $!value + 273.15 }
        $!value
    }
    method gist { self.Str }
    method Str  { "$!value degrees $!unit" }
}

sub postfix:<℃> { Temperature.new: $^value, :unit<C> }
sub postfix:<℉> { Temperature.new: $^value, :unit<F> }
sub postfix:<K> { Temperature.new: $^value, :unit<K> }

my $human := 36.6℃;
my $book  := 451℉;
my $sun   := 5778K;
say $human;                # OUTPUT: «36.6 degrees C␤»
say $human + $book + $sun; # OUTPUT: «6593.677777777778␤»
say 123K + 456K;           # OUTPUT: «579␤»

As we can see from the last two lines of the output, the type of the bridged result is not forced to be any particular core type. It is a Rat, when we instantiated Temperature with a Rat or when conversion was involved, and it is an Int when we instantiated Temperature with an Int.

method Complex

method Complex(Real:D: --> Complex:D)

Converts the number to a Complex with the number converted to a Num as its real part and 0e0 as the imaginary part.

method Rat

method Rat(Real:D: Real $epsilon = 1e-6)

Converts the number to a Rat with the precision $epsilon.

method Real

Defined as:

multi method Real(Real:D: --> Real:D)
multi method Real(Real:U: --> Real:D)

The :D variant simply returns the invocant. The :U variant issues a warning about using an uninitialized value in numeric context and then returns self.new.

routine rand

sub term:<rand> (--> Num:D)
method rand(Real:D: --> Real:D)

Returns a pseudo-random number between zero (inclusive) and the number (non-inclusive). The Bridge method is used to coerce the Real to a numeric that supports rand method.

The term form returns a pseudo-random Num between 0e0 (inclusive) and 1e0 (non-inclusive.)

method sign

method sign(Real:D:)

Returns -1 if the number is negative, 0 if it is zero and 1 otherwise.

method round

method round(Real:D: $scale = 1)

Rounds the number to scale $scale. If $scale is 1, rounds to an integer. If scale is 0.1, rounds to one digit after the comma etc.

method floor

method floor(Real:D --> Int:D)

Return the largest integer not greater than the number.

method ceiling

method ceiling(Real:D --> Int:D)

Returns the smallest integer not less than the number.

method truncate

method truncate(Real:D --> Int:D)

Rounds the number towards zero.

method polymod

method polymod(Real:D: +@mods)

Returns the remainders after applying sequentially all divisors in the @mods argument; the last element of the array will be the last remainder.

say (1e8+1).polymod(10 xx 8);  # OUTPUT: «(1 0 0 0 0 0 0 0 1)␤»

10 xx 8 is simply an array with eight number 10s; the first division by 10 will return 1 as a remainder, while the rest, up to the last, will return 0. With 8 divisors, as above, the result will have one more elements, in this case for the last remainder.

method base

method base(Real:D: Int:D $base where 2..36, $digits? --> Str:D)

Converts the number to a string, using $base as base. For $base larger than ten, capital Latin letters are used.

255.base(16);            # 'FF'

The optional $digits argument asks for that many digits of fraction (which may not be negative). If omitted, a reasonable default is chosen based on type. For Int this default is 0. For Num, the default is 8. For Rational, the number of places is scaled to the size of the denominator, with a minimum of 6.

A special value of Whatever (*) can be given as $digits, which functions the same as when $digits is not specified for all Real types except the Rationals. For Rationals, the Whatever indicates that you wish all of the possible digits of the fractional part, but use caution: since there's no detection of repeating fractional parts (the algorithm will eventually stop after generating 2**63 digits).

The final digit produced is always rounded.

say pi.base(10, 3);      # OUTPUT: «3.142␤»
say (1/128).base(10, *); # OUTPUT: «0.0078125␤»
say (1/100).base(10, *); # OUTPUT: «0.01␤»
say (1/3)  .base(10, *); # WRONG: endlessly repeating fractional part

For reverse operation, see parse-base

243 class Regex

String pattern

class Regex is Method { }

A regex is a kind of pattern that describes a set of strings. The process of finding out whether a given string is in the set is called matching. The result of such a matching is a Match object, which evaluates to True in boolean context if the string is in the set.

A regex is typically constructed by a regex literal

rx/ ^ab /;      # describes all strings starting with 'ab'
/ ^ ab /;       # same
rx/ \d ** 2/;   # describes all strings containing at least two digits

A named regex can be defined with the regex declarator followed by its definition in curly braces. Since any regex does Callable introspection requires referencing via &-sigil.

my regex R { \N };
say &R.^name; # OUTPUT: «Regex␤»

To match a string against a regex, you can use the smartmatch operator:

my $match = 'abc' ~~ rx/ ^ab /;
say $match.Bool;                # OUTPUT: «True␤»
say $match.orig;                # OUTPUT: «abc␤»
say $match.Str;                 # OUTPUT: «ab␤»
say $match.from;                # OUTPUT: «0␤»
say $match.to;                  # OUTPUT: «2␤»

Or you can evaluate the regex in boolean context, in which case it matches against the $_ variable

$_ = 'abc';
if / ^ab / {
    say '"abc" begins with "ab"';
}
else {
    say 'This is a weird alternative Universe';
}

Methods

method ACCEPTS

multi method ACCEPTS(Regex:D: Mu --> Match:D)
multi method ACCEPTS(Regex:D: @)
multi method ACCEPTS(Regex:D: %)

Matches the regex against the argument passed in. If the argument is Positional, it returns the first successful match of any list item. If the argument is Associative, it returns the first successful match of any key. Otherwise it interprets the argument as a Str and matches against it.

In the case of Positional and Associative matches, Nil is returned on failure.

method Bool

multi method Bool(Regex:D: --> Bool:D)

Matches against the caller's $_ variable, and returns True for a match or False for no match.

244 class Routine

Code object with its own lexical scope and

class Routine is Block { }

A Routine is a code object meant for larger unities of code than Block. Routine is the common superclass for Sub (and therefore operators) and Method, the two primary code objects for code reuse.

Routines serve as a scope limiter for return (i.e. a return returns from the innermost outer Routine).

The routine level is also the one at which multiness (multi subs and multi methods) are handled. Subroutines can also be declared anon. See the documentation on the anon declarator for more information.

Methods

method name

method name(Routine:D: --> Str:D)

Returns the name of the sub or method.

method package

method package(Routine:D:)

Returns the package in which the routine is defined.

method multi

method multi(Routine:D: --> Bool:D)

Returns True if the routine is a multi sub or method. Note that the name of a multi sub refers to its proto and this method would return false if called on it. It needs to be called on the candidates themselves:

multi foo ($, $) {};
say &foo.multi;             # OUTPUT: «False␤»
say &foo.candidates».multi; # OUTPUT: «(True)␤»

method candidates

method candidates(Routine:D: --> Positional:D)

Returns a list of multi candidates, or a one-element list with itself if it's not a multi

method cando

method cando(Capture $c)

Returns a possibly-empty list of candidates that can be called with the given Capture, ordered by narrowest candidate first. For methods, the first element of the Capture needs to be the invocant:

.signature.say for "foo".^can("comb")[0].cando: \(Cool, "o");
# OUTPUT: «(Cool $: Str $matcher, $limit = Inf, *%_)␤»

method wrap

method wrap(Routine:D: &wrapper)

Wraps (i.e. in-place modifies) the routine. That means a call to this routine first calls &wrapper, which then can (but doesn't have to) call the original routine with the callsame, callwith, nextsame and nextwith dispatchers. The return value from the routine is also the return value from the wrapper.

wrap returns an instance of a private class called Routine::WrapHandle, which you can pass to unwrap to restore the original routine.

method unwrap

method unwrap($wraphandle)

Restores the original routine after it has been wrapped with wrap. While the signature allows any type to be passed, only the Routine::WrapHandle type returned from wrap can usefully be.

method yada

method yada(Routine:D: --> Bool:D)

Returns True if the routine is a stub

say (sub f() { ... }).yada;      # OUTPUT: «True␤»
say (sub g() { 1;  }).yada;      # OUTPUT: «False␤»

trait is cached

multi sub trait_mod:<is>(Routine $r, :$cached!)

Causes the return value of a routine to be stored, so that when subsequent calls with the same list of arguments are made, the stored value can be returned immediately instead of re-running the routine.

This is still in experimental stage. Please check the corresponding section in the experimental features document

Useful when storing and returning the computed value is much faster than re-computing it every time, and when the time saved trumps the cost of the use of more memory.

Even if the arguments passed to the routine are "reference types" (such as objects or arrays), then for the purpose of caching they will only be compared based on their contents. Thus the second invocation will hit the cache in this case:

say foo( [1, 2, 3] );   # runs foo 
 say foo( [1, 2, 3] );   # doesn't run foo, uses cached value 

Since it's still at the experimental stage, you will have to insert the use experimental :cached; statement in any module or script that uses it.

use experimental :cached; 
 
 sub nth-prime(Int:D $x where * > 0) is cached { 
     say "Calculating {$x}th prime"; 
     return (2..*).grep(*.is-prime)[$x - 1]; 
 } 
 
 say nth-prime(43); 
 say nth-prime(43); 
 say nth-prime(43); 

produces this output:

Calculating 43th prime 
 191 
 191 
 191 

trait is pure

multi sub trait_mod:<is>(Routine $r, :$pure!)

Marks a subroutine as pure, that is, it asserts that for the same input, it will always produce the same output without any additional side effects.

The is pure trait is a promise by the programmer to the compiler that it can constant-fold calls to such functions when the arguments are known at compile time.

sub syllables() is pure {
    say "Generating syllables";
    my @vowels = <a e i o u>;
    return  @vowels.append: <k m n sh d r t y> X~ @vowels;
}

You can mark function as pure even if they throw exceptions in edge cases or if they modify temporary objects; hence the is pure trait can cover cases that the compiler cannot deduce on its own. On the other hand, you might not want to constant-fold functions that produce a large return value (such as the string or list repetition operators, infix x and xx) even if they are pure, to avoid large precompilation files.

To see it an action with a particular compiler you can try this example:

BEGIN { say ‘Begin’ } 
 say ‘Start’; 
 say (^100).map: { syllables().pick(2..5).join("") }; 
 
 
 # Example output: 
 # Begin 
 # Generating syllables 
 # Start 
 # (matiroi yeterani shoriyuru... 

Essentially this allows the compiler to perform some operations at compile time. The benefits of constant-folding may include better performance, especially in cases when the folded code is precompiled.

In addition, using a pure function or operator in sink context (that is, where the result is discarded) may lead to a warning. The code

sub double($x) is pure { 2 * $x };
double(21);
say "anything";
# WARNING: «Useless use of "double(21)" in expression "double(21)" in sink context (line 2)»

If you want to apply this trait to a multi, you need to apply it to the proto; it will not work otherwise, at least in versions 2018.08 and below.

trait is rw

multi sub trait_mod:<is>(Routine $r, :$rw!)

When a routine is modified with this trait, its return value will be writable. This is useful when returning variables or writable elements of hashes or arrays, for example:

sub walk(\thing, *@keys) is rw { 
     my $current := thing; 
     for @keys -> $k { 
         if $k ~~ Int { 
             $current := $current[$k]; 
         } 
         else { 
             $current := $current{$k}; 
         } 
     } 
     $current; 
 } 
 
 my %hash; 
 walk(%hash, 'some', 'key', 1, 2) = 'autovivified'; 
 
 say %hash.perl; 

produces

("some" => {"key" => [Any, [Any, Any, "autovivified"]]}).hash 

Note that return marks return values as read only; if you need an early exit from an is rw routine, you have to use return-rw instead.

trait is export

multi sub trait_mod:<is>(Routine $r, :$export!)

Marks a routine as exported to the rest of the world

module Foo { 
     sub double($x)  is export  { 
         2 * $x 
     } 
 } 
 
 import Foo;         # makes sub double available 
 say double 21;      # 42 

From inside another file you'd say use Foo; to load a module and import the exported functions.

See Exporting and Selective Importing Modules for more details.

trait is DEPRECATED

multi sub trait_mod:<is>(Routine:D $r, :$DEPRECATED!)

Marks a routine as deprecated, optionally with a message what to use instead.

This code

sub f() is DEPRECATED('the literal 42') { 42 } 
 say f(); 

produces this output:

42 
 Saw 1 occurrence of deprecated code. 
 ================================================================================ 
 Sub f (from GLOBAL) seen at: 
   deprecated.p6, line 2 
 Please use the literal 42 instead. 
 -------------------------------------------------------------------------------- 
 Please contact the author to have these occurrences of deprecated code 
 adapted, so that this message will disappear! 

trait is hidden-from-backtrace

multi sub trait_mod:<is>(Routine:D, :$hidden-from-backtrace!)

Hides a routine from showing up in a default backtrace. For example

sub inner { die "OH NOEZ" }; 
 sub outer { inner() }; 
 outer(); 

produces the error message and backtrace

OH NOEZ 
   in sub inner at bt.p6:1 
   in sub outer at bt.p6:2 
   in block <unit> at bt.p6:3 

but if inner is marked with hidden-from-backtrace

sub inner is hidden-from-backtrace { die "OH NOEZ" }; 
 sub outer { inner() }; 
 outer(); 

the error backtrace does not show it:

OH NOEZ 
   in sub outer at bt.p6:2 
   in block <unit> at bt.p6:3 
TODO: explain export tags

trait is default

Defined as

multi sub trait_mod:<is>(Routine:D $r, :$default!)

There is a special trait for Routines called is default. This trait is designed as a way to disambiguate multi calls that would normally throw an error because the compiler would not know which one to use. This means that given the following two Routines, the one with the is default trait will be called.

multi sub f() is default { say "Hello there" }
multi sub f() { say "Hello friend" }
f();   # OUTPUT: «"Hello there"␤»

The is default trait can become very useful for debugging and other uses but keep in mind that it will only resolve an ambiguous dispatch between two Routines of the same precedence. If one of the Routines is narrower than another, then that one will be called. For example:

multi sub f() is default { say "Hello there" } 
 multi sub f(:$greet) { say "Hello " ~ $greet } 
 f();   # "Use of uninitialized value $greet..." 

In this example, the multi without is default was called because it was actually narrower than the Sub with it.

trait is raw

Defined as:

multi sub trait_mod:<is>(Routine:D $r, :$raw!)

Gives total access to the data structure returned by the routine.

my @zipi = <zape zapatilla>; 
 sub þor() is raw { 
     return @zipi 
 }; 
 þor()[1] = 'pantuflo'; 
 say @zipi;  # OUTPUT: «[zape pantuflo]␤» 

245 class Routine::WrapHandle

Holds all information needed to unwrap a wrapped routine.

class WrapHandle { ... }

WrapHandle is a Rakudo private class created and returned by wrap. Its only use is to unwrap wrapped routines. Either call unwrap on a routine object or call the method restore on a Routine::WrapHandle object.

sub f() { say 'f was called' }
my $wrap-handle = &f.wrap({ say 'before'; callsame; say 'after' });
f;                    # OUTPUT: «before␤f was called␤after␤»
$wrap-handle.restore;
f;                    # OUTPUT: «f was called␤»

As such private class, it may suffer any kind of changes without prior notice. It is only mentioned here since it is visible by the user who checks the return type of the Routine.wrap method.

Methods

method restore

method restore(--> Bool:D)

Unwraps a wrapped routine and returns Bool::True on success.

246 class Scalar

A mostly transparent container used for indirections

class Scalar {}

A Scalar is an internal indirection which is for most purposes invisible during ordinary use of Perl 6. It is the default container type associated with the $ sigil. A literal Scalar may be placed around a literal value by enclosing the value in $(…). This notation will appear in the output of a .perl method in certain places where it is important to note the presence of Scalars.

When a value is assigned to a $-sigiled variable, the variable will actually bind to a Scalar, which in turn will bind to the value. When a Scalar is assigned to a $-sigiled variable, the value bound to by that Scalar will be bound to the Scalar which that variable was bound to (a new one will be created if necessary.)

In addition, Scalars delegate all method calls to the value which they contain. As such, Scalars are for the most part invisible. There is, however, one important place where Scalars have a visible impact: a Scalar will shield its content from flattening by most Perl 6 core list operations.

A $-sigiled variable may be bound directly to a value with no intermediate Scalar using the binding operator :=. You can tell if this has been done by examining the output of the introspective pseudo-method .VAR:

my $a = 1;
$a.^name.say;     # OUTPUT: «Int␤»
$a.VAR.^name.say; # OUTPUT: «Scalar␤»
my $b := 1;
$b.^name.say;     # OUTPUT: «Int␤»
$b.VAR.^name.say; # OUTPUT: «Int␤»

This same thing happens when values are assigned to an element of an Array, however, Lists directly contain their values:

my @a = 1, 2, 3;
@a[0].^name.say;            # OUTPUT: «Int␤»
@a[0].VAR.^name.say;        # OUTPUT: «Scalar␤»
[1, 2, 3][0].^name.say;     # OUTPUT: «Int␤»
[1, 2, 3][0].VAR.^name.say; # OUTPUT: «Scalar␤»
(1, 2, 3)[0].^name.say;     # OUTPUT: «Int␤»
(1, 2, 3)[0].VAR.^name.say; # OUTPUT: «Int␤»

Array elements may be bound directly to values using := as well; however, this is discouraged as it may lead to confusion. Doing so will break exact round-tripping of .perl output – since Arrays are assumed to place Scalars around each element, Scalars are not denoted with $ in the output of Array.perl.

[1, $(2, 3)].perl.say;     # OUTPUT: «[1, (2, 3)]␤»
(1, $(2, 3)).perl.say;     # OUTPUT: «(1, $(2, 3))␤»

Binding a Scalar to a $-sigiled variable replaces the existing Scalar in that variable, if any, with the given Scalar. That means more than one variable may refer to the same Scalar. Because the Scalar may be mutated, this makes it possible to alter the value of both variables by altering only one of them:

my $a = 1;
my $b := $a;
$b = 2;
$a.say;       # OUTPUT: «2␤»

SSA-style constants bind directly to their value with no intervening Scalar, even when assignment (=) is used. They may be forced to use a Scalar by assigning a $-sigiled variable to them, at which point, they behave entirely like $-sigiled variables.

my \c = 1;
c.^name.say;             # OUTPUT: «Int␤»
c.VAR.^name.say;         # OUTPUT: «Int␤»
my $a = 1;
my \d = $a;              # just "my \d = $ = 1" works, too
d.^name.say;             # OUTPUT: «Int␤»
d.VAR.^name.say;         # OUTPUT: «Scalar␤»
d = 2;                   # ok
c = 2;                   # fails
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Assignment::RO: Cannot modify an immutable Int␤»

Atomic operations on Scalar

A Scalar can have its value changed using a hardware-supported atomic compare and swap operation. This is useful when implementing lock free data structures and algorithms. It may also be fetched and assigned to in an "atomic" fashion, which ensures appropriate memory barriering and prevents unwanted optimizations of memory accesses.

A Scalar that will be used with an atomic operation should always be explicitly initialized with a value before any atomic operations are performed upon it. This is to avoid races with lazy allocation and auto-vivification. For example:

cas(@a[5], $expected, $value) 

Will work in principle since an Array consists of Scalar containers. However, the container is only bound into the array upon initial assignment. Therefore, there would be a race to do that binding. The Scalar atomic operations will never check for or do any such auto-vivification, so as to make such bugs much more evident (rather than only observed under stress).

Introspection

method of

method of(Scalar:D: --> Mu)

Returns the type constraint of the container.

Example:

my Cool $x = 42;
say $x.VAR.of;                  # OUTPUT: «(Cool)»

method default

method default(Scalar:D: --> Str)

Returns the default value associated with the container.

Example:

my $x is default(666) = 42;
say $x.VAR.default;             # OUTPUT: «666»

method name

method name(Scalar:D: --> Str)

Returns the name associated with the container.

Example:

my $x = 42;
say $x.VAR.name;                # OUTPUT: «$x»

method dynamic

method dynamic(Scalar:D: --> Bool)

Returns whether the variable is visible in dynamic variable lookups.

Example:

my $*FOO = 42;
say $*FOO.VAR.dynamic;          # OUTPUT: «True»

Routines

sub atomic-assign

Defined as:

multi sub atomic-assign($target is rw, $value)

Performs an atomic assignment of $value into the Scalar $target. The atomic-assign routine ensures that any required barriers are performed such that the changed value will be "published" to other threads.

sub atomic-fetch

multi sub atomic-fetch($target is rw)

Performs an atomic read of the value in the Scalar $target and returns the read value. Using this routine instead of simply using the variable ensures that the latest update to the variable from other threads will be seen, both by doing any required hardware barriers and also preventing the compiler from lifting reads. For example:

my $started = False;
start { atomic-assign($started, True) }
until atomic-fetch($started) { }

Is certain to terminate, while in:

my $started = False;
start { atomic-assign($started, True) }
until $started { }

It would be legal for a compiler to observe that $started is not updated in the loop, and so lift the read out of the loop, thus causing the program to never terminate.

sub cas

Defined as:

multi sub cas($target is rw, $expected, $value)
multi sub cas($target is rw, &operation)

Performs an atomic compare and swap of the value in the Scalar $target. The first form has semantics like:

my $seen = $target; 
 if $seen<> =:= $expected<> { 
     $target = $value; 
 } 
 return $seen; 

Except it is performed as a single hardware-supported atomic instruction, as if all memory access to $target were blocked while it took place. Therefore it is safe to attempt the operation from multiple threads without any other synchronization. Since it is a reference comparison, this operation is usually not sensible on value types.

For example:

constant NOT_STARTED = Any.new;
constant STARTED = Any.new;
my $master = NOT_STARTED;
await start {
    if cas($master, NOT_STARTED, STARTED) === NOT_STARTED {
        say "Master!"
    }
} xx 4

Will reliably only ever print Master! one time, as only one of the threads will be successful in changing the Scalar from NOT_STARTED to STARTED.

The second form, taking a code object, will first do an atomic fetch of the current value and invoke the code object with it. It will then try to do an atomic compare and swap of the target, using the value passed to the code object as $expected and the result of the code object as $value. If this fails, it will read the latest value, and retry, until a CAS operation succeeds.

Therefore, an item could be added to the head of a linked list in a lock free manner as follows:

class Node {
    has $.value;
    has Node $.next;
}
my Node $head = Node;
await start {
    for ^1000 -> $value {
        cas $head, -> $next { Node.new(:$value, :$next) }
    }
} xx 4;

This will reliably build up a linked list of 4000 items, with 4 nodes with each value ranging from 0 up to 999.

Operators

infix ⚛=

multi sub infix:<⚛=>($target is rw, $value)

Performs an atomic assignment of $value into the Scalar $target. The ⚛= operator ensures that any required barriers are performed such that the changed value will be "published" to other threads.

prefix ⚛

multi sub prefix:<⚛>($target is rw)

Performs an atomic read of the value in the Scalar $target and returns the read value. Using this operator instead of simply using the variable ensures that the latest update to the variable from other threads will be seen, both by doing any required hardware barriers and also preventing the compiler from lifting reads. For example:

my $started = False;
start { $started ⚛= True }
until ⚛$started { }

Is certain to terminate, while in:

my $started = False;
start { $started ⚛= True }
until $started { }

It would be legal for a compiler to observe that $started is not updated in the loop, and so lift the read out of the loop, thus causing the program to never terminate.

247 role Scheduler

Scheme for automatically assigning tasks to threads

role Scheduler {
    has &.uncaught_handler is rw
}

Common role for schedulers. A scheduler is a piece of code that determines which resources to use to run which task, and when.

Some operations for example on Proc::Async, Promise, Supply allow you to specify a scheduler explicitly; they generally expect those schedulers to follow the interface defined by Scheduler

Methods

method uncaught_handler

method uncaught_handler() is rw

RW-Accessor for the handler that is caught for uncaught exceptions from the code that is being scheduled and run.

method cue

method cue(&code, Instant :$at, :$in, :$every, :$times = 1; :&catch --> Cancellation)

Schedules a callable (&code) for execution and returns an instantiated Cancellation object to cancel the scheduling of the code for execution (which is especially important if you specify the every = time> named parameter. The adverbs control when and how the code is run:

$at can be an Instant before which the code won't be run. Alternatively $in is the number of seconds (possibly fractional) to wait before running the code. If $at is in the past or $in is negative, the delay is treated as zero. Implementations may equate to zero very small values (e.g. lower than 0.001s) of $in or result of $at - now.

If $every is specified, it is interpreted as the number of seconds (possibly fractional) to wait before re-executing the code. Implementations may treat too-small values as lowest resolution they support, possibly warning in such situations; e.g. treating 0.0001 as 0.001.

$times tells the scheduler how many times to run the code.

&catch is called with the Exception as its sole argument if &code dies.

If $at or $in are Inf, &code will never be run; if $every is Inf, &code will only be run once. If any of the three are -Inf, &code will be run immediately. If any of the three are NaN, an X::Scheduler::CueInNaNSeconds exception will be thrown. This only applies to releases 2019.05 and later.

One should call the cancel method on the returned Cancellation object to cancel the (possibly repeated) cueing of the code.

248 class Semaphore

Control access to shared resources by multiple threads

class Semaphore { }

Protect your shared code, data or device access using semaphores. An example is a printer manager managing a pool of printers without the need of storing print jobs when all printers are occupied. The next job is just blocked until a printer becomes available.

class print-manager {
  has Array $!printers;
  has Semaphore $!print-control;

  method BUILD( Int:D :$nbr-printers ) {
    for ^$nbr-printers -> $pc {
      $!printers[$pc] = { :name{"printer-$pc"} };
    }

    $!print-control .= new($nbr-printers);
  }

  method find-available-printer-and-print-it($job) { say "Is printed!"; }

  method print( $print-job ) {
    $!print-control.acquire;

    self.find-available-printer-and-print-it($print-job);

    $!print-control.release;
  }
}

Another example is a protection around code updating sensitive data. In such a case the semaphore is typically initialized to 1.

It is important to have a release on every exit of your program! While this is obvious, it is easy to fall in traps such as throwing an exception caused by some event. When the program dies there is no problem. When the exception is caught your program might eventually come back to the acquire method and will hang indefinitely.

Methods

method new

method new( int $permits )

Initialize the semaphore with the number of permitted accesses. E.g. when set to 2, program threads can pass the acquire method twice until it blocks on the third time acquire is called.

method acquire

method acquire()

Acquire access. When other threads have called the method before and the number of permits are used up, the process blocks until threads passed before releases the semaphore.

method try_acquire

method try_acquire(--> Bool)

Same as acquire but will not block. Instead it returns True if access is permitted or False otherwise.

method release

method release()

Release the semaphore raising the number of permissions. Any blocked thread will get access after that.

249 class Seq

An iterable, lazy sequence of values

class Seq is Cool does Iterable does PositionalBindFailover { }

A Seq represents anything that can lazily produce a sequence of values. A Seq is born in a state where iterating it will consume the values. However, calling .cache on a Seq will return a List that is still lazy, but stores the generated values for later access. However, assigning a Seq to an array consumes the Seq; alternatively, you can use the lazy statement prefix to avoid it from being iterated during the assignment:

# The Seq created by gather ... take is consumed on the spot here. 
 my @a = gather do { say 'consuming...'; take 'one' };  # OUTPUT: «consuming...␤» 
 
 # The Seq here is only consumed as we iterate over @a later. 
 my @a = lazy gather do { say 'consuming...'; take 'one' };  # outputs nothing. 
 .say for @a;  # OUTPUT: «consuming...␤one␤» 

A typical use case is method lines in IO::Handle, which could use a lot of memory if it stored all the lines read from the file. So

for open('README.md').lines -> $line { 
     say $line; 
 } 

won't keep all lines from the file in memory.

This implies that you cannot iterate the same Seq object twice (otherwise it couldn't throw away old values), so this dies:

my @a = 1, 2, 3;
my @b = <a b c>;
my \c = @a Z=> @b;
.say for c;
.say for c; # fails
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Seq::Consumed: This Seq has already been iterated, and its values consumed
# (you might solve this by adding .cache on usages of the Seq, or
# by assigning the Seq into an array)»

A high-level construct to generate a Seq is gather/take, as well as many built-in methods like map and grep, low-level constructors to create a Seq from an iterator or from looping constructs are available too.

Caution: No program should ever assume a Seq may only be iterated once even if not cached by the program. Caching is a volatile state exposed to the developer as an optimization. The Seq may become cached by many operations, including calling perl on the Seq (if called prior to a non-cached iteration). From version 6.d, you .perl can be called on consumed <Seq>. If a program assumes a Seq can only iterate once, but then is later changed to call one of these operations during the loop, that assumption will fail.

Methods

method new

method new(Iterator:D $iter --> Seq:D)

Creates a new Seq object from the iterator passed as the single argument.

method iterator

method iterator(Seq:D: --> Iterator:D)

Returns the underlying iterator, and marks the invocant as consumed. If called on an already consumed sequence, throws an error of type X::Seq::Consumed.

method is-lazy

method is-lazy(Seq:D: --> Bool:D)

Returns True if the sequence is lazy and potentially infinite, and False otherwise. If called on an already consumed sequence, throws an error of type X::Seq::Consumed.

method eager

method eager(Seq:D: --> List:D)

Returns an eagerly evaluated List based on the invocant sequence, and marks it as consumed. If called on an already consumed sequence, throws an error of type X::Seq::Consumed.

my $s = lazy 1..5;

say $s.is-lazy; # OUTPUT: «True␤»
say $s.eager;   # OUTPUT: «(1 2 3 4 5)␤»

say $s.eager;
CATCH {
    when X::Seq::Consumed {
        say 'Throws exception if already consumed';
    }
}
# OUTPUT: «Throws exception if already consumed␤»

method from-loop

multi method from-loop(&body --> Seq:D)
multi method from-loop(&body, &cond, :$repeat --> Seq:D)
multi method from-loop(&body, &cond, &afterward --> Seq:D)

These methods create new Seq-based callbacks.

The first form produces an infinite Seq by calling &body each time a new element is requested, using the return value from &body as the item. This emulates (or implements) a loop { body } construct.

The second form calls &cond before each call to &body, and terminates the sequence if &cond returns a false value. If $repeat is set to a true value, the first call to &cond is omitted, and &body called right away. This emulates (or implements) while cond { body } and repeat { body } while cond loops.

The third form enables C-style looping by calling a third callback, &afterward, after each call to &body.

method sink

Defined as:

method sink(--> Nil)

Calls sink-all if it is an Iterator, sink if the Sequence is a list.

say (1 ... 1000).sink; # OUTPUT: «Nil␤»

This is something you might want to do for the side effects of producing those values.

method skip

Defined as:

multi method skip(Int() $n = 1 --> Seq)

Returns a Seq containing whatever is left of the invocant after throwing away $n of the next available values. Negative values of $n count as 0. Also can take a WhateverCode to indicate how many values to skip from the end. Will block on lazy Seqs until the requested number of values have been discarded.

say (1..5).map({$_}).skip;      # OUTPUT: «(2,3,4,5)␤»
say (1..5).map({$_}).skip(3);   # OUTPUT: «(4,5)␤»
say (1..5).map({$_}).skip(5);   # OUTPUT: «()␤»
say (1..5).map({$_}).skip(-1);  # OUTPUT: «(1,2,3,4,5)␤»
say (1..5).map({$_}).skip(*-3); # OUTPUT: «(3,4,5)␤»

250 class Set

Immutable collection of distinct objects

class Set does Setty { }

A Set is an immutable set, meaning a collection of distinct elements in no particular order. (For mutable sets, see SetHash instead.)

Objects/values of any type are allowed as set elements. Within a Set, every element is guaranteed to be unique (in the sense that no two elements would compare positively with the === operator):

my $fruits = set <peach apple orange apple apple>; 
 
 say $fruits.elems;      # OUTPUT: «3␤» 
 say $fruits.keys.sort;  # OUTPUT: «apple orange peach␤» 

Sets can be treated as object hashes using the { } postcircumfix operator, which returns the value True for keys that are elements of the set, and False for keys that aren't:

my $fruits = set <peach apple orange apple apple>;
say $fruits<apple>;  # OUTPUT: «True␤»
say $fruits<kiwi>;   # OUTPUT: «False␤»

Creating Set objects

Sets can be composed using the set subroutine (or Set.new, for which it is a shorthand). Any positional parameters, regardless of their type, become elements of the set:

my $n = set "zero" => 0, "one" => 1, "two" => 2;
say $n.keys.perl;        # OUTPUT: «(:two(2), :zero(0), :one(1)).Seq␤»
say $n.keys.map(&WHAT);  # OUTPUT: «((Pair) (Pair) (Pair))␤»

Alternatively, the .Set coercer (or its functional form, Set()) can be called on an existing object to coerce it to a Set. Its semantics depend on the type and contents of the object. In general it evaluates the object in list context and creates a set with the resulting items as elements, although for Hash-like objects or Pair items, only the keys become elements of the set - and keys mapped to values which boolify to False are skipped:

my $n = ("zero" => 0, "one" => 1, "two" => 2).Set;
say $n.keys.perl;        # OUTPUT: «("one", "two").Seq␤»
say $n.keys.map(&WHAT);  # OUTPUT: «((Str) (Str))␤»

Furthermore, you can get a Set by using set operators (see next section) on objects of other types such as List, which will act like they internally call .Set on them before performing the operation. Be aware of the tight precedence of those operators though, which may require you to use parentheses around arguments:

say (1..5) (^) 4;  # OUTPUT: «set(1, 2, 3, 5)␤»

Of course, you can also create a Set with the .new method.

my $fruits = Set.new( <peach apple orange apple apple> );

Since 6.d (2019.03 and later) you can also use this syntax for parameterization of the Set, to specify which type of values are acceptable:

# only allow strings (Str) in the Set
my $fruits = Set[Str].new( <peach apple orange apple apple> );

# only allow whole numbers (Int) in the Set
my $fruits = Set[Int].new( <peach apple orange apple apple> );
# Type check failed in binding; expected Int but got Str ("peach")

Finally, you can create Set masquerading as a hash by using the is trait:

my %s is Set = <a b c>;
say %s<a>;  # True
say %s<d>;  # False

Since 6.d (2019.03 and later), this syntax also allows you to specify the type of values you would like to allow:

# limit to strings
my %s is Set[Str] = <a b c>;
say %s<a>;  # True
say %s<d>;  # False

# limit to whole numbers
my %s is Set[Int] = <a b c>;
# Type check failed in binding; expected Int but got Str ("a")

Operators

Perl 6 provides common set operators, which can take Sets (or any other collections) as input, and return result sets as new Set objects. For example:

my ($a, $b) = set(1, 2, 3), set(2, 4); 
 
 say $a (<) $b;  # OUTPUT: «False␤» 
 say $a (&) $b;  # OUTPUT: «set(2)␤» 
 say $a (^) $b;  # OUTPUT: «set(1, 3, 4)␤» 
 
 # Unicode versions: 
 say $a ⊂ $b;  # OUTPUT: «False␤» 
 say $a ∩ $b;  # OUTPUT: «set(2)␤» 
 say $a ⊖ $b;  # OUTPUT: «set(1, 3, 4)␤» 

See Set/Bag Operators for a complete list of set operators with detailed explanations.

Subroutines

sub set

sub set(*@args --> Set)

Creates a Set from the given @args

See Also

Sets, Bags, and Mixes

251 class SetHash

Mutable collection of distinct objects

class SetHash does Setty { }

A SetHash is a mutable set, meaning a collection of distinct elements in no particular order. (For immutable sets, see Set instead.)

Objects/values of any type are allowed as set elements. Within a Set, every element is guaranteed to be unique (in the sense that no two elements would compare positively with the === operator):

my $fruits = <peach apple orange apple apple>.SetHash; 
 
 say $fruits.elems;      # OUTPUT: «3␤» 
 say $fruits.keys.sort;  # OUTPUT: «apple orange peach␤» 

SetHashes can be treated as object hashes using the { } postcircumfix operator, which returns the value True for keys that are elements of the set, and False for keys that aren't. Assigning a value that boolifies to True or False, respectively, can be used to add or remove a set element:

my $fruits = <peach apple orange apple apple>.SetHash; 
 
 say $fruits<apple>;     # OUTPUT: «True␤» 
 say $fruits<kiwi>;      # OUTPUT: «False␤» 
 
 $fruits<apple kiwi> = False, True; 
 say $fruits.keys.sort;  # OUTPUT: «kiwi orange peach␤» 

Here is a convenient shorthand idiom for adding and removing SetHash elements:

my SetHash $fruits .= new; 
 say $fruits<cherry>;      # OUTPUT: «False␤» 
 $fruits<cherry>++; 
 say $fruits<cherry>;      # OUTPUT: «True␤» 
 $fruits<apple banana kiwi>»++; # Add multiple elements 
 
 $fruits<cherry>--; 
 say $fruits<cherry>;      # OUTPUT: «False␤» 
 $fruits<banana kiwi>»--; # Remove multiple elements 
 

Creating SetHash objects

SetHashes can be composed using SetHash.new. Any positional parameters, regardless of their type, become elements of the set:

my $n = SetHash.new: "zero" => 0, "one" => 1, "two" => 2;
say $n.keys.perl;        # OUTPUT: «(:two(2), :zero(0), :one(1)).Seq␤»
say $n.keys.map(&WHAT);  # OUTPUT: «((Pair) (Pair) (Pair))␤»

Alternatively, the .SetHash coercer (or its functional form, SetHash()) can be called on an existing object to coerce it to a SetHash. Its semantics depend on the type and contents of the object. In general it evaluates the object in list context and creates a set with the resulting items as elements, although for Hash-like objects or Pair items, only the keys become elements of the set - and keys mapped to values which boolify to False are skipped:

my $n = ("zero" => 0, "one" => 1, "two" => 2).SetHash;
say $n.keys.perl;        # OUTPUT: «("one", "two").Seq␤»
say $n.keys.map(&WHAT);  # OUTPUT: «((Str) (Str))␤»

It is also possible to initialize a single key with the use of {}:

my $sh = SetHash.new;
$sh{ 'key1' } = True;
$sh{ 'key2' } = 'Hello World!';
$sh{ 'key3' } = 0;  # does not store the key since 0.Bool is False
say $sh;            # OUTPUT: «SetHash(key1 key2)␤»
say $sh.keys.perl;  # OUTPUT: «("key1", "key2").Seq␤»

or, in order to initialize more than one key at the same time, use a list assignment:

my $sh = SetHash.new;
$sh{ 'a', 'b', 'c' } = True, False, True;
say $sh.keys.perl;  # OUTPUT: «("a", "c").Seq␤»

You can also create SetHash masquerading as a hash by using the is trait:

my %sh is SetHash = <a b c>;
say %sh<a>;  # True
say %sh<d>;  # False

Since 6.d (2019.03 and later) it is also possible to specify the type of values you would like to allow in a SetHash. This can either be done when calling .new:

# only allow Pairs
my $n = SetHash[Pair].new: "zero" => 0, "one" => 1, "two" => 2;

or using the masquerading syntax:

# only allow strings
my %sh is SetHash[Str] = <a b c>;
say %sh<a>;  # True
say %sh<d>;  # False

# only allow whole numbers
my %sh is SetHash[Int] = <a b c>;
# Type check failed in binding; expected Int but got Str ("a")

Operators

Perl 6 provides common set operators, which can take SetHashes (or any other collections) as input, although result sets are returned as immutable Sets. For example:

my ($a, $b) = SetHash.new(1, 2, 3), SetHash.new(2, 4); 
 
 say $a (<) $b;  # OUTPUT: «False␤» 
 say $a (&) $b;  # OUTPUT: «set(2)␤» 
 say $a (^) $b;  # OUTPUT: «set(1, 3, 4)␤» 
 say $a (|) $b;  # OUTPUT: «set(1, 2, 3, 4)␤» 
 
 # Unicode versions: 
 say $a ⊂ $b;  # OUTPUT: «False␤» 
 say $a ∩ $b;  # OUTPUT: «set(2)␤» 
 say $a ⊖ $b;  # OUTPUT: «set(1, 3, 4)␤» 
 say $a ∪ $b;  # OUTPUT: «set(1, 2, 3, 4)␤» 

See Set/Bag Operators for a complete list of set operators with detailed explanations.

See Also

Sets, Bags, and Mixes

252 role Setty

Collection of distinct objects

role Setty does QuantHash { }

A role for collections which make sure that each element can only appear once. See Set and SetHash.

Methods

method new-from-pairs

Defined as:

method new-from-pairs(*@pairs --> Setty:D)

Constructs a Setty object from a list of Pair objects given as positional arguments:

say Set.new-from-pairs: 'butter' => 0.22, 'salt' => 0, 'sugar' => 0.02;
# OUTPUT: «set(butter, sugar)␤»

Note: be sure you aren't accidentally passing the Pairs as positional arguments; the quotes around the keys in the above example are significant.

method grab

method grab($count = 1)

Removes and returns $count elements chosen at random (without repetition) from the set.

If * is passed as $count, or $count is greater than or equal to the size of the set, then all its elements are removed and returned in random order.

Only works on mutable sets; When used on an immutable set, it results in an exception.

method grabpairs

method grabpairs($count = 1)

Removes $count elements chosen at random (without repetition) from the set, and returns a list of Pair objects whose keys are the grabbed elements and whose values are True.

If * is passed as $count, or $count is greater than or equal to the size of the set, then all its elements are removed and returned as Pairs in the aforementioned way in random order.

Only works on mutable sets; When used on an immutable set, it results in an exception.

method pick

multi method pick($count = 1)

Returns $count elements chosen at random (without repetition) from the set.

If * is passed as $count, or $count is greater than or equal to the size of the set, then all its elements are returned in random order (shuffled).

method pickpairs

Defined as:

multi method pickpairs(Setty:D: --> Pair:D)
multi method pickpairs(Setty:D: $count --> Seq:D)

Returns a Pair or a Seq of Pairs depending on the candidate of the method being invoked. Each Pair returned has an element of the invocant as its key and True as its value. In contrast to grabpairs, the elements are 'picked' without replacement.

If * is passed as $count, or $count is greater than or equal to the number of elements of the invocant, then all element/True Pairs from the invocant are returned in a random sequence; i.e. they are returned shuffled;

Note that each pickpairs invocation maintains its own private state and has no effect on subsequent pickpairs invocations.

my $numbers = set (4, 2, 3);
say $numbers.pickpairs;                           # OUTPUT: «4 => True␤»
say $numbers.pickpairs(1);                        # OUTPUT: «(3 => True)␤»
say $numbers.pickpairs(*);                        # OUTPUT: «(2 => True 4 => True 3 => True)␤»

method roll

multi method roll($count = 1)

Returns a lazy list of $count elements, each randomly selected from the set. Each random choice is made independently, like a separate die roll where each die face is a set element.

If * is passed as $count, the list is infinite.

method antipairs

Defined as:

multi method antipairs(Setty:D: --> Seq:D)

Returns all elements in the set and True as a Seq of Pairs, where the element itself is the value, i.e. the opposite of method pairs.

my $s = Set.new(1, 2, 3, 1);
say $s.antipairs.sort;                            # OUTPUT: «(True => 1 True => 2 True => 3)␤»

method keys

Defined as:

multi method keys(Setty:D: --> Seq:D)

Returns a Seq of all elements of the set.

my $s = Set.new(1, 2, 3);
say $s.keys;                                      # OUTPUT: «(3 1 2)␤»

method values

Defined as:

multi method values(Setty:D: --> Seq:D)

Returns a Seq containing as many True values as the set has elements.

my $s = Set.new(1, 2, 3);
say $s.values;                                    # OUTPUT: «(True True True)␤»

method kv

Defined as:

multi method kv(Setty:D: --> Seq:D)

Returns a Seq of the set's elements and True values interleaved.

my $s = Set.new(1, 2, 3);
say $s.kv;                                        # OUTPUT: «(3 True 1 True 2 True)␤»

method elems

method elems(--> Int)

The number of elements of the set.

method total

method total(--> Int)

The total of all the values of the QuantHash object. For a Setty object, this is just the number of elements.

method minpairs

Defined As:

multi method minpairs(Setty:D: --> Seq:D)

Returns the value of self.pairs (as all Pairs have minimum values). See also Any.minpairs

method maxpairs

Defined As:

multi method maxpairs(Setty:D: --> Seq:D)

Returns the value of self.pairs (as all Pairs have maximum values). See also Any.maxpairs

method default

Defined as:

method default(--> False)

Returns the default value of the invocant, i.e. the value which is returned when trying to access an element in the Setty object which has not been previously initialized or when accessing an element which has explicitly been set to Nil or False.

my $s1 = SetHash.new(1, 2, 3);
say $s1{2};                                           # OUTPUT: «True␤»
$s1{2} = Nil;
say $s1{2};                                           # OUTPUT: «False␤»
# access non initialized element
say $s1{4};                                           # OUTPUT: «False␤»

method ACCEPTS

method ACCEPTS($other)

Returns True if $other and self contain all the same elements, and no others.

method Bag

Defined as:

method Bag(Setty:D: --> Bag:D)

Returns a Bag containing the elements of the invocant.

my Bag $b = Set.new(1, 2, 3).Bag;
say $b;                                           # OUTPUT: «bag(3, 1, 2)␤»

method BagHash

Defined as:

method BagHash(Setty:D: --> BagHash:D)

Returns a BagHash containing the elements of the invocant.

my BagHash $b = Set.new(1, 2, 3).BagHash;
say $b;                                           # OUTPUT: «BagHash.new(3, 1, 2)␤»

method Bool

Defined as:

multi method Bool(Setty:D: --> Bool:D)

Returns True if the invocant contains at least one element.

my $s1 = Set.new(1, 2, 3);
say $s1.Bool;                                     # OUTPUT: «True␤»

my $s2 = $s1 ∩ Set.new(4, 5);                     # set intersection operator
say $s2.Bool;                                     # OUTPUT: «False␤»

method Mix

Defined as:

method Mix(Setty:D: --> Mix:D)

Returns a Mix containing the elements of the invocant.

my Mix $b = Set.new(1, 2, 3).Mix;
say $b;                                           # OUTPUT: «mix(3, 1, 2)␤»

method MixHash

Defined as:

method MixHash(Setty:D: --> MixHash:D)

Returns a MixHash containing the elements of the invocant.

my MixHash $b = Set.new(1, 2, 3).MixHash;
say $b;                                           # OUTPUT: «MixHash.new(3, 1, 2)␤»

See Also

Sets, Bags, and Mixes

253 class Signature

Parameter list pattern

class Signature { }

A signature is a static description of the parameter list of a code object. That is, it describes what and how many arguments you need to pass to the code or function in order to call it.

Passing arguments to a signature binds the arguments, contained in a Capture, to the signature.

Signature literals

Signatures appear inside parentheses after subroutine and method names, on blocks after a -> or <-> arrow, as the input to variable declarators like my, or as a separate term starting with a colon.

sub f($x) { }
#    ^^^^ Signature of sub f
my method x() { }
#          ^^ Signature of a method
my $s = sub (*@a) { }
#           ^^^^^ Signature of an anonymous function

for <a b c> -> $x { }
#              ^^   Signature of a Block

my ($a, @b) = 5, (6, 7, 8);
#  ^^^^^^^^ Signature of a variable declarator

my $sig = :($a, $b);
#          ^^^^^^^^ Standalone Signature object

Signature literals can be used to define the signature of a callback or a closure.

sub f(&c:(Int)) { }
sub will-work(Int) { }
sub won't-work(Str) { }
f(&will-work);

f(&won't-work);
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::TypeCheck::Binding::Parameter: Constraint type check failed in binding to parameter '&c'␤»

f(-> Int { 'this works too' } );

Smartmatching signatures against a List is supported.

my $sig = :(Int $i, Str $s);
say (10, 'answer') ~~ $sig;
# OUTPUT: «True␤»
my $sub = sub ( Str $s, Int $i ) { return $s xx $i };
say $sub.signature ~~ :( Str, Int );
# OUTPUT: «True␤»
given $sig {
    when :(Str, Int) { say 'mismatch' }
    when :($, $)     { say 'match' }
    default          { say 'no match' }
}
# OUTPUT: «match␤»

It matches the second when clause since :($, $) represents a Signature with two scalar, anonymous, arguments, which is a more general version of $sig.

When smartmatching against a Hash, the signature is assumed to consist of the keys of the Hash.

my %h = left => 1, right => 2;
say %h ~~ :(:$left, :$right);
# OUTPUT: «True␤»

Parameter separators

A signature consists of zero or more parameters, separated by commas.

my $sig = :($a, @b, %c);
sub add($a, $b) { $a + $b };

As an exception the first parameter may be followed by a colon instead of a comma to mark the invocant of a method. The invocant is the object that was used to call the method, which is usually bound to self. By specifying it in the signature, you can change the variable name it is bound to.

method ($a: @b, %c) {};       # first argument is the invocant

class Foo {
    method whoami($me:) {
        "Well I'm class $me.^name(), of course!"
    }
}
say Foo.whoami; # OUTPUT: «Well I'm class Foo, of course!␤»

Type constraints

Parameters can optionally have a type constraint (the default is Any). These can be used to restrict the allowed input to a function.

my $sig = :(Int $a, Str $b); 

Type constraints can have any compile-time defined value

subset Positive-integer of Int where * > 0; 
 sub divisors(Positive-integer $n) { $_ if $n %% $_ for 1..$n }; 
 divisors 2.5; 
 # ERROR «Type check failed in binding to parameter '$n'; 
 # expected Positive-integer but got Rat (2.5) $n)» 
 divisors -3; 
 # ERROR: «Constraint type check failed in binding to parameter '$n'; 
 # expected Positive-integer but got Int (-3)» 

Please note that in the code above type constraints are enforced at two different levels: the first level checks if it belongs to the type in which the subset is based, in this case Int. If it fails, a Type check error is produced. Once that filter is cleared, the constraint that defined the subset is checked, producing a Constraint type check error if it fails.

Anonymous arguments are fine too, if you don't actually need to refer to a parameter by name, for instance to distinguish between different signatures in a multi or to check the signature of a Callable.

my $sig = :($, @, %a);          # two anonymous and a "normal" parameter
$sig = :(Int, Positional);      # just a type is also fine (two parameters)
sub baz(Str) { "Got passed a Str" }

Type constraints may also be type captures.

In addition to those nominal types, additional constraints can be placed on parameters in the form of code blocks which must return a true value to pass the type check

sub f(Real $x where { $x > 0 }, Real $y where { $y >= $x }) { }

The code in where clauses has some limitations: anything that produces side-effects (e.g., printing output, pulling from an iterator, or increasing a state variable) is not supported and may produce surprising results if used. Also, the code of the where clause may run more than once for a single typecheck in some implementations.

The where clause doesn't need to be a code block, anything on the right of the where-clause will be used to smartmatch the argument against it. So you can also write:

multi factorial(Int $ where 0) { 1 }
multi factorial(Int $x)        { $x * factorial($x - 1) }

The first of those can be shortened to

multi factorial(0) { 1 }

i.e., you can use a literal directly as a type and value constraint on an anonymous parameter.

Tip: pay attention to not accidentally leave off a block when you, say, have several conditions:

-> $y where   .so && .name    {}( sub one   {} ); # WRONG!!
-> $y where { .so && .name }  {}( sub two   {} ); # OK!
-> $y where   .so &  .name.so {}( sub three {} ); # Also good

The first version is wrong and will issue a warning about a sub object coerced to string. The reason is the expression is equivalent to ($y ~~ ($y.so && $y.name)); that is "call .so, and if that is True, call .name; if that is also True use its value for smartmatching…". It's the result of (.so && .name) it will be smartmatched against, but we want to check that both .so and .name are truthy values. That is why an explicit Block or a Junction is the right version.

All previous arguments that are not part of a sub-signature in a Signature are accessible in a where-clause that follows an argument. Therefore, the where-clause of the last argument has access to all arguments of a signature that are not part of a sub-signature. For a sub-signature place the where-clause inside the sub-signature.

sub foo($a, $b where * == $a ** 2) { say "$b is a square of $a" }
foo 2, 4; # OUTPUT: «4 is a square of 2␤»»
# foo 2, 3;
# OUTPUT: «Constraint type check failed in binding to parameter '$b'…»

Constraining optional arguments

Optional arguments can have constraints, too. Any where clause on any parameter will be executed, even if it's optional and not provided by the caller. In that case you may have to guard against undefined values within the where clause.

sub f(Int $a, UInt $i? where { !$i.defined or $i > 5 }) { ... }

Constraining slurpy arguments

Slurpy arguments can not have type constraints. A where-clause in conjunction with a Junction can be used to that effect.

sub f(*@a where {$_.all ~~ Int}) { say @a }; 
 f(42); 
 f(<a>); 
 CATCH { default { say .^name, ' ==> ', .Str }  } 
 # OUTPUT: «[42]␤Constraint type check failed in binding to parameter '@a' ...» 

Constraining named arguments

Constraints against Named arguments apply to the value part of the colon-pair.

sub f(Int :$i){};
f :i<forty-two>;
CATCH { default { say .^name, ' ==> ', .Str }  }
# OUTPUT: «X::TypeCheck::Binding::Parameter ==> Type check failed in
# binding to parameter '$i'; expected Int but got Str ("forty-two")␤»

Constraining argument definiteness

Normally, a type constraint only checks whether the value of the parameter is of the correct type. Crucially, both object instances and type objects will satisfy such a constraint as illustrated below:

say  42.^name;    # OUTPUT: «Int␤»
say  42 ~~ Int;   # OUTPUT: «True␤»
say Int ~~ Int;   # OUTPUT: «True␤»

Note how both 42 and Int satisfy the match.

Sometimes we need to distinguish between these object instances (42) and type objects (Int). Consider the following code:

sub limit-lines(Str $s, Int $limit) {
    my @lines = $s.lines;
    @lines[0 .. min @lines.elems, $limit].join("\n")
}
say (limit-lines "a \n b \n c \n d \n", 3).perl; # "a \n b \n c \n d "
say limit-lines Str, 3;
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Multi::NoMatch: Cannot resolve caller lines(Str: );
# none of these signatures match:
#     (Str:D $: :$count!, *%_)
#     (Str:D $: $limit, *%_)
#     (Str:D $: *%_)»
say limit-lines "a \n b", Int; # Always returns the max number of lines

Here we really only want to deal with string instances, not type objects. To do this, we can use the :D type constraint. This constraint checks that the value passed is an object instance, in a similar fashion to calling its DEFINITE (meta)method.

To warm up, let's apply :D to the right-hand side of our humble Int example:

say  42 ~~ Int:D;  # OUTPUT: «True␤»
say Int ~~ Int:D;  # OUTPUT: «False␤»

Note how only 42 matches Int:D in the above.

Returning to limit-lines, we can now amend its signature to catch the error early:

sub limit-lines(Str:D $s, Int $limit) { };
say limit-lines Str, 3;
CATCH { default { put .^name ~ '--' ~ .Str } };
# OUTPUT: «Parameter '$s' of routine 'limit-lines' must be an object instance of type 'Str',
#          not a type object of type 'Str'.  Did you forget a '.new'?»

This is much better than the way the program failed before, since here the reason for failure is clearer.

It's also possible that type objects are the only ones that make sense for a routine to accept. This can be done with the :U type constraint, which checks whether the value passed is a type object rather than an object instance. Here's our Int example again, this time with :U applied:

say  42 ~~ Int:U;  # OUTPUT: «False␤»
say Int ~~ Int:U;  # OUTPUT: «True␤»

Now 42 fails to match Int:U while Int succeeds.

Here's a more practical example:

sub can-turn-into(Str $string, Any:U $type) {
   return so $string.$type;
}
say can-turn-into("3", Int);        # OUTPUT: «True␤»
say can-turn-into("6.5", Int);      # OUTPUT: «True␤»
say can-turn-into("6.5", Num);      # OUTPUT: «True␤»
say can-turn-into("a string", Num); # OUTPUT: «False␤»

Calling can-turn-into with an object instance as its second parameter will yield a constraint violation as intended:

say can-turn-into("a string", 123); 
 # OUTPUT: «Parameter '$type' of routine 'can-turn-into' must be a type object 
 # of type 'Any', not an object instance of type 'Int'...» 

For explicitly indicating the normal behavior, that is, not constraining whether the argument will be an instance or a type object, :_ can be used, but this is unnecessary. :(Num:_ $) is the same as :(Num $).

To recap, here is a quick illustration of these type constraints, also known collectively as type smileys:

# Checking a type object
say Int ~~ Any:D;    # OUTPUT: «False␤»
say Int ~~ Any:U;    # OUTPUT: «True␤»
say Int ~~ Any:_;    # OUTPUT: «True␤»

# Checking an object instance
say 42 ~~ Any:D;     # OUTPUT: «True␤»
say 42 ~~ Any:U;     # OUTPUT: «False␤»
say 42 ~~ Any:_;     # OUTPUT: «True␤»

# Checking a user-supplied class
class Foo {};
say Foo ~~ Any:D;    # OUTPUT: «False␤»
say Foo ~~ Any:U;    # OUTPUT: «True␤»
say Foo ~~ Any:_;    # OUTPUT: «True␤»

# Checking an instance of a class
my $f = Foo.new;
say $f  ~~ Any:D;    # OUTPUT: «True␤»
say $f  ~~ Any:U;    # OUTPUT: «False␤»
say $f  ~~ Any:_;    # OUTPUT: «True␤»

The Classes and Objects document further elaborates on the concepts of instances and type objects and discovering them with the .DEFINITE method.

Keep in mind all parameters have values; even optional ones have default values that are the type object of the constrained type for explicit type constraints. If no explicit type constraint exists, the default value is an Any type object for methods, submethods, and subroutines, and a Mu type object for blocks. This means that if you use the :D type smiley, you'd need to provide a default value or make the parameter required. Otherwise, the default value would be a type object, which would fail the definiteness constraint.

sub divide (Int:D :$a = 2, Int:D :$b!) { say $a/$b }
divide :1a, :2b; # OUTPUT: «0.5␤»

The default value will kick in when that particular parameter, either positional or named, gets no value at all.

sub f($a = 42){
  my $b is default('answer');
  say $a;
  $b = $a;
  say $b
};
f;     # OUTPUT: «42␤42␤»
f Nil; # OUTPUT: «Nil␤answer␤»

$a has 42 as its default value. With no value, $a will be assigned the default value declared in the Signature. However, in the second case, it does receive a value, which happens to be Nil. Assigning Nil to any variable resets it to its default value, which has been declared as 'answer' by use of the default trait. That explains what happens the second time we call f. Routine parameters and variables deal differently with default value, which is in part clarified by the different way default values are declared in each case (using = for parameters, using the default trait for variables).

Note: in 6.c language, the default value of :U/:D constrained variables was a type object with such a constraint, which is not initializable, thus you cannot use the .= operator, for example.

use v6.c; 
 my Int:D $x .= new: 42; 
 # OUTPUT: You cannot create an instance of this type (Int:D) 
 # in block <unit> at -e line 1 

In the 6.d language, the default default is the type object without the smiley constraint:

use v6.d; 
 my Int:D $x .= new: 42; # OUTPUT: «42␤» 

A closing remark on terminology: this section is about the use of the type smileys :D and :U to constrain the definiteness of arguments. Occasionally definedness is used as a synonym for definiteness; this may be confusing, since the terms have subtly different meanings.

As explained above, definiteness is concerned with the distinction between type objects and object instances. A type object is always indefinite, while an object instance is always definite. Whether an object is a type object/indefinite or an object instance/definite can be verified using the DEFINITE (meta)method.

Definiteness should be distinguished from definedness, which is concerned with the difference between defined and undefined objects. Whether an object is defined or undefined can be verified using the defined-method, which is implemented in class Mu. By default a type object is considered undefined, while an object instance is considered defined; that is: .defined returns False on a type object, and True otherwise. But this default behavior may be overridden by subclasses. An example of a subclass that overrides the default .defined behavior is Failure, so that even an instantiated Failure acts as an undefined value:

my $a = Failure;                # Initialize with type object
my $b = Failure.new("foo");     # Initialize with object instance
say $a.DEFINITE;                # Output: «False␤» : indefinite type object
say $b.DEFINITE;                # Output: «True␤»  : definite object instance
say $a.defined;                 # Output: «False␤» : default response
say $b.defined;                 # Output: «False␤» : .defined override

Constraining signatures of Callables

The signature of a Callable parameter can be constrained by specifying a Signature literal right after the parameter (no whitespace allowed):

sub f(&c:(Int, Str))  { say c(10, 'ten') };
sub g(Int $i, Str $s) { $s ~ $i };
f(&g);
# OUTPUT: «ten10␤»

This shorthand syntax is available only for parameters with the & sigil. For others, you need to use the long version:

sub f($c where .signature ~~ :(Int, Str))  { say $c(10, 'ten') }
sub g(Num $i, Str $s) { $s ~ $i }
sub h(Int $i, Str $s) { $s ~ $i }
# f(&g); # Constraint type check failed
f(&h);   # OUTPUT: «ten10␤»

Constraining return types

There are multiple ways to constrain return types on a Routine. All versions below are currently valid and will force a type check on successful execution of a routine.

Nil and Failure are always allowed as return types, regardless of any type constraint. This allows Failure to be returned and passed on down the call chain.

sub foo(--> Int) { Nil };
say foo.perl; # OUTPUT: «Nil␤»

Type captures are not supported.

Return type arrow: -->

This form of indicating return types (or constants) in the signature is preferred, since it can handle constant values while the others can't. For consistency, it is the only form accepted on this site.

The return type arrow has to be placed at the end of the parameter list, with or without a , before it.

sub greeting1(Str $name  --> Str) { say "Hello, $name" } # Valid 
 sub greeting2(Str $name, --> Str) { say "Hello, $name" } # Valid 
 
 sub favorite-number1(--> 42) {        } # OUTPUT: 42 
 sub favorite-number2(--> 42) { return } # OUTPUT: 42 

If the type constraint is a constant expression, it is used as the return value of the routine. Any return statement in that routine has to be argumentless.

sub foo(Str $word --> 123) { say $word; return; } 
 my $value = foo("hello"); # OUTPUT: hello 
 say $value;               # OUTPUT: 123 
# The code below will not compile 
 sub foo(Str $word --> 123) { say $word; return $word; } 
 my $value = foo("hello"); 
 say $value; 

returns

The keyword returns following a signature declaration has the same function as --> with the caveat that this form does not work with constant values. You cannot use it in a block either. That is why the pointy arrow form is always preferred.

sub greeting(Str $name) returns Str { say "Hello, $name" } # Valid 
sub favorite-number returns 42 {        } # This will fail. 

of

of is just the real name of the returns keyword.

sub foo() of Int { 42 }; # Valid 
sub foo() of 42 {  };    # This will fail. 

prefix(C-like) form

This is similar to placing type constraints on variables like my Type $var = 20;, except the $var is a definition for a routine.

my Int sub bar { 1 };     # Valid 
my 42 sub bad-answer {};  # This will fail. 

Coercion type

To accept one type but coerce it automatically to another, use the accepted type as an argument to the target type. If the accepted type is Any it can be omitted.

sub f(Int(Str) $want-int, Str() $want-str) {
    say $want-int.^name ~ ' ' ~ $want-str.^name
}
f '10', 10;
# OUTPUT: «Int Str␤»

use MONKEY;
augment class Str { method Date() { Date.new(self) } };
sub foo(Date(Str) $d) { say $d.^name; say $d };
foo "2016-12-01";
# OUTPUT: «Date␤2016-12-01␤»

The coercion is performed by calling the method with the name of the type to coerce to, if it exists (e.g. Foo(Bar) coercer, would call method Foo). The method is assumed to return the correct type—no additional checks on the result are currently performed.

Coercion can also be performed on return types:

sub square-str (Int $x --> Str(Int)) { 
     $x² 
 } 
 
 for 2,4, *²  … 256 -> $a { 
     say $a, "² is ", square-str( $a ).chars, " figures long"; 
 } 
 
 # OUTPUT: «2² is 1 figures long␤ 
 #          4² is 2 figures long␤ 
 #          16² is 3 figures long␤ 
 #          256² is 5 figures long␤» 

In this example, coercing the return type to String allows us to directly apply string methods, such as the number of characters.

Slurpy (A.K.A. variadic) parameters

A function is variadic if it can take a varying number of arguments; that is, its arity is not fixed. Therefore, optional, named, and slurpy parameters are variadic. An array or hash parameter can be marked as slurpy by leading single (*) or double asterisk (**) or a leading plus (+). A slurpy parameter can bind to an arbitrary number of arguments (zero or more), and it will result in a type that is compatible with the sigil.

These are called "slurpy" because they slurp up any remaining arguments to a function, like someone slurping up noodles.

$ = :($a, @b);  # exactly two arguments, where the second one must be Positional 
 $ = :($a, *@b); # at least one argument, @b slurps up any beyond that 
 $ = :(*%h);     # no positional arguments, but any number of named arguments 
 
 sub one-arg (@)  { } 
 sub slurpy  (*@) { } 
 one-arg (5, 6, 7); # ok, same as one-arg((5, 6, 7)) 
 slurpy  (5, 6, 7); # ok 
 slurpy   5, 6, 7 ; # ok 
 # one-arg(5, 6, 7) ; # X::TypeCheck::Argument 
 # one-arg  5, 6, 7 ; # X::TypeCheck::Argument 
 
 sub named-names (*%named-args) { %named-args.keys }; 
 say named-names :foo(42) :bar<baz>; # OUTPUT: «foo bar␤» 

Positional and named slurpies can be combined; named arguments (i.e., Pairs) are collected in the specified hash, positional arguments in the array:

sub combined-slurpy (*@a, *%h) { { array => @a, hash => %h } } 
 # or: sub combined-slurpy (*%h, *@a) { ... } 
 
 say combined-slurpy(one => 1, two => 2); 
 # OUTPUT: «{array => [], hash => {one => 1, two => 2}}␤» 
 say combined-slurpy(one => 1, two => 2, 3, 4); 
 # OUTPUT: «{array => [3 4], hash => {one => 1, two => 2}}␤» 
 say combined-slurpy(one => 1, two => 2, 3, 4, five => 5); 
 # OUTPUT: «{array => [3 4], hash => {five => 5, one => 1, two => 2}}␤» 
 say combined-slurpy(one => 1, two => 2, 3, 4, five => 5, 6); 
 # OUTPUT: «{array => [3 4 6], hash => {five => 5, one => 1, two => 2}}␤» 

Note that positional parameters aren't allowed after slurpy parameters:

:(*@args, $last); 
 # ===SORRY!=== Error while compiling: 
 # Cannot put required parameter $last after variadic parameters 

Normally a slurpy parameter will create an Array (or compatible type), create a new Scalar container for each argument, and assign the value from each argument to those Scalars. If the original argument also had an intermediary Scalar it is bypassed during this process, and is not available inside the called function.

Sigiled parameters will always impose a context on the collected arguments. Sigilless parameters can also be used slurpily, preceded by a + sign, to work with whatever initial type they started with:

sub zipi( +zape ) { 
     zape.^name => zape 
 }; 
 say zipi( "Hey "); # OUTPUT: «List => (Hey )␤» 
 say zipi( 1...* ); # OUTPUT: «Seq => (...)␤» 

Slurpy parameters have special behaviors when combined with some traits and modifiers, as described in the section on slurpy array parameters.

Types of slurpy array parameters

There are three variations to slurpy array parameters.

Each will be described in detail in the next few sections. As the difference between each is a bit nuanced, examples are provided for each to demonstrate how each slurpy convention varies from the others.

Flattened slurpy

Slurpy parameters declared with one asterisk will flatten arguments by dissolving one or more layers of bare Iterables.

my @array = <a b c>; 
 my $list := <d e f>; 
 sub a(*@a)  { @a.perl.say }; 
 a(@array);                 # OUTPUT: «["a", "b", "c"]» 
 a(1, $list, [2, 3]);       # OUTPUT: «[1, "d", "e", "f", 2, 3]» 
 a([1, 2]);                 # OUTPUT: «[1, 2]» 
 a(1, [1, 2], ([3, 4], 5)); # OUTPUT: «[1, 1, 2, 3, 4, 5]» 
 a(($_ for 1, 2, 3));       # OUTPUT: «[1, 2, 3]» 

A single asterisk slurpy flattens all given iterables, effectively hoisting any object created with commas up to the top level.

Unflattened slurpy

Slurpy parameters declared with two stars do not flatten any Iterable arguments within the list, but keep the arguments more or less as-is:

my @array = <a b c>; 
 my $list := <d e f>; 
 sub b(**@b) { @b.perl.say }; 
 b(@array);                 # OUTPUT: «[["a", "b", "c"],]␤» 
 b(1, $list, [2, 3]);       # OUTPUT: «[1, ("d", "e", "f"), [2, 3]]␤» 
 b([1, 2]);                 # OUTPUT: «[[1, 2],]␤» 
 b(1, [1, 2], ([3, 4], 5)); # OUTPUT: «[1, [1, 2], ([3, 4], 5)]␤» 
 b(($_ for 1, 2, 3));       # OUTPUT: «[(1, 2, 3),]␤» 

The double asterisk slurpy hides the nested comma objects and leaves them as-is in the slurpy array.

Single argument rule slurpy

A slurpy parameter created using a plus engages the "single argument rule", which decides how to handle the slurpy argument based upon context. Basically, if only a single argument is passed and that argument is Iterable, that argument is used to fill the slurpy parameter array. In any other case, +@ works like **@.

my @array = <a b c>; 
 my $list := <d e f>; 
 sub c(+@b) { @b.perl.say }; 
 c(@array);                 # OUTPUT: «["a", "b", "c"]␤» 
 c(1, $list, [2, 3]);       # OUTPUT: «[1, ("d", "e", "f"), [2, 3]]␤» 
 c([1, 2]);                 # OUTPUT: «[1, 2]␤» 
 c(1, [1, 2], ([3, 4], 5)); # OUTPUT: «[1, [1, 2], ([3, 4], 5)]␤» 
 c(($_ for 1, 2, 3));       # OUTPUT: «[1, 2, 3]␤» 

For additional discussion and examples, see Slurpy Conventions for Functions.

Type captures

Type captures allow deferring the specification of a type constraint to the time the function is called. They allow referring to a type both in the signature and the function body.

sub f(::T $p1, T $p2, ::C){
    # $p1 and $p2 are of the same type T, that we don't know yet
    # C will hold a type we derive from a type object or value
    my C $division = $p1 / $p2;
    return sub (T $p1) {
        $division * $p1;
    }
}

# The first parameter is Int and so must be the 2nd.
# We derive the 3rd type from calling the operator that is used in &f.
my &s = f(10, 2, Int.new / Int.new);
say s(2); # 10 / 2 * 2 == 10

Positional vs. named arguments

An argument can be positional or named. By default, arguments are positional, except slurpy hash and arguments marked with a leading colon :. The latter is called a colon-pair. Check the following signatures and what they denote:

$ = :($a);               # a positional argument
$ = :(:$a);              # a named argument of name 'a'
$ = :(*@a);              # a slurpy positional argument
$ = :(*%h);              # a slurpy named argument

On the caller side, positional arguments are passed in the same order as the arguments are declared.

sub pos($x, $y) { "x=$x y=$y" }
pos(4, 5);                          # OUTPUT: «x=4 y=5»

In the case of named arguments and parameters, only the name is used for mapping arguments to parameters. If a fat arrow is used to construct a Pair only those with valid identifiers as keys are recognized as named arguments.

sub named(:$x, :$y) { "x=$x y=$y" } 
 named( y => 5, x => 4);             # OUTPUT: «x=4 y=5» 

You can invoke the routine using a variable with the same name as the named argument; in that case : will be used for the invocation so that the name of the variable is understood as the key of the argument.

sub named-shortcut( :$shortcut ) {
    say "Looks like $shortcut"
}
named-shortcut( shortcut => "to here"); # OUTPUT: «Looks like to here␤»
my $shortcut = "Þor is mighty";
named-shortcut( :$shortcut );           # OUTPUT: «Looks like Þor is mighty␤»

It is possible to have a different name for a named argument than the variable name:

sub named(:official($private)) { "Official business!" if $private }
named :official;

Argument aliases

The colon-pair syntax can be used to provide aliases for arguments:

sub alias-named(:color(:$colour), :type(:class($kind))) {
    say $colour ~ " " ~ $kind
}
alias-named(color => "red", type => "A");    # both names can be used
alias-named(colour => "green", type => "B"); # more than two names are ok
alias-named(color => "white", class => "C"); # every alias is independent

The presence of the colon : will decide whether we are creating a new named argument or not. :$colour will not only be the name of the aliased variable, but also a new named argument (used in the second invocation). However, $kind will just be the name of the aliased variable, that does not create a new named argument. More uses of aliases can be found in sub MAIN.

A function with named arguments can be called dynamically, dereferencing a Pair with | to turn it into a named argument.

multi f(:$named) { note &?ROUTINE.signature };
multi f(:$also-named) { note &?ROUTINE.signature };
for 'named', 'also-named' -> $n {
    f(|($n => rand))                # OUTPUT: «(:$named)␤(:$also-named)␤»
}

my $pair = :named(1);
f |$pair;                           # OUTPUT: «(:$named)␤»

The same can be used to convert a Hash into named arguments.

sub f(:$also-named) { note &?ROUTINE.signature };
my %pairs = also-named => 4;
f |%pairs;                              # OUTPUT: «(:$also-named)␤»

A Hash that contains a list may prove problematic when slipped into named arguments. To avoid the extra layer of containers coerce to Map before slipping.

class C { has $.x; has $.y; has @.z };
my %h = <x y z> Z=> (5, 20, [1,2]);
say C.new(|%h.Map);
# OUTPUT: «C.new(x => 5, y => 20, z => [1, 2])␤»

You can create as many aliases to a named argument as you want:

sub alias-named(:color(:$colour), 
                 :variety(:style(:sort(:type(:class($kind)))))) { 
     return $colour ~ " " ~ $kind 
 } 
 say alias-named(color => "red", style => "A"); 
 say alias-named(colour => "green", variety => "B"); 
 say alias-named(color => "white", class => "C"); 

Optional and mandatory arguments

Positional parameters are mandatory by default, and can be made optional with a default value or a trailing question mark:

$ = :(Str $id);         # required parameter
$ = :($base = 10);      # optional parameter, default value 10
$ = :(Int $x?);         # optional parameter, default is the Int type object

Named parameters are optional by default, and can be made mandatory with a trailing exclamation mark:

$ = :(:%config);        # optional parameter
$ = :(:$debug = False); # optional parameter, defaults to False
$ = :(:$name!);         # mandatory 'name' named parameter

Default values can depend on previous parameters, and are (at least notionally) computed anew for each call

$ = :($goal, $accuracy = $goal / 100);
$ = :(:$excludes = ['.', '..']);        # a new Array for every call

Dynamic variables

Dynamic variables are allowed in signatures although they don't provide special behavior because argument binding does connect two scopes anyway.

Destructuring arguments

Non-scalar parameters can be followed or substituted by a sub-signature in parentheses, which will destructure the argument given. The destructuring of a list is just its elements:

sub first(@array ($first, *@rest)) { $first }

or

sub first([$f, *@]) { $f }

While the destructuring of a hash is its pairs:

sub all-dimensions(% (:length(:$x), :width(:$y), :depth(:$z))) {
    $x andthen $y andthen $z andthen True
}

Pointy loops can also destructure hashes, allowing assignment to variables:

my %hhgttu = (:40life, :41universe, :42everything);
for %hhgttu -> (:$key, :$value) {
  say "$key → $value";
}
# OUTPUT: «universe → 41␤life → 40␤everything → 42␤»

In general, an object is destructured based on its attributes. A common idiom is to unpack a Pair's key and value in a for loop:

for <Peter Paul Merry>.pairs -> (:key($index), :value($guest)) { }

However, this unpacking of objects as their attributes is only the default behavior. To make an object get destructured differently, change its Capture method.

Sub-signatures

To match against a compound parameter use a sub-signature following the argument name in parentheses.

sub foo(|c(Int, Str)){
   put "called with {c.perl}"
};
foo(42, "answer");
# OUTPUT: «called with \(42, "answer")␤»

Long names

To exclude certain parameters from being considered in multiple dispatch, separate them with a double semicolon.

multi sub f(Int $i, Str $s;; :$b) { say "$i, $s, {$b.perl}" };
f(10, 'answer');
# OUTPUT: «10, answer, Any␤»

Capture parameters

Prefixing a parameter with a vertical bar | makes the parameter a Capture, using up all the remaining positional and named arguments.

This is often used in proto definitions (like proto foo (|) {*}) to indicate that the routine's multi definitions can have any type constraints. See proto for an example.

If bound to a variable arguments can be forwarded as a whole using the slip operator |.

sub a(Int $i, Str $s) { say $i.^name ~ ' ' ~ $s.^name }
sub b(|c) { say c.^name; a(|c) }
b(42, "answer");
# OUTPUT: «Capture␤Int Str␤»

Parameter traits and modifiers

By default, parameters are bound to their argument and marked as read-only. One can change that with traits on the parameter.

The is copy trait causes the argument to be copied, and allows it to be modified inside the routine

sub count-up($x is copy) {
    $x = ∞ if $x ~~ Whatever;
    .say for 1..$x;
}

The is rw trait, which stands for is read-write, makes the parameter bind to a variable (or other writable container). Assigning to the parameter changes the value of the variable at the caller side.

sub swap($x is rw, $y is rw) {
    ($x, $y) = ($y, $x);
}

On slurpy parameters, is rw is reserved for future use by language designers.

The is raw trait is automatically applied to parameters declared with a backslash as a "sigil", and may also be used to make normally sigiled parameters behave like these do. In the special case of slurpies, which normally produce an Array full of Scalars as described above, is raw will instead cause the parameter to produce a List. Each element of that list will be bound directly as raw parameter.

To explicitly ask for a read-only parameter use the is readonly trait. Please note that this applies only to the container. The object inside can very well have mutator methods and Perl 6 will not enforce immutability on the attributes of the object.

Traits can be followed by the where clause:

sub ip-expand-ipv6($ip is copy where m:i/^<[a..f\d\:]>**3..39$/) { }

Methods

method params

method params(Signature:D: --> Positional)

Returns the list of Parameter objects that make up the signature.

method arity

method arity(Signature:D: --> Int:D)

Returns the minimal number of positional arguments required to satisfy the signature.

method count

method count(Signature:D: --> Real:D)

Returns the maximal number of positional arguments which can be bound to the signature. Returns Inf if there is a slurpy positional parameter.

method returns

Whatever the Signature's return constraint is:

:($a, $b --> Int).returns # OUTPUT: «(Int)»

method ACCEPTS

multi method ACCEPTS(Signature:D: Signature $topic)
multi method ACCEPTS(Signature:D: Capture $topic)
multi method ACCEPTS(Signature:D: Mu \topic)

If $topic is a Signature returns True if anything accepted by $topic would also be accepted by the invocant, otherwise returns False:

:($a, $b) ~~ :($foo, $bar, $baz?);   # OUTPUT: «True»
:(Int $n) ~~ :(Str);                 # OUTPUT: «False»

The $topic is a Capture, returns True if it can be bound to the invocant, i.e., if a function with invocant's Signature would be able to be called with the $topic:

\(1, 2, :foo) ~~ :($a, $b, :foo($bar)); # OUTPUT: «True»
\(1, :bar)    ~~ :($a);                 # OUTPUT: «False»

Lastly, the candidate with Mu \topic converts topic to Capture and follows the same semantics as Capture $topic:

<a b c d>  ~~ :(Int $a);      # OUTPUT: «False»
42         ~~ :(Int);         # OUTPUT: «False» (Int.Capture throws)
set(<a b>) ~~ :(:$a, :$b);    # OUTPUT: «True»

Since where clauses are not introspectable, the method cannot determine whether two signatures ACCEPTS the same sort of where-constrained parameters. Such comparisons will return False. This includes signatures with literals, which are just sugar for the where-constraints:

say :(42) ~~ :($ where 42)    # OUTPUT: «False␤»

method Capture

Defined as:

method Capture()

Throws X::Cannot::Capture.

Runtime creation of Signature objects (6.d, 2019.03 and later)

Signature.new(params => (...), returns => Type, arity => 1, count => 1) 

In some situations, specifically when working with the MetaObject Protocol, it makes sense to create Signature objects programmatically. For this purpose, you can call the new method with the following named parameters:

A list of Parameter objects for this signature.

Any constraint the return value should match. Defaults to Mu, which effectively implies no return value constraint check.

The minimal number of positional arguments required to satisfy the signature. Defaults to the number of Parameter objects given with the params parameter.

The maximal number of positional arguments which can be bound to the signature. Defaults to the arity if not specified. Specify Inf if there is a slurpy positional parameter.

254 class Slip

A kind of List that automatically flattens into an outer container

class Slip is List {}

A Slip is a List that automatically flattens into an outer List (or other list-like container or iterable).

For example it allows you to write a map that produces more than one value into the result without nesting:

say <a b c>.map({ ($_, $_.uc).Slip }).join('|');        # OUTPUT: «a|A|b|B|c|C␤» 

In contrast, when returning an ordinary List, the resulting list is nested:

say <a b c>.map({ $_, $_.uc }).join('|');               # OUTPUT: «a A|b B|c C␤» 

To create a Slip, either coerce another list-like type to it by calling the Slip method, or use the slip subroutine:

# This says "1" and then says "2", rather than saying "(1 2)"
.say for gather {
    take slip(1, 2);
}

A Slip may also be created by using the prefix:<|> operator. This differs from the slip subroutine in both precedence and treatment of single arguments. In fact, prefix:<|> only takes a single argument, so in that way, it behaves closer to the .Slip method than the slip subroutine.

my $l = (1, 2, 3); 
 say (1, slip 2, 3).perl;  # says (1, 2, 3)      , slips 2, 3 into (1, …) 
 say (0, slip $l).perl;    # says (0, $(1, 2, 3)), $l does not break apart 
 say (0, $l.Slip).perl;    # says (0, 1, 2, 3)   , slips from $l into (0, …) 
 say (|$l).perl;           # says slip(1, 2, 3)  , breaks apart $l 
 say (0, (|$l, 4), 5);     # says (0 (1 2 3 4) 5), slips from $l into (…, 4) 
 say (0, ($l.Slip, 4), 5); # says (0 (1 2 3 4) 5), slips from $l into (…, 4) 
 say (0, (slip $l, 4), 5); # says (0 (1 2 3) 4 5), slips ($l, 4) into (0, …, 5) 
 say (0, ($l, 4).Slip, 5); # says (0 (1 2 3) 4 5), slips ($l, 4) into (0, …, 5) 

Loops that do not want to produce a value for an iteration use Slips, rather than empty Lists to do so, as do if statements that do not run their blocks.

Please note that prefix:<|> will also apply parameters in a slippy manner to a routine call. It does not forward a Slip to the called routine, that includes return and take.

my \l = gather for 1..10 -> $a, $b { take |($a, $b) }; say l.perl;
# OUTPUT: «((1, 2), (3, 4), (5, 6), (7, 8), (9, 10)).Seq␤»
my \m= gather for 1..10 -> $a, $b { take ($a, $b).Slip }; say m.perl;
# OUTPUT: «(1, 2, 3, 4, 5, 6, 7, 8, 9, 10).Seq␤»

Methods

method List

Defined as:

multi method List(Slip:D: --> List:D)

Turns it into a list.

sub slip

Defined as:

multi sub slip(--> Empty)
multi sub slip(@args --> Slip:D)
multi sub slip(+args --> Slip:D)

Creates a Slip from its arguments by calling .Slip on the object formed by them. Returns Empty if called with void arguments.

Constants

constant Empty

Empty is a Slip of the empty List.

say "".comb ~~ Empty;
# OUTPUT: «True␤»

255 class Stash

Table for "our"-scoped symbols

class Stash is Hash { }

A Stash is a hash that is used for symbol tables at the package scoping level in Perl 6.

To get a Stash, you can call the .WHO pseudo-method on a package (because it answers the question who lives here?), or if you write the package name as a literal, append two colons:

class Boring {
    class Nested { };
    our sub package_sub { }
    my sub lexical { };
    method a_method() { }
}
say Boring::.^name;             # OUTPUT: «Stash␤»
say Boring.WHO === Boring::;    # OUTPUT: «True␤»

Since it inherits from Hash, you can use all the usual hash functionality:

say Boring::.keys.sort;         # OUTPUT: «(&package_sub Nested)␤» 
 say Boring::<Nested>;           # OUTPUT: «(Nested)␤» 

As the example above shows only "our"-scoped things appear in the Stash (nested classes are "our" by default, but can be excluded with "my".) Lexicals and methods are not included in a Stash, since they do not live in the package table. Lexicals live in a separate lexical pad, which is only visible from inside the scope. Methods (in the case that the package is also a class) have a separate method table, and are accessible through introspection on the class itself, via .can and .^methods.

256 class Str

String of characters

class Str is Cool does Stringy { }

Built-in class for strings. Objects of type Str are immutable, but read the FAQ to understand precisely what this means.

Methods

routine chop

multi method chop(Str:D:)
multi method chop(Str:D: Int() $chopping)

Returns the string with $chopping characters removed from the end.

say "Whateverable".chop(3.6);  # OUTPUT: «Whatevera␤»
my $string= "Whateverable";
say $string.chop("3");         # OUTPUT: «Whatevera␤»

The $chopping positional is converted to Int before being applied to the string.

routine chomp

Defined as:

multi sub    chomp(Str:D  --> Str:D)
multi method chomp(Str:D: --> Str:D)

Returns the string with a logical newline (any codepoint that has the NEWLINE property) removed from the end.

Examples:

say chomp("abc\n");       # OUTPUT: «abc␤»
say "def\r\n".chomp;      # OUTPUT: «def␤» NOTE: \r\n is a single grapheme!
say "foo\r".chomp;        # OUTPUT: «foo␤»

method contains

Defined as:

multi method contains(Str:D: Cool:D $needle --> Bool:D)
multi method contains(Str:D: Str:D $needle --> Bool:D)
multi method contains(Str:D: Cool:D $needle, Int(Cool:D) $pos --> Bool:D)
multi method contains(Str:D: Str:D $needle, Int:D $pos --> Bool:D)

Coerces the invocant (represented in the signature by Str:D:, that would be the haystack) and first argument (which we are calling $needle) to Str (if it's not already, that is, in the first and third multi forms), and searches for $needle in the invocant (or haystack) starting from $pos characters into the string, if that is included as an argument. Returns True if $needle is found. $pos is an optional parameter, and if it's not present, contains will search from the beginning of the string (using the first two forms of the multi).

say <Hello, World>.contains('Hello', 0);   # OUTPUT: «True␤»
say "Hello, World".contains('Hello');      # OUTPUT: «True␤»
say "Hello, World".contains('hello');      # OUTPUT: «False␤»
say "Hello, World".contains('Hello', 1);   # OUTPUT: «False␤»
say "Hello, World".contains(',');          # OUTPUT: «True␤»
say "Hello, World".contains(',', 3);       # OUTPUT: «True␤»
say "Hello, World".contains(',', 10);      # OUTPUT: «False␤»

In the first example, coercion is used to convert a List to a Str. In the 4th case, the 'Hello' string is not found since we have started looking at the second position in it (index 1). Note that because of how a List or Array is coerced into a Str, the results may sometimes be surprising. See traps.

routine lc

Defined as:

multi sub    lc(Str:D  --> Str:D)
multi method lc(Str:D: --> Str:D)

Returns a lower-case version of the string.

Examples:

lc("A"); # RESULT: «"a"»
"A".lc;  # RESULT: «"a"»

routine uc

multi sub    uc(Str:D  --> Str:D)
multi method uc(Str:D: --> Str:D)

Returns an uppercase version of the string.

routine fc

multi sub    fc(Str:D  --> Str:D)
multi method fc(Str:D: --> Str:D)

Does a Unicode "fold case" operation suitable for doing caseless string comparisons. (In general, the returned string is unlikely to be useful for any purpose other than comparison.)

routine tc

multi sub    tc(Str:D  --> Str:D)
multi method tc(Str:D: --> Str:D)

Does a Unicode "titlecase" operation, that is changes the first character in the string to title case, or to upper case if the character has no title case mapping

routine tclc

multi sub    tclc(Str:D  --> Str:D)
multi method tclc(Str:D: --> Str:D)

Turns the first character to title case, and all other characters to lower case

routine wordcase

multi sub    wordcase(Cool $x  --> Str) 
 multi sub    wordcase(Str:D $x --> Str) 
 multi method wordcase(Str:D: :&filter = &tclc, Mu :$where = True --> Str) 

Returns a string in which &filter has been applied to all the words that match $where. By default, this means that the first letter of every word is capitalized, and all the other letters lowercased.

method unival

multi method unival(Str:D --> Numeric)

Returns the numeric value that the first codepoint in the invocant represents, or NaN if it's not numeric.

say '4'.unival;     # OUTPUT: «4␤»
say '¾'.unival;     # OUTPUT: «0.75␤»
say 'a'.unival;     # OUTPUT: «NaN␤»

method univals

multi method univals(Str:D --> List)

Returns a list of numeric values represented by each codepoint in the invocant string, and NaN for non-numeric characters.

say "4a¾".univals;  # OUTPUT: «(4 NaN 0.75)␤»

routine chars

multi sub    chars(Cool  $x --> Int:D)
multi sub    chars(Str:D $x --> Int:D)
multi sub    chars(str   $x --> int)
multi method chars(Str:D:   --> Int:D)

Returns the number of characters in the string in graphemes. On the JVM, this currently erroneously returns the number of codepoints instead.

method encode

multi method encode(Str:D $encoding = 'utf8', :$replacement, Bool() :$translate-nl = False, :$strict)

Returns a Blob which represents the original string in the given encoding and normal form. The actual return type is as specific as possible, so $str.encode('UTF-8') returns a utf8 object, $str.encode('ISO-8859-1') a buf8. If :translate-nl is set to True, it will translate newlines from \n to \n\r, but only in Windows. $replacement indicates how characters are going to be replaced in the case they are not available in the current encoding, while $strict indicates whether unmapped codepoints will still decode; for instance, codepoint 129 which does not exist in windows-1252.

my $str = "Þor is mighty";
say $str.encode("ascii", :replacement( 'Th') ).decode("ascii");
# OUTPUT: «Thor is mighty␤»

In this case, any unknown character is going to be substituted by Th. We know in advance that the character that is not known in the ascii encoding is Þ, so we substitute it by its latin equivalent, Th. In the absence of any replacement set of characters, :replacement is understood as a Bool:

say $str.encode("ascii", :replacement).decode("ascii"); # OUTPUT: «?or is mighty␤» 

If :replacement is not set or assigned a value, the error Error encoding ASCII string: could not encode codepoint 222 will be issued (in this case, since þ is codepoint 222).

Since the Blob returned by encode is the original string in normal form, and every element of a Blob is a byte, you can obtain the length in bytes of a string by calling a method that returns the size of the Blob on it:

say "þor".encode.bytes; # OUTPUT: «4␤» 
 say "þor".encode.elems; # OUTPUT: «4␤» 

routine index

multi method index(Str:D: Cool:D $needle --> Int:D)
multi method index(Str:D: Str:D $needle --> Int:D)
multi method index(Str:D: Cool:D $needle, Cool:D $pos --> Int:D)
multi method index(Str:D: Str:D $needle, Int:D $pos --> Int:D)

Searches for $needle in the string starting from $pos (if present). It returns the offset into the string where $needle was found, and Nil if it was not found.

Examples:

say index "Camelia is a butterfly", "a";     # OUTPUT: «1␤»
say index "Camelia is a butterfly", "a", 2;  # OUTPUT: «6␤»
say index "Camelia is a butterfly", "er";    # OUTPUT: «17␤»
say index "Camelia is a butterfly", "Camel"; # OUTPUT: «0␤»
say index "Camelia is a butterfly", "Onion"; # OUTPUT: «Nil␤»

say index("Camelia is a butterfly", "Onion").defined ?? 'OK' !! 'NOT'; # OUTPUT: «NOT␤»

Other forms of index, including a sub, are inherited from Cool. Check them there.

routine rindex

multi sub    rindex(Str:D $haystack, Str:D $needle, Int $startpos = $haystack.chars --> Int)
multi method rindex(Str:D $haystack: Str:D $needle, Int $startpos = $haystack.chars --> Int)

Returns the last position of $needle in $haystack not after $startpos. Returns Nil if $needle wasn't found.

Examples:

say rindex "Camelia is a butterfly", "a";     # OUTPUT: «11␤»
say rindex "Camelia is a butterfly", "a", 10; # OUTPUT: «6␤»

method indices

Defined as:

multi method indices(Str:D: Str:D $needle, :$overlap --> List:D)
multi method indices(Str:D: Str:D $needle, Int:D $start, :$overlap --> List:D)

Searches for all occurrences of $needle in the string starting from position $start, or zero if it is not specified, and returns a List with all offsets in the string where $needle was found, or an empty list if it was not found.

If the optional parameter :overlap is specified the search continues from the index directly following the previous match, otherwise the search will continue after the previous match.

say "banana".indices("a");              # OUTPUT: «(1 3 5)␤»
say "banana".indices("ana");            # OUTPUT: «(1)␤»
say "banana".indices("ana", :overlap);  # OUTPUT: «(1 3)␤»
say "banana".indices("ana", 2);         # OUTPUT: «(3)␤»

method match

method match($pat, :continue(:$c), :pos(:$p), :global(:$g), :overlap(:$ov), :exhaustive(:$ex), :st(:$nd), :rd(:$th), :$nth, :$x --> Match)

Performs a match of the string against $pat and returns a Match object if there is a successful match; it returns (Any) otherwise. Matches are stored in the default match variable $/. If $pat is not a Regex object, match will coerce the argument to a Str and then perform a literal match against $pat.

A number of optional named parameters can be specified, which alter how the match is performed.

The :continue adverb takes as an argument the position where the regex should start to search. If no position is specified for :c it will default to 0 unless $/ is set, in which case it defaults to $/.to.

Takes a position as an argument. Fails if regex cannot be matched from that position, unlike :continue.

Instead of searching for just one match and returning a Match object, search for every non-overlapping match and return them in a List.

Finds all matches including overlapping matches, but only returns one match from each starting position.

Finds all possible matches of a regex, including overlapping matches and matches that start at the same position.

Returns the nth match in the string. The argument can be a Numeric or an Iterable producing monotonically increasing numbers (that is, the next produced number must be larger than the previous one). The Iterable will be lazily reified and if non-monotonic sequence is encountered an exception will be thrown.

If Iterable argument is provided the return value and $/ variable will be set to a possibly-empty List of Match objects.

Takes as an argument the number of matches to return, stopping once the specified number of matches has been reached. The value must be a Numeric or a Range; other values will cause .match to return a Failure containing X::Str::Match::x exception.

Examples:

say "properly".match('perl');                     # OUTPUT: «「perl」␤» 
 say "properly".match(/p.../);                     # OUTPUT: «「prop」␤» 
 say "1 2 3".match([1,2,3]);                       # OUTPUT: «「1 2 3」␤» 
 say "a1xa2".match(/a./, :continue(2));            # OUTPUT: «「a2」␤» 
 say "abracadabra".match(/ a .* a /, :exhaustive); 
 # OUTPUT: «(「abracadabra」 「abracada」 「abraca」 「abra」 「acadabra」 「acada」 「aca」 「adabra」 「ada」 「abra」)␤» 
 say 'several words here'.match(/\w+/,:global);    # OUTPUT: «(「several」 「words」 「here」)␤» 
 say 'abcdef'.match(/.*/, :pos(2));                # OUTPUT: «「cdef」␤» 
 say "foo[bar][baz]".match(/../, :1st);            # OUTPUT: «「fo」␤» 
 say "foo[bar][baz]".match(/../, :2nd);            # OUTPUT: «「o[」␤» 
 say "foo[bar][baz]".match(/../, :3rd);            # OUTPUT: «「ba」␤» 
 say "foo[bar][baz]".match(/../, :4th);            # OUTPUT: «「r]」␤» 
 say "foo[bar][baz]bada".match('ba', :x(2));       # OUTPUT: «(「ba」 「ba」)␤» 

method Numeric

Defined as:

method Numeric(Str:D: --> Numeric:D)

Coerces the string to Numeric using semantics equivalent to val routine. Fails with X::Str::Numeric if the coercion to a number cannot be done.

Only Unicode characters with property Nd, as well as leading and trailing whitespace are allowed, with the special case of the empty string being coerced to 0. Synthetic codepoints (e.g. "7\x[308]") are forbidden.

While Nl and No characters can be used as numeric literals in the language, their conversion via Str.Numeric will fail, by design. See unival if you need to coerce such characters to Numeric.

method Int

Defined as:

method Int(Str:D: --> Int:D)

Coerces the string to Int, using the same rules as Str.Numeric.

method Rat

Defined as:

method Rat(Str:D: --> Rational:D)

Coerces the string to a Rat object, using the same rules as Str.Numeric. If the denominator is larger than 64-bits is it still kept and no degradation to Num occurs.

method Bool

Defined as:

method Bool(Str:D: --> Bool:D)

Returns False if the string is empty, True otherwise.

routine parse-base

multi sub    parse-base(Str:D $num, Int:D $radix --> Numeric)
multi method parse-base(Str:D $num: Int:D $radix --> Numeric)

Performs the reverse of base by converting a string with a base-$radix number to its Numeric equivalent. Will fail if radix is not in range 2..36 or if the string being parsed contains characters that are not valid for the specified base.

1337.base(32).parse-base(32).say; # OUTPUT: «1337␤»
'Perl6'.parse-base(30).say;       # OUTPUT: «20652936␤»
'FF.DD'.parse-base(16).say;       # OUTPUT: «255.863281␤»

See also: :16<FF> syntax for number literals

routine parse-names

sub    parse-names(Str:D $names  --> Str:D)
method parse-names(Str:D $names: --> Str:D)

DEPRECATED. Use uniparse instead. Existed in Rakudo implementation as a proof of viability implementation before being renamed and will be removed when 6.e language is released.

routine uniparse

sub    uniparse(Str:D $names  --> Str:D)
method uniparse(Str:D $names: --> Str:D)

Takes string with comma-separated Unicode names of characters and returns a string composed of those characters. Will fail if any of the characters' names are empty or not recognized. Whitespace around character names is ignored.

say "I {uniparse 'TWO HEARTS'} Perl"; # OUTPUT: «I 💕 Perl␤»
'TWO HEARTS, BUTTERFLY'.uniparse.say; # OUTPUT: «💕🦋␤»

Note that unlike \c[...] construct available in string interpolation, uniparse does not accept decimal numerical values. Use chr routine to convert those:

say "\c[1337]"; # OUTPUT: «Թ␤»
say '1337'.chr; # OUTPUT: «Թ␤»

Note: before being standardized in 2017.12, this routine was known under its working name of parse-names. This denomination will be removed in the 6.e version.

routine split

multi sub    split(  Str:D $delimiter, Str:D $input, $limit = Inf, 
   :$skip-empty, :$v, :$k, :$kv, :$p) 
multi sub    split(Regex:D $delimiter, Str:D $input, $limit = Inf, 
   :$skip-empty, :$v, :$k, :$kv, :$p) 
multi sub    split(List:D $delimiters, Str:D $input, $limit = Inf, 
   :$skip-empty, :$v, :$k, :$kv, :$p) 
multi method split(Str:D:   Str:D $delimiter, $limit = Inf, 
   :$skip-empty, :$v, :$k, :$kv, :$p) 
multi method split(Str:D: Regex:D $delimiter, $limit = Inf, 
   :$skip-empty, :$v, :$k, :$kv, :$p) 
multi method split(Str:D: List:D $delimiters, $limit = Inf, 
   :$skip-empty, :$v, :$k, :$kv, :$p) 

Splits a string up into pieces based on delimiters found in the string.

If DELIMITER is a string, it is searched for literally and not treated as a regex. If DELIMITER is the empty string, it effectively returns all characters of the string separately (plus an empty string at the begin and at the end). If PATTERN is a regular expression, then that will be used to split up the string. If DELIMITERS is a list, then all of its elements will be considered a delimiter (either a string or a regular expression) to split the string on.

The optional LIMIT indicates in how many segments the string should be split, if possible. It defaults to Inf (or *, whichever way you look at it), which means "as many as possible". Note that specifying negative limits will not produce any meaningful results.

A number of optional named parameters can be specified, which alter the result being returned. The :v, :k, :kv and :p named parameters all perform a special action with regards to the delimiter found.

If specified, do not return empty strings before or after a delimiter.

Also return the delimiter. If the delimiter was a regular expression, then this will be the associated Match object. Since this stringifies as the delimiter string found, you can always assume it is the delimiter string if you're not interested in further information about that particular match.

Also return the index of the delimiter. Only makes sense if a list of delimiters was specified: in all other cases, this will be 0.

Also return both the index of the delimiter, as well as the delimiter.

Also return the index of the delimiter and the delimiter as a Pair.

Examples:

say split(";", "a;b;c").perl;           # OUTPUT: «("a", "b", "c").Seq␤»
say split(";", "a;b;c", :v).perl;       # OUTPUT: «("a", ";", "b", ";", "c").Seq␤»
say split(";", "a;b;c", 2).perl;        # OUTPUT: «("a", "b;c").Seq␤»
say split(";", "a;b;c", 2, :v).perl;    # OUTPUT: «("a", ";", "b;c").Seq␤»
say split(";", "a;b;c,d").perl;         # OUTPUT: «("a", "b", "c,d").Seq␤»
say split(/\;/, "a;b;c,d").perl;        # OUTPUT: «("a", "b", "c,d").Seq␤»
say split(<; ,>, "a;b;c,d").perl;       # OUTPUT: «("a", "b", "c", "d").Seq␤»
say split(/<[;,]>/, "a;b;c,d").perl;    # OUTPUT: «("a", "b", "c", "d").Seq␤»
say split(<; ,>, "a;b;c,d", :k).perl;   # OUTPUT: «("a", 0, "b", 0, "c", 1, "d").Seq␤»
say split(<; ,>, "a;b;c,d", :kv).perl;  # OUTPUT: «("a", 0, ";", "b", 0, ";", "c", 1, ",", "d").Seq␤»

say "".split("x").perl;                 # OUTPUT: «("",).Seq␤»
say "".split("x", :skip-empty).perl;    # OUTPUT: «().Seq␤»

say "abcde".split("").perl;             # OUTPUT: «("", "a", "b", "c", "d", "e", "").Seq␤»
say "abcde".split("",:skip-empty).perl; # OUTPUT: «("a", "b", "c", "d", "e").Seq␤»

routine comb

multi sub    comb(Str:D   $matcher, Str:D $input, $limit = Inf)
multi sub    comb(Regex:D $matcher, Str:D $input, $limit = Inf, Bool :$match)
multi sub    comb(Int:D $size, Str:D $input, $limit = Inf)
multi method comb(Str:D $input:)
multi method comb(Str:D $input: Str:D   $matcher, $limit = Inf)
multi method comb(Str:D $input: Regex:D $matcher, $limit = Inf, Bool :$match)
multi method comb(Str:D $input: Int:D $size, $limit = Inf)

Searches for $matcher in $input and returns a Seq of non-overlapping matches limited to at most $limit matches. If $matcher is a Regex, each Match object is converted to a Str, unless $match is set.

If no matcher is supplied, a Seq of characters in the string is returned, as if the matcher was rx/./.

Examples:

say "abc".comb.perl;                 # OUTPUT: «("a", "b", "c").Seq␤»
say 'abcdefghijk'.comb(3).perl;      # OUTPUT: «("abc", "def", "ghi", "jk").Seq␤»
say 'abcdefghijk'.comb(3, 2).perl;   # OUTPUT: «("abc", "def").Seq␤»
say comb(/\w/, "a;b;c").perl;        # OUTPUT: «("a", "b", "c").Seq␤»
say comb(/\N/, "a;b;c").perl;        # OUTPUT: «("a", ";", "b", ";", "c").Seq␤»
say comb(/\w/, "a;b;c", 2).perl;     # OUTPUT: «("a", "b").Seq␤»
say comb(/\w\;\w/, "a;b;c", 2).perl; # OUTPUT: «("a;b",).Seq␤»
say comb(/.<(.)>/, "<>[]()").perl;   # OUTPUT: «(">", "]", ")").Seq␤»

If the matcher is an integer value, comb behaves as if the matcher was rx/ . ** {1..$matcher} /, but which is optimized to be much faster.

Note that a Regex matcher may control which portion of the matched text is returned by using features which explicitly set the top-level capture.

routine lines

Defined as:

multi method lines(Str:D: $limit)
multi method lines(Str:D:)

Returns a list of lines (without trailing newline characters), i.e. the same as a call to $input.comb( / ^^ \N* /, $limit ) would.

Examples:

say lines("a\nb").perl;    # OUTPUT: «("a", "b").Seq␤»
say lines("a\nb").elems;   # OUTPUT: «2␤»
say "a\nb".lines.elems;    # OUTPUT: «2␤»
say "a\n".lines.elems;     # OUTPUT: «1␤»

You can limit the number of lines returned by setting the $limit variable to a non-zero, non-Infinity value:

say <not there yet>.join("\n").lines( 2 ); # OUTPUT: «(not there)␤»

DEPRECATED as of 6.d language, the :count argument was used to return the total number of lines:

say <not there yet>.join("\n").lines( :count ); # OUTPUT: «3␤»

Use elems call on the returned Seq instead:

say <not there yet>.join("\n").lines.elems; # OUTPUT: «3␤»

routine words

multi method words(Str:D: $limit)
multi method words(Str:D:)

Returns a list of non-whitespace bits, i.e. the same as a call to $input.comb( / \S+ /, $limit ) would.

Examples:

say "a\nb\n".words.perl;       # OUTPUT: «("a", "b").Seq␤»
say "hello world".words.perl;  # OUTPUT: «("hello", "world").Seq␤»
say "foo:bar".words.perl;      # OUTPUT: «("foo:bar",).Seq␤»
say "foo:bar\tbaz".words.perl; # OUTPUT: «("foo:bar", "baz").Seq␤»

It can also be used as a subroutine, turning the first argument into the invocant. $limit is optional, but if it is provided (and not equal to Inf), it will return only the first $limit words.

say words("I will be very brief here", 2); # OUTPUT: «(I will)␤»

routine flip

multi sub    flip(Str:D  --> Str:D)
multi method flip(Str:D: --> Str:D)

Returns the string reversed character by character.

Examples:

"Perl".flip;  # RESULT: «lreP»
"ABBA".flip;  # RESULT: «ABBA»

method starts-with

multi method starts-with(Str:D: Str(Cool) $needle --> Bool:D)

Returns True if the invocant is identical to or starts with $needle.

say "Hello, World".starts-with("Hello");     # OUTPUT: «True␤»
say "https://perl6.org/".starts-with('ftp'); # OUTPUT: «False␤»

method ends-with

multi method ends-with(Str:D: Str(Cool) $needle --> Bool:D)

Returns True if the invocant is identical to or ends with $needle.

say "Hello, World".ends-with('Hello');      # OUTPUT: «False␤»
say "Hello, World".ends-with('ld');         # OUTPUT: «True␤»

method subst

multi method subst(Str:D: $matcher, $replacement, *%opts)

Returns the invocant string where $matcher is replaced by $replacement (or the original string, if no match was found).

There is an in-place syntactic variant of subst spelled s/matcher/replacement/ and with adverb following the s or inside the matcher.

$matcher can be a Regex, or a literal Str. Non-Str matcher arguments of type Cool are coerced to Str for literal matching. If a Regex $matcher is used, the $/ special variable will be set to Nil (if no matches occurred), a Match object, or a List of Match objects (if multi-match options like :g are used).

Literal replacement substitution

my $some-string = "Some foo";
my $another-string = $some-string.subst(/foo/, "string"); # gives 'Some string'
$some-string.=subst(/foo/, "string"); # in-place substitution. $some-string is now 'Some string'

Callable

The replacement can be a Callable in which the current Match object will be placed in the $/ variable, as well as the $_ topic variable. Using a Callable as replacement is how you can refer to any of the captures created in the regex:

# Using capture from $/ variable (the $0 is the first positional capture)
say 'abc123defg'.subst(/(\d+)/, { " before $0 after " });
# OUTPUT: «abc before 123 after defg␤»

# Using capture from $/ variable (the $<foo> is a named capture)
say 'abc123defg'.subst(/$<foo>=\d+/, { " before $<foo> after " });
# OUTPUT: «abc before 123 after defg␤»

# Using WhateverCode to operate on the Match given in $_:
say 'abc123defg'.subst(/(\d+)/, "[ " ~ *.flip ~ " ]");
# OUTPUT: «abc[ 321 ]defg␤»

# Using a Callable to generate substitution without involving current Match:
my $i = 41;
my $str = "The answer is secret.";
say $str.subst(/secret/, {++$i}); # The answer to everything
# OUTPUT: «The answer is 42.␤»

Adverbs

The following adverbs are supported

short long meaning
:g :global tries to match as often as possible
:nth(Int|Callable|Whatever) only substitute the nth match; aliases: :st, :nd, :rd, and :th
:ss :samespace preserves whitespace on substitution
:ii :samecase preserves case on substitution
:mm :samemark preserves character marks (e.g. 'ü' replaced with 'o' will result in 'ö')
:x(Int|Range|Whatever) substitute exactly $x matches

Note that only in the s/// form :ii implies :i and :ss implies :s. In the method form, the :s and :i modifiers must be added to the regex, not the subst method call.

More Examples

Here are other examples of usage:

my $str = "Hey foo foo foo";
$str.subst(/foo/, "bar", :g); # global substitution - returns Hey bar bar bar

$str.subst(/foo/, "no subst", :x(0)); # targeted substitution. Number of times to substitute. Returns back unmodified.
$str.subst(/foo/, "bar", :x(1)); #replace just the first occurrence.

$str.subst(/foo/, "bar", :nth(3)); # replace nth match alone. Replaces the third foo. Returns Hey foo foo bar

The :nth adverb has readable English-looking variants:

say 'ooooo'.subst: 'o', 'x', :1st; # OUTPUT: «xoooo␤»
say 'ooooo'.subst: 'o', 'x', :2nd; # OUTPUT: «oxooo␤»
say 'ooooo'.subst: 'o', 'x', :3rd; # OUTPUT: «ooxoo␤»
say 'ooooo'.subst: 'o', 'x', :4th; # OUTPUT: «oooxo␤»

method subst-mutate

NOTE: .subst-mutate is deprecated in the 6.d version, and will be removed in future ones. You can use subst with .= method call assignment operator or s/// substitution operator instead.

Where subst returns the modified string and leaves the original unchanged, it is possible to mutate the original string by using subst-mutate. If the match is successful, the method returns a Match object representing the successful match, otherwise returns Nil. If :nth (or one of its aliases) with Iterable value, :g, :global, or :x arguments are used, returns a List of Match objects, or an empty List if no matches occurred.

my $some-string = "Some foo";
my $match = $some-string.subst-mutate(/foo/, "string");
say $some-string;  # OUTPUT: «Some string␤»
say $match;        # OUTPUT: «「foo」␤»
$some-string.subst-mutate(/<[oe]>/, '', :g); # remove every o and e, notice the :g named argument from .subst

If a Regex $matcher is used, the $/ special variable will be set to Nil (if no matches occurred), a Match object, or a List of Match objects (if multi-match options like :g are used).

routine substr

multi sub    substr(Str:D $s, $from, $chars?  --> Str:D)
multi sub    substr(Str:D $s, Range  $from-to --> Str:D)
multi method substr(Str:D $s: $from, $chars?  --> Str:D)
multi method substr(Str:D $s: Range $from-to  --> Str:D)

Returns a substring of the original string, between the indices specified by $from-to's endpoints (coerced to Int) or from index $from and of length $chars.

Both $from and $chars can be specified as Callable, which will be invoked with the length of the original string and the returned value will be used as the value for the argument. If $from or $chars are not Callable, they'll be coerced to Int.

If $chars is omitted or is larger than the available characters, the string from $from until the end of the string is returned. If $from-to's starting index or $from is less than zero, X::OutOfRange exception is thrown. The $from-to's ending index is permitted to extend past the end of string, in which case it will be equivalent to the index of the last character.

say substr("Long string", 3..6);     # RESULT: «g st␤»
say substr("Long string", 6, 3);     # RESULT: «tri␤»
say substr("Long string", 6);        # RESULT: «tring␤»
say substr("Long string", 6, *-1);   # RESULT: «trin␤»
say substr("Long string", *-3, *-1); # RESULT: «in␤»

method substr-eq

multi method substr-eq(Str:D:  Str(Cool) $test-string, Int(Cool) $from --> Bool)
multi method substr-eq(Cool:D: Str(Cool) $test-string, Int(Cool) $from --> Bool)

Returns True if the $test-string exactly matches the String object, starting from the given initial index $from. For example, beginning with the string "foobar", the substring "bar" will match from index 3:

my $string = "foobar";
say $string.substr-eq("bar", 3);    # OUTPUT: «True␤»

However, the substring "barz" starting from index 3 won't match even though the first three letters of the substring do match:

my $string = "foobar";
say $string.substr-eq("barz", 3);   # OUTPUT: «False␤»

Naturally, to match the entire string, one merely matches from index 0:

my $string = "foobar";
say $string.substr-eq("foobar", 0); # OUTPUT: «True␤»

Since this method is inherited from the Cool type, it also works on integers. Thus the integer 42 will match the value 342 starting from index 1:

my $integer = 342;
say $integer.substr-eq(42, 1);      # OUTPUT: «True␤»

As expected, one can match the entire value by starting at index 0:

my $integer = 342;
say $integer.substr-eq(342, 0);     # OUTPUT: «True␤»

Also using a different value or an incorrect starting index won't match:

my $integer = 342;
say $integer.substr-eq(42, 3);      # OUTPUT: «False␤»
say $integer.substr-eq(7342, 0);    # OUTPUT: «False␤»

method substr-rw

method substr-rw($from, $length = *)

A version of substr that returns a Proxy functioning as a writable reference to a part of a string variable. Its first argument, $from specifies the index in the string from which a substitution should occur, and its last argument, $length specifies how many characters are to be replaced. If not specified, $length defaults to the length of the string.

For example, in its method form, if one wants to take the string "abc" and replace the second character (at index 1) with the letter "z", then one does this:

my $string = "abc";
$string.substr-rw(1, 1) = "z";
$string.say;                         # OUTPUT: «azc␤»

Note that new characters can be inserted as well:

my $string = 'azc';
$string.substr-rw(2, 0) = "-Zorro-"; # insert new characters BEFORE the character at index 2
$string.say;                         # OUTPUT: «az-Zorro-c␤»

substr-rw also has a function form, so the above examples can also be written like so:

my $string = "abc";
substr-rw($string, 1, 1) = "z";
$string.say;                          # OUTPUT: «azc␤»
substr-rw($string, 2, 0) = "-Zorro-";
$string.say;                          # OUTPUT: «az-Zorro-c␤»

It is also possible to alias the writable reference returned by substr-rw for repeated operations:

my $string = "A character in the 'Flintstones' is: barney";
$string ~~ /(barney)/;
my $ref := substr-rw($string, $0.from, $0.to-$0.from);
$string.say;
# OUTPUT: «A character in the 'Flintstones' is: barney␤»
$ref = "fred";
$string.say;
# OUTPUT: «A character in the 'Flintstones' is: fred␤»
$ref = "wilma";
$string.say;
# OUTPUT: «A character in the 'Flintstones' is: wilma␤»

routine samemark

multi sub samemark(Str:D $string, Str:D $pattern --> Str:D)
method    samemark(Str:D: Str:D $pattern --> Str:D)

Returns a copy of $string with the mark/accent information for each character changed such that it matches the mark/accent of the corresponding character in $pattern. If $string is longer than $pattern, the remaining characters in $string receive the same mark/accent as the last character in $pattern. If $pattern is empty no changes will be made.

Examples:

say 'åäö'.samemark('aäo');                        # OUTPUT: «aäo␤»
say 'åäö'.samemark('a');                          # OUTPUT: «aao␤»

say samemark('Pêrl', 'a');                        # OUTPUT: «Perl␤»
say samemark('aöä', '');                          # OUTPUT: «aöä␤»

method succ

method succ(Str:D --> Str:D)

Returns the string incremented by one.

String increment is "magical". It searches for the last alphanumeric sequence that is not preceded by a dot, and increments it.

'12.34'.succ;      # RESULT: «13.34»
'img001.png'.succ; # RESULT: «img002.png»

The actual increment step works by mapping the last alphanumeric character to a character range it belongs to, and choosing the next character in that range, carrying to the previous letter on overflow.

'aa'.succ;   # RESULT: «ab»
'az'.succ;   # RESULT: «ba»
'109'.succ;  # RESULT: «110»
'α'.succ;    # RESULT: «β»
'a9'.succ;   # RESULT: «b0»

String increment is Unicode-aware, and generally works for scripts where a character can be uniquely classified as belonging to one range of characters.

method pred

method pred(Str:D: --> Str:D)

Returns the string decremented by one.

String decrementing is "magical" just like string increment (see succ). It fails on underflow

'b0'.pred;           # RESULT: «a9» 
 'a0'.pred;           # Failure 
 'img002.png'.pred;   # RESULT: «img001.png» 

routine ord

multi sub    ord(Str:D  --> Int:D)
multi method ord(Str:D: --> Int:D)

Returns the codepoint number of the base characters of the first grapheme in the string.

Example:

ord("A"); # 65
"«".ord;  # 171

method ords

multi method ords(Str:D: --> Seq)

Returns a list of Unicode codepoint numbers that describe the codepoints making up the string.

Example:

"aå«".ords; # (97 229 171)

Strings are represented as graphemes. If a character in the string is represented by multiple codepoints, then all of those codepoints will appear in the result of ords. Therefore, the number of elements in the result may not always be equal to chars, but will be equal to codes; codes computes the codepoints in a different way, so the result might be faster.

The codepoints returned will represent the string in NFC. See the NFD, NFKC, and NFKD methods if other forms are required.

method trans

multi method trans(Str:D: Pair:D \what, *%n --> Str)
multi method trans(Str:D: *@changes, :complement(:$c), :squash(:$s), :delete(:$d) --> Str)

Replaces one or many characters with one or many characters. Ranges are supported, both for keys and values. Regexes work as keys. In case a list of keys and values is used, substrings can be replaced as well. When called with :complement anything but the matched value or range is replaced with a single value; with :delete the matched characters without corresponding replacement are removed. Combining :complement and :delete will remove anything but the matched values, unless replacement characters have been specified, in which case, :delete would be ignored. The adverb :squash will reduce repeated matched characters to a single character.

Example:

my $str = 'say $x<b> && $y<a>';
$str.=trans( '<' => '«' );
$str.=trans( '<' => '«', '>' => '»' );

$str.=trans( [ '<'   , '>'   , '&' ] =>
             [ '&lt;', '&gt;', '&amp;' ]);

$str.=trans( ['a'..'y'] => ['A'..'z'] );

"abcdefghij".trans(/<[aeiou]> \w/ => '');                     # RESULT: «cdgh»

"a123b123c".trans(['a'..'z'] => 'x', :complement);            # RESULT: «axxxbxxxc»
"a123b123c".trans('23' => '', :delete);                       # RESULT: «a1b1c»
"aaa1123bb123c".trans('a'..'z' => 'A'..'Z', :squash);         # RESULT: «A1123B123C»
"aaa1123bb123c".trans('a'..'z' => 'x', :complement, :squash); # RESULT: «aaaxbbxc»

Please note that the behavior of the two versions of the multi method is slightly different. The first form will transpose only one character if the origin is also one character:

say "abcd".trans( "a" => "zz" );  # OUTPUT: «zbcd␤» 
 say "abcd".trans( "ba" => "yz" ); # OUTPUT: «zycd␤» 

In the second case, behavior is as expected, since the origin is more than one char long. However, if the Pair in the multi method does not have a Str as an origin or target, it is handled to the second multi method, and behavior changes:

say "abcd".trans: ["a"] => ["zz"]; # OUTPUT: «zzbcd␤»

In this case, neither origin nor target in the Pair are Str; the method with the Pair signature then calls the second, making this call above equivalent to "abcd".trans: ["a"] => ["zz"], (with the comma behind, making it a Positional, instead of a Pair), resulting in the behavior shown as output.

method indent

multi method indent(Int $steps where { $_ == 0 } )
multi method indent(Int $steps where { $_ > 0  } )
multi method indent($steps where { .isa(Whatever) || .isa(Int) && $_ < 0 } )

Indents each line of the string by $steps. If $steps is negative, it outdents instead. If $steps is *, then the string is outdented to the margin:

"  indented by 2 spaces\n    indented even more".indent(*)
    eq "indented by 2 spaces\n  indented even more"

method trim

method trim(Str:D: --> Str)

Remove leading and trailing whitespace. It can be used both as a method on strings and as a function. When used as a method it will return the trimmed string. In order to do in-place trimming, one needs to write .=trim

my $line = '   hello world    ';
say '<' ~ $line.trim ~ '>';        # OUTPUT: «<hello world>␤»
say '<' ~ trim($line) ~ '>';       # OUTPUT: «<hello world>␤»
$line.trim;
say '<' ~ $line ~ '>';             # OUTPUT: «<   hello world    >␤»
$line.=trim;
say '<' ~ $line ~ '>';             # OUTPUT: «<hello world>␤»

See also trim-trailing and trim-leading.

method trim-trailing

method trim-trailing(Str:D: --> Str)

Removes the whitespace characters from the end of a string. See also trim.

method trim-leading

method trim-leading(Str:D: --> Str)

Removes the whitespace characters from the beginning of a string. See also trim.

method NFC

method NFC(Str:D: --> NFC:D)

Returns a codepoint string in NFC format (Unicode Normalization Form C / Composed).

method NFD

method NFD(Str:D: --> NFD:D)

Returns a codepoint string in NFD format (Unicode Normalization Form D / Decomposed).

method NFKC

method NFKC(Str:D: --> NFKC:D)

Returns a codepoint string in NFKC format (Unicode Normalization Form KC / Compatibility Composed).

method NFKD

method NFKD(Str:D: --> NFKD:D)

Returns a codepoint string in NFKD format (Unicode Normalization Form KD / Compatibility Decomposed).

method ACCEPTS

multi method ACCEPTS(Str:D: $other)

Returns True if the string is the same as $other.

method Capture

Defined as:

method Capture()

Throws X::Cannot::Capture.

routine val

multi sub val(Str:D $MAYBEVAL, :$val-or-fail)

Given a Str that may be parsable as a numeric value, it will attempt to construct the appropriate allomorph, returning one of IntStr, NumStr, RatStr or ComplexStr or a plain Str if a numeric value cannot be parsed. If the :val-or-fail adverb is provided it will return an X::Str::Numeric rather than the original string if it cannot parse the string as a number.

say val("42").^name;    # OUTPUT: «IntStr␤»
say val("42e0").^name;  # OUTPUT: «NumStr␤»
say val("42.0").^name;  # OUTPUT: «RatStr␤»
say val("42+0i").^name; # OUTPUT: «ComplexStr␤»

While characters belonging to the Unicode categories Nl (number letters) and No (other numbers) can be used as numeric literals in the language, they will not be converted to a number by val, by design. See unival if you need to convert such characters to Numeric.

257 class StrDistance

Contains the result of a string transformation.

StrDistance objects are used to represent the return of the string transformation operator.

say (($ = "fold") ~~ tr/old/new/).^name;  # OUTPUT: «StrDistance␤»

A StrDistance object will stringify to the resulting string after the transformation, and will numify to the distance between the two strings.

my $str = "fold"; 
 my $str-dist = ($str ~~ tr/old/new/); 
 say ~$str-dist;  # OUTPUT: «fnew␤» 
 say +$str-dist;  # OUTPUT: «3␤» 

Methods

method before

This is actually a class attribute, and called as a method returns the string before the transformation:

say $str-dist.before; # OUTPUT: «fold␤» 

method after

Also a class attribute, returns the string after the transformation:

say $str-dist.after;  # OUTPUT: «fnew␤» 

method Bool

Returns True if before is different from after.

method Numeric

Returns the distance as a number.

method Int

Defined as:

multi method Int(StrDistance:D:)

Returns the distance between the string before and after the transformation.

method Str

Defined as:

multi method Str(StrDistance:D: --> Str)

Returns an after string value.

    my $str-dist = ($str ~~ tr/old/new/); 
     say $str-dist.Str; # OUTPUT: «fnew␤» 
     say ~$str-dist;    # OUTPUT: «fnew␤» 

258 role Stringy

String or object that can act as a string

role Stringy { ... }

Common role for string types (such as Str).

259 class Sub

Subroutine

class Sub is Routine { }

A type for subroutines and operators. Subs are created with the sub declarator keyword followed by an optional identifier. This short tutorial explains how operators are declared. For details of a sub's parameter list, see Signature.

Note that subs that go by the same name as coercers will not take precedence over them. Use the &-sigil to call them.

sub Int(Str $s){'what?'};
say [Int, Int('42'),&Int('42')];
# OUTPUT: «[(Int) 42 what?]␤»

Subs can be nested and scoped with my and our, whereby my is the default. A sub declared with my cannot be reached from any outer scope. An our scoped sub will not redefine a sub of the same name in the outer scope. Any sub can be accessed via a closure from any outer scope. For instance, in this example

sub can-be-seener( $whatever ) {
  my sub can-be-seen ( $objection ) {
    return $whatever but $objection;
  }
  return &can-be-seen
}

my $objectioner = can-be-seener( "Really?");
say $objectioner(42).Int; # OUTPUT: «42␤»

$objectioner will contain the can-be-seen subroutine, even if it has been declared in another scope; calling it with 42 will return "Really?" with the number 42 mixed in, as shown in the last sentence.

Operators

Operators are also Subs. Their definition includes the category they belong to and their code, precedence and associativity. The syntax used in their definition is an example of extended identifiers.

Traits

A Trait is a sub that is applied at compile time to various objects like classes, routines or containers. It is declared with the trait_mod declarator followed by a colon and a string literal containing the name of the trait. A single positional parameter defines the type of the object that the trait is applied to. A single named argument defines the secondary name and may carry arguments when the trait is called. Traits are a special grammar category and are allowed to be placed after most language object names or parameter lists.

say 'start';
multi sub trait_mod:<is>(Sub $s, :$foo){
    say "⟨is foo⟩ has been called with ⟨$foo⟩ on {$s.WHICH}";
}
sub bar() is foo<oi‽> {
    say 'bar has been called'
}
bar();
# OUTPUT: «⟨is foo⟩ has been called with ⟨oi‽⟩ on Sub|47563000␤start␤bar has been called␤»

Use destructuring to call traits with complex arguments.

multi trait_mod:<is>(Variable $a, :@foo [$firstpos, *@restpos, :$named, *%restnameds]) {
    say [$firstpos, @restpos, $named, %restnameds]
}
my $x is foo[1,2,3,:named<a>, :2b, :3c] = 1
# OUTPUT: «[1 [2 3] a {b => 2, c => 3}]␤»

Despite its funky syntax, a trait is just a normal Sub. We can apply traits to it (or even themselves) and we can apply traits to objects at runtime.

multi sub trait_mod:<is> (Sub $s, :$foo) is foo {
    say 'is foo called'
}
sub bar {}
&trait_mod:<is>(&bar, :foo);
# OUTPUT: «is foo called␤is foo called␤»

260 class Submethod

Member function that is not inherited by subclasses

class Submethod is Routine {}

A Submethod is a method that is not inherited by child classes. They are typically used for per-class initialization and tear-down tasks which are called explicitly per class in an inheritance tree, usually for enforcing a particular order. For example object construction with the BUILD submethod happens from the least-derived to most-derived, so that the most-derived (child) classes can depend on the parent already being initialized.

Submethods are of type Submethod, and are declared with the submethod declarator:

class Area {
    has $.size;
    submethod BUILD(:$x, :$y, :$z) {
        $!size = $x * $y * $z;
    }
}

Methods

method gist

Defined as:

multi method gist(Submethod:D:)

Returns the name of the submethod.

261 class Supplier

Live Supply factory

class Supplier { }

This is a factory for live Supply objects, which provides the mechanism for emitting new values onto the supplies:

my $supplier = Supplier.new;
my $supply_1 = $supplier.Supply;
$supply_1.tap(-> $v { say "One $v" });
my $supply_2 = $supplier.Supply;
$supply_2.tap(-> $v { say "Two $v" });
$supplier.emit(42);

Will output:

One 42 
 Two 42 

on demand supplies are created by the factory methods of the Supply class or by the supply keyword. A mixture of a live and on-demand Supply can be created with a Supplier::Preserving.

Methods

method new

method new()

The Supplier constructor.

method Supply

method Supply(Supplier:D: --> Supply)

This creates a new Supply object to which any values which are emitted on this supplier are passed. This is the factory for all live supplies.

method emit

method emit(Supplier:D: Mu \value)

Sends the given value to all of the taps on all of the supplies created by Supply on this Supplier.

method done

method done(Supplier:D:)

Calls the done callback on all the taps that have one.

my $supplier = Supplier.new;
my $supply   = $supplier.Supply;
$supply.tap(-> $v { say $v }, done => { say "no more answers" });
$supplier.emit(42);
$supplier.done;

Will output:

42 
 no more answers 

method quit

multi method quit(Supplier:D: Exception $ex)
multi method quit(Supplier:D: Str() $message)

Calls the quit callback on all the taps that have one, passing the exception to them. If called with a Str the exception will be an X::AdHoc with the supplied message.

This is meant for shutting down a supply with an error.

262 class Supplier::Preserving

Cached live Supply factory

class Supplier::Preserving is Supplier { }

This is a factory for live Supply objects, which provides the mechanism for emitting new values onto the supplies, whereby values are kept when no consumer has tapped into the Supply. Any tapping will consume the already stored and future values.

Starting a preserving Supply and consuming its values after it is done:

my $p = Supplier::Preserving.new;
start for ^3 {
    $p.emit($_);
    LAST {
        say „done after { now - BEGIN now}s“;
        $p.done;
    }
}
sleep 2;
react {
    whenever $p.Supply { $_.say; }
    whenever Promise.in(2) { done }
}
say „also done after { now - BEGIN now }s“

Will output:

done after 0.0638467s 
 0 
 1 
 2 
 also done after 4.0534119s 

Methods

method new

method new()

The Supplier constructor.

263 class Supply

Asynchronous data stream with multiple subscribers

class Supply {}

A supply is a thread-safe, asynchronous data stream like a Channel, but it can have multiple subscribers (taps) that all get the same values flowing through the supply.

It is a thread-safe implementation of the Observer Pattern, and central to supporting reactive programming in Perl 6.

There are two types of Supplies: live and on demand. When tapping into a live supply, the tap will only see values that are flowing through the supply after the tap has been created. Such supplies are normally infinite in nature, such as mouse movements. Closing such a tap does not stop mouse events from occurring, it just means that the values will go by unseen. All tappers see the same flow of values.

A tap on an on demand supply will initiate the production of values, and tapping the supply again may result in a new set of values. For example, Supply.interval produces a fresh timer with the appropriate interval each time it is tapped. If the tap is closed, the timer simply stops emitting values to that tap.

A live Supply is obtained from the Supplier factory method Supply. New values are emitted by calling emit on the Supplier object.

my $supplier = Supplier.new;
my $supply = $supplier.Supply;
$supply.tap(-> $v { say "$v" });
$supplier.emit(42); # Will cause the tap to output "42"

The live method returns True on live supplies. Factory methods such as interval, from-list will return on demand supplies.

A live Supply that keeps values until tapped the first time can be created with Supplier::Preserving.

Further examples can be found in the concurrency page.

Methods that return Taps

method tap

method tap(Supply:D: &emit = -> $ { }, 
         :&done, 
         :&quit, 
         :&tap 
     --> Tap:D) 

Creates a new tap (a kind of subscription if you will), in addition to all existing taps. The first positional argument is a piece of code that will be called when a new value becomes available through the emit call.

The &done callback can be called in a number of cases: if a supply block is being tapped, when a done routine is reached; if a supply block is being tapped, it will be automatically triggered if the supply block reaches the end; if the done method is called on the parent Supplier (in the case of a supply block, if there are multiple Suppliers referenced by whenever, they must all have their done method invoked for this to trigger the &done callback of the tap as the block will then reach its end).

The &quit callback is called if the tap is on a supply block which exits with an error. It is also called if the quit method is invoked on the parent Supplier (in the case of a supply block any one Supplier quitting with an uncaught exception will call the &quit callback as the block will exit with an error). The error is passed as a parameter to the callback.

The &tap callback is called once the Tap object is created, which is passed as a parameter to the callback. The callback is called ahead of emit/done/quit, providing a reliable way to get the Tap object. One case where this is useful is when the Supply begins emitting values synchronously, since the call to .tap won't return the Tap object until it is done emitting, preventing it from being stopped if needed.

Method tap returns an object of type Tap, on which you can call the close method to cancel the subscription.

my $s = Supply.from-list(0 .. 5);
my $t = $s.tap(-> $v { say $v }, done => { say "no more ticks" });

Produces:

0 
 1 
 2 
 3 
 4 
 5 
 no more ticks 

method act

method act(Supply:D: &act --> Tap:D)

Creates a tap on the given supply with the given code. Differently from tap, the given code is guaranteed to be only executed by one thread at a time.

Utility methods

method Capture

Defined as:

method Capture(Supply:D --> Capture:D)

Equivalent to calling .List.Capture on the invocant.

method Channel

method Channel(Supply:D: --> Channel:D)

Returns a Channel object that will receive all future values from the supply, and will be closed when the Supply is done, and quit (shut down with error) when the supply is quit.

method Promise

method Promise(Supply:D: --> Promise:D)

Returns a Promise that will be kept when the Supply is done. If the Supply also emits any values, then the Promise will be kept with the final value. Otherwise, it will be kept with Nil. If the Supply ends with a quit instead of a done, then the Promise will be broken with that exception.

my $supplier = Supplier.new;
my $s = $supplier.Supply;
my $p = $s.Promise;
$p.then(-> $v { say "got $v.result()" });
$supplier.emit('cha');         # not output yet
$supplier.done();              # got cha

The Promise method is most useful when dealing with supplies that will tend to produce just one value, when only the final value is of interest, or when only completion (successful or not) is relevant.

method live

method live(Supply:D: --> Bool:D)

Returns True if the supply is "live", that is, values are emitted to taps as soon as they arrive. Always returns True in the default Supply (but for example on the supply returned from Supply.from-list it's False).

say Supplier.new.Supply.live;    # OUTPUT: «True␤»

method schedule-on

method schedule-on(Supply:D: Scheduler $scheduler)

Runs the emit, done and quit callbacks on the specified scheduler.

This is useful for GUI toolkits that require certain actions to be run from the GUI thread.

Methods that wait until the supply is done

method wait

method wait(Supply:D:)

Taps the Supply it is called on, and blocks execution until the either the supply is done (in which case it evaluates to the final value that was emitted on the Supply, or Nil if not value was emitted) or quit (in which case it will throw the exception that was passed to quit).

my $s = Supplier.new;
start {
  sleep 1;
  say "One second: running.";
  sleep 1;
  $s.emit(42);
  $s.done;
}
$s.Supply.wait;
say "Two seconds: done";

method list

method list(Supply:D: --> List:D)

Taps the Supply it is called on, and returns a lazy list that will be reified as the Supply emits values. The list will be terminated once the Supply is done. If the Supply quits, then an exception will be thrown once that point in the lazy list is reached.

method grab

method grab(Supply:D: &when-done --> Supply:D)

Taps the Supply it is called on. When it is done, calls &when-done and then emits the list of values that it returns on the result Supply. If the original Supply quits, then the exception is immediately conveyed on the return Supply.

my $s = Supply.from-list(4, 10, 3, 2);
my $t = $s.grab(&sum);
$t.tap(&say);           # OUTPUT: «19␤»

method reverse

method reverse(Supply:D: --> Supply:D)

Taps the Supply it is called on. Once that Supply emits done, all of the values it emitted will be emitted on the returned Supply in reverse order. If the original Supply quits, then the exception is immediately conveyed on the return Supply.

my $s = Supply.from-list(1, 2, 3);
my $t = $s.reverse;
$t.tap(&say);           # OUTPUT: «3␤2␤1␤»

method sort

method sort(Supply:D: &custom-routine-to-use? --> Supply:D)

Taps the Supply it is called on. Once that Supply emits done, all of the values that it emitted will be sorted, and the results emitted on the returned Supply in the sorted order. Optionally accepts a comparator Block. If the original Supply quits, then the exception is immediately conveyed on the return Supply.

my $s = Supply.from-list(4, 10, 3, 2);
my $t = $s.sort();
$t.tap(&say);           # OUTPUT: «2␤3␤4␤10␤»

Methods that return another Supply

method from-list

method from-list(Supply:U: +@values --> Supply:D)

Creates an on-demand supply from the values passed to this method.

my $s = Supply.from-list(1, 2, 3);
$s.tap(&say);           # OUTPUT: «1␤2␤3␤»

method share

method share(Supply:D: --> Supply:D)

Creates a live supply from an on-demand supply, thus making it possible to share the values of the on-demand supply on multiple taps, instead of each tap seeing its own copy of all values from the on-demand supply.

# this says in turn: "first 1" "first 2" "second 2" "first 3" "second 3"
my $s = Supply.interval(1).share;
$s.tap: { "first $_".say };
sleep 1.1;
$s.tap: { "second $_".say };
sleep 2

method flat

method flat(Supply:D: --> Supply:D)

Creates a supply on which all of the values seen in the given supply are flattened before being emitted again.

method do

method do(Supply:D: &do --> Supply:D)

Creates a supply to which all values seen in the given supply, are emitted again. The given code, executed for its side-effects only, is guaranteed to be only executed by one thread at a time.

method on-close

method on-close(Supply:D: &on-close --> Supply:D)

Returns a new Supply which will run &on-close whenever a Tap of that Supply is closed. This includes if further operations are chained on to the Supply. (for example, $supply.on-close(&on-close).map(*.uc)). When using a react or supply block, using the CLOSE phaser is usually a better choice.

my $s = Supplier.new;
my $tap = $s.Supply.on-close({ say "Tap closed" }).tap(
    -> $v { say "the value is $v" },
    done    => { say "Supply is done" },
    quit    => -> $ex { say "Supply finished with error $ex" },
);

$s.emit('Perl 6');
$tap.close;        # OUTPUT: «Tap closed␤»

method interval

method interval(Supply:U: $interval, $delay = 0, :$scheduler = $*SCHEDULER --> Supply:D)

Creates a supply that emits a value every $interval seconds, starting $delay seconds from the call. The emitted value is an integer, starting from 0, and is incremented by one for each value emitted.

Implementations may treat too-small values as lowest resolution they support, possibly warning in such situations; e.g. treating 0.0001 as 0.001. For 6.d language version, the minimal value specified is 0.001.

method grep

method grep(Supply:D: Mu $test --> Supply:D)

Creates a new supply that only emits those values from the original supply that smartmatch against $test.

my $supplier = Supplier.new;
my $all      = $supplier.Supply;
my $ints     = $all.grep(Int);
$ints.tap(&say);
$supplier.emit($_) for 1, 'a string', 3.14159;   # prints only 1

method map

method map(Supply:D: &mapper --> Supply:D)

Returns a new supply that maps each value of the given supply through &mapper and emits it to the new supply.

my $supplier = Supplier.new;
my $all      = $supplier.Supply;
my $double   = $all.map(-> $value { $value * 2 });
$double.tap(&say);
$supplier.emit(4);           # RESULT: «8»

method batch

method batch(Supply:D: :$elems, :$seconds --> Supply:D)

Creates a new supply that batches the values of the given supply by either the number of elements in the batch (using :elems) or the maximum number of seconds (using the :seconds) or both. Any remaining values are emitted in a final batch when the supply is done.

method elems

method elems(Supply:D: $seconds? --> Supply:D)

Creates a new supply in which changes to the number of values seen are emitted. It optionally also takes an interval (in seconds) if you only want to be updated every so many seconds.

method head

method head(Supply:D: Int(Cool) $number = 1 --> Supply:D)

Creates a "head" supply with the same semantics as List.head.

my $s = Supply.from-list(4, 10, 3, 2);
my $hs = $s.head(2);
$hs.tap(&say);           # OUTPUT: «4␤10␤»

method tail

method tail(Supply:D: Int(Cool) $number = 1 --> Supply:D)

Creates a "tail" supply with the same semantics as List.tail.

my $s = Supply.from-list(4, 10, 3, 2);
my $ts = $s.tail(2);
$ts.tap(&say);           # OUTPUT: «3␤2␤»

method rotor

method rotor(Supply:D: @cycle --> Supply:D)

Creates a "rotoring" supply with the same semantics as List.rotor.

method delayed

method delayed(Supply:D: $seconds, :$scheduler = $*SCHEDULER --> Supply:D)

Creates a new supply in which all values flowing through the given supply are emitted, but with the given delay in seconds.

method throttle

method throttle(Supply:D: 
   $limit,                 # values / time or simultaneous processing 
   $seconds or $callable,  # time-unit / code to process simultaneously 
   $delay = 0,             # initial delay before starting, in seconds 
   :$control,              # supply to emit control messages on (optional) 
   :$status,               # supply to tap status messages from (optional) 
   :$bleed,                # supply to bleed messages to (optional) 
   :$vent-at,              # bleed when so many buffered (optional) 
   :$scheduler,            # scheduler to use, default $*SCHEDULER 
   --> Supply:D) 

Produces a Supply from a given Supply, but makes sure the number of messages passed through, is limited.

It has two modes of operation: per time-unit or by maximum number of execution of a block of code: this is determined by the second positional parameter.

The first positional parameter specifies the limit that should be applied.

If the second positional parameter is a Callable, then the limit indicates the maximum number of parallel processes executing the Callable, which is given the value that was received. The emitted values in this case will be the Promises that were obtained from starting the Callable.

If the second positional parameter is a numeric value, it is interpreted as the time-unit (in seconds). If you specify .1 as the value, then it makes sure you don't exceed the limit for every tenth of a second.

If the limit is exceeded, then incoming messages are buffered until there is room to pass on / execute the Callable again.

The third positional parameter is optional: it indicates the number of seconds the throttle will wait before passing on any values.

The :control named parameter optionally specifies a Supply that you can use to control the throttle while it is in operation. Messages that can be sent, are strings in the form of "key:value". Please see below for the types of messages that you can send to control the throttle.

The :status named parameter optionally specifies a Supply that will receive any status messages. If specified, it will at least send one status message after the original Supply is exhausted. See status message below.

The :bleed named parameter optionally specifies a Supply that will receive any values that were either explicitly bled (with the bleed control message), or automatically bled (if there's a vent-at active).

The :vent-at named parameter indicates the number of values that may be buffered before any additional value will be routed to the :bleed Supply. Defaults to 0 if not specified (causing no automatic bleeding to happen). Only makes sense if a :bleed Supply has also been specified.

The :scheduler named parameter indicates the scheduler to be used. Defaults to $*SCHEDULER.

control messages

These messages can be sent to the :control Supply. A control message consists of a string of the form "key: value", e.g. "limit: 4".

Change the number of messages (as initially given in the first positional) to the value given.

Route the given number of buffered messages to the :bleed Supply.

Change the maximum number of buffered values before automatic bleeding takes place. If the value is lower than before, will cause immediate rerouting of buffered values to match the new maximum.

Send a status message to the :status Supply with the given id.

status message

The status return message is a hash with the following keys:

The current number of messages / callables that is still allowed to be passed / executed.

The number of messages routed to the :bleed Supply.

The number of messages currently buffered because of overflow.

The number of messages emitted (passed through).

The id of this status message (a monotonically increasing number). Handy if you want to log status messages.

The current limit that is being applied.

The maximum number of messages that may be buffered before they're automatically re-routed to the :bleed Supply.

Examples

Have a simple piece of code announce when it starts running asynchronously, wait a random amount of time, then announce when it is done. Do this 6 times, but don't let more than 3 of them run simultaneously.

my $s = Supply.from-list(^6);  # set up supply
my $t = $s.throttle: 3,        # only allow 3 at a time
{                              # code block to run
    say "running $_";          # announce we've started
    sleep rand;                # wait some random time
    say "done $_"              # announce we're done
}                              # don't need ; because } at end of line
$t.wait;                       # wait for the supply to be done

and the result of one run will be:

running 0 
 running 1 
 running 2 
 done 2 
 running 3 
 done 1 
 running 4 
 done 4 
 running 5 
 done 0 
 done 3 
 done 5 

method stable

method stable(Supply:D: $time, :$scheduler = $*SCHEDULER --> Supply:D)

Creates a new supply that only passes on a value flowing through the given supply if it wasn't superseded by another value in the given $time (in seconds). Optionally uses another scheduler than the default scheduler, using the :scheduler parameter.

To clarify the above, if, during the timeout $time, additional values are emitted to the Supplier all but the last one will be thrown away. Each time an additional value is emitted to the Supplier, during the timeout, $time is reset.

This method can be quite useful when handling UI input, where it is not desired to perform an operation until the user has stopped typing for a while rather than on every keystroke.

my $supplier = Supplier.new; 
 my $supply1 = $supplier.Supply; 
 $supply1.tap(-> $v { say "Supply1 got: $v" }); 
 $supplier.emit(42); 
 
 my Supply $supply2 = $supply1.stable(5); 
 $supply2.tap(-> $v { say "Supply2 got: $v" }); 
 sleep(3); 
 $supplier.emit(43);  # will not be seen by $supply2 but will reset $time 
 $supplier.emit(44); 
 sleep(10); 
 # OUTPUT: «Supply1 got: 42␤Supply1 got: 43␤Supply1 got: 44␤Supply2 got: 44␤» 

As can be seen above, $supply1 received all values emitted to the Supplier while $supply2 only received one value. The 43 was thrown away because it was followed by another 'last' value 44 which was retained and sent to $supply2 after approximately eight seconds, this due to the fact that the timeout $time was reset after three seconds.

method reduce

method reduce(Supply:D: &with --> Supply:D)

Creates a "reducing" supply with the same semantics as List.reduce.

my $supply = Supply.from-list(1..5).reduce({$^a + $^b});
$supply.tap(-> $v { say "$v" }); # OUTPUT: «15␤»

method produce

method produce(Supply:D: &with --> Supply:D)

Creates a "producing" supply with the same semantics as List.produce.

my $supply = Supply.from-list(1..5).produce({$^a + $^b});
$supply.tap(-> $v { say "$v" }); # OUTPUT: «1␤3␤6␤10␤15␤»

method lines

method lines(Supply:D: :$chomp = True --> Supply:D)

Creates a supply that will emit the characters coming in line by line from a supply that's usually created by some asynchronous I/O operation. The optional :chomp parameter indicates whether to remove line separators: the default is True.

method words

method words(Supply:D: --> Supply:D)

Creates a supply that will emit the characters coming in word for word from a supply that's usually created by some asynchronous I/O operation.

my $s = Supply.from-list("Hello Word!".comb);
my $ws = $s.words;
$ws.tap(&say);           # OUTPUT: «Hello␤Word!␤»

method unique

method unique(Supply:D: :$as, :$with, :$expires --> Supply:D)

Creates a supply that only provides unique values, as defined by the optional :as and :with parameters (same as with List.unique). The optional :expires parameter how long to wait (in seconds) before "resetting" and not considering a value to have been seen, even if it's the same as an old value.

method squish

method squish(Supply:D: :$as, :$with --> Supply:D)

Creates a supply that only provides unique values, as defined by the optional :as and :with parameters (same as with List.squish).

method max

method max(Supply:D: &custom-routine-to-use = &infix:<cmp> --> Supply:D)

Creates a supply that only emits values from the given supply if they are larger than any value seen before. In other words, from a continuously ascending supply it will emit all the values. From a continuously descending supply it will only emit the first value. The optional parameter specifies the comparator, just as with Any.max.

method min

method min(Supply:D: &custom-routine-to-use = &infix:<cmp> --> Supply:D)

Creates a supply that only emits values from the given supply if they are smaller than any value seen before. In other words, from a continuously descending supply it will emit all the values. From a continuously ascending supply it will only emit the first value. The optional parameter specifies the comparator, just as with Any.min.

method minmax

method minmax(Supply:D: &custom-routine-to-use = &infix:<cmp> --> Supply:D)

Creates a supply that emits a Range every time a new minimum or maximum values is seen from the given supply. The optional parameter specifies the comparator, just as with Any.minmax.

method skip

method skip(Supply:D: Int(Cool) $number = 1 --> Supply:D)

Returns a new Supply which will emit all values from the given Supply except for the first $number values, which will be thrown away.

my $supplier = Supplier.new; 
 my $supply = $supplier.Supply; 
 $supply = $supply.skip(3); 
 $supply.tap({ say $_ }); 
 $supplier.emit($_) for 1..10; # OUTPUT: «4␤5␤6␤7␤8␤9␤10␤» 

method start

method start(Supply:D: &startee --> Supply:D)

Creates a supply of supplies. For each value in the original supply, the code object is scheduled on another thread, and returns a supply either of a single value (if the code succeeds), or one that quits without a value (if the code fails).

This is useful for asynchronously starting work that you don't block on.

Use migrate to join the values into a single supply again.

method migrate

method migrate(Supply:D: --> Supply:D)

Takes a Supply which itself has values that are of type Supply as input. Each time the outer Supply emits a new Supply, this will be tapped and its values emitted. Any previously tapped Supply will be closed. This is useful for migrating between different data sources, and only paying attention to the latest one.

For example, imagine an application where the user can switch between different stocks. When they switch to a new one, a connection is established to a web socket to get the latest values, and any previous connection should be closed. Each stream of values coming over the web socket would be represented as a Supply, which themselves are emitted into a Supply of latest data sources to watch. The migrate method could be used to flatten this supply of supplies into a single Supply of the current values that the user cares about.

Here is a simple simulation of such a program:

my Supplier $stock-sources .= new; 
 
 sub watch-stock($symbol) { 
     $stock-sources.emit: supply { 
         say "Starting to watch $symbol"; 
         whenever Supply.interval(1) { 
             emit "$symbol: 111." ~ 99.rand.Int; 
         } 
         CLOSE say "Lost interest in $symbol"; 
     } 
 } 
 
 $stock-sources.Supply.migrate.tap: *.say; 
 
 watch-stock('GOOG'); 
 sleep 3; 
 watch-stock('AAPL'); 
 sleep 3; 

Which produces output like:

Starting to watch GOOG 
 GOOG: 111.67 
 GOOG: 111.20 
 GOOG: 111.37 
 Lost interest in GOOG 
 Starting to watch AAPL 
 AAPL: 111.55 
 AAPL: 111.6 
 AAPL: 111.6 

Methods that combine supplies

method merge

method merge(Supply @*supplies --> Supply:D)

Creates a supply to which any value seen from the given supplies, is emitted. The resulting supply is done Only when all given supplies are done. Can also be called as a class method.

method zip

method zip(Supply @*supplies, :&with = &[,] --> Supply:D)

Creates a supply that emits combined values as soon as there is a new value seen on all of the supplies. By default, Lists are created, but this can be changed by specifying your own combiner with the :with parameter. The resulting supply is done as soon as any of the given supplies are done. Can also be called as a class method.

method zip-latest

method zip-latest(Supply @*supplies, :&with = &[,], :$initial --> Supply:D)

Creates a supply that emits combined values as soon as there is a new value seen on any of the supplies. By default, Lists are created, but this can be changed by specifying your own combiner with the :with parameter. The optional :initial parameter can be used to indicate the initial state of the combined values. By default, all supplies have to have at least one value emitted on them before the first combined values is emitted on the resulting supply. The resulting supply is done as soon as any of the given supplies are done. Can also be called as a class method.

I/O features exposed as supplies

sub signal

sub signal(*@signals, :$scheduler = $*SCHEDULER)

Creates a supply for the Signal enums (such as SIGINT) specified, and an optional :scheduler parameter. Any signals received, will be emitted on the supply. For example:

signal(SIGINT).tap( { say "Thank you for your attention"; exit 0 } );

would catch Control-C, thank you, and then exit.

To go from a signal number to a Signal, you can do something like this:

signal(Signal(2)).tap( -> $sig { say "Received signal: $sig" } );

The list of supported signals can be found by checking Signal::.keys (as you would any enum). For more details on how enums work see enum.

Note: Rakudo versions up to 2018.05 had a bug due to which numeric values of signals were incorrect on some systems. For example, Signal(10) was returning SIGBUS even if it was actually SIGUSR1 on a particular system. That being said, using signal(SIGUSR1) was working as expected on all Rakudo versions except 2018.04, 2018.04.1 and 2018.05, where the intended behavior can be achieved by using signal(SIGBUS) instead. These issues are resolved in Rakudo releases after 2018.05.

method IO::Notification.watch-path

method watch-path($path --> Supply:D) 

Creates a supply to which the OS will emit values to indicate changes on the filesystem for the given path. Also has a shortcut with the watch method on an IO object, like this:

IO::Notification.watch-path(".").act( { say "$^file changed" } ); 
 ".".IO.watch.act(                     { say "$^file changed" } );   # same 

264 role Systemic

Information related to the build system

Built-in class for providing built system related information. Usually accessed through dynamic variables mixing this role such as the $*KERNEL, $*VM, or $*PERL.

Methods

method auth

Instance method returning the "auth" (as in "author" or "authority") of the object. Returns "unknown" if the "auth" could not be established.

method config

Instance returning a hash with object configuration information. Subject to change without notice, but can be helpful in environments where only one type of virtual machine is in use, or to find about the configuration of any other object that mixes in this role.

method desc

Instance method returning the "desc" (as in "description") of the VM object. Returns a Str type object if the "desc" could not be established.

method name

Instance method returning the name of the object.

method signature

Instance method returning the signature of the object. Returns a Blob type object if the signature could not be established.

method version

Instance method returning the version of the object as a Version object. Returns a Version object "unknown" if the version could not be established.

method gist

method gist( Systemic:D: )

Instance method returning the name and version of the object.

say $*PERL.gist; # OUTPUT: «Perl 6 (6.c)␤»

$*PERL is an object of the Perl type, which mixes in this role and thus implements this method.

method Str

method Str

Instance method returning the name of the object.

say $*PERL.Str; # OUTPUT: «Perl 6␤»

265 class Tap

Subscription to a Supply

class Tap {}

A Tap is a subscription to a Supply.

my $s = Supplier.new;
my $tap = $s.Supply.on-close({ say "Tap closed" }).tap(
    -> $v { say "the value is $v" },
    done    => { say "Supply is done" },
    quit    => -> $ex { say "Supply finished with error $ex" },
);

# later
$tap.close;

Methods

method close

method close(Tap:D:)

Closes the tap.

266 class Telemetry

Collect performance state for analysis

class Telemetry { }

Note: This class is a Rakudo-specific feature and not standard Perl 6.

On creation, a Telemetry object contains a snapshot of various aspects of the current state of the virtual machine. This is in itself useful, but generally one needs two snapshots for the difference (which is a Telemetry::Period object).

The Telemetry object is really a collection of snapshots taken by different "instruments". By default, the Telemetry::Instrument::Usage and Telemetry::Instrument::ThreadPool instruments are activated.

The Telemetry (and Telemetry::Period) object also Associative. This means that you can treat a Telemetry object as a read-only Hash, with all of the data values of the instruments as keys.

You can determine which instruments Telemetry should use by setting the $*SAMPLER dynamic variable, which is a Telemetry::Sampler object.

Currently, the following instruments are supported by the Rakudo core:

Provides (in alphabetical order): cpu, cpu-sys, cpu-user, cpus, id-rss, inb, invcsw, is-rss, ix-rss, majf, max-rss, minf, mrcv, msnd, nsig, nswp, volcsw, outb, util% and wallclock. For complete documentation of the meaning of these data values, see Telemetry::Instrument::Usage.

Provides (in alphabetical order): tad, tcd, thid, tjd, tsd and tys. For complete documentation of the meaning of these data values, see Telemetry::Instrument::Thread.

Provides (in alphabetical order): atc, atq, aw, gtc, gtq, gw, s, ttc, ttq and tw. For complete documentation of the meaning of these data values, see Telemetry::Instrument::ThreadPool.

Does not provide any data by itself: one must indicate which variables are to be monitored, which will then become available as methods with the same name on the instrument. For complete documentation, see Telemetry::Instrument::AdHoc.

routine T

sub T()

Shortcut for Telemetry.new. It is exported by default. Since the Telemetry class also provides an Associative interface, one can easily interpolate multiple values in a single statement:

use Telemetry; 
 say "Used {T<max-rss cpu>} (KiB CPU) so far"; 

routine snap

multi sub snap(--> Nil)
multi sub snap(@s --> Nil)

The snap subroutine is shorthand for creating a new Telemetry object and pushing it to an array for later processing. It is exported by default.

use Telemetry; 
 my @t; 
 for ^5 { 
     snap(@t); 
     # do some stuff 
     LAST snap(@t); 
 } 

If no array is specified, it will use an internal array for convenience.

routine snapper

sub snapper($sleep = 0.1, :$stop, :$reset --> Nil)

The snapper routine starts a separate thread that will call snap repeatedly until the end of program. It is exported by default.

By default, it will call snap every 0.1 second. The only positional parameter is taken to be the delay between snaps.

Please see the snapper module for externally starting a snapper without having to change the code. Simply adding -Msnapper as a command line parameter, will then start a snapper for you.

routine periods

multi sub periods( --> Seq)
multi sub periods(@s --> Seq)

The periods subroutine processes an array of Telemetry objects and generates a Seq of Telemetry::Period objects out of that. It is exported by default.

.<cpu wallclock>.say for periods(@t); 
 
 # OUTPUT: 
 # ==================== 
 # (164 / 160) 
 # (23 / 21) 
 # (17 / 17) 
 # (15 / 16) 
 # (29 / 28) 

If no array is specified, it will use the internal array of snap without parameters and will reset that array upon completion (so that new snaps can be added again).

use Telemetry; 
 for ^5 { 
     snap; 
     LAST snap; 
 } 
 say .<cpu wallclock>.join(" / ") for periods; 
 
 # OUTPUT: 
 # ==================== 
 # 172 / 168 
 # 24 / 21 
 # 17 / 18 
 # 17 / 16 
 # 27 / 27 

If only one snap was done, another snap will be done to create at least one Telemetry::Period object.

routine report

multi sub report(:@columns, :$legend, :$header-repeat, :$csv, :@format)

The report subroutine generates a report about an array of Telemetry objects. It is exported by default. These can have been created by regularly calling snap, or by having a snapper running. If no positional parameter is used, it will assume the internal array to which the parameterless snap pushes.

Below are the additional named parameters of report.

Specify the names of the columns to be included in the report. Names can be specified with the column name (e.g. gw). If not specified, defaults to what is specified in the RAKUDO_REPORT_COLUMNS environment variable. If that is not set either, defaults to:

wallclock util% max-rss gw gtc tw ttc aw atc 

Specifies after how many lines the header should be repeated in the report. If not specified, defaults to what is specified in the RAKUDO_REPORT_HEADER_REPEAT environment variable. If that is not set either, defaults to 32.

Specifies whether a legend should be added to the report. If not specified, defaults to what is specified in the RAKUDO_REPORT_LEGEND environment variable. If that is not set either, defaults to True.

If there are snaps available in the internal array at the end of the program, then report will be automatically generated and printed on STDERR.

module snapper

Start a thread taking repeated system state snapshots.

This module contains no subroutines or methods or anything. It is intended as a shortcut for starting the snapper subroutine of the Telemetry module, allowing taking snapshots of the execution of a program without needing to change the program. Simple loading the module with -Msnapper will do all that is needed to start the snapper, and have a report printed on STDERR upon completion of the program.

The RAKUDO_SNAPPER environment variable can be set to indicate the time between snapshots. If not specified, it will default to 0.1 seconds.

267 class Telemetry::Instrument::Thread

Instrument for collecting Thread data

class Telemetry::Instrument::Thread { }

Note: This class is a Rakudo-specific feature and not standard Perl 6.

Objects of this class are generally not created by themselves, but rather through making a snapshot.

This class provides the following data points (in alphabetical order):

The number of threads that ended with an exception (threads-aborted).

The number of threads that completed without any problem (threads-completed).

Highest OS thread ID seen (thread-highest-id).

The number of threads that were joined (threads-joined).

The number of threads that were started (threads-started).

The number of times a thread was yielded (threads-yielded).

268 class Telemetry::Instrument::ThreadPool

Instrument for collecting ThreadPoolScheduler data

class Telemetry::Instrument::ThreadPool { }

Note: This class is a Rakudo-specific feature and not standard Perl 6.

Objects of this class are generally not created by themselves, but rather through making a snapshot.

This class provides the following data points (in alphabetical order):

The number of tasks completed by affinity thread workers (affinity-tasks-completed).

The number of tasks queued for execution for affinity thread workers (affinity-tasks-queued).

The number of affinity thread workers (affinity-workers).

The number of tasks completed by general workers (general-tasks-completed).

The number of tasks queued for execution by general worker (general-tasks-queued).

The number of general workers (general-workers).

The number of supervisor threads running, usually 0 or 1 (supervisor>).

The number of tasks completed by timer workers (timer-tasks-completed).

The number of tasks queued for execution by timer workers (timer-tasks-queued).

The number of timer workers (timer-workers).

269 class Telemetry::Instrument::Usage

Instrument for collecting getrusage data

class Telemetry::Instrument::Usage { }

Note: This class is a Rakudo-specific feature and not standard Perl 6.

Objects of this class are generally not created by themselves, but rather through making a snapshot.

Useful readings

This class provides the following generally usable readings (in alphabetical order):

The total amount of CPU time (in microseconds), essentially the sum of cpu-user and cpu-sys.

The number of microseconds of CPU used by the system.

The number of microseconds of CPU used by the user program.

The number of CPU's active, essentially cpu divided by wallclock.

The maximum resident set size (in KiB).

Percentage of CPU utilization, essentially 100 * cpus / number of CPU cores.

The time the program has been executing (in microseconds).

Less useful readings

The following readings may or may not contain sensible information, mostly depending on hardware and OS being used. Please check your local getrusage documentation for their exact meaning:

name        getrusage struct name 
 ====        ===================== 
 max-rss     ru_maxrss 
 ix-rss      ru_ixress 
 id-rss      ru_idrss 
 is-rss      ru_isrss 
 minf        ru_minflt 
 majf        ru_majflt 
 nswp        ru_nswap 
 inb         ru_inblock 
 outb        ru_oublock 
 msnd        ru_msgsnd 
 mrcv        ru_msgrcv 
 nsig        ru_nsignals 
 volcsw      ru_nvcsw 
 invcsw      ru_nivcsw 

270 class Telemetry::Period

Performance data over a period

class Telemetry::Period is Telemetry { } 

Note: This class is a Rakudo-specific feature and not standard Perl 6.

# basic usage 
 use Telemetry; 
 my $t0 = Telemetry.new; 
 # execute some code 
 my $t1 = Telemetry.new; 
 my $period = $t1 - $t0;  # creates Telemetry::Period object 
 say "Code took $period<wallclock> microseconds to execute"; 

A Telemetry::Period object contains the difference between two Telemetry objects. It is generally not created by calling .new, but it can be if needed. For all practical purposes, it is the same as the Telemetry object, but the meaning of the values is different (and the values are generally much smaller, as they usually are the difference of two big values of the Telemetry objects from which it was created).

271 class Telemetry::Sampler

Telemetry instrument pod

class Telemetry::Sampler { } 

Note: This class is a Rakudo-specific feature and not standard Perl 6.

use Telemetry; 
 $*SAMPLER.set-instruments(<Usage ThreadPool>); # default setting 

One usually does not create any Telemetry::Sampler objects: when the Telemetry module is loaded, a Telemetry::Sampler object is automatically created in the $*SAMPLER dynamic variable.

An object of the Telemetry::Sampler class knows about which instruments to use when making a snapshot.

method new

method new(Telemetry::Sampler: @instruments --> Telemetry::Sampler:D) 

The new method takes a list of instruments. If no instruments are specified, then it will look at the RAKUDO_TELEMETRY_INSTRUMENTS environment variable to find specification of instruments. If that is not available either, then Telemetry::Instrument::Usage and Telemetry::Instrument::ThreadPool will be assumed.

Instruments can be specified by either the type object of the instrument class (e.g. Telemetry::Instrument::Usage) or by a string, in which case it will be automatically prefixed with "Telemetry::Instrument::", so "Usage" would be the same as Telemetry::Instrument::Usage.

method set-instruments

method set-instruments(Telemetry::Sampler:D @instruments --> Nil) 

Allows one to change the instruments on an existing Instrument::Sampler object. Generally only used by calling it on the $*SAMPLER dynamic variable. Takes the same parameters as new, except that specifying no instruments will actually remove all of the instruments, effectively blocking any snap taking.

272 module Test

Writing and running tests

This module provides a testing framework, and is used in the official suite that tests the specification. All its functions emit output conforming to the Test Anything Protocol.

Methods

sub plan

Defined as:

multi sub plan(Cool:D :skip-all($reason)!)
multi sub plan($number_of_tests)

Specify the count of tests -- usually written at the beginning of a test file.

plan 15;   # expect to run 15 tests 

In subtests, plan is used to specify the count of tests within the subtest.

If a plan is used, it's not necessary to specify the end of testing with done-testing.

You can also provide a :skip-all named argument instead of a test count, to indicate that you want to skip all of the tests. Such a plan will call exit, unless used inside of a subtest.

plan :skip-all<These tests are only for Windows> unless $*DISTRO.is-win; 
 plan 1; 
 ok dir 'C:/'; # this won't get run on non-Windows 

If used in a subtest, it will instead return from that subtest's Callable. For that reason, to be able to use :skip-all inside a subtest, you must use a sub instead of a regular block:

plan 2; 
 subtest "Some Windows tests" => sub { # <-- note the `sub`; can't use bare block 
     plan :skip-all<We aren't on Windows> unless $*DISTRO.is-win; 
     plan 1; 
     ok dir 'C:/'; # this won't get run on non-Windows 
 } 
 ok 42; # this will run everywhere and isn't affected by skip-all inside subtest 

Note that plan with :skip-all is to avoid performing any tests without marking the test run as failed (i.e. the plan is to not run anything and that's all good). Use skip-rest to skip all further tests, once the run has started (i.e. planned to run some tests, maybe even ran some, but now we're skipping all the rest of them). Use bail-out to fail the test run without running any further tests (i.e. things are so bad, there's no point in running anything else; we've failed).

sub done-testing

Defined as:

sub done-testing()

Specify that testing has finished. Use this function when you don't have a plan with the number of tests to run. A plan is not required when using done-testing.

It's recommended that the done-testing function be removed and replaced with a plan function when all tests are finalized. Use of plan can help detect test failures otherwise not reported because tests were accidentally skipped due to bugs in the tests or bugs in the compiler. For example:

    sub do-stuff {@}; 
     use Test; 
     ok .is-prime for do-stuff; 
     done-testing; 
     # output: 
     1..0 

The above example is where a done-testing fails. do-stuff() returned nothing and tested nothing, even though it should've returned results to test. But the test suite doesn't know how many tests were meant to be run, so it passes.

Adding plan gives a true picture of the test:

    sub do-stuff {@}; 
     use Test; 
     plan 1; 
     ok .is-prime for do-stuff; 
     # output: 
     1..1 
     # Looks like you planned 1 test, but ran 0 

Note that leaving the done-testing in place will have no effect on the new test results, but it should be removed for clarity.

sub ok

Defined as:

multi sub ok(Mu $cond, $desc = '')

The ok function marks a test as passed if the given $value evaluates to True. The nok function marks a test as passed if the given value evaluates to False. Both functions accept an optional description of the test as second parameter.

    my $response; my $query; ...; 
     ok  $response.success, 'HTTP response was successful'; 
     nok $query.error,      'Query completed without error'; 

In principle, you could use ok for every kind of comparison test, by including the comparison in the expression passed to $value:

    sub factorial($x) { ... }; 
     ok factorial(6) == 720, 'Factorial - small integer'; 

However, where possible it's better to use one of the specialized comparison test functions below, because they can print more helpful diagnostics output in case the comparison fails.

sub nok

Defined as:

multi sub nok(Mu $cond, $desc = '')

The nok function marks a test as passed if the given value evaluates to False. It also accepts an optional description of the test as second argument.

    my $response; my $query; ...; 
     ok  $response.success, 'HTTP response was successful'; 
     nok $query.error,      'Query completed without error'; 

sub is

Defined as

multi sub is(Mu $got, Mu:U $expected, $desc = '')
multi sub is(Mu $got, Mu:D $expected, $desc = '')

Marks a test as passed if $value and $expected compare positively with the eq operator, unless $expected is a type object, in which case === operator will be used instead; accepts an optional description of the test as the last argument.

NOTE: eq operator the is() uses stringifies, which means is() is not a good function for testing more complex things, such as lists: is (1, (2, (3,))), [1, 2, 3] passes the test, even though the operands are vastly different. For those cases, use is-deeply routine

    my $pdf-document; sub factorial($x) { ... }; ...; 
     is $pdf-document.author, "Joe", 'Retrieving the author field'; 
     is factorial(6),         720,   'Factorial - small integer'; 
     my Int $a; 
     is $a, Int, 'The variable $a is an unassigned Int'; 

Note: if only whitespace differs between the values, is() will output failure message differently, to show the whitespace in each values. For example, in the output below, the second test shows the literal \t in the got: line:

is "foo\tbar", "foo\tbaz";   # expected: 'foo     baz'␤#      got: 'foo   bar' 
 is "foo\tbar", "foo    bar"; # expected: "foo    bar"␤#      got: "foo\tbar" 

sub isnt

Defined as:

multi sub isnt(Mu $got, Mu:U $expected, $desc = '')
multi sub isnt(Mu $got, Mu:D $expected, $desc = '')

Marks a test as passed if $value and $expected are not equal using the same rules as is(). The function accepts an optional description of the test.

    isnt pi, 3, 'The constant π is not equal to 3'; 
     my Int $a = 23; 
     $a = Nil; 
     isnt $a, Nil, 'Nil should not survive being put in a container'; 

sub is_approx

Defined as:

multi sub is_approx(Mu $got, Mu $expected, $desc = '')

NOTE: Deprecated as of version 6.d. Please use is-approx instead.

Checks if result and the expected value are approximately equal to a certain degree of tolerance, fixed to 1e-5 or one-millionth of the expected value is its value is less than that.

use Test; 
 is_approx(1e4, 1e4-1e-6, "Real close"); # OUTPUT: «ok 1 - Real close␤» 

(This will print also a deprecation notice if you're using 6.d)

sub is-approx

Defined as:

multi sub is-approx(Numeric $got, Numeric $expected, $desc = '')
multi sub is-approx(Numeric $got, Numeric $expected, Numeric $abs-tol, 
                     $desc = '') 
multi sub is-approx(Numeric $got, Numeric $expected, $desc = '', 
                     Numeric :$rel-tol is required) 
multi sub is-approx(Numeric $got, Numeric $expected, $desc = '', 
                     Numeric :$abs-tol is required) 
multi sub is-approx(Numeric $got, Numeric $expected, $desc = '', 
                     Numeric :$rel-tol is required, 
                     Numeric :$abs-tol is required) 

Marks a test as passed if the $value and $expected numerical values are approximately equal to each other. The subroutine can be called in numerous ways that let you test using relative tolerance ($rel-tol) or absolute tolerance ($abs-tol) of different values.

If no tolerance is set, the function will base the tolerance on the absolute value of $expected: if it's smaller than 1e-6, use absolute tolerance of 1e-5; if it's larger, use relative tolerance of 1e-6.

    my Numeric ($value, $expected, $abs-tol, $rel-tol) = ... 
 
     is-approx $value, $expected; 
     is-approx $value, $expected, 'test description'; 
 
     is-approx $value, $expected, $abs-tol; 
     is-approx $value, $expected, $abs-tol, 'test description'; 
 
     is-approx $value, $expected, :$rel-tol; 
     is-approx $value, $expected, :$rel-tol, 'test description'; 
 
     is-approx $value, $expected, :$abs-tol; 
     is-approx $value, $expected, :$abs-tol, 'test description'; 
 
     is-approx $value, $expected, :$abs-tol, :$rel-tol; 
     is-approx $value, $expected, :$abs-tol, :$rel-tol, 'test description'; 

Absolute tolerance

When an absolute tolerance is set, it's used as the actual maximum value by which the $value and $expected can differ. For example:

    is-approx 3, 4, 2; # success 
     is-approx 3, 6, 2; # fail 
 
     is-approx 300, 302, 2; # success 
     is-approx 300, 400, 2; # fail 
     is-approx 300, 600, 2; # fail 

Regardless of values given, the difference between them cannot be more than 2.

Relative tolerance

When a relative tolerance is set, the test checks the relative difference between values. Given the same tolerance, the larger the numbers given, the larger the value they can differ by can be.

For example:

    is-approx 10, 10.5, :rel-tol<0.1>; # success 
     is-approx 10, 11.5, :rel-tol<0.1>; # fail 
 
     is-approx 100, 105, :rel-tol<0.1>; # success 
     is-approx 100, 115, :rel-tol<0.1>; # fail 

Both versions use 0.1 for relative tolerance, yet the first can differ by about 1 while the second can differ by about 10. The function used to calculate the difference is:

              |value - expected| 
 ⁣rel-diff = ──────────────────────── 
            max(|value|, |expected|) 

and the test will fail if rel-diff is higher than $rel-tol.

Both absolute and relative tolerance specified

is-approx $value, $expected, :rel-tol<.5>, :abs-tol<10>; 

When both absolute and relative tolerances are specified, each will be tested independently, and the is-approx test will succeed only if both pass.

sub is-approx-calculate

Defined as:

sub is-approx-calculate ($got,$expected,$abs-tol where { !.defined or $_ >= 0 },$rel-tol where { !.defined or $_ >= 0 },$desc)

This is the actual routine called by is-approx when absolute and relative tolerance are specified. They are tested independently, and the test succeeds only if both pass.

sub is-deeply

Defined as:

multi sub is-deeply(Seq:D $got, Seq:D $expected, $reason = '')
multi sub is-deeply(Seq:D $got, Mu $expected, $reason = '')
multi sub is-deeply(Mu $got, Seq:D $expected, $reason = '')
multi sub is-deeply(Mu $got, Mu $expected, $reason = '')

Marks a test as passed if $value and $expected are equivalent, using the same semantics as the eqv operator. This is the best way to check for equality of (deep) data structures. The function accepts an optional description of the test as the last argument.

use Test; 
 plan 1; 
 
 sub string-info(Str() $_) { 
     Map.new: ( 
       length  =>  .chars, 
       char-counts => Bag.new-from-pairs: ( 
           letters => +.comb(/<:letter>/), 
           digits  => +.comb(/<:digit>/), 
           other   => +.comb(/<.-:letter-:digit>/), 
     )) 
 } 
 
 is-deeply string-info('42 Butterflies ♥ Perl'), Map.new(( 
     :21length, 
     char-counts => Bag.new-from-pairs: ( :15letters, :2digits, :4other, ) 
 )), 'string-info gives right info'; 

Note: for historical reasons, Seq:D arguments to is-deeply get converted to Lists. If you want to ensure strict Seq comparisons, use cmp-ok $got, 'eqv', $expected, $desc instead.

sub cmp-ok

multi sub cmp-ok(Mu $got is raw, $op, Mu $expected is raw, $desc = '')

Compares $value and $expected with the given $comparison comparator and passes the test if the comparison yields a True value. The description of the test is optional.

The $comparison comparator can be either a Callable or a Str containing an infix operator, such as '==', a '~~', or a user-defined infix.

    cmp-ok 'my spelling is apperling', '~~', /perl/, "bad speller"; 

Metaoperators cannot be given as a string; pass them as a Callable instead:

    cmp-ok <a b c>, &[!eqv], <b d e>, 'not equal'; 

A Callable $comparison lets you use custom comparisons:

    sub my-comp { $^a / $^b  < rand }; 
     cmp-ok 1, &my-comp, 2, 'the dice giveth and the dice taketh away' 
     cmp-ok 2, -> $a, $b { $a.is-prime and $b.is-prime and $a < $b }, 7, 
         'we got primes, one larger than the other!'; 

sub isa-ok

Defined as:

multi sub isa-ok(Mu $var, Mu $type, $desc = "The object is-a '$type.perl()'")

Marks a test as passed if the given object $value is, or inherits from, the given $expected-type. For convenience, types may also be specified as a string. The function accepts an optional description of the test, which defaults to a string that describes the object.

    class Womble {} 
     class GreatUncleBulgaria is Womble {} 
     my $womble = GreatUncleBulgaria.new; 
 
     isa-ok $womble, Womble, "Great Uncle Bulgaria is a womble"; 
     isa-ok $womble, 'Womble';     # equivalent 

sub can-ok

Defined as:

multi sub can-ok(Mu $var, Str $meth,$desc = "..." )

Marks a test as passed if the given $variable can run the given $method-name. The function accepts an optional description. For instance:

    class Womble {}; 
     my $womble = Womble.new; 
 
     # with automatically generated test description 
     can-ok $womble, 'collect-rubbish'; 
     #  => An object of type 'Womble' can do the method 'collect-rubbish' 
 
     # with human-generated test description 
     can-ok $womble, 'collect-rubbish', "Wombles can collect rubbish"; 
     #  => Wombles can collect rubbish 

sub does-ok

Defined as:

multi sub does-ok(Mu $var, Mu $type, $desc = "...")

Marks a test as passed if the given $variable can do the given $role. The function accepts an optional description of the test.

    # create a Womble who can invent 
     role Invent { 
         method brainstorm { say "Aha!" } 
     } 
     class Womble {} 
     class Tobermory is Womble does Invent {} 
 
     # ... and later in the tests 
     use Test; 
 
     my $tobermory = Tobermory.new; 
 
     # with automatically generated test description 
     does-ok $tobermory, Invent; 
     #  => The object does role Type 
 
     does-ok $tobermory, Invent, "Tobermory can invent"; 
     #  => Tobermory can invent 

sub like

Defined as:

sub like(Str() $got, Regex:D $expected,$desc = "text matches $expected.perl()")

Use it this way:

    like 'foo', /fo/, 'foo looks like fo'; 

Marks a test as passed if the $value, when coerced to a string, matches the $expected-regex. The function accepts an optional description of the test with a default value printing the expected match.

sub unlike

Defined as:

multi sub unlike(Str() $got, Regex:D $expected,$desc = "text does not match $expected.perl()")

Used this way:

    unlike 'foo', /bar/, 'foo does not look like bar'; 

Marks a test as passed if the $value, when coerced to a string, does not match the $expected-regex. The function accepts an optional description of the test, which defaults to printing the text that did not match.

sub use-ok

Defined as:

multi sub use-ok(Str $code, $desc = "$code module can be use-d ok")

Marks a test as passed if the given $module loads correctly.

    use-ok 'Full::Qualified::ModuleName'; 

sub dies-ok

Defined as:

multi sub dies-ok(Callable $code, $reason = '')

Marks a test as passed if the given $code throws an exception.

The function accepts an optional description of the test.

sub saruman(Bool :$ents-destroy-isengard) { 
     die "Killed by Wormtongue" if $ents-destroy-isengard; 
 } 
 
 dies-ok { saruman(ents-destroy-isengard => True) }, "Saruman dies"; 

sub lives-ok

Defined as:

multi sub lives-ok(Callable $code, $reason = '')

Marks a test as passed if the given $code does not throw an exception.

The function accepts an optional description of the test.

sub frodo(Bool :$destroys-ring) { 
     die "Oops, that wasn't supposed to happen" unless $destroys-ring; 
 } 
 
 lives-ok { frodo(destroys-ring => True) }, "Frodo survives"; 

sub eval-dies-ok

Defined as:

multi sub eval-dies-ok(Str $code, $reason = '')

Marks a test as passed if the given $string throws an exception when evaled as code.

The function accepts an optional description of the test.

eval-dies-ok q[my $joffrey = "nasty"; 
                die "bye bye Ned" if $joffrey ~~ /nasty/], 
     "Ned Stark dies"; 

sub eval-lives-ok

Defined as:

multi sub eval-lives-ok(Str $code, $reason = '')

Marks a test as passed if the given $string does not throw an exception when evaled as code.

The function accepts an optional description of the test.

eval-lives-ok q[my $daenerys-burns = False; 
                 die "Oops, Khaleesi now ashes" if $daenerys-burns], 
     "Dany is blood of the dragon"; 

sub throws-like

Defined as:

sub throws-like($code, $ex_type, $reason?, *%matcher)

Marks a test as passed if the given $code throws the specific exception expected exception type $ex_type. The code $code may be specified as something Callable or as a string to be EVALed. The exception may be specified as a type object or as a string containing its type name.

If an exception was thrown, it will also try to match the matcher hash, where the key is the name of the method to be called on the exception, and the value is the value it should have to pass. For example:

sub frodo(Bool :$destroys-ring) { 
     fail "Oops. Frodo dies" unless $destroys-ring 
 }; 
 throws-like { frodo }, Exception, message => /dies/; 

The function accepts an optional description of the test as the third positional argument.

The routine makes Failures fatal. If you wish to avoid that, use no fatal pragma and ensure the tested code does not sink the possible Failures. If you wish to test that the code returns a Failure instead of throwing, use fails-like routine instead.

sub fails-not-throws { +"a" } 
 # test passes, even though it's just a Failure and would not always throw: 
 throws-like { fails-not-throws }, Exception; 
 
 # test detects nothing thrown, because our Failure wasn't sunk or made fatal: 
 throws-like { no fatal; my $ = fails-not-throws; Nil }, Exception; 

Please note that you can only use the string form (for EVAL) if you are not referencing any symbols in the surrounding scope. If you are, you should encapsulate your string with a block and an EVAL instead. For instance:

throws-like { EVAL q[ fac("foo") ] }, X::TypeCheck::Argument; 

sub fails-like

Defined as:

sub fails-like ( \test where Callable:D|Str:D, $ex-type, $reason?, *%matcher)

Same interface as throws-like, except checks that the code returns a Failure instead of throwing. If the code does throw or if the returned Failure has already been handled, that will be considered as a failed test.

fails-like { +"a" }, X::Str::Numeric, 
     :message(/'Cannot convert string to number'/), 
     'converting non-numeric string to number fails'; 

sub subtest

Defined as:

multi sub subtest(Pair $what)
multi sub subtest($desc, &subtests)
multi sub subtest(&subtests, $desc = '')

The subtest function executes the given block, consisting of usually more than one test, possibly including a plan or done-testing, and counts as one test in plan, todo, or skip counts. It will pass the test only if all tests in the block pass. The function accepts an optional description of the subtest.

class Womble {} 
 
 class GreatUncleBulgaria is Womble { 
     has $.location = "Wimbledon Common"; 
     has $.spectacles = True; 
 } 
 
 subtest { 
     my $womble = GreatUncleBulgaria.new; 
 
     isa-ok $womble,            Womble,             "Correct type"; 
     is     $womble.location,   "Wimbledon Common", "Correct location"; 
     ok     $womble.spectacles,                     "Correct eyewear"; 
 
 }, "Check Great Uncle Bulgaria"; 

You can also place the description as the first positional argument, or use a Pair with description as the key and subtest's code as the value. This can be useful for subtests with large bodies.

subtest 'A bunch of tests', { 
     plan 42; 
     ... 
     ... 
 } 
 
 subtest 'Another bunch of tests' => { 
     plan 72; 
     ... 
     ... 
 } 

sub todo

Defined as:

multi sub todo($reason, $count = 1)

Sometimes tests just aren't ready to be run, for instance a feature might not yet be implemented, in which case tests can be marked as todo. Or it could be the case that a given feature only works on a particular platform - in which case one would skip the test on other platforms.

Mark $count tests as TODO, giving a $reason as to why. By default only one test will be marked TODO.

    sub my-custom-pi { 3 }; 
 
     todo 'not yet precise enough';         # Mark the test as TODO. 
     is my-custom-pi(), pi, 'my-custom-pi'; # Run the test, but don't report 
                                            # failure in test harness. 

The result from the test code above will be something like:

not ok 1 - my-custom-pi# TODO not yet precise enough 
 
 # Failed test 'my-custom-pi' 
 # at test-todo.t line 7 
 # expected: '3.14159265358979' 
 #      got: '3' 

Note that if you todo a subtest, all of the failing tests inside of it will be automatically marked TODO as well and will not count towards your original TODO count.

sub skip

Defined as:

multi sub skip()
multi sub skip($reason, $count = 1)

Skip $count tests, giving a $reason as to why. By default only one test will be skipped. Use such functionality when a test (or tests) would die if run.

sub num-forward-slashes($arg) { ... } ; 
 
 if $*KERNEL ~~ 'linux' { 
     is num-forward-slashes("/a/b"),             2; 
     is num-forward-slashes("/a//b".IO.cleanup), 2; 
 } 
 else { 
     skip "Can't use forward slashes on Windows", 2; 
 } 

Note that if you mark a test as skipped, you must also prevent that test from running.

sub skip-rest

Defined as:

sub skip-rest($reason = '<unknown>')

Skip the remaining tests. If the remainder of the tests in the test file would all fail due to some condition, use this function to skip them, providing an optional $reason as to why.

my $location; sub womble { ... }; ...; 
 unless $location ~~ "Wimbledon Common" { 
     skip-rest "We can't womble, the remaining tests will fail"; 
     exit; 
 } 
 
 # tests requiring functional wombling 
 ok womble(); 
 # ... 

Note that skip-rest requires a plan to be set, otherwise the skip-rest call will throw an error. Note that skip-rest does not exit the test run. Do it manually, or use conditionals to avoid running any further tests.

See also plan :skip-all('...') to avoid running any tests at all and bail-out to abort the test run and mark it as failed.

sub bail-out

sub bail-out ($desc?)

If you already know the tests will fail, you can bail out of the test run using bail-out():

my $has-db-connection; 
 ... 
 $has-db-connection  or bail-out 'Must have database connection for testing'; 

The function aborts the current test run, signaling failure to the harness. Takes an optional reason for bailing out. The subroutine will call exit(), so if you need to do a clean-up, do it before calling bail-out().

If you want to abort the test run, but without marking it as failed, see skip-rest or plan :skip-all('...')

sub pass

Defined as:

multi sub pass($desc = '')

The pass function marks a test as passed. flunk marks a test as not passed. Both functions accept an optional test description.

pass "Actually, this test has passed"; 
 flunk "But this one hasn't passed"; 

Since these subroutines do not provide indication of what value was received and what was expected, they should be used sparingly, such as when evaluating a complex test condition.

sub flunk

multi sub flunk($reason = '')

The opposite of pass, makes a test fail with an optional message.

sub diag

sub diag($message)

Display diagnostic information in a TAP-compatible manner on the standard error stream. This is usually used when a particular test has failed to provide information that the test itself did not provide. Or it can be used to provide visual markers on how the testing of a test-file is progressing (which can be important when doing stress testing).

diag "Yay!  The tests got to here!"; 

273 class Thread

Concurrent execution of code (low-level)

class Thread {}

A thread is a sequence of instructions that can (potentially) run in parallel to others. Class Thread provides a bit of abstraction over threads provided by the underlying virtual machines (which in turn might or might not be operating system threads).

Since threads are fairly low-level, most applications should use other primitives, like start, which also runs in parallel and returns a Promise.

my @threads = (^10).map: { 
     Thread.start( 
         name => "Sleepsorter $_", 
         sub { 
             my $rand = (^10).pick; 
             sleep $rand; 
             say $rand; 
         }, 
     ); 
 } 
 
 .finish for @threads; 

The current thread is available in the dynamic variable $*THREAD.

Methods

method new

method new(:&code!, Bool :$app_lifetime = False, Str :$name = '<anon>' --> Thread:D)

Creates and returns a new Thread, without starting it yet. &code is the code that will be run in a separate thread.

$name is a user-specified string that identifies the thread.

If $app_lifetime is set to True, then the thread is killed when the main thread of the process terminates. If set to False, the process will only terminate when the thread has finished.

method start

method start(Thread:U: &code, Bool :$app_lifetime = False, Str :$name = '<anon>' --> Thread:D)

Creates, runs and returns a new Thread. Note that it can (and often does) return before the thread's code has finished running.

method run

method run(Thread:D:)

Runs the thread, and returns the invocant. It is an error to run a thread that has already been started.

method id

method id(Thread:D: --> Int:D)

Returns a numeric, unique thread identifier.

method finish

method finish(Thread:D)

Waits for the thread to finish. This is called join in other programming systems.

method join

method join(Thread:D)

Waits for the thread to finish.

method yield

method yield(Thread:U)

Tells the scheduler to prefer another thread for now.

Thread.yield;

method app_lifetime

method app_lifetime(Thread:D: --> Bool:D)

Returns False unless the named parameter :app_lifetime is specifically set to True during object creation. If the method returns False it means that the process will only terminate when the thread has finished while True means that the thread will be killed when the main thread of the process terminates.

my $t1 = Thread.new(code => { for 1..5 -> $v { say $v }});
my $t2 = Thread.new(code => { for 1..5 -> $v { say $v }}, :app_lifetime);

say $t1.app_lifetime;                 # OUTPUT: «False␤»
say $t2.app_lifetime;                 # OUTPUT: «True␤»

method name

method name(Thread:D: --> Str:D)

Returns the user defined string, which can optionally be set during object creation in order to identify the Thread, or '<anon>' if no such string was specified.

my $t1 = Thread.new(code => { for 1..5 -> $v { say $v }});
my $t2 = Thread.new(code => { for 1..5 -> $v { say $v }}, name => 'my thread');

say $t1.name;                 # OUTPUT: «<anon>␤»
say $t2.name;                 # OUTPUT: «my thread␤»

method Numeric

method Numeric(Thread:D: --> Int:D)

Returns a numeric, unique thread identifier, i.e. the same as id.

method Str

method Str(Thread:D: --> Str:D)

Returns a string which contains the invocants thread id and name.

my $t = Thread.new(code => { for 1..5 -> $v { say $v }}, name => 'calc thread');
say $t.Str;                           # OUTPUT: «Thread<3>(calc thread)␤»

method is-initial-thread

method is-initial-thread(--> Bool)

Returns a Bool indicating whether the current thread (if called as a class method) or the Thread object on which it is called, is the initial thread the program started on.

say Thread.is-initial-thread;    # True if this is the initial thread
say $*THREAD.is-initial-thread;  # True if $*THREAD is the initial thread

Please note there is no guarantee that this is actually the main thread from the OS's point of view. Also note that if you need this other than from a pure introspection / debugging point of view, that there are probably better ways to achieve what you're trying to achieve.

Routines

sub full-barrier

sub full-barrier()

Performs a full memory barrier, preventing re-ordering of reads/writes. Required for implementing some lock-free data structures and algorithms.

274 class ThreadPoolScheduler

Scheduler that distributes work among a pool of threads

class ThreadPoolScheduler does Scheduler {} 

The ThreadPoolScheduler has a range of number of threads that it maintains, and it distributes work among those threads. When the upper limit of threads isn't reached yet, and there is work pending, it spawns new threads to handle the work.

Methods

new

method new(Int :$initial_threads = 0, Int :$max_threads=16)

Creates a new ThreadPoolScheduler object with the given range of threads to maintain.

275 Subset UInt

Unsigned integer (arbitrary-precision)

The UInt is defined as a subset of Int:

my subset UInt of Int where {not .defined or $_ >= 0}; 

Consequently, it cannot be instantiated or subclassed; however, that shouldn't affect most normal uses.

Some examples of its behavior and uses:

say UInt ~~ Int; # OUTPUT: «True␤»
my UInt $u = 0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff; # 64-bit unsigned value
say $u.base(16); # OUTPUT: «FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF␤» (32 digits)
++$u;
say $u.base(16); # OUTPUT: «100000000000000000000000000000000␤» (33 digits!)
my Int $i = $u;
say $i.base(16); # same as above
say $u.^name;    # OUTPUT: «Int␤» - UInt is a subset, so the type is still Int.
say $i.^name;    # OUTPUT: «Int␤»
# Difference in assignment
my UInt $a = 5;  # nothing wrong
my UInt $b = -5; # Exception about failed type check
my UInt $c = 0;
--$c;            # Exception again
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::TypeCheck::Assignment: Type check failed in assignment to $b; expected UInt but got Int (-5)␤»

# Non-assignment operations are fine
my UInt $d = 0;
say $d - 3;      # OUTPUT: «-3␤»

276 class Uni

A string of Unicode codepoints

class Uni does Positional[uint32] does Stringy { }

Unlike Str, which is made of Grapheme clusters, Uni is string strictly made of Unicode codepoints. That is, base characters and combining characters are separate elements of a Uni instance.

Uni presents itself with a list-like interface of integer Codepoints.

Typical usage of Uni is through one of its subclasses, NFC, NFD, NFKD and NFKC, which represent strings in one of the Unicode Normalization Forms of the same name.

Methods

method new

method new(*@codes --> Uni:D)

Creates a new Uni instance from the given codepoint numbers.

method NFC

method NFC(Uni:D: --> NFC:D)

Returns a NFC (Normal Form Composed)-converted version of the invocant.

method NFD

method NFD(Uni:D: --> NFD:D)

Returns a NFD (Normal Form Decomposed)-converted version of the invocant.

method NFKC

method NFKC(Uni:D: --> NFKC:D)

Returns a NFKC (Normal Form Compatibility Composed)-converted version of the invocant.

method NFKD

method NFKD(Uni:D: --> NFKD:D)

Returns a NFKD (Normal Form Compatibility Decomposed)-converted version of the invocant.

method codes

method codes(Uni:D: --> Int:D)

Returns the number of codepoints in the invocant.

method elems

method elems(Uni:D: --> Int:D)

Returns the number of codepoints in the invocant.

277 class VM

Perl 6 Virtual Machine related information

class VM does Systemic { }

Built-in class for providing information about the virtual machine in which Perl 6 is running. Usually accessed through the $*VM dynamic variable.

Methods

method osname

Defined as:

multi method osname(VM:U:)
multi method osname(VM:D:)

Instance / Class method returning the name of the Operating System, as known by the configuration of the VM object / currently running virtual machine.

method precomp-ext

Instance method returning a string of the extension that should be used for precompiled files of the VM object.

method precomp-target

Instance method returning a string of the value of the compilation target that should be used when precompiling source-files with the VM object.

method prefix

Instance method returning a string of the path in which the virtual machine of the VM object is installed.

278 class ValueObjAt

Unique identification for value types

class ValueObjAt is ObjAt { }

A subclass of ObjAt that should be used to indicate that a class produces objects that are value types (in other words: are immutable after they have been initialized.

my %h = a => 42;        # mutable Hash
say %h.WHICH;           # OUTPUT: «ObjAt.new("Hash|1402...888")␤»

my %m is Map = a => 42; # immutable Map
say %m.WHICH;           # OUTPUT: «ValueObjAt.new("Map|AAF...09F61F")␤»

If you create a class that should be considered a value type, you should add a WHICH method to that class that returns a ValueObjAt object, for instance:

class YourClass {
    has $.foo;  # note these are not mutable
    has $.bar;

    method WHICH() {
        ValueObjAt.new("YourClass|$!foo|$!bar");
    }
}

Note that it is customary to always start the identifying string with the name of the object, followed by a "|". This to prevent confusion with other classes that may generate similar string values: the name of the class should then be enough of a differentiator to prevent collisions.

279 class Variable

Object representation of a variable for use in traits

class Variable {}

Variables have a wealth of compile-time information, but at runtime, accesses to a variable usually act on the value stored inside it, not the variable itself. The runtime class of a variable is Scalar.

Class Variable holds the compile-time information that traits can use to introspect and manipulate variables.

Traits

trait is default

Sets the default value with which a variable is initialized, and to which it is reset when Nil is assigned to it. Trait arguments are evaluated at compile time. Closures won't do what you expect: they are stored as is and need to be called by hand.

my Int $x is default(42);
say $x;     # OUTPUT: «42␤»
$x = 5;
say $x;     # OUTPUT: «5␤»
# explicit reset:
$x = Nil;
say $x;     # OUTPUT: «42␤»

The trait is default can be used also with subscripting things like arrays and hashes:

my @array is default( 'N/A' ); 
 @array[22].say;  # OUTPUT: N/A 
 @array = Nil; 
 @array.say;      # OUTPUT: [N/A] 
 @array[4].say;   # OUTPUT: N/A 
 
 my %hash is default( 'no-value-here' ); 
 %hash<non-existent-key>.say; # OUTPUT: no-value-here 
 %hash<foo> = 'bar'; 
 %hash<>.say;                 # OUTPUT: {foo => bar} 
 %hash<wrong-key>.say;        # OUTPUT: no-value-here 

trait is dynamic

multi sub trait_mod:<is>(Variable:D, :$dynamic)

Marks a variable as dynamic, that is, accessible from inner dynamic scopes without being in an inner lexical scope.

sub introspect() { 
     say  $CALLER::x ; 
 } 
 my $x  is dynamic  = 23; 
 introspect;         # OUTPUT: «23␤» 
 { 
     # not dynamic 
     my $x; 
     introspect()    # dies with an exception of  type X::Caller::NotDynamic 
 } 

The is dynamic trait is a rather cumbersome way of creating and accessing dynamic variables. A much easier way is to use the * twigil:

sub introspect() { 
     say  $*x ; 
 } 
 my $*x = 23; 
 introspect;         # OUTPUT: «23␤» 
 { 
     # not dynamic 
     my $x; 
     introspect()    # dies with an exception of  type X::Dynamic::NotFound 
 } 

trait of

multi sub trait_mod:<of>(Mu:U $target, Mu:U $type)

Sets the type constraint of a container bound to a variable.

my $i of Int = 42;
$i = "forty plus two";
CATCH { default { say .^name, ' ', .Str } }
# OUTPUT: «X::TypeCheck::Assignment Type check failed in assignment to $i; expected Int but got Str ("forty plus two")␤»

You can use any value defined in compile time as a type constraint, including constants:

constant \T = Int;
my $i of T = 42;

which would be equivalent to the previous definition.

Methods

method name

method name(Variable:D: str)

Returns the name of the variable, including the sigil.

280 class Version

Module version descriptor

class Version { }

Version objects identify version of software components (and potentially other entities). Perl 6 uses them internally for versioning modules.

A version consists of several parts, which are visually represented by joining them with a dot. A version part is usually an integer, a string like alpha, or a Whatever-star *. The latter is used to indicate that any version part is acceptable in another version that is compared to the current one.

say v1.0.1 ~~ v1.*;     # OUTPUT: «True␤»
say v1.0.1 ~~ v1.*.1;   # OUTPUT: «True␤»

The first part of version literals contains v and a number; this might be followed by alphanumeric and Whatever parts and trailed by +. Multiple parts are separate with a dot .. A trailing + indicates that higher versions are OK in comparisons:

say v1.2 ~~ v1.0;                 # OUTPUT: «False␤»
say v1.2 ~~ v1.0+;                # OUTPUT: «True␤»
say v0.and.anything.else ~~ v0+;  # OUTPUT: «True␤»

In comparisons, order matters, and every part is compared in turn.

say v1.2 cmp v2.1;      # OUTPUT: «Less␤»

The + suffix is always taken into account in comparisons:

say v1.0.1+ <=> v1.0.1; # OUTPUT: «More␤»

And * (Whatever) is too, and considered always Less than whatever digit is in the corresponding part, even if * is trailed by +:

say v1.* <=> v1.0;      # OUTPUT: «Less␤»
say v1.* <= v1.0;       # OUTPUT: «True␤»
say v1.*+ <= v1.0;      # OUTPUT: «True␤»

Please note that method calls, including pseudo methods like WHAT, require version literals either to be enclosed with parentheses or use some other method to separate them from the dot that denotes a method call, like in these examples:

say (v0.and.some.*.stuff).parts;  # OUTPUT: «(0 and some * stuff)␤»
say v0.and.some.*.stuff .parts;   # OUTPUT: «(0 and some * stuff)␤»

Methods

method new

method new(Str:D $s)

Creates a Version from a string $s. The string is combed for the numeric, alphabetic, and wildcard components of the version object. Any characters other than alphanumerics and asterisks are assumed to be equivalent to a dot. A dot is also assumed between any adjacent numeric and alphabetic characters.

method parts

method parts(Version:D: --> List:D)

Returns the list of parts that make up this Version object

my $v1 = v1.0.1;
my $v2 = v1.0.1+;
say $v1.parts;                                    # OUTPUT: «(1 0 1)␤»
say $v2.parts;                                    # OUTPUT: «(1 0 1)␤»

The + suffix is not considered a part of the Version object, and thus not returned by this method, as shown above in the $v2 variable.

method plus

method plus(Version:D: --> Bool:D)

Returns True if comparisons against this version allow larger versions too.

my $v1 = v1.0.1;
my $v2 = v1.0.1+;
say $v1.plus;                                     # OUTPUT: «False␤»
say $v2.plus;                                     # OUTPUT: «True␤»

method Str

method Str(Version:D: --> Str:D)

Returns a string representation of the invocant.

my $v1 = v1.0.1;
my $v2 = Version.new('1.0.1');
say $v1.Str;                                      # OUTPUT: «1.0.1␤»
say $v2.Str;                                      # OUTPUT: «1.0.1␤»

method gist

method gist(Version:D: --> Str:D)

Returns a string representation of the invocant, just like Str, prepended with a lower-case v.

my $v1 = v1.0.1;
my $v2 = Version.new('1.0.1');
say $v1.gist;                                      # OUTPUT: «v1.0.1␤»
say $v2.gist;                                      # OUTPUT: «v1.0.1␤»

method Capture

Defined as:

method Capture()

Throws X::Cannot::Capture.

281 class Whatever

Placeholder for the value of an unspecified argument

class Whatever { }

Whatever is a class whose objects don't have any explicit meaning; it gets its semantics from other routines that accept Whatever-objects as markers to do something special. Using the * literal as an operand creates a Whatever object.

Much of *'s charm comes from Whatever-currying. When * is used in term position, that is, as an operand, in combination with most operators, the compiler will transform the expression into a closure of type WhateverCode, which is actually a Block that can be used wherever Callables are accepted.

my $c = * + 2;          # same as   -> $x { $x + 2 };
say $c(4);              # OUTPUT: «6␤»

Multiple * in one expression generate closures with as many arguments:

my $c = * + *;          # same as   -> $x, $y { $x + $y }

Using * in complex expressions will also generate closures:

my $c = 4 * * + 5;      # same as   -> $x { 4 * $x + 5 }

Calling a method on * also creates a closure:

<a b c>.map: *.uc;      # same as    <a b c>.map: -> $char { $char.uc } 

As mentioned before, not all operators and syntactic constructs curry * (or Whatever-stars) to WhateverCode. In the following cases, * will remain a Whatever object.

Exception Example What it does
comma 1, *, 2 generates a List with a * element
range operators 1 .. * Range.new(:from(1), :to(*));
series operator 1 ... * infinite list
assignment $x = * assign * to $x
binding $x := * bind * to $x
list repetition 1 xx * generates an infinite list

The range operators are handled specially. They do not curry with Whatever-stars, but they do curry with WhateverCode

say (1..*).^name;       # OUTPUT: «Range␤»
say ((1..*-1)).^name;   # OUTPUT: «WhateverCode␤»

This allows all these constructs to work:

.say for 1..*;          # infinite loop 

and

my @a = 1..4;
say @a[0..*];           # OUTPUT: «(1 2 3 4)␤»
say @a[0..*-2];         # OUTPUT: «(1 2 3)␤»

Because Whatever-currying is a purely syntactic compiler transform, you will get no runtime currying of stored Whatever-stars into WhateverCodes.

my $x = *; 
 $x + 2;   # Not a closure, dies because it can't coerce $x to Numeric 
 CATCH { default { put .^name, ': ', .Str } }; 
 # OUTPUT: «X::Multi::NoMatch: Cannot resolve caller Numeric(Whatever: ); 
 # none of these signatures match:␤ 
 # (Mu:U \v: *%_)» 

The use cases for stored Whatever-stars involve those curry-exception cases mentioned above. For example, if you want an infinite series by default.

my $max    = potential-upper-limit() // *; 
 my $series = known-lower-limit() ... $max; 

A stored * will also result in the generation of a WhateverCode in the specific case of smartmatch. Note that this is not actually the stored * which is being curried, but rather the * on the left-hand side.

my $constraint           = find-constraint() // *; 
 my $maybe-always-matcher = * ~~ $constraint; 

If this hypothetical find-constraint were to have found no constraint, $maybe-always-matcher would evaluate to True for anything.

$maybe-always-matcher(555);      # True 
 $maybe-always-matcher(Any);      # True 

HyperWhatever's functionality is similar to Whatever, except it refers to multiple values, instead of a single one.

Methods

method ACCEPTS

multi method ACCEPTS(Whatever:D: Mu $other)
multi method ACCEPTS(Whatever:U: Mu $other)

If the invocant is an instance, always returns True. If the invocant is a type object, performs a typecheck.

say 42 ~~ (*);       # OUTPUT: «True␤»
say 42 ~~ Whatever;  # OUTPUT: «False␤»

method Capture

Defined as:

method Capture()

Throws X::Cannot::Capture.

282 class WhateverCode

Code object constructed by Whatever-currying

class WhateverCode is Code { }

WhateverCode objects are the result of Whatever-currying. See the Whatever documentation for details.

When you wish to control how a method or function interprets any Whatever star, you may use multi dispatch with Whatever and WhateverCode parameters to do so, as in the following example:

class Cycle {
      has $.pos;
      has @.vals;
}

multi sub get-val(Cycle $c, Int $idx) {
      $c.vals[$idx % $c.vals.elems]
}

# Define what to do with a stand-alone * as the second argument
multi sub get-val(Cycle $c, Whatever $idx) {
    get-val($c, $c.pos);
}

# Define what to do with a * WhateverCode in an expression
multi sub get-val(Cycle $c, WhateverCode $idx) {
    get-val($c, $idx($c.pos));
}

my Cycle $c .= new(:pos(2), :vals(0..^10));

say get-val($c, 3);   # OUTPUT: «3␤»
say get-val($c, *);   # OUTPUT: «2␤»
say get-val($c, *-1); # OUTPUT: «1␤»

The WhateverCode does the Callable role, so it should be possible to introspect the type of Callable it contains; for instance, continuing the previous example, we can add a multi that handles a WhateverCode with two arguments via checking the signature:

# Define what to do with two * in an expression 
 multi sub get-val(Cycle $c, WhateverCode $idx where { .arity == 2 }) { 
     get-val($c, $idx($c.pos, $c.vals.elems)); 
 } 
 
 say get-val($c, * + * div 2); # 2 + 10/2 = 7 

Note, though, that subexpressions may impose their own Whatever star rules:

my @a = (0, 1, 2); 
 say get-val($c, @a[*-1]) # 2, because the star belongs to the Array class 

This can make the ownership of Whatever stars become confusing rather quickly, so be careful not to overdo it.

You may instead type-constrain using Callable type in order to accept any Callable, including WhateverCode:

sub run-with-rand (Callable $code) { $code(rand) };
run-with-rand *.say;           # OUTPUT: «0.773672071688484␤»
run-with-rand {.say};          # OUTPUT: «0.38673179353983␤»
run-with-rand sub { $^v.say }; # OUTPUT: «0.0589543603685792␤»

Type-constraining with &-sigiled parameter works equally well and is shorter to type:

sub run-with-rand (&code) { code time };

283 class X::AdHoc

Error with a custom message

class X::AdHoc is Exception { } 

X::AdHoc is the type into which objects are wrapped if they are thrown as exceptions, but don't inherit from Exception.

Its benefit over returning non-Exception objects is that it gives access to all the methods from class Exception, like backtrace and rethrow.

You can obtain the original object with the payload method.

try {
    die [404, 'File not found']; # throw non-exception object
}
print "Got HTTP code ",
    $!.payload[0],          # 404
    " and backtrace ",
    $!.backtrace.Str;

Note that young code will often be prototyped using X::AdHoc and then later be revised to use more specific subtypes of Exception. As such it is usually best not to explicitly rely on receiving an X::AdHoc – in many cases using the string returned by the .message method, which all Exceptions must have, is preferable. Please note that we need to explicitly call .Str to stringify the backtrace correctly.

Methods

method payload

Returns the original object which was passed to die.

method Numeric

Defined as

method Numeric()

Converts the payload to Numeric and returns it

method from-slurpy

Defined as

method from-slurpy (|cap)

Creates a new exception from a capture and returns it. The capture will have the SlurpySentry role mixed in, so that the .message method behaves in a different when printing the message.

try { 
     X::AdHoc.from-slurpy( 3, False, "Not here" ).throw 
 }; 
 print $!.payload.^name; # OUTPUT: «Capture+{X::AdHoc::SlurpySentry}» 
 print $!.message;       # OUTPUT: «3FalseNot here» 

The SlurpySentry role joins the elements of the payload, instead of directly converting them to a string.

284 class X::Anon::Augment

Compilation error due to augmenting an anonymous package

class X::Anon::Augment does X::Comp { }

Compile time error thrown when trying to augment an anonymous package.

For example

use MONKEY-TYPING; 
 augment class { } 

Dies with

Cannot augment anonymous class 

Methods

method package-kind

method package-kind returns Str:D

Returns the kind of package (module, class, grammar, ...) that the code tried to augment.

285 class X::Anon::Multi

Compilation error due to declaring an anonymous multi

class X::Anon::Multi does X::Comp { }

Compile time error thrown when an anonymous multi is being declared.

For example

multi method () { } 

dies with

Cannot put multi on anonymous method 

Methods

method multiness

method multiness(--> Str:D)

Returns a string describing the multiness that the original code used, for example "multi" or "proto".

method routine-type

method routine-type(--> Str:D)

Returns a string describing the type of routine that was declared, for example "sub" or "method".

286 class X::Assignment::RO

Exception thrown when trying to assign to something read-only

class X::Assignment::RO is Exception {}

Code like

sub f() { 42 };
f() = 'new value';  # throws an X::Assignment::RO
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Assignment::RO: Cannot modify an immutable Any␤»

throws an exception of type X::Assignment::RO.

Methods

method typename

method typename(X::Assignment::RO:D: --> Str)

Returns the type name of the value on the left-hand side

287 class X::Attribute::NoPackage

Compilation error due to declaring an attribute outside of a package

class X::Attribute::NoPackage does X::Comp { }

Compile time error thrown when an attribute is declared where it does not make sense (for example in the mainline).

For example

has $.x; 

Dies with

You cannot declare attribute '$.x' here; maybe you'd like a class or a role? 

Methods

method name

method name(--> Str:D)

Returns the name of the attribute

288 class X::Attribute::Package

Compilation error due to declaring an attribute in an ineligible package

class X::Attribute::Package does X::Comp { }

Compile time error, thrown when the compiler encounters an attribute declaration inside a package that does not support attributes.

For example

module A { has $.x } 

dies with

A module cannot have attributes, but you tried to declare '$.x' 

Methods

method name

method name(--> Str:D)

Returns the name of the attribute that triggered this error.

method package-kind

method package-kind(--> Str:D)

Returns the kind of package (package, module) that doesn't support attributes.

289 class X::Attribute::Required

Compilation error due to not declaring an attribute with the

class X::Attribute::NoPackage does X::MOP { }

Compile time error thrown when a required attribute is not assigned when creating an object.

For example

my class Uses-required { 
     has $.req is required 
 }; 
 my $object = Uses-required.new() 

Dies with

OUTPUT: «(exit code 1) The attribute '$!req' is required, but you did not provide a value for it.␤» 

Methods

method name

method name(--> Str:D)

Returns the name of the attribute.

method why

method why(--> Str:D)

Returns the reason why that attribute is required, and it will be included in the message if provided. That reason is taken directly from the is required trait.

my class Uses-required { 
     has $.req is required("because yes") 
 }; 
 my $object = Uses-required.new();                                  │ 
 # OUTPUT: 
 # «(exit code 1) The attribute '$!req' is required because because yes,␤ 
 # but you did not provide a value for it.␤» 

290 class X::Attribute::Undeclared

Compilation error due to an undeclared attribute

class X::Attribute::Undeclared is X::Undeclared { }

Thrown when code refers to an attribute that has not been declared.

For example the code

class A { method m { $!notthere } } 

Produces the error

Attribute $!notthere not declared in class A 

Methods

method package-kind

Returns the kind of package the attribute was used in (for example class, grammar)

method package-name

Returns the name of the package in which the offensive attribute reference was performed.

291 class X::Augment::NoSuchType

Compilation error due to augmenting a non-existing type

class X::Augment::NoSuchType does X::Comp { }

Thrown when trying to augment a type which doesn't exist.

For example

use MONKEY-TYPING; 
 augment class NoSuch { } 

dies with

You tried to augment class NoSuch, but it does not exist 

Methods

method package-kind

method package-kind(--> Str:D)

Returns the kind of package (class, grammar) that is being tried to augment

method package

Returns the name that was tried to augment, but which doesn't exist.

292 class X::Bind

Error due to binding to something that is not a variable or container

class X::Bind is Exception {}

If you write code like this:

floor(1.1) := 42; 

it dies with an X::Bind exception:

Cannot use bind operator with this left-hand side 

293 class X::Bind::NativeType

Compilation error due to binding to a natively typed variable

class X::Bind::NativeType does X::Comp { }

Compile-time error thrown when trying to bind to a natively typed variable.

Since native variables explicitly don't have the concept of a container at runtime, it does not make sense to support both binding and assignment; Perl 6 supports only assignment (which makes more sense, because native types are value types).

For example the code

my int $x := 3; 

dies with

Cannot bind to natively typed variable '$x'; use assignment instead 

and can be fixed by writing it as

my int $x = 3;

Methods

method name

method name(--> Str:D)

Returns the name of the variable.

294 class X::Bind::Slice

Error due to binding to a slice

class X::Bind::Slice is Exception {}

When you try to bind to an array or hash slice:

my @a; @a[0, 1] := [42];
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Bind::Slice: Cannot bind to Array slice␤»

and

my %h; %h<a b> := {};
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Bind::Slice: Cannot bind to Hash slice␤»

you get an exception of type ::Bind::Slice

Methods

method type

method type(X::Bind::Slice:D:)

returns the type object of the thing that you tried to slice-bind, for example Array, List or Hash.

295 class X::Caller::NotDynamic

Error while trying to access a non dynamic variable through CALLER

class X::Caller::NotDynamic is Exception { }

Thrown when trying to access a non dynamic variable through CALLER

A typical error message is

Cannot access '$x' through CALLER, because it is not declared as dynamic 

Methods

method symbol

Returns the name of the symbol that was passed to CALLER.

296 class X::Channel::ReceiveOnClosed

Error due to calling receive on a closed channel

class X::Channel::ReceiveOnClosed {}

This exception is thrown when a calling receive on a Channel that has been closed:

my $s = Channel.new;
$s.close;
$s.receive;     # Cannot receive a message on a closed channel
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Channel::ReceiveOnClosed: Cannot receive a message on a closed channel␤»

Methods

method channel

method Channel(X::Channel::ReceiveOnClosed:D: --> Channel:D)

Returns the Channel object on which the receive method was called.

297 class X::Channel::SendOnClosed

Error due to calling send on a closed channel

class X::Channel::SendOnClosed {}

This exception is thrown when a calling send on a Channel that has been closed:

my $s = Channel.new;
$s.close;
$s.send(42);
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Channel::SendOnClosed: Cannot send a message on a closed channel␤»

Methods

method channel

method Channel(X::Channel::SendOnClosed:D: --> Channel:D)

Returns the Channel object on which the send method was called.

298 role X::Comp

Common role for compile-time errors

role X::Comp is Exception { }

Common role for compile-time errors.

Note that since the backtrace of a compile time error generally shows routines from the compiler, not from user-space programs, the Backtrace returned from the backtrace method is not very informative. Instead the exception carries its own filename, line and column attributes and public accessors.

If an error occurs while creating an object (like a class or routine) at compile time, generally the exception associated with it does not hold a reference to the object (for example a class would not be fully composed, and thus not usable). In those cases the name of the would-be-created object is included in the error message instead.

Methods

method filename

The filename in which the compilation error occurred

method line

The line number in which the compilation error occurred.

method column

The column number of location where the compilation error occurred. (Rakudo does not implement that yet).

299 class X::Composition::NotComposable

Compilation error due to composing an ineligible type

class X::Composition::NotComposable is Exception { }

Thrown when trying to compose a type into a target type, but the composer type cannot be used for composition (roles and enums are generally OK).

For example

class A { } 
 class B does A { } 

dies with

===SORRY!=== 
 ␤A is not composable, so B cannot compose it 

because does is reserved for role composition, and A is not a role, nor something that knows how to turn into a role.

The fix is to either make A a role, or use inheritance (class B is A { }) instead.

Methods

method target-name

method target-name(--> Str:D)

Returns the name of the type that should be composed, but failed.

method composer

method composer(--> Mu)

Returns the type that should be composed into the target, but which isn't a role.

300 class X::Constructor::Positional

Error due to passing positional arguments to a default constructor

class X::Constructor::Positional is Exception { }

Thrown from Mu.new when positional arguments are passed to it.

For example

class A { };
A.new(2, 3);
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Constructor::Positional: Default constructor for 'A' only takes named arguments␤»

301 role X::Control

Role for control exceptions

role X::Control is Exception { }

This role turns an exception into a control exception, such as CX::Next or CX::Take. It has got no code other than the definition.

Since Rakudo 2019.03, throwing an object that mixes in this role X::Control can raise a control exception which is caught by the CONTROL phaser instead of CATCH. This allows to define custom control exceptions.

For example, the custom CX::Oops control exception we define below:

class CX::Vaya does X::Control { 
     has $.message 
 } 
 
 sub ea { 
     CONTROL { 
         default { 
             say "Controlled { .^name }: { .message }" 
         } 
     } 
     CX::Vaya.new( message => "I messed up!" ).throw; 
 
 } 
 ea; 
 # OUTPUT: «Controlled CX::Vaya: I messed up!␤» 

302 class X::ControlFlow

Error due to calling a loop control command in an ineligible scope

class X::ControlFlow is Exception { }

Thrown when a control flow construct (such as next or redo) is called outside the dynamic scope of an enclosing construct that is supposed to catch them.

For example

last;
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::ControlFlow: last without loop construct␤»

Methods

method illegal

method illegal returns Str:D

Returns the name of the control flow command that was called.

method enclosing

method enclosing returns Str:D

Returns the name of the missing enclosing construct.

303 class X::ControlFlow::Return

Error due to calling return outside a routine

class X::ControlFlow::Return is X::ControlFlow { }

Thrown when a return is called from outside a routine.

return;
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::ControlFlow::Return: Attempt to return outside of any Routine␤»

304 class X::DateTime::TimezoneClash

Error due to using both time zone offset and :timezone

class X::DateTime::TimezoneClash does X::Temporal is Exception { } 

This exception is thrown when code tries to create a DateTime object specifying both a time zone offset and the named argument :timezone.

say DateTime.new('2015-12-24T12:23:00+0200');                   # works 
 say DateTime.new('2015-12-24T12:23:00', timezone => 7200);      # works 
 say DateTime.new('2015-12-24T12:23:00+0200', timezone => 7200); # exception 

Methods

sub message Defined as:

method message()

Returns 'DateTime.new(Str): :timezone argument not allowed with a timestamp offset'

305 class X::Declaration::Scope

Compilation error due to a declaration with an ineligible scope

class X::Declaration::Scope does X::Comp { } 

Compile time error thrown when a declaration does not harmonize with the declared scope.

For example

has sub f() { } 

dies with

===SORRY!=== 
 Cannot use 'has' with sub declaration 

Methods

method scope

method scope(--> Str:D)

Returns a string representation of the scope, usually the same keyword that is used for the declaration ("my", "our", "has", ...);

method declaration

method declaration(--> Str:D)

Describes the symbol that has been declared in a wrong scope.

306 class X::Declaration::Scope::Multi

Compilation error due to declaring a multi with an ineligible scope

class X::Declaration::Scope::Multi is X::Declaration::Scope { }

Thrown when a multi is declared with an incompatible scope.

For example our multi sub foo() { } dies with

===SORRY!=== 
 Cannot use 'our' with individual multi candidates. Please declare an our-scoped proto instead 

307 class X::Does::TypeObject

Error due to mixing into a type object

class X::Does::TypeObject is Exception {}

When you try to add one or more roles to a type object with does after it has been composed, an error of type X::Does::TypeObject is thrown:

Mu does Numeric;    # Cannot use 'does' operator with a type object. 

The correct way to apply roles to a type is at declaration time:

class GrassmannNumber does Numeric { ... }; 
 role AlgebraDebugger does IO { ... }; 
 grammar IntegralParser does AlgebraParser { ... }; 

Roles may only be runtime-mixed into defined object instances:

GrassmannNumber.new does AlgebraDebugger; 

(This restriction may be worked around by using augment or supersede, or with dark Metamodel magics, but this will likely result in a significant performance penalty.)

Methods

method type

method type(X::Does::TypeObject:D: --> Mu:U)

Returns the type object into which the code tried to mix in a role.

308 class X::Dynamic::NotFound

Runtime error thrown when a dynamic variable does not exist

class X::Dynamic::NotFound is Exception {}

This exception is raised when a dynamic variable that has not been declared is used.

$*dynamic-not-found = 33; 
 # OUTPUT: «Dynamic variable $*dynamic-not-found not found␤» 

Methods

method name

method name(--> Str:D)

Returns the name of the variable that has not been found.

309 class X::Eval::NoSuchLang

Error due to specifying an unknown language for EVAL

class X::Eval::NoSuchLang is Exception { }

Error thrown when EVAL($str, :$lang) specifies a language that the compiler does not know how to handle.

For example

EVAL 'boo', lang => "bar";
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Eval::NoSuchLang: No compiler available for language 'bar'␤»

Methods

method lang

method lang()

Returns the language that EVAL did not know how to handle.

310 class X::Export::NameClash

Compilation error due to exporting the same symbol twice

class X::Export::NameClash does X::Comp { }

Compile time error thrown when a symbol is exported twice.

For example

sub f() is export { }; 
 { 
     sub f() is export { } 
 } 

dies with

===SORRY!=== 
 A symbol '&f' has already been exported 

Methods

method symbol

Returns the symbol that is exported twice.

311 role X::IO

IO related error

role X::IO does X::OS {}

Common role for IO related errors.

This role does not provide any additional methods.

312 class X::IO::Chdir

Error while trying to change the working directory

class X::IO::Chdir does X::IO is Exception { } 

Error class when a chdir call failed.

For example

chdir '/home/other' 

throws

Failed to change the working directory to '/home/other': permission denied 

Methods

method path

Returns the path that was passed to the failed chdir call.

313 class X::IO::Chmod

Error while trying to change file permissions

class X::IO::Chmod does X::IO is Exception { } 

Error class for failed chmod calls.

A typical error message is

Failed to set the mode of '/home/other' to '0o777': Permission denied 

314 class X::IO::Copy

Error while trying to copy a file

class X::IO::Copy does X::IO is Exception { } 

Error class for failed file copy operations. A typical error message is

Failed to copy 'source' to 'destination': permission denied 

Methods

method from

Returns the source of the failed copy operation

method to

Returns the destination of the failed copy operation

315 class X::IO::Cwd

Error while trying to determine the current working directory

class X::IO::Cwd does X::IO is Exception { } 

Error class when the runtime fails to determine the current directory.

A typical error message is

Failed to get the working directory: permission denied 

316 class X::IO::Dir

Error while trying to get a directory's contents

class X::IO::Dir does X::IO is Exception { } 

Error class that is thrown when a dir call fails.

A typical error message is

Failed to get the directory contents of '/tmp/': No such file or directory 

Methods

method path

Returns the path that dir failed to read.

317 class X::IO::DoesNotExist

Error while doing file tests on a non existing path

class X::IO::DoesNotExist does X::IO is Exception { } 

Thrown when doing file test operations on a non existing path.

A typical error message is

Failed to find 'euler-5.p6' while trying to do '.f' 

Methods

method path

Returns the path that was passed to the failed call.

method trying

Returns a string describing the failed operation.

318 class X::IO::Link

Error while trying to create a link

class X::IO::Link does X::IO is Exception { } 

Error class for failed link operation.

A typical error message is

Failed to create link called 'my-link' on target 'does-not exist': Failed to link file 

Methods

method target

Returns the name of the link target, i.e. the existing file.

method name

Returns the name of the link that could not be created.

319 class X::IO::Mkdir

Error while trying to create a directory

class X::IO::Mkdir does X::IO is Exception { } 

Error class for failed mkdir operations.

A typical error message is

Failed to create directory 'destination' with mode '0o755': File exists 

Methods

method path

Returns the path that the mkdir operation failed to create.

method mode

Returns the permissions mask of the failed mkdir operation as an Int.

320 class X::IO::Move

Error while trying to move a file

class X::IO::Move does X::IO is Exception { } 

Error class for a failed file move operation. A typical error message is

Failed to move '/tmp/alpha.p6' to 'test.p6': :createonly specified and destination exists 

Methods

method from

Returns the source of the failed move operation

method to

Returns the destination of the failed move operation

321 class X::IO::Rename

Error while trying to rename a file or directory

class X::IO::Rename does X::IO is Exception { } 

Error class for failed file or directory rename operations. A typical error message is

Failed to rename 'source' to 'destination': is a directory 

Methods

method from

Returns the source of the failed rename operation

method to

Returns the destination of the failed rename operation

322 class X::IO::Rmdir

Error while trying to remove a directory

my class X::IO::Rmdir does X::IO is Exception { } 

Error class for failed rmdir operations.

A typical error message is

Failed to remove the directory 'lib': Directory not empty 

Methods

method path

Returns the path rmdir failed to remove

323 class X::IO::Symlink

Error while trying to create a symbolic link

class X::IO::Symlink does X::IO is Exception { } 

Error class for failed symlink creation.

A typical error message is

Failed to create symlink called 'euler' on target '/home/myhome/euler-1.p6': Failed to symlink file: file already exist 

Methods

method name

Returns the path that symlink failed to create.

method target

Returns the path that symlink failed to create a link to.

324 class X::IO::Unlink

Error while trying to remove a file

class X::IO::Unlink does X::IO is Exception { } 

Error class for failed unlink operation.

A typical error message is

Failed to remove the file 'secret': Permission defined 

Methods

method path

Returns the path that unlink failed to delete.

325 class X::Inheritance::NotComposed

Error due to inheriting from a type that's not composed yet

class X::Inheritance::NotComposed is Exception {}

When you try to inherit from a class that hasn't been composed, an exception of type X::Inheritance::NotComposed is thrown.

Usually this happens because it's not yet fully parsed, or that is stubbed:

For example

class A { ... };    # literal ... for stubbing 
 class B is A { }; 

dies with

===SORRY!=== 
 'B' cannot inherit from 'A' because 'A' isn't composed yet (maybe it is stubbed) 

The second common way to trigger this error is by trying to inherit from a class from within the class body.

For example

class Outer { 
     class Inner is Outer { 
     } 
 } 

dies with

===SORRY!=== 
 'Outer::Inner' cannot inherit from 'Outer' because 'Outer' isn't composed yet (maybe it is stubbed) 

Methods

method child-name

method child-name(X::Inheritance::NotComposed:D: --> Str:D)

Returns the name of the type that tries to inherit.

method parent-name

method parent-name(X::Inheritance::NotComposed:D: --> Str:D)

Returns the name of the parent type that the type tries to inherit from

326 class X::Inheritance::Unsupported

Compilation error due to inheriting from an ineligible type

class X::Inheritance::Unsupported does X::Comp { }

Compile time error thrown when trying to inherit from a type that does not support inheritance (like a package or an enum).

For example

enum A <Ax Ay>; 
 class B is A { }; 

dies with

===SORRY!=== 
 A does not support inheritance, so B cannot inherit from it 

Methods

method child-typename

The name of the type that tries to inherit.

method parent

The type object that the child tried to inherit from.

327 class X::Method::InvalidQualifier

Error due to calling a qualified method from an ineligible class

class X::Method::InvalidQualifier is Exception { }

Thrown when a method is call in the form $invocant.TheClass::method if <$invocant> does not conform to TheClass.

For example

1.Str::split(/a/);
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Method::InvalidQualifier: Cannot dispatch to method split on Str because it is not inherited or done by Int␤»

Methods

method method

method method(--> Str:D)

Returns the name of the (unqualified) method.

method invocant

Returns the invocant of the failed, qualified method call

method qualifier-type

Returns the type by which the method call was qualified.

328 class X::Method::NotFound

Error due to calling a method that isn't there

class X::Method::NotFound is Exception {}

Thrown when the user tries to call a method that isn't there.

For example

1.no-such 

throws

No such method 'no-such' for invocant of type 'Int' 

Methods

method method

method method(--> Str:D)

Returns the method name that was invoked.

method typename

method typename(--> Str:D)

Returns the name of the invocant type.

method private

method private(--> Bool:D)

Returns True for private methods, and False for public methods.

method addendum

method addendum(--> Str:D)

Returns additional explanations or hints.

Note: addendum was introduced in Rakudo 2019.03.

329 class X::Method::Private::Permission

Compilation error due to calling a private method without permission

class X::Method::Private::Permission does X::Comp { }

Compile time error thrown when the code contains a call to a private method that isn't defined in the current class, and when no appropriate trusts relation is defined that permits the private method call.

For example

1!Int::foo 

dies with

===SORRY!=== 
 Cannot call private method 'foo' on package Int because it does not trust GLOBAL 

Methods

method method

method method(--> Str:D)

The name of the private method

method source-package

method source-package(--> Mu:D)

Returns the type object that (supposedly) contains the private method.

method calling-package

method calling-package(--> Mu:D)

Returns the package in which the calling code is, and which the source package does not trust.

330 class X::Method::Private::Unqualified

Compilation error due to an unqualified private method call

class X::Method::Private::Unqualified does X::Comp { }

Compile time error thrown when a private method call on anything but self is not fully qualified.

For example

1!priv 

dies with

===SORRY!=== 
 Private method call to priv must be fully qualified with the package containing the method 

Methods

method method

method method(--> Str:D)

Returns the name of the private method that triggered the error.

331 class X::Mixin::NotComposable

Error due to using an ineligible type as a mixin

class X::Mixin::NotComposable is Exception { }

Thrown when a mixin with infix does or but is done with a composer that cannot be used for mixin.

For example

class A { };
1 but A;
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Mixin::NotComposable: Cannot mix in non-composable type A into object of type Int␤»

The compile-time equivalent of this error is X::Composition::NotComposable

Methods

method target

method target()

Returns the target of the failed mixin operation.

method rolish

method rolish()

Returns the thing that could not act as a role for mixing it in

332 class X::NYI

Error due to use of an unimplemented feature

class X::NYI is Exception { }

Error class for unimplemented features. NYI stands for Not Yet Implemented.

If a Perl 6 compiler is not yet feature complete, it may throw an X::NYI exception when a program uses a feature that it can detect and is somehow specified is not yet implemented.

A full-featured Perl 6 compiler must not throw such exceptions, but still provide the X::NYI class for compatibility reasons.

A typical error message is

HyperWhatever is not yet implemented. Sorry. 

Methods

method new

method new( :$feature, :$did-you-mean, :$workaround)

This is the default constructor for X:NYI which can take three parameters with obvious meanings.

class Nothing { 
     method ventured( $sub, **@args) { 
         X::NYI.new( feature => &?ROUTINE.name, 
                     did-you-mean => "gained", 
                     workaround => "Implement it yourself" ).throw; 
     } 
 } 
 
 my $nothing = Nothing.new; 
 $nothing.ventured("Nothing", "Gained"); 

In this case, we are throwing an exception that indicates that the ventured routine has not been implemented; we use the generic &?ROUTINE.name to not tie the exception to the method name in case it is changed later on. This code effectively throws this exception

# OUTPUT: 
 # ventured not yet implemented. Sorry. 
 # Did you mean: gained? 
 # Workaround: Implement it yourself 
 #   in method ventured at NYI.p6 line 6 
 #   in block <unit> at NYI.p6 line 14 

Using the exception properties, it composes the message that we see there.

method feature

Returns a Str describing the missing feature.

method did-you-mean

Returns a Str indicating the optional feature that is already implemented.

method workaround

It helpfully shows a possible workaround for the missing feature, if it's been declared.

method message

Returns the message including the above properties.

333 class X::NoDispatcher

Error due to calling a dispatch command in an ineligible scope

class X::NoDispatcher is Exception { }

When a redispatcher like nextsame is called without being in the dynamic scope of a call where a redispatch is possible, an X::NoDispatcher is thrown.

For example

nextsame; # In the mainline
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::NoDispatcher: nextsame is not in the dynamic scope of a dispatcher␤»

Methods

method redispatcher

method redispatcher(--> Str:D)

Returns the name of the redispatcher function that did not succeed.

334 class X::Numeric::Real

Error while trying to coerce a number to a Real type

class X::Numeric::Real is Exception { }

Occurs when an attempt to coerce a Numeric to a Real, Num, Int or Rat fails (due to a number with a nonzero imaginary part, for instance).

For example

say (1+2i).Int;
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Numeric::Real: Can not convert 1+2i to Int: imaginary part not zero␤»

Methods

method source

method source(--> Numeric:D)

Returns the number that failed to coerce to Real.

method target

method target()

Returns the type to which the coercion was attempted.

method reason

method reason(--> Str:D)

Returns the reason that the conversion failed.

335 role X::OS

Error reported by the operating system

role X::OS { has $.os-error }

Common role for all exceptions that are triggered by some error reported by the operating system (failed IO, system calls, fork, memory allocation).

Methods

method os-error

method os-error(--> Str:D)

Returns the error as reported by the operating system.

336 class X::Obsolete

Compilation error due to use of obsolete syntax

class X::Obsolete does X::Comp { }

Syntax error thrown when the user is attempting to use constructs from other languages.

For example

m/abc/i 

dies with

===SORRY!=== 
 Unsupported use of /i; in Perl 6 please use :i 

Methods

method old

method old(--> Str:D)

Returns a textual description of the obsolete syntax construct

method replacement

method replacement(--> Str:D)

Describes what to use instead of the obsolete syntax.

method when

method when(--> Str:D)

Returns a string describing the state of the language (usually " in Perl 6").

337 class X::OutOfRange

Error due to indexing outside of an allowed range

class X::OutOfRange is Exception { }

General error when something (for example an array index) is out of an allowed range.

For example

say 42[2];
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::OutOfRange: Index out of range. Is: 2, should be in 0..0␤»

since scalars generally act as a one-element list.

Methods

method what

method what(--> Str:D)

Verbal description of the thing that was out of range (e.g. "array index", "month").

method got

method got()

Returns the object that was considered out of range (often an integer)

method range

method range(--> Range:D)

Returns a Range object describing the permissible range for the object returned from .got.

method comment

method comment(--> Str)

Returns an additional comment that is included in the error message.

338 class X::Package::Stubbed

Compilation error due to a stubbed package that is never defined

class X::Package::Stubbed does X::Comp { }

Thrown at CHECK time when there are packages stubbed but not later defined.

For example

class A { ... }     # literal ... 
 class B { ... }     # literal ... 

dies with

===SORRY!=== 
 The following packages were stubbed but not defined: 
     A 
     B 

Methods

method packages

method packages(--> Positional:D)

Returns a list of packages that were stubbed but not defined.

339 class X::Parameter::Default

Compilation error due to an unallowed default value in a signature

class X::Parameter::Default does X::Comp { }

Compile-time error thrown when a parameter in a signature has default value, but isn't allowed to have one. That is the case with slurpy parameters (because a slurpy always binds successfully, even to zero arguments) and with mandatory parameters.

Example:

sub f($x! = 3) { } 

dies with

===SORRY!=== 
 Cannot put default on required parameter $x 

And

sub f(*@ = 3) { } 

dies with

===SORRY!=== 
 Cannot put default on anonymous slurpy parameter 

Methods

method how

Returns a string describing how the parameter is qualified that makes it disallow default values, for example "slurpy" or "mandatory".

method parameter

Returns the parameter name

340 class X::Parameter::MultipleTypeConstraints

Compilation error due to a parameter with multiple type constraints

class X::Parameter::MultipleTypeConstraints does X::Comp { }

Compile time error thrown when a parameter has multiple type constraints. This is not allowed in Perl 6.0.

Example:

sub f(Cool Real $x) { } 

dies with

Parameter $x may only have one prefix type constraint 

Methods

method parameter

Returns the name of the offensive parameter.

341 class X::Parameter::Placeholder

Compilation error due to an unallowed placeholder in a signature

class X::Parameter::Placeholder does X::Comp { }

Thrown when a placeholder parameter is used inside a signature where a normal parameter is expected. The reason is often that a named parameter :$param was misspelled as $:param.

For example

sub f($:param) { } 

dies with

===SORRY!=== 
 In signature parameter, placeholder variables like $:param are illegal 
 you probably meant a named parameter: ':$param' 

Methods

method parameter

The text of the offensive parameter declaration ($:param in the example above).

method right

Suggestion on how to write the parameter declaration instead (:$param in the example above).

342 class X::Parameter::Twigil

Compilation error due to an unallowed twigil in a signature

class X::Parameter::Twigil does X::Comp { }

Thrown when a parameter in a signature has a twigil that it may not have. Only !, . and * as twigils are allowed.

Example:

sub f($=foo) { } 

dies with

===SORRY!=== 
 In signature parameter $=foo, it is illegal to use the = twigil 

Methods

method parameter

The name of the offensive parameter ($=foo in the example above)

method twigil

The illegally used twigil.

343 class X::Parameter::WrongOrder

Compilation error due to passing parameters in the wrong order

class X::Parameter::WrongOrder does X::Comp { }

Compile time error that is thrown when parameters in a signature in the wrong order (for example if an optional parameter comes before a mandatory parameter).

For example

sub f($a?, $b) { } 

dies with

===SORRY!=== 
 Cannot put required parameter $b after optional parameters 

Methods

method misplaced

Returns the kind of misplaced parameter (for example "mandatory", "positional").

method parameter

Returns the name of the (first) misplaced parameter

method after

Returns a string describing other parameters after which the current parameter was illegally placed (for example "variadic", "positional" or "optional").

344 class X::Phaser::Multiple

Compilation error due to multiple phasers of the same type

class X::Phaser::Multiple does X::Comp { }

Thrown when multiple phasers of the same type occur in a block, but only one is allowed (for example CATCH or CONTROL).

For example

CATCH { }; CATCH { } 

dies with

===SORRY!=== 
 Only one CATCH block is allowed 

Methods

method block

Returns the name of the phaser that occurred more than once.

345 class X::Phaser::PrePost

Error due to a false return value of a PRE/POST phaser

class X::Phaser::PrePost is Exception { } 

Thrown when the condition inside a PRE or POST phaser evaluate to a false value.

For example

sub f($x) { PRE { $x ~~ Int } };
f "foo";
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: X::Phaser::PrePost: Precondition '{ $x ~~ Int }' failed«␤»

Methods

method phaser

method phaser(--> Str:D)

Returns the name of the failed phaser, "PRE" or "POST".

method condition

method condition(--> Str:D)

Returns the part of the source code that describes the phaser condition.

346 class X::Placeholder::Block

Compilation error due to a placeholder in an ineligible block

class X::Placeholder::Block does X::Comp {}

Thrown when a placeholder variable is used in a block that does not allow a signature.

For example

class A { $^foo } 

dies with

Placeholder variable $^foo may not be used here because the surrounding block takes no signature 

Methods

method placeholder

Returns the name of the (first) illegally used placeholder.

347 class X::Placeholder::Mainline

Compilation error due to a placeholder in the mainline

class X::Placeholder::Mainline is X::Placeholder::Block { }

Thrown when a placeholder variable is used in the mainline, i.e. outside of any explicit block.

For example

$^x; 

dies with

===SORRY!=== 
 Cannot use placeholder parameter $^x outside of a sub or block 

Note that this error can also occur when you think something is a block, but it really is a postcircumfix:<{ }>, for example

my %h; 
 say %h{ $^x }; 
 #     ^^^^^^^  not a block, so $^x is part of the mainline 

348 role X::Pod

Pod related error

role X::Pod { }

Common role for Pod related errors.

349 role X::Proc::Async

Exception thrown by Proc::Async

role X::Proc::Async is Exception { ... }

All exceptions thrown by Proc::Async do this common role.

Methods

method proc

method proc(X::Proc::Async:D --> Proc::Async)

Returns the object that threw the exception.

350 class X::Proc::Async::AlreadyStarted

Error due to calling start on an already started Proc::Async object

class X::Proc::Async::AlreadyStarted is Exception {}

When you call start twice on the same Proc::Async object, the second invocation will die with an X::Proc::Async::AlreadyStarted exception.

my $proc = Proc::Async.new("echo");
$proc.start;
$proc.start;
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Proc::Async::AlreadyStarted: Process has already been started␤»

351 class X::Proc::Async::BindOrUse

Error due to trying to bind a handle that is also used

    class X::Proc::Async::BindOrUse does X::Proc::Async {} 

In general, it occurs when there's some mistake in the direction the stream flows, for instance:

my $p = Proc::Async.new("ls", :w); 
 my $h = "ls.out".IO.open(:w); 
 $p.bind-stdin($h); 
 # Fails with OUTPUT: «Cannot both bind stdin to a handle and also use :w␤» 

In this case, stdin is already bound and cannot be used again; one of them should flow :out and the other one :w to work correctly.

352 class X::Proc::Async::CharsOrBytes

Error due to tapping the same Proc::Async stream for both text and binary reading

class X::Proc::Async::CharsOrBytes is Exception {}

A Proc::Async object allows subscription to the output or error stream either for bytes (Blob) or for text data (Str), but not for both. If you do try both, it throws an exception of type X::Proc::Async::CharsOrBytes.

my $proc = Proc::Async.new('echo');
$proc.stdout.tap(&print);
$proc.stdout(:bin).tap(&print);
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Proc::Async::CharsOrBytes: Can only tap one of chars or bytes supply for stdout␤»

Methods

method handle

method handle(X::Proc::Async::CharsOrBytes:D: --> Str:D)

Returns the name of the handle that was accessed both for text and for binary data, stdout or stderr.

353 class X::Proc::Async::MustBeStarted

Error due to interacting with a Proc::Async stream before spawning its process

class X::Proc::Async::MustBeStarted is Exception {}

Several methods from Proc::Async expect that the external program has been spawned (by calling .start on it), including say, write, print and close-stdin. If one of those methods is called before .start was called, they throw an exception of type X::Proc::Async::MustBeStarted.

Proc::Async.new('echo', :w).say(42);
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Proc::Async::MustBeStarted: Process must be started first before calling 'say'␤»

Methods

method method

method method(X::Proc::Async::MustBeStarted:D --> Str:D)

Returns the name of the method that was illegally called before starting the external program.

354 class X::Proc::Async::OpenForWriting

Error due to writing to a read-only Proc::Async object

class X::Proc::Async::OpenForWriting is Exception {}

When a Proc::Async object is opened only for reading from the external program (no :w passed to open), and a write operation such as write, print and say is performed, an exception of type X::Proc::Async::OpenForWriting is thrown:

my $proc = Proc::Async.new("echo");
$proc.start;
$proc.say(42);
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Proc::Async::OpenForWriting: Process must be opened for writing with :w to call 'say'␤»

To fix that you can use writable commands with :w flag:

my $prog = Proc::Async.new(:w, 'cat');
$prog.stdout.tap( -> $str {
    print $str;
});
my $promise = $prog.start;
await $prog.say('foo');
$prog.close-stdin;
await $promise;

Methods

method method

method method(X::Proc::Async::OpenForWriting:D:)

Returns the method name that was called and which caused the exception.

355 class X::Proc::Async::TapBeforeSpawn

Error due to tapping a Proc::Async stream after spawning its process

class X::Proc::Async::TapBeforeSpawn is Exception {}

If the stdout or stderr methods of Proc::Async are called after the program has been started, an exception of type X::Proc::Async::TapBeforeSpawn is thrown.

my $proc = Proc::Async.new("echo", "foo");
$proc.start;
$proc.stdout.tap(&print);
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Proc::Async::TapBeforeSpawn: To avoid data races, you must tap stdout before running the process␤»

The right way is the reverse order

my $proc = Proc::Async.new("echo", "foo");
$proc.stdout.tap(&print);
await $proc.start;

Methods

method handle

method handle(X::Proc::Async::TapBeforeSpawn:D: --> Str:D)

Returns the name of the handle (stdout or stderr) that was accessed after the program started.

356 class X::Proc::Unsuccessful

Exception thrown if a Proc object is sunk after the process it ran exited unsuccessfully

class X::Proc::Unsuccessful is Exception {}

Methods

method proc

method proc(X::Proc::Unsuccessful:D --> Proc)

Returns the object that threw the exception.

357 class X::Promise::CauseOnlyValidOnBroken

Error due to asking why an unbroken promise has been broken.

class X::Promise::CauseOnlyValidOnBroken is Exception { }

This exception is thrown when code expects a Promise to be broken, and asks why it has been broken, but the Promise has in fact, not yet been broken.

Methods

method promise

method promise()

Returns the Promise that was asked about.

method status

method status()

Returns the status the Promise had at that time.

358 class X::Promise::Vowed

Error due to directly trying to keep/break a vowed promise.

class X::Promise::Vowed is Exception { }

This exception is thrown when code tries to keep/break an already vowed promise without going through the corresponding Vow object.

Methods

method promise

method promise()

Returns the vowed Promise.

359 class X::Redeclaration

Compilation error due to declaring an already declared symbol

class X::Redeclaration does X::Comp { }

Thrown when a symbol (variable, routine, type, parameter, ...) is redeclared. Note that redeclarations are generally fine in an inner scope, but if the redeclaration appears in the same scope as the original declaration, it usually indicates an error and is treated as one.

Examples

my $x; my $x; 

dies with

===SORRY!=== 
 Redeclaration of symbol $x 

It works with routines too:

sub f() { } 
 sub f() { } 

dies with

===SORRY!=== 
 Redeclaration of routine f 

But those are fine

my $x; 
 sub f() { 
     my $x;          # not a redeclaration, 
                     # because it's in an inner scope 
     sub f() { };    # same 
 } 

Methods

method symbol

Returns the name of the symbol that was redeclared.

method what

Returns the kind of symbol that was redeclared. Usually symbol, but can also be routine, type etc.

method postfix

Returns a string that is attached to the end of the error message. It usually explains the particular problem in more detail, or suggests way to fix the problem.

360 class X::Role::Initialization

Error due to passing an initialization value to an ineligible role

class X::Role::Initialization is Exception { }

Thrown when the SomeRole($init) syntax is used, but SomeRole does not have exactly one public attribute.

For example:

role R { }; "D2" but R(2) 
 CATCH { default { put .^name, ': ', .Str } } 
 # OUTPUT: «X::Role::Initialization: Can only supply an initialization value for a role if it has a single public attribute, but this is not the case for 'R'␤» 

Methods

method role

method role()

Returns the role that caused the error.

361 class X::Scheduler::CueInNaNSeconds

Error caused by passing NaN to Scheduler.cue as :at, :in, or :every

class X::Scheduler::CueInNaNSeconds is Exception { }

When calling ThreadPoolScheduler.cue or CurrentThreadScheduler.cue with :at, :in, or :every as NaN, this exception gets thrown. For example, the following code:

my Cancellation $c = $*SCHEDULER.cue({ 
     say 'This will never output :('; 
 }, at => NaN); 

Throws with:

Cannot pass NaN as a number of seconds to Scheduler.cue 

This class only exists in releases 2019.05 and later.

362 class X::Seq::Consumed

Error due to trying to reuse a consumed sequence

class X::Seq::Consumed is Exception { }

This exception is thrown when a piece of code tries to reuse a Seq which has already been iterated.

363 class X::Sequence::Deduction

Error due to constructing a sequence from ineligible input

class X::Sequence::Deduction is Exception { }

Exception type thrown when the ... sequence operator is being called without an explicit closure, and the sequence cannot be deduced.

364 class X::Signature::NameClash

Compilation error due to two named parameters with the same name

my class X::Signature::NameClash does X::Comp { }

Compile time error thrown when two named parameters have the same name, potentially through aliases.

For example

sub f(:$a, :a(:@b)) { } 

dies with

===SORRY!=== 
 Name a used for more than one named parameter 

Methods

method name

method name(--> Str:D)

Returns the name that was used for more than one parameter.

365 class X::Signature::Placeholder

Compilation error due to placeholders in a block with a signature

class X::Signature::Placeholder does X::Comp { } 

Compile time error thrown when a block has both an explicit signature and placeholder parameters.

For example

sub f() { $^x } 

dies with

===SORRY!=== 
 Placeholder variable '$^x' cannot override existing signature 

Methods

method placeholder

method placeholder(--> Str:D)

Returns the name of a placeholder that was used in a block that already had a signature.

366 class X::Str::Numeric

Error while trying to coerce a string to a number

class X::Str::Numeric is Exception { }

Error thrown (or wrapped in a Failure) when a conversion from string to a number fails.

For example

say +"42 answers";
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Str::Numeric: Cannot convert string to number: trailing characters after number in '42⏏ answers' (indicated by ⏏)␤»

Methods

method source

method source(--> Str:D)

Returns the string that was attempted to convert to a number

method pos

method pos(--> Int:D)

Gives the position into the string where the parsing failed.

method reason

method reason(--> Int:D)

Verbal description of the reason why the conversion failed.

367 class X::StubCode

Runtime error due to execution of stub code

class X::StubCode is Exception { }

Thrown when a piece of stub code (created via !!! or ...) is executed.

Methods

method message

Returns the custom message provided to !!!, or a reasonable default if none was provided.

368 role X::Syntax

Syntax error thrown by the compiler

role X::Syntax does X::Comp { }

Common role for syntax errors thrown by the compiler.

369 class X::Syntax::Augment::WithoutMonkeyTyping

Compilation error due to augmenting a type without the

class X::Syntax::Augment::WithoutMonkeyTyping does X::Syntax { }

Compile time error thrown when augment is used without use MONKEY-TYPING.

Since augment is considered a rather unsafe and impolite action, you have to pre-declare your intent with the use MONKEY-TYPING; pragma.

If you don't do that, like here

augment class Int { }; 

you get the error

===SORRY!=== 
 augment not allowed without 'use MONKEY-TYPING' 

370 class X::Syntax::Comment::Embedded

Compilation error due to a malformed inline comment

class X::Syntax::Comment::Embedded does X::Syntax { }

Syntax error thrown when #` is encountered and it is not followed by an opening curly brace.

For example

#` 

dies with

===SORRY!=== 
 Opening bracket is required for #` comment 

371 class X::Syntax::Confused

Compilation error due to unrecognized syntax

class X::Syntax::Confused does X::Syntax { } 

The most general syntax error, if no more specific error message can be given.

For example

1∞ 

dies with

===SORRY!=== 
 Confused 

372 class X::Syntax::InfixInTermPosition

Compilation error due to an infix in term position

class X::Syntax::InfixInTermPosition does X::Syntax { }

Syntax error thrown when the parser expects a term, but finds an infix operator instead.

For example

1, => 2; 

dies with

===SORRY!=== 
 Preceding context expects a term, but found infix => instead 

Methods

method infix

method infix(--> Str:D)

Returns the symbol of the infix that was found in term position.

373 class X::Syntax::Malformed

Compilation error due to a malformed construct (usually a declarator)

class X::Syntax::Malformed does X::Syntax {}

The Perl 6 compiler throws errors of type X::Syntax::Malformed when it knows what kind of declaration it is parsing, and encounters a syntax error, but can't give a more specific error message.

my Int a;   # throws an X::Syntax::Malformed 

produces

===SORRY!=== 
 Malformed my 
 at -e:1 
 ------> my Int ⏏a 

Methods

method what

method what(X::Syntax::Malformed:D: --> Str)

Returns a description of the thing that was being parsed.

374 class X::Syntax::Missing

Compilation error due to a missing piece of syntax

class X::Syntax::Missing does X::Syntax { }

Syntax error thrown when the previous piece of syntax requires the existence of another piece of syntax, and that second piece is missing.

For example

for 1, 2, 3; 

dies with

===SORRY!=== 
 Missing block 

because a for that is not a statement modifier must be followed by a block.

Methods

method what

method what(--> Str:D)

Returns a string description of the missing syntax element.

375 class X::Syntax::NegatedPair

Compilation error due to passing an argument to a negated colonpair

class X::Syntax::NegatedPair does X::Syntax { }

Thrown if a colonpair illegally has a value, for example :!a(1). This is an error because the ! negation implies that the value is False.

A typical error message from this class is Argument not allowed on negated pair with key 'a'.

Methods

method key

Returns the key of the pair that caused the error.

376 class X::Syntax::NoSelf

Compilation error due to implicitly using a

class X::Syntax::NoSelf does X::Syntax { }

Compile time error thrown when $.foo style calls are used where no invocant is available.

For example the code

$.meth; 

in the program body throws the error

===SORRY!=== 
 Variable $.meth used where no 'self' is available 

because $.meth is short for $(self.meth), and there is no self available in mainline.

Methods

method variable

Returns the variable/method call that caused the error.

377 class X::Syntax::Number::RadixOutOfRange

Compilation error due to an unallowed radix in a number literal

class X::Syntax::Number::RadixOutOfRange does X::Syntax { }

Syntax error that is thrown when the radix of a radix number is not allowed, like :1<1> or :42<ouch> .

Methods

method radix

method radix(--> Int:D)

The offensive radix.

378 class X::Syntax::P5

Compilation error due to use of Perl 5-only syntax

class X::Syntax::P5 does X::Syntax { }

Syntax error thrown when some piece of code is clearly Perl 5, not Perl 6.

For example

for my $a (1, 2) { }; 

dies with

===SORRY!=== 
 This appears to be Perl 5 code 

379 class X::Syntax::Regex::Adverb

Compilation error due to an unrecognized regex adverb

class X::Syntax::Regex::Adverb does X::Syntax { }

Syntax error thrown when an unrecognized or illegal regex adverb is encountered.

For example

rx:g/a/ 

dies with

===SORRY!=== 
 Adverb g not allowed on rx 

because :g belongs to a match operation, not a regex itself.

Methods

method adverb

method adverb(--> Str:D)

Returns the illegally used adverb

method construct

method construct(--> Str:D)

Returns the name of the construct that adverb was used on (m, ms, rx, s, ss).

380 class X::Syntax::Regex::SolitaryQuantifier

Compilation error due to a regex quantifier without preceding atom

class X::Syntax::Regex::SolitaryQuantifier does X::Syntax { }

Syntax error when a stand alone quantifier (without a preceding atom to quantify) is encountered in a regular expression.

For example

/ * /; 

dies with

===SORRY!=== 
 Quantifier quantifies nothing 

381 class X::Syntax::Reserved

Compilation error due to use of syntax reserved for future use

class X::Syntax::Reserved does X::Syntax { }

Syntax error thrown when a syntax is used which is reserved for future expansion.

For example

my @a(); 

dies with

===SORRY!=== 
 The () shape syntax in array declarations is reserved 

Methods

method reserved

method reserved(--> Str:D)

Returns a text description of the reserved syntax.

method instead

method instead(--> Str)

Describes what to use instead of the reserved syntax (if anything).

382 class X::Syntax::Self::WithoutObject

Compilation error due to invoking

class X::Syntax::Self::WithoutObject does X::Syntax { }

Syntax error thrown when self is referenced in a place where no invocant is available.

For example

self; 

outside a class or role declaration dies with

===SORRY!=== 
 'self' used where no object is available 

383 class X::Syntax::Signature::InvocantMarker

Compilation error due to a misplaced invocant marker in a signature

class X::Syntax::Signature::InvocantMarker does X::Syntax { }

Syntax error when the invocant in a signature is anywhere else than after the first parameter.

For example

:($a, $b: $c); 

dies with

===SORRY!=== 
 Can only use : as invocant marker in a signature after the first parameter 

See also: Signature.

384 class X::Syntax::Term::MissingInitializer

Compilation error due to declaring a term without initialization

class X::Syntax::Term::MissingInitializer does X::Syntax { }

Syntax error when a term (a backslash variable) is declared without initialization assignment.

For example

my \foo; 

dies with

===SORRY!=== 
 Term definition requires an initializer 

Valid code would be

my \foo = 42; 

385 class X::Syntax::UnlessElse

Compilation error due to an

class X::Syntax::UnlessElse does X::Syntax { }

Syntax error thrown when an unless clause is followed by an else clause.

For example

unless 1 { } else { }; 

dies with

===SORRY!=== 
 "unless" does not take "else", please rewrite using "if" 

386 class X::Syntax::Variable::Match

Compilation error due to declaring a match variable

class X::Syntax::Variable::Match does X::Syntax { }

Syntax error thrown when a match variable like $<thing> was declared.

For example

my $<thing>; 

dies with

===SORRY!=== 
 Cannot declare a match variable 

387 class X::Syntax::Variable::Numeric

Compilation error due to declaring a numeric symbol

class X::Syntax::Variable::Numeric does X::Syntax { }

Syntax error thrown when trying to declare numeric symbols.

For example

my @101; 

dies with

===SORRY!=== 
 Cannot declare a numeric variable 

Methods

method what

method what returns Str:D

Returns a verbal description of the kind of symbol that was declared (variable, parameter, attribute).

388 class X::Syntax::Variable::Twigil

Compilation error due to an unallowed twigil in a declaration

class X::Syntax::Variable::Twigil does X::Syntax { }

Syntax error thrown when a variable with a twigil is used in an incompatible declaration.

For example

my $!foo; 

dies with

===SORRY!=== 
 Cannot use ! twigil on my variable 

Methods

method twigil

method twigil(--> Str:D)

Returns the twigil that was illegally used

method scope

method scope(--> Str:D)

Returns the scope that did not harmonize with the twigil.

389 role X::Temporal

Error related to DateTime or Date

role X::Temporal is Exception { }

A common exception type for all errors related to DateTime or Date.

390 class X::Temporal::InvalidFormat

Error due to using an invalid format when creating a DateTime or Date

class X::Temporal::InvalidFormat does X::Temporal is Exception { } 

This exception is thrown when code tries to create a DateTime or Date object using an invalid format.

my $dt = Date.new("12/25/2015"); 
 CATCH { default { put .^name, ': ', .Str } }; 
 # OUTPUT: «X::Temporal::InvalidFormat: Invalid Date string '12/25/2015'; use yyyy-mm-dd instead␤» 

Methods

method invalid-str

Returns the invalid format string (12/25/2015 in the example above)

method target

Returns the target type (Date in the example above)

method format

Returns valid format strings for the target type in question, (yyyy-mm-dd in the example above)

391 class X::TypeCheck

Error due to a failed type check

class X::TypeCheck is Exception { }

Error class thrown when a type check fails.

Methods

method operation

method operation(--> Str:D)

Returns a string description of the operation that failed, for example "assignment", "binding", "return".

method got

method got()

Returns the object that failed to type check

method expected

method expected()

Returns the type object against which the check failed.

392 class X::TypeCheck::Assignment

Error due to a failed type check during assignment

class X::TypeCheck::Assignment is X::TypeCheck { }

Error class thrown when the type check of an assignment fails.

For example, this will die

my Int $x = "foo";
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::TypeCheck::Assignment: Type check failed in assignment to $x; expected Int but got Str ("foo")␤»

though compilers are allowed to detect obvious cases like this example and complain at compile time with a different error.

393 class X::TypeCheck::Binding

Error due to a failed type check during binding

class X::TypeCheck::Binding is X::TypeCheck { }

Thrown when the type check of a binding operation fails.

For example:

my Int $x := "foo";
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::TypeCheck::Binding: Type check failed in binding; expected Int but got Str ("foo")␤»

Note that the compiler is free to detect obvious errors at compile time, and complain with a different error at compile time.

394 class X::TypeCheck::Return

Error due to a failed typecheck during

class X::TypeCheck::Return is X::TypeCheck { }

Thrown when a return type check fails.

For example

sub f(--> Int) { "foo" }
f();
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::TypeCheck::Return: Type check failed for return value; expected Int but got Str ("foo")␤»

395 class X::TypeCheck::Splice

Compilation error due to a macro trying to splice a non-AST value

class X::TypeCheck::Splice is X::TypeCheck does X::Comp { }

Compile time error thrown when a Macro or an unquote/hole in a quasi quote does not return an AST.

For example

use experimental :macros; 
 macro quasi-ast { quasi { {{{'not AST'}}} };}; 
 say quasi-ast; 

dies with

===SORRY!=== 
 Type check failed in macro application; expected AST but got Str("not AST") 

This is because you are purposefully creating something that does not evaluate to an abstract syntax tree. To fix, instead write

use experimental :macros; 
 macro an-ast { 
     quasi { 'yes AST' } 
 } 
 say an-ast;              # OUTPUT: «yes AST␤» 

Methods

method action

method action(--> Str:D)

Returns a verbal description of the action that triggered the error, "macro application" or "unquote evaluation".

396 class X::Undeclared

Compilation error due to an undeclared symbol

class X::Undeclared does X::Comp {}

Thrown when the compiler encounters a symbol that has not been declared, but needs to be.

Example

$x; 

results in

===SORRY!=== 
 Variable $x is not declared 

Methods

method symbol

Returns the name of the undeclared symbol

method what

Returns the kind of symbol that was not declared (for example variable, type, routine).

Since The symbol wasn't declared, the compiler sometimes has to guess (or rather disambiguate) what kind of symbol it encounter that wasn't declared. For example if you write

say a; 

Then the disambiguation defaults to reporting a missing subroutine, even though declaring a constant a = 'a' would also make the error go away.

397 class atomicint

Integer (native storage at the platform's atomic operation size)

class atomicint is Int is repr('P6int') { }

An atomicint is a native integer sized such that CPU-provided atomic operations can be performed upon it. On a 32-bit CPU it will typically be 32 bits in size, and on an a 64-bit CPU it will typically be 64 bits in size. It exists to allow writing portable code that uses atomic operations.

Note: Rakudo releases before 2017.08 had no support for atomicints.

# Would typically only work on a 64-bit machine and VM build.
my int64 $active = 0;
$active⚛++;

# Would typically only work on a 32-bit machine and VM build.
my int32 $active = 0;
$active⚛++;

# Will work portably, though can only portably assume range of 32 bits.
my atomicint $active = 0;
$active⚛++;

The use of the atomicint type does not automatically provide atomicity; it must be used in conjunction with the atomic operations.

# Correct (will always output 80000)
my atomicint $total = 0;
await start { for ^20000 { $total⚛++ } } xx 4;
say $total;

# *** WRONG *** due to lack of use of the atomicint type.
# Either works correctly or dies, depending on platform.
my int $total = 0;
await start { for ^20000 { $total⚛++ } } xx 4;
say $total;

# *** WRONG *** due to lack of use of the atomic increment operator.
my atomicint $total = 0;
await start { for ^20000 { $total++ } } xx 4;
say $total;

Routines

sub atomic-assign

Defined as:

multi sub atomic-assign(atomicint $ is rw, int $value)
multi sub atomic-assign(atomicint $ is rw, Int() $value)

Performs an atomic assignment to a native integer, which may be in a lexical, attribute, or native array element. If $value cannot unbox to a 64-bit native integer due to being too large, an exception will be thrown. If the size of atomicint is only 32 bits, then an out of range $value will be silently truncated. The atomic-assign routine ensures that any required barriers are performed such that the changed value will be "published" to other threads.

sub atomic-fetch

Defined as:

multi sub atomic-fetch(atomicint $ is rw)

Performs an atomic read of a native integer, which may live in a lexical, attribute, or native array element. Using this routine instead of simply using the variable ensures that the latest update to the variable from other threads will be seen, both by doing any required hardware barriers and also preventing the compiler from lifting reads. For example:

my atomicint $i = 0;
start { atomic-assign($i, 1) }
while atomic-fetch($i) == 0 { }

Is certain to terminate, while in:

my atomicint $i = 0;
start { atomic-assign($i, 1) }
while $i == 0 { }

It would be legal for a compiler to observe that $i is not updated in the loop, and so lift the read out of the loop, thus causing the program to never terminate.

sub atomic-fetch-inc

Defined as:

multi sub atomic-fetch-inc(atomicint $ is rw)

Performs an atomic increment on a native integer. This will be performed using hardware-provided atomic operations. Since the operation is atomic, it is safe to use without acquiring a lock. Returns the value as seen before incrementing it. Overflow will wrap around silently.

sub atomic-fetch-dec

Defined as:

multi sub atomic-fetch-dec(atomicint $ is rw)

Performs an atomic decrement on a native integer. This will be performed using hardware-provided atomic operations. Since the operation is atomic, it is safe to use without acquiring a lock. Returns the value as seen before decrementing it. Overflow will wrap around silently.

sub atomic-fetch-add

Defined as:

multi sub atomic-fetch-add(atomicint $ is rw, int $value)
multi sub atomic-fetch-add(atomicint $ is rw, Int() $value)

Performs an atomic addition on a native integer. This will be performed using hardware-provided atomic operations. Since the operation is atomic, it is safe to use without acquiring a lock. Returns the value as seen before the addition was performed. Overflow will wrap around silently. If $value is too big to unbox to a 64-bit integer, an exception will be thrown. If $value otherwise overflows atomicint then it will be silently truncated before the addition is performed.

sub atomic-fetch-sub

Defined as:

multi sub atomic-fetch-sub(atomicint $ is rw, int $value)
multi sub atomic-fetch-sub(atomicint $ is rw, Int() $value)

Performs an atomic subtraction on a native integer. This will be performed using hardware-provided atomic operations. Since the operation is atomic, it is safe to use without acquiring a lock. Returns the value as seen before the subtraction was performed. Underflow will wrap around silently. If $value is too big to unbox to a 64-bit integer, an exception will be thrown. If $value otherwise overflows atomicint then it will be silently truncated before the subtraction is performed.

sub atomic-inc-fetch

multi sub atomic-inc-fetch(atomicint $ is rw)

Performs an atomic increment on a native integer. This will be performed using hardware-provided atomic operations. Since the operation is atomic, it is safe to use without acquiring a lock. Returns the value resulting from the increment. Overflow will wrap around silently.

sub atomic-dec-fetch

multi sub atomic-dec-fetch(atomicint $ is rw)

Performs an atomic decrement on a native integer. This will be performed using hardware-provided atomic operations. Since the operation is atomic, it is safe to use without acquiring a lock. Returns the value resulting from the decrement. Overflow will wrap around silently.

sub cas

Defined as:

multi sub cas(atomicint $target is rw, int $expected, int $value)
multi sub cas(atomicint $target is rw, Int() $expected, Int() $value)
multi sub cas(atomicint $target is rw, &operation)

Performs an atomic compare and swap of the native integer value in location $target. The first two forms have semantics like:

my int $seen = $target; 
 if $seen == $expected { 
     $target = $value; 
 } 
 return $seen; 

Except it is performed as a single hardware-supported atomic instruction, as if all memory access to $target were blocked while it took place. Therefore it is safe to attempt the operation from multiple threads without any other synchronization. For example:

my atomicint $master = 0;
await start {
    if cas($master, 0, 1) == 0 {
        say "Master!"
    }
} xx 4

Will reliably only ever print Master! one time, as only one of the threads will be successful in changing the 0 into a 1.

Both $expected and $value will be coerced to Int and unboxed if needed. An exception will be thrown if the value cannot be represented as a 64-bit integer. If the size of atomicint is only 32 bits then the values will be silently truncated to this size.

The third form, taking a code object, will first do an atomic fetch of the current value and invoke the code object with it. It will then try to do an atomic compare and swap of the target, using the value passed to the code object as $expected and the result of the code object as $value. If this fails, it will read the latest value, and retry, until a CAS operation succeeds. Therefore, an atomic multiply of an atomicint $i by 2 could be implemented as:

cas $i, -> int $current { $current * 2 } 

If another thread changed the value while $current * 2 was being calculated then the block would be called again with the latest value for a further attempt, and this would be repeated until success.

Operators

infix ⚛=

multi sub infix:<⚛=>(atomicint $ is rw, int $value)
multi sub infix:<⚛=>(atomicint $ is rw, Int() $value)

Performs an atomic assignment to a native integer, which may be in a lexical, attribute, or native array element. If $value cannot unbox to a 64-bit native integer due to being too large, an exception will be thrown. If the size of atomicint is only 32 bits, then an out of range $value will be silently truncated. The ⚛= operator ensures that any required barriers are performed such that the changed value will be "published" to other threads.

prefix ⚛

multi sub prefix:<⚛>(atomicint $ is rw)

Performs an atomic read of a native integer, which may live in a lexical, attribute, or native array element. Using this operator instead of simply using the variable ensures that the latest update to the variable from other threads will be seen, both by doing any required hardware barriers and also preventing the compiler from lifting reads. For example:

my atomicint $i = 0;
start { $i ⚛= 1 }
while ⚛$i == 0 { }

Is certain to terminate, while in:

my atomicint $i = 0;
start { $i ⚛= 1 }
while $i == 0 { }

It would be legal for a compiler to observe that $i is not updated in the loop, and so lift the read out of the loop, thus causing the program to never terminate.

prefix ++⚛

multi sub prefix:<++⚛>(atomicint $ is rw)

Performs an atomic increment on a native integer. This will be performed using hardware-provided atomic operations. Since the operation is atomic, it is safe to use without acquiring a lock. Returns the value resulting from the increment. Overflow will wrap around silently.

postfix ⚛++

multi sub postfix:<⚛++>(atomicint $ is rw)

Performs an atomic increment on a native integer. This will be performed using hardware-provided atomic operations. Since the operation is atomic, it is safe to use without acquiring a lock. Returns the value as seen before incrementing it. Overflow will wrap around silently.

prefix --⚛

multi sub prefix:<--⚛>(atomicint $ is rw)

Performs an atomic decrement on a native integer. This will be performed using hardware-provided atomic operations. Since the operation is atomic, it is safe to use without acquiring a lock. Returns the value resulting from the decrement. Overflow will wrap around silently.

postfix ⚛--

multi sub postfix:<⚛-->(atomicint $ is rw)

Performs an atomic decrement on a native integer. This will be performed using hardware-provided atomic operations. Since the operation is atomic, it is safe to use without acquiring a lock. Returns the value as seen before decrementing it. Overflow will wrap around silently.

infix ⚛+=

Defined as:

multi sub infix:<⚛+=>(atomicint $ is rw, int $value)
multi sub infix:<⚛+=>(atomicint $ is rw, Int() $value)

Performs an atomic addition on a native integer. This will be performed using hardware-provided atomic operations. Since the operation is atomic, it is safe to use without acquiring a lock. Evaluates to the result of the addition. Overflow will wrap around silently. If $value is too big to unbox to a 64-bit integer, an exception will be thrown. If $value otherwise overflows atomicint then it will be silently truncated before the addition is performed.

infix ⚛-=

Defined as:

multi sub infix:<⚛-=>(atomicint $ is rw, int $value)
multi sub infix:<⚛-=>(atomicint $ is rw, Int() $value)

Performs an atomic subtraction on a native integer. This will be performed using hardware-provided atomic operations. Since the operation is atomic, it is safe to use without acquiring a lock. Evaluates to the result of the subtraction. Underflow will wrap around silently. If $value is too big to unbox to a 64-bit integer, an exception will be thrown. If $value otherwise overflows atomicint then it will be silently truncated before the subtraction is performed.

infix ⚛−=

Synonym for ⚛-= using U+2212 minus.

398 Independent routines

Routines not defined within any class or role.

These routines are defined in different files together with a class, but are not actually attached to any particular class or role.

routine EVAL

Defined as:

proto sub EVAL($code where Blob|Cool|Callable, Str() :$lang = 'perl6', 
                 PseudoStash :$context, *%n) 
multi sub EVAL($code, Str :$lang where { ($lang // '') eq 'Perl5' }, 
                 PseudoStash :$context) 

This routine coerces Cool $code to Str. If $code is a Blob, it'll be processed using the same encoding as the $lang compiler would: for perl6 $lang, uses utf-8; for Perl5, processes using the same rules as perl.

This works as-is with a literal string parameter. More complex input, such as a variable or string with embedded code, is illegal by default. This can be overridden in any of several ways:

use MONKEY-SEE-NO-EVAL; # Or...
use MONKEY;             # shortcut that turns on all MONKEY pragmas
use Test;

# any of the above allows:
EVAL "say { 5 + 5 }";   # OUTPUT: «10␤»

In case the MONKEY-SEE-NO-EVAL pragma is not activated, the compiler will complain with a EVAL is a very dangerous function!!! exception. And it is essentially right, since that will run arbitrary code with the same permissions as the program. You should take care of cleaning the code that is going to pass through EVAL if you activate the MONKEY-SEE-NO-EVAL pragma.

Please note that you can interpolate to create routine names using quotation, as can be seen in this example or other ways to interpolate to create identifier names. This only works, however, for already declared functions and other objects and is thus safer to use.

Symbols in the current lexical scope are visible to code in an EVAL.

my $answer = 42;
EVAL 'say $answer;';    # OUTPUT: «42␤»

However, since the set of symbols in a lexical scope is immutable after compile time, an EVAL can never introduce symbols into the surrounding scope.

EVAL 'my $lives = 9'; say $lives;   # error, $lives not declared 

Furthermore, the EVAL is evaluated in the current package:

module M {
    EVAL 'our $answer = 42'
}
say $M::answer;         # OUTPUT: «42␤»

And also in the current language, meaning any added syntax is available:

sub infix:<mean>(*@a) is assoc<list> {
    @a.sum / @a.elems
}
EVAL 'say 2 mean 6 mean 4';     # OUTPUT: «4␤»

An EVAL statement evaluates to the result of the last statement:

sub infix:<mean>(*@a) is assoc<list> { 
     @a.sum / @a.elems 
 } 
 say EVAL 'say 1; 2 mean 6 mean 4';         # OUTPUT: «1␤4␤» 

EVAL is also a gateway for executing code in other languages:

EVAL "use v5.20; say 'Hello from perl5!'", :lang<Perl5>; 

You need to have Inline::Perl5 for this to work correctly.

sub EVALFILE

Defined as:

sub EVALFILE($filename where Blob|Cool, :$lang = 'perl6')

Slurps the specified file and evaluates it. Behaves the same way as EVAL with regard to Blob decoding, scoping, and the $lang parameter. Evaluates to the value produced by the final statement in the file.

EVALFILE "foo.p6"; 

sub mkdir

Defined as:

sub    mkdir(IO() $path, Int() $mode = 0o777 --> IO::Path:D)

Creates a new directory; see mode for explanation and valid values for $mode. Returns the IO::Path object pointing to the newly created directory on success; fails with X::IO::Mkdir if directory cannot be created.

Also creates parent directories, as needed (similar to *nix utility mkdir with -p option); that is, mkdir "foo/bar/ber/meow" will create foo, foo/bar, and foo/bar/ber directories if they do not exist, as well as foo/bar/ber/meow.

sub chdir

Defined as:

sub chdir(IO() $path, :$d = True, :$r, :$w, :$x --> IO::Path:D)

Changes value of $*CWD variable to the provided $path, optionally ensuring the new path passes several file tests. NOTE: that this routine does NOT alter the process's current directory (see &*chdir).

Returns IO::Path representing new $*CWD on success. On failure, returns Failure and leaves $*CWD untouched. The $path can be any object with an IO method that returns an IO::Path object. The available file tests are:

By default, only :d test is performed.

chdir         '/tmp'; # change $*CWD to '/tmp' and check its .d is True 
 chdir :r, :w, '/tmp'; # … check its .r and .w are True 
 chdir '/not-there';   # returns Failure 

Note that the following construct is a mistake:

# WRONG! DO NOT DO THIS! 
 my $*CWD = chdir '/tmp/'; 

Use indir instead.

sub &*chdir

Defined as:

PROCESS::<&chdir> = sub (IO() $path --> IO::Path:D) { } 

Changes value of $*CWD variable to the provided $path and sets the process's current directory to the value of $path.absolute. NOTE: that in most cases, you want to use chdir routine instead.

Returns an IO::Path representing the new $*CWD on success. On failure, returns Failure and leaves $*CWD untouched. The $path can be any object with an IO method that returns an IO::Path object.

Note that unlike regular chdir, there are no arguments to specify which file tests to perform.

&*chdir('/tmp');  # change $*CWD and process's current directory to '/tmp' 
 &*chdir('/not-there'); # returns Failure 

Note that the following construct is a mistake:

# WRONG! DO NOT DO THIS! 
 my $*CWD = &*chdir('/tmp'); 

Use the following, instead; or see indir if you do not need to change process's current directory:

temp $*CWD; 
 &*chdir('/tmp'); 

sub chmod

Defined as:

sub chmod(Int() $mode, *@filenames --> List)

Coerces all @filenames to IO::Path and calls IO::Path.chmod with $mode on them. Returns a List containing a subset of @filenames for which chmod was successfully executed.

chmod 0o755, <myfile1  myfile2>; # make two files executable by the owner

sub indir

Defined as:

sub indir(IO() $path, &code, :$d = True, :$r, :$w, :$x --> Mu)

Takes Callable &code and executes it after locally (to &code) changing $*CWD variable to an IO::Path object based on $path, optionally ensuring the new path passes several file tests. If $path is relative, it will be turned into an absolute path, even if an IO::Path object was given. NOTE: that this routine does NOT alter the process's current directory (see &*chdir). The $*CWD outside of the &code is not affected, even if &code explicitly assigns a new value to $*CWD.

Returns the return value of &code on success. On failure to successfully change $*CWD, returns Failure. WARNING: keep in mind that lazily evaluated things might end up NOT having the $*CWD set by indir in their dynamic scope by the time they're actually evaluated. Either ensure the generators have their $*CWD set or eagerly evaluate them before returning the results from indir:

say indir("/tmp", {
    gather { take ".".IO }
})».CWD; # OUTPUT: «(/home/camelia)␤»

say indir("/tmp", {
    eager gather { take ".".IO }
})».CWD; # OUTPUT: «(/tmp)␤»

say indir("/tmp", {
    my $cwd = $*CWD;
    gather { temp $*CWD = $cwd; take ".".IO }
})».CWD; # OUTPUT: «(/tmp)␤»

The routine's $path argument can be any object with an IO method that returns an IO::Path object. The available file tests are:

By default, only :d test is performed.

say $*CWD;                   # OUTPUT: «"/home/camelia".IO␤»
indir '/tmp', { say $*CWD }; # OUTPUT: «"/tmp".IO␤»
say $*CWD;                   # OUTPUT: «"/home/camelia".IO␤»

indir '/not-there', {;};     # returns Failure; path does not exist

sub print

Defined as:

multi sub print(**@args --> True)
multi sub print(Junction:D --> True)

Prints the given text on standard output (the $*OUT filehandle), coercing non-Str objects to Str by calling .Str method. Junction arguments autothread and the order of printed strings is not guaranteed.

print "Hi there!\n";   # OUTPUT: «Hi there!␤»
print "Hi there!";     # OUTPUT: «Hi there!»
print [1, 2, 3];       # OUTPUT: «1 2 3»

To print text and include the trailing newline, use put.

sub put

Defined as:

multi sub put(**@args --> True)
multi sub put(Junction:D --> True)

Same as print, except it uses print-nl (which prints a newline, by default) at the end. Junction arguments autothread and the order of printed strings is not guaranteed.

put "Hi there!\n";   # OUTPUT: «Hi there!␤␤»
put "Hi there!";     # OUTPUT: «Hi there!␤»
put [1, 2, 3];       # OUTPUT: «1 2 3␤»

sub say

Defined as:

multi sub say(**@args --> True)

Prints the "gist" of given objects. Same as put, except uses .gist method to obtain string representation of the object.

NOTE: the .gist method of some objects, such as Lists, returns only partial information about the object (hence the "gist"). If you mean to print textual information, you most likely want to use put instead.

say Range;        # OUTPUT: «(Range)␤»
say class Foo {}; # OUTPUT: «(Foo)␤»
say 'I ♥ Perl6';  # OUTPUT: «I ♥ Perl6␤»
say 1..Inf;       # OUTPUT: «1..Inf␤»

routine note

Defined as:

method note(Mu: -->Bool:D)
multi sub note(            --> Bool:D)
multi sub note(Str:D $note --> Bool:D)
multi sub note(**@args     --> Bool:D)

Like say, except prints output to $*ERR handle (STDERR). If no arguments are given to subroutine forms, will use string "Noted".

note;       # STDERR OUTPUT: «Noted␤» 
 note 'foo'; # STDERR OUTPUT: «foo␤» 
 note 1..*;  # STDERR OUTPUT: «1..Inf␤» 

sub prompt

multi sub prompt()
multi sub prompt($msg)

Prints $msg to $*OUT handle if $msg was provided, then gets a line of input from $*IN handle. By default, this is equivalent to printing $msg to STDOUT, reading a line from STDIN, removing the trailing new line, and returning the resultant string. As of Rakudo 2018.08, prompt will create allomorphs for numeric values, equivalent to calling val prompt.

my $name = prompt "What's your name? "; 
 say "Hi, $name! Nice to meet you!"; 
 my $age = prompt("Say your age (number)"); 
 my Int $years = $age; 
 my Str $age-badge = $age; 

In the code above, $age will be duck-typed to the allomorph IntStr if it's entered correctly as a number.

sub open

multi sub open(IO() $path, |args --> IO::Handle:D)

Creates a handle with the given $path, and calls IO::Handle.open, passing any of the remaining arguments to it. Note that IO::Path type provides numerous methods for reading and writing from files, so in many common cases you do not need to open files or deal with IO::Handle type directly.

my $fh = open :w, '/tmp/some-file.txt'; 
 $fh.say: 'I ♥ writing Perl code'; 
 $fh.close; 
 
 $fh = open '/tmp/some-file.txt'; 
 print $fh.readchars: 4; 
 $fh.seek: 7, SeekFromCurrent; 
 say $fh.readchars: 4; 
 $fh.close; 
 
 # OUTPUT: «I ♥ Perl␤» 

sub slurp

Defined as:

multi sub slurp(IO::Handle:D $fh = $*ARGFILES, |c)
multi sub slurp(IO() $path, |c)

Slurps the contents of the entire file into a Str (or Buf if :bin). Accepts :bin and :enc optional named parameters, with the same meaning as open(); possible encodings are the same as in all the other IO methods and are listed in encoding routine. The routine will fail if the file does not exist, or is a directory. Without any arguments, sub slurp operates on $*ARGFILES, which defaults to $*IN in the absence of any filenames.

# read entire file as (Unicode) Str 
 my $text_contents   = slurp "path/to/file"; 
 
 # read entire file as Latin1 Str 
 my $text_contents   = slurp "path/to/file", enc => "latin1"; 
 
 # read entire file as Buf 
 my $binary_contents = slurp "path/to/file", :bin; 

sub spurt

Defined as:

multi spurt(IO() $path, |c)

The $path can be any object with an IO method that returns an IO::Path object. Calls IO::Path.spurt on the $path, forwarding any of the remaining arguments.

Options

The encoding with which the contents will be written.

Boolean indicating whether to append to a (potentially) existing file. If the file did not exist yet, it will be created. Defaults to False.

Boolean indicating whether to fail if the file already exists. Defaults to False.

Examples

# write directly to a file 
 spurt 'path/to/file', 'default text, directly written'; 
 
 # write directly with a non-Unicode encoding 
 spurt 'path/to/latin1_file', 'latin1 text: äöüß', :enc<latin1>; 
 
 spurt 'file-that-already-exists', 'some text';           # overwrite file's contents: 
 spurt 'file-that-already-exists', ' new text', :append;  # append to file's contents: 
 say slurp 'file-that-already-exists';                    # OUTPUT: «some text new text␤» 
 
 # fail when writing to a pre-existing file 
 spurt 'file-that-already-exists', 'new text', :createonly; 
 # OUTPUT: «Failed to open file /home/camelia/file-that-already-exists: file already exists …» 

sub run

Defined as:

sub run( 
     *@args ($, *@), 
     :$in = '-', 
     :$out = '-', 
     :$err = '-', 
     Bool :$bin = False, 
     Bool :$chomp = True, 
     Bool :$merge = False, 
     Str:D :$enc = 'UTF-8', 
     Str:D :$nl = "\n", 
     :$cwd = $*CWD, 
     Hash() :$env = %*ENV 
 --> Proc:D) 

Runs an external command without involving a shell and returns a Proc object. By default, the external command will print to standard output and error, and read from standard input.

run 'touch', '>foo.txt'; # Create a file named >foo.txt

run <<rm >foo.txt>>; # Another way to use run, using word quoting for the
                     # arguments

If you want to pass some variables you can still use < >, but try to avoid using « » as it will do word splitting if you forget to quote variables:

my $file = ‘--my arbitrary filename’; 
 run ‘touch’, ‘--’, $file;  # RIGHT 
 run <touch -->, $file;     # RIGHT 
 
 run «touch -- "$file"»;    # RIGHT but WRONG if you forget quotes 
 run «touch -- $file»;      # WRONG; touches ‘--my’, ‘arbitrary’ and ‘filename’ 
 run ‘touch’, $file;        # WRONG; error from `touch` 
 run «touch "$file"»;       # WRONG; error from `touch` 

Note that -- is required for many programs to disambiguate between command-line arguments and filenames that begin with hyphens.

A sunk Proc object for a process that exited unsuccessfully will throw. If you wish to ignore such failures, simply use run in non-sink context:

run 'false';     # SUNK! Will throw
run('false').so; # OK. Evaluates Proc in Bool context; no sinking

If you want to capture standard output or error instead of having it printed directly you can use the :out or :err arguments respectively, which will make them available using the Proc.out method:

my $proc = run 'echo', 'Perl 6 is Great!', :out, :err;
$proc.out.slurp(:close).say; # OUTPUT: «Perl 6 is Great!␤»
$proc.err.slurp(:close).say; # OUTPUT: «␤»

You can use these arguments to redirect them to a filehandle, thus creating a kind of pipe:

my $ls-alt-handle = open :w, '/tmp/cur-dir-ls-alt.txt';
my $proc = run "ls", "-alt", :out($ls-alt-handle);
# (The file will contain the output of the ls -alt command)

These argument are quite flexible and admit, for instance, handles to redirect them. See Proc and Proc::Async for more details.

See also new for more examples.

sub shell

multi sub shell($cmd, :$in = '-', :$out = '-', :$err = '-', 
                 Bool :$bin, Bool :$chomp = True, Bool :$merge, 
                 Str :$enc, Str:D :$nl = "\n", :$cwd = $*CWD, :$env) 

Runs a command through the system shell, which defaults to %*ENV<ComSpec> /c in Windows, /bin/sh -c otherwise. All shell meta characters are interpreted by the shell, including pipes, redirects, environment variable substitutions and so on. Shell escapes are a severe security concern and can cause confusion with unusual file names. Use run if you want to be safe.

The return value is of type Proc.

shell 'ls -lR | gzip -9 > ls-lR.gz';

See Proc for more details, for example on how to capture output.

routine unpolar

Defined as:

method unpolar(Real $angle)
multi sub unpolar(Real $mag, Real $angle)

Returns a Complex with the coordinates corresponding to the angle in radians and magnitude corresponding to the object value or $mag in the case it's being used as a sub

say 1.unpolar(⅓*pi);
# OUTPUT: «0.5000000000000001+0.8660254037844386i␤»

routine printf

Defined as:

method printf (*@args)
multi sub printf(Cool:D $format, *@args)

As a method, takes the object as a format using the same language as Str.sprintf; as a sub, its first argument will be the format string, and the rest of the arguments will be substituted in the format following the format conventions.

"%s is %s".printf("þor", "mighty");    # OUTPUT: «þor is mighty»
printf( "%s is %s", "þor", "mighty");  # OUTPUT: «þor is mighty»

routine sprintf

Defined as:

method sprintf(*@args)
multi sub sprintf(Cool:D $format, *@args)

Formats and outputs a string, following the same language as Str.sprintf, using as such format either the object (if called in method form) or the first argument (if called as a routine)

sprintf( "%s the %d%s", "þor", 1, "st").put; #OUTPUT: «þor the 1st␤»
sprintf( "%s is %s", "þor", "mighty").put;   # OUTPUT: «þor is mighty␤»
"%s's weight is %.2f %s".sprintf( "Mjölnir", 3.3392, "kg").put;
# OUTPUT: «Mjölnir's weight is 3.34 kg␤»

This function is mostly identical to the C library's sprintf and printf functions. The only difference between the two functions is that sprintf returns a string while the printf function writes to a filehandle. sprintf returns a Str, not a literal.

The $format is scanned for % characters. Any % introduces a format token. Directives guide the use (if any) of the arguments. When a directive other than % is used, it indicates how the next argument passed is to be formatted into the string to be created.

The information below is for a fully functioning sprintf implementation which hasn't been achieved yet. Formats or features not yet implemented are marked NYI.

The directives are:

% a literal percent sign
c a character with the given codepoint
s a string
d a signed integer, in decimal
u an unsigned integer, in decimal
o an unsigned integer, in octal
x an unsigned integer, in hexadecimal
e a floating-point number, in scientific notation
f a floating-point number, in fixed decimal notation
g a floating-point number, in %e or %f notation
X like x, but using uppercase letters
E like e, but using an uppercase "E"
G like g, but with an uppercase "E" (if applicable)
b an unsigned integer, in binary

Compatibility:

i a synonym for %d
D a synonym for %ld
U a synonym for %lu
O a synonym for %lo
F a synonym for %f

Modifiers change the meaning of format directives, but are largely no-ops (the semantics are still being determined).

h interpret integer as native "short" (typically int16)
NYI l interpret integer as native "long" (typically int32 or int64)
NYI ll interpret integer as native "long long" (typically int64)
NYI L interpret integer as native "long long" (typically uint64)
NYI q interpret integer as native "quads" (typically int64 or larger)

Between the % and the format letter, you may specify several additional attributes controlling the interpretation of the format. In order, these are:

Format parameter index

An explicit format parameter index, such as 2$. By default, sprintf will format the next unused argument in the list, but this allows you to take the arguments out of order:

sprintf '%2$d %1$d', 12, 34;      # OUTPUT: «34 12␤»
sprintf '%3$d %d %1$d', 1, 2, 3;  # OUTPUT: «3 1 1␤»

Flags

One or more of:

space prefix non-negative number with a space
+ prefix non-negative number with a plus sign
- left-justify within the field
0 use leading zeros, not spaces, for required padding
# ensure the leading "0" for any octal, prefix non-zero hexadecimal with "0x" or "0X", prefix non-zero binary with "0b" or "0B"

For example:

sprintf '<% d>',  12;   # RESULT: «< 12>␤»
sprintf '<% d>',   0;   # RESULT: «< 0>"»
sprintf '<% d>', -12;   # RESULT: «<-12>␤»
sprintf '<%+d>',  12;   # RESULT: «<+12>␤»
sprintf '<%+d>',   0;   # RESULT: «<+0>"»
sprintf '<%+d>', -12;   # RESULT: «<-12>␤»
sprintf '<%6s>',  12;   # RESULT: «<    12>␤»
sprintf '<%-6s>', 12;   # RESULT: «<12    >␤»
sprintf '<%06s>', 12;   # RESULT: «<000012>␤»
sprintf '<%#o>',  12;   # RESULT: «<014>␤»
sprintf '<%#x>',  12;   # RESULT: «<0xc>␤»
sprintf '<%#X>',  12;   # RESULT: «<0XC>␤»
sprintf '<%#b>',  12;   # RESULT: «<0b1100>␤»
sprintf '<%#B>',  12;   # RESULT: «<0B1100>␤»

When a space and a plus sign are given as the flags at once, the space is ignored:

sprintf '<%+ d>', 12;   # RESULT: «<+12>␤»
sprintf '<% +d>', 12;   # RESULT: «<+12>␤»

When the # flag and a precision are given in the %o conversion, the necessary number of 0s is added at the beginning. If the value of the number is 0 and the precision is 0, it will output nothing; precision 0 or smaller than the actual number of elements will return the number with 0 to the left:

say sprintf '<%#.5o>', 0o12;     # OUTPUT: «<00012>␤»
say sprintf '<%#.5o>', 0o12345;  # OUTPUT: «<012345>␤»
say sprintf '<%#.0o>', 0;        # OUTPUT: «<>␤» zero precision and value 0 results in no output!
say sprintf '<%#.0o>', 0o1       # OUTPUT: «<01>␤»

Vector flag

This flag tells Perl 6 to interpret the supplied string as a vector of integers, one for each character in the string. Perl 6 applies the format to each integer in turn, then joins the resulting strings with a separator (a dot, '.', by default). This can be useful for displaying ordinal values of characters in arbitrary strings:

NYI sprintf "%vd", "AB\x[100]";           # "65.66.256" 

You can also explicitly specify the argument number to use for the join string using something like *2$v; for example:

NYI sprintf '%*4$vX %*4$vX %*4$vX',       # 3 IPv6 addresses 
         @addr[1..3], ":"; 

(Minimum) Width

Arguments are usually formatted to be only as wide as required to display the given value. You can override the width by putting a number here, or get the width from the next argument (with * ) or from a specified argument (e.g., with *2$):

 sprintf "<%s>", "a";           # RESULT: «<a>␤» 
  sprintf "<%6s>", "a";          # RESULT: «<     a>␤» 
  sprintf "<%*s>", 6, "a";       # RESULT: «<     a>␤» 
  NYI sprintf '<%*2$s>', "a", 6; # "<     a>" 
  sprintf "<%2s>", "long";       # RESULT: «<long>␤» (does not truncate) 

If a field width obtained through * is negative, it has the same effect as the - flag: left-justification.

Precision, or maximum width

You can specify a precision (for numeric conversions) or a maximum width (for string conversions) by specifying a . followed by a number. For floating-point formats, except g and G, this specifies how many places right of the decimal point to show (the default being 6). For example:

# these examples are subject to system-specific variation
sprintf '<%f>', 1;    # RESULT: «"<1.000000>"␤»
sprintf '<%.1f>', 1;  # RESULT: «"<1.0>"␤»
sprintf '<%.0f>', 1;  # RESULT: «"<1>"␤»
sprintf '<%e>', 10;   # RESULT: «"<1.000000e+01>"␤»
sprintf '<%.1e>', 10; # RESULT: «"<1.0e+01>"␤»

For "g" and "G", this specifies the maximum number of digits to show, including those prior to the decimal point and those after it; for example:

# These examples are subject to system-specific variation.
sprintf '<%g>', 1;        # RESULT: «<1>␤»
sprintf '<%.10g>', 1;     # RESULT: «<1>␤»
sprintf '<%g>', 100;      # RESULT: «<100>␤»
sprintf '<%.1g>', 100;    # RESULT: «<1e+02>␤»
sprintf '<%.2g>', 100.01; # RESULT: «<1e+02>␤»
sprintf '<%.5g>', 100.01; # RESULT: «<100.01>␤»
sprintf '<%.4g>', 100.01; # RESULT: «<100>␤»

For integer conversions, specifying a precision implies that the output of the number itself should be zero-padded to this width, where the 0 flag is ignored:

(Note that this feature currently works for unsigned integer conversions, but not for signed integer.)

sprintf '<%.6d>', 1;      # <000001> 
 NYI sprintf '<%+.6d>', 1;     # <+000001> 
 NYI sprintf '<%-10.6d>', 1;   # <000001    > 
 sprintf '<%10.6d>', 1;    # <    000001> 
 NYI sprintf '<%010.6d>', 1;   #     000001> 
 NYI sprintf '<%+10.6d>', 1;   # <   +000001> 
 sprintf '<%.6x>', 1;         # RESULT: «<000001>␤» 
 sprintf '<%#.6x>', 1;        # RESULT: «<0x000001>␤» 
 sprintf '<%-10.6x>', 1;      # RESULT: «<000001    >␤» 
 sprintf '<%10.6x>', 1;       # RESULT: «<    000001>␤» 
 sprintf '<%010.6x>', 1;      # RESULT: «<    000001>␤» 
 sprintf '<%#10.6x>', 1;      # RESULT: «<  0x000001>␤» 

For string conversions, specifying a precision truncates the string to fit the specified width:

sprintf '<%.5s>', "truncated";   # RESULT: «<trunc>␤»
sprintf '<%10.5s>', "truncated"; # RESULT: «<     trunc>␤»

You can also get the precision from the next argument using .*, or from a specified argument (e.g., with .*2$):

sprintf '<%.6x>', 1;       # RESULT: «<000001>␤» 
 sprintf '<%.*x>', 6, 1;    # RESULT: «<000001>␤» 
 NYI sprintf '<%.*2$x>', 1, 6;  # "<000001>" 
 NYI sprintf '<%6.*2$x>', 1, 4; # "<  0001>" 

If a precision obtained through * is negative, it counts as having no precision at all:

sprintf '<%.*s>',  7, "string";   # RESULT: «<string>␤»
sprintf '<%.*s>',  3, "string";   # RESULT: «<str>␤»
sprintf '<%.*s>',  0, "string";   # RESULT: «<>␤»
sprintf '<%.*s>', -1, "string";   # RESULT: «<string>␤»
sprintf '<%.*d>',  1, 0;          # RESULT: «<0>␤»
sprintf '<%.*d>',  0, 0;          # RESULT: «<>␤»
sprintf '<%.*d>', -1, 0;          # RESULT: «<0>␤»

Size

For numeric conversions, you can specify the size to interpret the number as using l, h, V, q, L, or ll. For integer conversions (d u o x X b i D U O), numbers are usually assumed to be whatever the default integer size is on your platform (usually 32 or 64 bits), but you can override this to use instead one of the standard C types, as supported by the compiler used to build Perl 6:

(Note: None of the following have been implemented.)

hh interpret integer as C type "char" or "unsigned char"
h interpret integer as C type "short" or "unsigned short"
j interpret integer as C type "intmax_t", only with a C99 compiler (unportable)
l interpret integer as C type "long" or "unsigned long"
q, L, or ll interpret integer as C type "long long", "unsigned long long", or "quad" (typically 64-bit integers)
t interpret integer as C type "ptrdiff_t"
z interpret integer as C type "size_t"

Order of arguments

Normally, sprintf takes the next unused argument as the value to format for each format specification. If the format specification uses * to require additional arguments, these are consumed from the argument list in the order they appear in the format specification before the value to format. Where an argument is specified by an explicit index, this does not affect the normal order for the arguments, even when the explicitly specified index would have been the next argument.

So:

my $a = 5; my $b = 2; my $c = 'net';
sprintf "<%*.*s>", $a, $b, $c; # RESULT: «<   ne>␤»

uses $a for the width, $b for the precision, and $c as the value to format; while:

NYI sprintf '<%*1$.*s>', $a, $b; 

would use $a for the width and precision and $b as the value to format.

Here are some more examples; be aware that when using an explicit index, the $ may need escaping:

sprintf "%2\$d %d\n",      12, 34;     # RESULT: «34 12␤␤» 
 sprintf "%2\$d %d %d\n",   12, 34;     # RESULT: «34 12 34␤␤» 
 sprintf "%3\$d %d %d\n",   12, 34, 56; # RESULT: «56 12 34␤␤» 
 NYI sprintf "%2\$*3\$d %d\n",  12, 34,  3; # " 34 12\n" 
 NYI sprintf "%*1\$.*f\n",       4,  5, 10; # "5.0000\n" 

Other examples:

NYI sprintf "%ld a big number", 4294967295; 
 NYI sprintf "%%lld a bigger number", 4294967296; 
 sprintf('%c', 97);                  # RESULT: «a␤» 
 sprintf("%.2f", 1.969);             # RESULT: «1.97␤» 
 sprintf("%+.3f", 3.141592);         # RESULT: «+3.142␤» 
 sprintf('%2$d %1$d', 12, 34);       # RESULT: «34 12␤» 
 sprintf("%x", 255);                 # RESULT: «ff␤» 

Special case: sprintf("<b>%s</b>\n", "Perl 6") will not work, but one of the following will:

sprintf Q:b "<b>%s</b>\n",  "Perl 6"; # RESULT: «<b>Perl 6</b>␤␤» 
 sprintf     "<b>\%s</b>\n", "Perl 6"; # RESULT: «<b>Perl 6</b>␤␤» 
 sprintf     "<b>%s\</b>\n", "Perl 6"; # RESULT: «<b>Perl 6</b>␤␤» 

sub flat

Defined as:

multi flat(**@list)
multi flat(Iterable \a)

Constructs a list which contains any arguments provided, and returns the result of calling the .flat method (inherited from Any) on that list or Iterable:

say flat 1, (2, (3, 4), $(5, 6)); # OUTPUT: «(1 2 3 4 (5 6))␤»

routine unique

Defined as:

multi sub unique(+values, |c)

Returns a sequence of unique values from the invocant/argument list, such that only the first occurrence of each duplicated value remains in the result list. unique uses the semantics of the === operator to decide whether two objects are the same, unless the optional :with parameter is specified with another comparator. The order of the original list is preserved even as duplicates are removed.

Examples:

say <a a b b b c c>.unique;   # OUTPUT: «(a b c)␤»
say <a b b c c b a>.unique;   # OUTPUT: «(a b c)␤»

(Use squish instead if you know the input is sorted such that identical objects are adjacent.)

The optional :as parameter allows you to normalize/canonicalize the elements before unique-ing. The values are transformed for the purposes of comparison, but it's still the original values that make it to the result list; however, only the first occurrence will show up in that list:

Example:

say <a A B b c b C>.unique(:as(&lc))      # OUTPUT: «(a B c)␤»

One can also specify the comparator with the optional :with parameter. For instance if one wants a list of unique hashes, one could use the eqv comparator.

Example:

my @list = %(a => 42), %(b => 13), %(a => 42);
say @list.unique(:with(&[eqv]))           # OUTPUT: «({a => 42} {b => 13})␤»

Note: since :with Callable has to be tried with all the items in the list, this makes unique follow a path with much higher algorithmic complexity. You should try to use the :as argument instead, whenever possible.

routine repeated

Defined as:

multi sub    repeated(+values, |c)

This returns a sequence of repeated values from the invocant/argument list. It takes the same parameters as unique, but instead of passing through any elements when they're first seen, they're only passed through as soon as they're seen for the second time (or more).

Examples:

say <a a b b b c c>.repeated;                   # OUTPUT: «(a b b c)␤»
say <a b b c c b a>.repeated;                   # OUTPUT: «(b c b a)␤»
say <a A B b c b C>.repeated(:as(&lc));         # OUTPUT: «(A b b C)␤»

my @list = %(a => 42), %(b => 13), %(a => 42);
say @list.repeated(:with(&[eqv]))               # OUTPUT: «({a => 42})␤»

As in the case of unique the associative argument :as takes a Callable that normalizes the element before comparison, and :with takes a the equality comparison function that is going to be used.

routine squish

Defined as:

sub          squish( +values, |c)

Returns a sequence of values from the invocant/argument list where runs of one or more values are replaced with only the first instance. Like unique, squish uses the semantics of the === operator to decide whether two objects are the same. Unlike unique, this function only removes adjacent duplicates; identical values further apart are still kept. The order of the original list is preserved even as duplicates are removed.

Examples:

say <a a b b b c c>.squish; # OUTPUT: «(a b c)␤»
say <a b b c c b a>.squish; # OUTPUT: «(a b c b a)␤»

The optional :as parameter, just like with unique, allows values to be temporarily transformed before comparison.

The optional :with parameter is used to set an appropriate comparison operator:

say [42, "42"].squish;                      # OUTPUT: «(42 42)␤»
# Note that the second item in the result is still Str
say [42, "42"].squish(with => &infix:<eq>); # OUTPUT: «(42)␤»
# The resulting item is Int

sub emit

Defined as

sub emit(\value --> Nil)

If used outside any supply or react block, throws an exception emit without supply or react. Within a Supply block, it will add a message to the stream.

my $supply = supply { 
   for 1 .. 10 { 
       emit($_); 
   } 
 } 
 $supply.tap( -> $v { say "First : $v" }); 

See also the page for emit methods.

sub undefine

Defined as:

multi sub undefine(Mu    \x)
multi sub undefine(Array \x)
multi sub undefine(Hash  \x)

DEPRECATED in 6.d language version and will be removed in 6.e. For Array and Hash, it will become equivalent to assigning Empty; for everything else, equivalent to assigning Nil or Empty in the case of arrays or hashes, whose use is advised.

Control routines

Routines that change the flow of the program, maybe returning a value.

sub exit

Defined as:

multi sub exit()
multi sub exit(Int(Any) $status)

Exits the current process with return code $status or zero if no value has been specified. The exit value ($status), when different from zero, has to be opportunely evaluated from the process that catches it (e.g., a shell); it is the only way to return an exit code different from zero from a Main.

exit prevents the LEAVE phaser to be executed, but it will run the code in the &*EXIT variable.

exit should be used as last resort only to signal the parent process about an exit code different from zero, and not to terminate exceptionally a method or a sub: use exceptions instead.

sub done

Defined as

sub done(--> Nil)

If used outside any supply or react block, throws an exception done without supply or react. Within a Supply block, it will indicate the supply will no longer emit anything. See also documentation on method done.

my $supply = supply { 
     for 1 .. 3 { 
         emit($_); 
     } 
     done; 
 } 
 $supply.tap( -> $v { say "Second : $v" }, done => { say "No more" }); 
 # OUTPUT: OUTPUT: «Second : 1␤Second : 2␤Second : 3␤No More␤» 

The block passed to the done named argument will be run when done is called within the supply block.

399 class utf8

Mutable uint8 buffer for utf8 binary data

class utf8 does Blob[uint8] is repr('VMArray') {}

A utf8 is a subtype of Blob which is specifically uint8 data for holding UTF-8 encoded text.

my utf8 $b = "hello".encode;
say $b[1].fmt("0x%X"); # OUTPUT: «0x65␤»
TOCIndex
  • declarator grammar 530
  • enum 988
  • Enums 988
  • proto regex 530
  • regex >> 896
  • regex ~ 909
  • regex « 896
  • regex » 896
  • ! (negation metaoperator) 591
  • ! (private methods) 252
  • !== 592
  • !eq 593
  • $ (item contextualizer) 1185
  • $ (variable) 1093
  • $! 1076
  • $$ (Perl 5) 211
  • $* 1074
  • $*ARGFILES 1114
  • $*COLLATION 1148 1186
  • $*CWD 1125
  • $*DEFAULT-READ-ELEMS 1150
  • $*DISTRO 1127
  • $*ERR 1120
  • $*EXECUTABLE 1134
  • $*EXECUTABLE-NAME 1135
  • $*GROUP 1138
  • $*HOME 1141
  • $*HOMEDRIVE 1139
  • $*HOMEPATH 1140
  • $*IN 1118
  • $*INIT-INSTANT 1123
  • $*KERNEL 1126
  • $*OUT 1119
  • $*PERL 1129
  • $*PID 1130
  • $*PROGRAM 1132
  • $*PROGRAM-NAME 1131
  • $*REPO 1122
  • $*SAMPLER 1146
  • $*SCHEDULER 1145
  • $*SPEC 1142
  • $*THREAD 1144
  • $*TMPDIR 1143
  • $*TOLERANCE 1149
  • $*TZ 1124
  • $*USAGE 269 1136 1147
  • $*USER 1137
  • $*VM 1128
  • $. 1077
  • $0 (Perl 5) 212
  • $: 1079
  • $= 1080
  • $? 1075
  • $?CLASS 1106
  • $?DISTRIBUTION 1110
  • $?FILE 1100
  • $?LINE 1101
  • $?MODULE 1105
  • $?NL 1109
  • $?PACKAGE 1104
  • $?ROLE 1107
  • $?TABSTOP 1108
  • $^ 1078
  • $_ (Perl 5) 209
  • $~ 1081
  • $~MAIN 1082
  • $~P5Regex 1087
  • $~Quasi 1084
  • $~Quote 1083
  • $~Regex 1085
  • $~Trans 1086
  • %*ENV 1121
  • %*SUB-MAIN-OPTS 264
  • %?RESOURCES 1103
  • %_ 508
  • %INC (Perl 5) 214
  • & (interpolation) 857
  • &*ARGS-TO-CAPTURE 1116
  • &*EXIT 1133
  • &*GENERATE-USAGE 1117
  • <-> 1193
  • <?> 534
  • () empty list 1232
  • + (Single argument rule slurpy) 1271
  • ++⚛ 1059
  • -- 631
  • --> 1263
  • --⚛ 1061
  • .( ) 623
  • ... (forward declaration) 969
  • ... operators 722
  • ...^ operators 723
  • .[ ] 624
  • .DEFINITE 234
  • .{ } 625
  • // 713
  • 0b (radix form) 952
  • 0d (radix form) 953
  • 0o (radix form) 954
  • 0x (radix form) 955
  • 6model 450
  • : 1242
  • :! 1244
  • :$ 1245
  • :$translate-nl 562
  • :() 1255
  • :: package 741
  • ::($c).m 760
  • ::() 759
  • ::?CLASS 1102
  • :a (quoting adverb) 839
  • :array (quoting adverb) 840
  • :auth<> (class) 983
  • :auth<> (grammar) 990
  • :auth<> (role) 987
  • :b (quoting adverb) 847
  • :backslash (quoting adverb) 848
  • :c (quoting adverb) 845
  • :cached 1156
  • :closure (quoting adverb) 846
  • :delete (subscript adverb) 943
  • :double (quoting adverb) 836
  • :exec (quoting adverb) 828
  • :exists (subscript adverb) 942
  • :f (quoting adverb) 843
  • :function (quoting adverb) 844
  • :h (quoting adverb) 841
  • :hash (quoting adverb) 842
  • :heredoc (quoting adverb) 850
  • :k (subscript adverb) 946
  • :kv (subscript adverb) 945
  • :my 902
  • :nl-out 563
  • :our 903
  • :p (subscript adverb) 944
  • :q (quoting adverb) 833
  • :qq (quoting adverb) 835
  • :quotewords (quoting adverb) 832
  • :s (quoting adverb) 837
  • :scalar (quoting adverb) 838
  • :single (quoting adverb) 834
  • :sym<> 530
  • :to (quoting adverb) 849
  • :v (quoting adverb) 851
  • :v (subscript adverb) 947
  • :val (quoting adverb) 852
  • :ver<> (class) 982
  • :ver<> (grammar) 989
  • :ver<> (role) 986
  • :w (quoting adverb) 829
  • :words (quoting adverb) 830
  • :ww (quoting adverb) 831
  • :x (quoting adverb) 827
  • :{} 538
  • < > word quote 859
  • 533
  • =>  1243
  • @ list contextualizer 1184
  • @*ARGS 1115
  • @_ 507
  • @_ (Perl 5) 210
  • @INC (Perl 5) 213
  • [ ] (typed array) 542
  • [+] (reduction metaoperators) 599
  • [\] (triangular reduction metaoperators) 600
  • [] (reduction metaoperators) 598
  • \ (container binding) 457
  • \ (quoting) 856
  • \ (sigilless scalar) 1253
  • \ (sigilless variables) 1072
  • \() (Capture) 1202
  • \c[] unicode name 997
  • ^methods 260
  • __FILE__ - perlfunc 73
  • __LINE__ - perlfunc 101
  • __PACKAGE__ - perlfunc 123
  • __SUB__ - perlfunc 177
  • A."$m"() 761
  • abs - perlfunc 36
  • Abstract Class 328
  • accept - perlfunc 37
  • accessor methods 244
  • Actions 535
  • Admonitory stub operator 734
  • Advent Calendar 329
  • Adverb 330
  • Adverbial Pair 331
  • ALAP 355
  • alarm - perlfunc 38
  • Allomorph 332
  • also declarator 259
  • anon state variables 1091
  • Anonymous 333
  • anonymous arguments 1258
  • Any (Basics) 17
  • Any junction operator 668
  • API 334
  • Apocalypse 335
  • ARGS-TO-CAPTURE 270
  • Argument 509
  • argument aliases 1275
  • Arity 336
  • array indexing operator 608
  • array subscript operator 608
  • ascii 1215
  • ASCII operator 337
  • Asynchronous Phasers CLOSE 802
  • Asynchronous Phasers DOC 803
  • Asynchronous Phasers LAST 800
  • Asynchronous Phasers QUIT 801
  • atan2 - perlfunc 39
  • Attribute 566
  • attributes 235
  • autopun 356
  • Autothreading 339
  • backlog 357
  • Backtracking 340
  • behavior 230
  • BigEndian 1209
  • bind - perlfunc 40
  • binmode - perlfunc 41
  • bless 256
  • bless - perlfunc 42
  • block 341
  • block (Basics) 25
  • block constructor 606
  • Books 305
  • Boolean 1196
  • Boolean (literals) 960
  • Boolean context 462
  • Bot 358
  • break - perlfunc 43
  • buf16 1198
  • buf32 1199
  • buf64 1200
  • buf8 1197
  • BUILD 257
  • but 579
  • byte 780
  • bytecode 342
  • C and C++ (FAQ) 313
  • CALLER (package) 748
  • caller - perlfunc 44
  • CALLERS (package) 749
  • Camelia 343
  • capture literal (Capture) 1201
  • CArray 559
  • CArray methods 560
  • CATCH 501
  • chdir - perlfunc 45
  • chmod - perlfunc 46
  • chomp - perlfunc 47
  • chop - perlfunc 48
  • chr - perlfunc 49
  • chroot - perlfunc 50
  • Circular dependencies (FAQ) 319
  • circumfix operator 584
  • class 225
  • class variables 247
  • classes 226
  • classes inheritance 258
  • classes accessors 245
  • classes attributes 236
  • classes behavior 231
  • classes encapsulation 238
  • classes has 229
  • classes is 980
  • classes methods 249
  • CLIENT (package) 757
  • close - perlfunc 51
  • closedir - perlfunc 52
  • closures 514
  • Colon List 345
  • colon list (Pair) 1246
  • Colon Pair 344
  • colon pair (Pair) 1241
  • command line arguments 262
  • Community 346
  • compilation unit 360
  • COMPILING(package) 747
  • compunit 286
  • compunit (glossary) 359
  • CompUnit (Rakudo classes) 277
  • connect - perlfunc 53
  • constant (Prefix) 1094
  • constant (Terms) 455
  • Constraint 1257
  • constructors 254
  • continue - perlfunc 54
  • control flow blocks 465
  • control flow fail 493
  • control flow for 477
  • control flow given 482
  • control flow last 497
  • control flow loop 488
  • control flow next 496
  • control flow once 494
  • control flow proceed 485
  • control flow quietly 495
  • control flow redo 498
  • control flow return-rw 492
  • control flow statements 464
  • control flow succeed 486
  • control flow unless 471
  • control flow when 476
  • control flow default when 484
  • control flow do 467
  • control flow else elsif 470
  • control flow gather take 478
  • control flow given statement 487
  • control flow if 469
  • control flow orwith 473
  • control flow Phasers 466
  • control flow repeat 490
  • control flow return 491
  • control flow start 468
  • control flow supply emit 481
  • control flow while until 489
  • control flow with 472
  • control flow without 474
  • CORE (package) 744
  • Core standard library (FAQ) 316
  • Coroutine (FAQ) 323
  • cos - perlfunc 55
  • CPAN (FAQ) 308
  • cross product operator 720
  • crypt - perlfunc 56
  • CStruct (native representation) 558
  • Data::Dumper (FAQ) 320
  • Date and time functions 499
  • Date ranges 500
  • dbm - perlfunc 57
  • dd 1157
  • declarator 511 512
  • declarator blocks #= 452
  • declarator blocks #| 451
  • declarator class 565
  • declarator module 961
  • declarator multi 510
  • declarator package 961
  • declarator regex 912
  • declarator role 576
  • declarator role (typesystem) 984
  • declarator rule 528
  • declarator sub 504
  • declarator token 527
  • declarator unit 961
  • declarator unit (MAIN) 267
  • declaring a list of variables 1089
  • decont 347
  • defined - perlfunc 58
  • defined-or operator 712
  • DEFINITE 233
  • delete - perlfunc 59
  • deref 561
  • DESTROY 223
  • DESTROY metamodel 1234
  • destructuring arguments 1278
  • die - perlfunc 60
  • diffy 348
  • dispatch callsame 520
  • dispatch callwith 521
  • dispatch nextcallee 525
  • dispatch nextsame 522
  • dispatch nextwith 523
  • dispatch samewith 524
  • dispatch wrapped routines 526
  • do (statement prefix) 933
  • do - perlfunc 61
  • does 577
  • does-ok 456
  • dump - perlfunc 62
  • dumper 1158
  • DWIM 361
  • DYNAMIC (package) 750
  • dynamic subset 992
  • each - perlfunc 63
  • eager (statement prefix) 928
  • ecosystem 309
  • Emacs 282
  • encapsulation 237
  • Encoding::Decoder 1206
  • Encoding::Encoder 1205
  • Endian 1210
  • Enumeration 988
  • eof - perlfunc 64
  • error variable 1099
  • escaping characters 879
  • escaping quote 853
  • eval - perlfunc 65
  • evalbytes - perlfunc 66
  • exec - perlfunc 67
  • Exegesis 349
  • exists - perlfunc 68
  • exit - perlfunc 69
  • exp - perlfunc 70
  • experimental pragma 810
  • extra named arguments 1235
  • FALLBACK (method) 973
  • FALLBACK (trait handles) 979
  • False 1195
  • fatal pragma 811
  • Fatal stub operator 733
  • fc - perlfunc 71
  • fcntl - perlfunc 72
  • fiddly 350
  • fileno - perlfunc 74
  • filetests - perlfunc 35
  • flap 362
  • flattening  941
  • flock - perlfunc 75
  • foo 295
  • for (Basics) 15
  • fork - perlfunc 76
  • formats - perlfunc 77
  • fossil 363
  • FQN 253
  • FSVO 364
  • FTFY 365
  • Futures 273
  • gather (statement prefix) 936
  • GENERATE-USAGE 272
  • get and set - perlfunc 83
  • getc - perlfunc 78
  • getpeernmae - perlfunc 79
  • getpgrp - perlfunc 80
  • getppid - perlfunc 81
  • getpriority - perlfunc 82
  • getshock - perlfunc 84
  • glob - perlfunc 85
  • GLOBAL (package) 745
  • gmtime - perlfunc 86
  • goto - perlfunc 87
  • gradual typing 366
  • Grapheme 1204
  • greatest common divisor operator 653
  • grep - perlfunc 88
  • handles trait 978
  • has 228
  • hash constructor 606
  • hash indexing operator 609
  • hash subscript operator 609
  • hex - perlfunc 89
  • hidden-from-USAGE 266
  • HOW (reserved method) 976
  • hyper (statement prefix) 929
  • hyper << 597
  • hyper >> 597
  • hyper « 597
  • hyper » 597
  • ibus 279
  • identifier (Basics) 6
  • identifier identifiers 950
  • iffy 351
  • IIRC 367
  • IMHO 368
  • import 285
  • import - perlfunc 90
  • in-range 1249
  • index - perlfunc 91
  • Inf (definition) 1238
  • infix ≅ 698
  • infix operator 582
  • infix þ 294
  • instance 352
  • int 762
  • int - perlfunc 92
  • int @ 766
  • int16 771
  • int32 772
  • int64 773
  • int8 770
  • integer bit shift operator left 651
  • integer bit shift operator right 652
  • Interface 353
  • internals pragma 812
  • interpolating into names 758
  • Introspection 545
  • invocant 250
  • invocant pragma 813
  • invocant (Basics) 13
  • ioctl - perlfunc 93
  • IPC 283
  • IRC 354
  • is (trait) 962
  • is (type of variable) 1071
  • is assoc (trait) 519
  • is default (Attribute) 1188
  • is default (Routine) 1252
  • is default (Variable) 1290
  • is equiv 517
  • is itemized? 554
  • is looser 518
  • is repr 557
  • is rw (class) 981
  • is tighter 516
  • isms pragma 814
  • iso-8859-1 1214
  • item = 717
  • IterationEnd 1231
  • IWBN 369
  • join - perlfunc 94
  • Junction (FAQ) 321
  • keys - perlfunc 95
  • kill - perlfunc 96
  • last - perlfunc 97
  • laziness in Iterable objects 540
  • lazy (statement prefix) 927
  • lazy list gather 479
  • lazy list take 480
  • lazy list … 726
  • lc - perlfunc 98
  • lcfirst - perlfunc 99
  • least common multiple operator 654
  • length - perlfunc 100
  • LEXICAL (package) 753
  • Lexing 389
  • LGTM 371
  • LHF 370
  • LHS 391
  • lib pragma 815
  • link (method) 1230
  • link (sub) 1229
  • link - perlfunc 102
  • list = 728
  • List assignment operator 729
  • list context 463
  • listen - perlfunc 103
  • Literal 390
  • LittleEndian 1208
  • local - perlfunc 104
  • localtime - perlfunc 105
  • lock - perlfunc 106
  • log - perlfunc 107
  • Loose 439
  • lstat - perlfunc 108
  • LTA 372
  • m// - perlfunc 109
  • macros 1152
  • MAIN 263
  • Mainline 393
  • mandatory named argument 1277
  • map - perlfunc 110
  • match variable 1096
  • matching adverb :1st 918
  • matching adverb :2nd 918
  • matching adverb :3rd 918
  • matching adverb :c 919
  • matching adverb :continue 919
  • matching adverb :ex 920
  • matching adverb :exhaustive 920
  • matching adverb :g 921
  • matching adverb :global 921
  • matching adverb :nth 918
  • matching adverb :ov 923
  • matching adverb :overlap 923
  • matching adverb :p 922
  • matching adverb :pos 922
  • Mayspec 394
  • Member 568
  • META6.json 292
  • method (Basics) 12
  • method (declarator) 971
  • method call 611
  • method defined 1236
  • method operators 586
  • methodop >>. 621
  • methodop .& 612
  • methodop .* 619
  • methodop .+ 618
  • methodop .? 616
  • methodop .^ 614
  • methodop ». 620
  • methods 248
  • mkdir - perlfunc 111
  • MMD 397
  • MoarVM 395
  • MONKEY pragma 808
  • MONKEY-GUTS pragma 805
  • MONKEY-SEE-NO-EVAL pragma 806
  • MONKEY-TYPING pragma 807
  • MOP 544
  • msg* - perlfunc 112
  • Multi-Dispatch 396
  • multi-method 398
  • MY (package) 742
  • my (Sub) 1286
  • my - perlfunc 113
  • named argument 1274
  • named regex 1250
  • named-anywhere 265
  • nameless variables 1092
  • NaN (definition) 1240
  • native array 769
  • nativecall 555
  • NativeEndian 1207
  • new (method) 574
  • newline pragma 816
  • next - perlfunc 114
  • Niecza 399
  • Nil assignment 1237
  • no - perlfunc 115
  • non-string keys 536
  • Normalization 993
  • Not Quite Perl 401
  • NQP 400
  • nqp pragma 817
  • NQP (FAQ) 325
  • NST 373
  • num 764
  • num @ 767
  • num32 778
  • num64 779
  • Number (literals) 956
  • number context 460
  • Numeric bitwise AND operator 650
  • NYI 402
  • object hash 537
  • objects bless 255
  • oct - perlfunc 116
  • once (statement prefix) 935
  • only method 972
  • OOP 222
  • opcode 403
  • open - perlfunc 117
  • opendir - perlfunc 118
  • Operator 404
  • operator conditional 715
  • operator flipflop 716
  • operator ternary 714
  • operators . 251
  • Opt 374
  • optional argument 1276
  • ord - perlfunc 119
  • orelse 738
  • OUR (package) 743
  • our (Sub) 1287
  • our - perlfunc 120
  • OUTER (package) 751
  • OUTERS (package) 752
  • P5 377
  • P6 378
  • p6doc 1159
  • p6doc (FAQ) 310
  • p6y 416
  • pack 1151
  • pack - perlfunc 121
  • package - perlfunc 122
  • pair constructor 718
  • Pairs (literals) 958
  • Parameter 406
  • parameter **@ 1270
  • parameter *% 1267
  • parameter *@ 1266
  • parameter | 1281
  • Parameterized Roles 578
  • parameters pragma 818
  • PARENT (package) 756
  • Parrot 407
  • Parse Tree 405
  • PAST 408
  • PATH 1182
  • PB 375
  • Perl 409
  • PERL 410
  • PERL6_EXCEPTIONS_HANDLER 1163
  • PERL6LIB 34 1161
  • perldoc (FAQ) 311
  • Perl 5 modules (FAQ) 312
  • Perl 6 Distribution (FAQ) 326
  • Perl 6 Implementation (FAQ) 324
  • Phasers BEGIN 784
  • Phasers CATCH 797
  • Phasers CHECK 785
  • Phasers COMPOSE 799
  • Phasers CONTROL 798
  • Phasers END 787
  • Phasers ENTER 788
  • Phasers FIRST 794
  • Phasers INIT 786
  • Phasers KEEP 790
  • Phasers LAST 796
  • Phasers LEAVE 789
  • Phasers NEXT 795
  • Phasers POST 793
  • Phasers PRE 792
  • Phasers UNDO 791
  • Phasers will trait 783
  • pipe - perlfunc 124
  • POD 411
  • pointy blocks 505
  • pop - perlfunc 125
  • pos - perlfunc 126
  • positional argument 1273
  • POSIX (FAQ) 315
  • postcircumfix operator 585
  • postfix ++ 632
  • postfix call 626
  • postfix decrement operator 634
  • postfix increment operator 633
  • postfix operator 583
  • POV 412
  • PR 376
  • precompilation pragma 819
  • Precompile (FAQ) 318
  • prefix & 513
  • prefix ++ 628
  • prefix decrement operator 630
  • prefix increment operator 629
  • prefix operator 581
  • print - perlfunc 127
  • printf - perlfunc 128
  • Private methods 572
  • PROCESS (package) 746
  • Property 567
  • Propspec 413
  • prototype - perlfunc 129
  • pugs 415
  • Pull request 414
  • push - perlfunc 130
  • put (Basics) 29
  • Python 215 216 217 218 219 220 221
  • QAST 417
  • qr (Perl 5) 132
  • quasi (macros) 1153
  • quietly (statement prefix) 931
  • quote " " 855
  • quote ' ' 854
  • quote / / 868
  • quote << >> 863
  • quote heredocs :to 866
  • quote m 868
  • quote Q 826
  • quote q 854
  • quote qq 855
  • quote qqw 861
  • quote qqww 862
  • quote qqx 865
  • quote qww 860
  • quote qx 864
  • quote rx 868
  • quote s/ / / 907
  • quote « » 863
  • quote 「 」 826
  • quote-words 604
  • quoting - perlfunc 131
  • qw 604
  • qw word quote 858
  • R reverse metaoperator 594
  • race (statement prefix) 930
  • Raku 418
  • Rakudo 419
  • Rakudo Raku and Perl 6 (FAQ) 296
  • Rakudo Star distribution and compiler-only release (FAQ) 317
  • Rakudo Star DMG binary installer (FAQ) 298
  • Rakudo Star docker image (FAQ) 300
  • Rakudo Star for Linux (FAQ) 301
  • Rakudo Star for Mac (FAQ) 303
  • Rakudo Star for Windows (FAQ) 302
  • Rakudo Star MSI binary installer (FAQ) 299
  • Rakudo Star release cycle (FAQ) 327
  • RAKUDO_BACKTRACE_SETTING 1167
  • RAKUDO_DEFAULT_READ_ELEMS 1176
  • RAKUDO_DEPRECATIONS_FATAL 1165
  • RAKUDO_DISABLE_MULTILINE 1174
  • RAKUDO_ERROR_COLOR 1177
  • RAKUDO_HIST 1175
  • RAKUDO_LINE_EDITOR 1173
  • RAKUDO_LOG_PRECOMP 1172
  • RAKUDO_MAX_THREADS 1178
  • RAKUDO_MODULE_DEBUG 1162
  • RAKUDO_NO_DEPRECATIONS 1164
  • RAKUDO_PRECOMP_DIST 1169
  • RAKUDO_PRECOMP_LOADING 1170
  • RAKUDO_PRECOMP_WITH 1171
  • RAKUDO_PREFIX 1168
  • RAKUDO_SNAPPER 1183
  • RAKUDO_VERBOSE_STACKFRAME 1166
  • rakudobrew (FAQ) 304
  • RAKUDOLIB 1160
  • rand - perlfunc 133
  • react 276
  • react (statement prefix) 938
  • read - perlfunc 134
  • readdir - perlfunc 135
  • readline - perlfunc 136
  • readlink - perlfunc 137
  • readpipe - perlfunc 138
  • recv - perlfunc 139
  • redo - perlfunc 140
  • ref - perlfunc 141
  • regex << 896
  • regex . 869
  • regex 893
  • regex <|w> 893
  • regex Named captures 904
  • regex Regex Interpolation 913
  • regex tilde 909
  • regex $ 891
  • regex $$ 892
  • regex % 884
  • regex %% 884
  • regex & 890
  • regex && 889
  • regex ( ) 900
  • regex : 885
  • regex <( )> 905
  • regex <-[ ]> 878
  • regex <:property> 877
  • regex <[ ]> 878
  • regex ? 886
  • regex [ ] 901
  • regex \D 875
  • regex \d 875
  • regex \h 872
  • regex \H 872
  • regex \N 870
  • regex \n 870
  • regex \S 874
  • regex \s 874
  • regex \T 871
  • regex \t 871
  • regex \V 873
  • regex \v 873
  • regex \w 876
  • regex \W 876
  • regex ^ 891
  • regex ^^ 892
  • regex adverb :i 914
  • regex adverb :ignorecase 914
  • regex adverb :ignoremark 915
  • regex adverb :m 915
  • regex adverb :r 916
  • regex adverb :ratchet 916
  • regex adverb :s 917
  • regex adverb :sigspace 917
  • regex after 899
  • regex before 898
  • regex deprecated \b 894
  • regex deprecated \B 895
  • regex deprecated \K 906
  • regex negative lookaround assertion 897
  • regex positive lookaround assertion 897
  • regex quantifier * 881
  • regex quantifier ** 883
  • regex quantifier + 880
  • regex quantifier ? 882
  • regex | 888
  • regex || 887
  • Regular Expressions 867
  • Reify 420
  • rename - perlfunc 142
  • Repository 421
  • repr 556
  • requires - perlfunc 143
  • reset - perlfunc 144
  • resume (Exceptions) 503
  • return - perlfunc 145
  • Return type arrow 1264
  • return-rw 1251
  • reverse - perlfunc 146
  • rewinddir - perlfunc 147
  • RHS 422
  • rindex - perlfunc 148
  • rmdir - perlfunc 149
  • roast 423
  • role 424
  • RSN 379
  • RT 380
  • Ruby Quickstart (FAQ) 307
  • rule 425
  • RUN-MAIN 271
  • rvalue 426
  • S sequential metaoperator 603
  • s/// - perlfunc 150
  • say (Basics) 27 28
  • say - perlfunc 151
  • scalar - perlfunc 152
  • seek - perlfunc 153
  • seekdir - perlfunc 154
  • SeekFromBeginning 1223
  • SeekFromCurrent 1224
  • SeekFromEnd 1225
  • select - perlfunc 155
  • semget - perlfunc 156
  • semop - perlfunc 157
  • send - perlfunc 158
  • SETGOAL 910
  • setpgrp - perlfunc 159
  • setpriority - perlfunc 160
  • setsockopt - perlfunc 161
  • SETTING (package) 755
  • Shaped arrays 543
  • shift - perlfunc 162
  • shm* - perlfunc 163
  • shutdown - perlfunc 164
  • Sigil 429
  • sigil $ 1067
  • sigil % 1069
  • sigil & 1070
  • sigil @ 1068
  • Sigilless Variable 430
  • sigils & 239
  • Sigils (FAQ) 322
  • signature literal 1254
  • sin - perlfunc 165
  • sink (statement prefix) 934
  • sink context 458
  • sinking 459
  • sleep - perlfunc 166
  • Slot 569
  • slurpy argument 1268
  • SlurpySentry 1292
  • smartmatch operator 697
  • sockets - perlfunc 167
  • soft pragma 820
  • sort - perlfunc 168
  • spaceship operator 677
  • Special Variables (Perl 5) 208
  • Specification (FAQ) 306
  • Spesh 431
  • splice - perlfunc 169
  • split - perlfunc 170
  • sprintf - perlfunc 171
  • sqrt - perlfunc 172
  • srand - perlfunc 173
  • start (statement prefix) 937
  • state 227
  • state - perlfunc 174
  • statement (Basics) 2
  • STD 432
  • str 765
  • str @ 768
  • strict pragma 821
  • String (literals) 951
  • string context 461
  • Stub 433
  • stub operator 732
  • study - perlfunc 175
  • sub - perlfunc 176
  • sub EXPORT 290
  • sub-signature 1279
  • submethod DESTROY 224
  • Submethods 573
  • subset 991
  • substitution adverb :ii 924
  • substitution adverb :mm 925
  • substitution adverb :samecase 924
  • substitution adverb :samemark 925
  • substitution adverb :samespace 926
  • substitution adverb :ss 926
  • substr - perlfunc 178
  • supersede 1088
  • supply (on-demand) 274
  • supply (statement prefix) 939
  • switch (given) 483
  • Symbol 434
  • symlink (method) 1228
  • symlink (sub) 1227
  • symlink - perlfunc 179
  • Synopsis 435
  • syntax -> 506
  • syntax \ 948
  • Syntax Analysis 436
  • syntax DEFINITE 552
  • syntax HOW 550
  • syntax Unspace 949
  • syntax VAR 553
  • syntax WHAT 546
  • syntax WHERE 549
  • syntax WHICH 547
  • syntax WHO 548
  • syntax WHY 551
  • sys* - perlfunc 181
  • syscall - perlfunc 180
  • system - perlfunc 182
  • syswrite - perlfunc 183
  • tell - perlfunc 184
  • telldir - perlfunc 185
  • TEMP 1180
  • test suite 437
  • Texas operator 338
  • Thunk 438
  • tie - perlfunc 186
  • Tight 440
  • time - perlfunc 187
  • times - perlfunc 188
  • TIMTOWTDI 381
  • TMI 382
  • TMP 1181
  • TMPDIR 1179
  • TMTOWTDI 383
  • TOP 531
  • topic variable 1095
  • tr/// - perlfunc 189
  • trace pragma 822
  • trait is raw 1284
  • trait is copy 1282
  • trait is DEPRECATED (Attribute) 1191
  • trait is readonly 1285
  • trait is required (Attribute) 1190
  • trait is rw 1283
  • trait is rw (Attribute) 1192
  • trait_mod (declarator) 1288
  • traits is rw 246
  • True 1194
  • truncate - perlfunc 190
  • try (statement prefix) 932
  • try blocks 502
  • tty 1226
  • TWEAK 575
  • Twigil 1073
  • twigils 240
  • twigils ! 241
  • twigils . 242
  • twigils accessors 243
  • twine 441
  • Type capture 1272
  • Type Capture (role) 985
  • type constraint 1256
  • type constraint :_ 1262
  • type constraint :D 1260
  • type constraint :U 1261
  • type object 232
  • Type objects 564
  • typed array 541
  • UB 443
  • uc - perlfunc 191
  • ucfirst - perlfunc 192
  • UGT 384
  • uint 763
  • uint16 775
  • uint32 776
  • uint64 777
  • uint8 774
  • undef - perlfunc 193
  • UNIT (package) 754
  • UNIX library functions (FAQ) 314
  • unlink - perlfunc 194
  • unpack - perlfunc 195
  • unquoting (macros) 1154
  • unshift - perlfunc 196
  • untie - perlfunc 197
  • upto operator 643
  • USAGE 268
  • use - perlfunc 198
  • use lib 291
  • use soft (pragma) 515
  • utf-16 1220
  • utf16 1219
  • utf16-be 1218
  • utf16-le 1217
  • UTF8-C8 995
  • utime - perlfunc 199
  • v (version) 1291
  • v6 pragma 823
  • v6 (Basics) 1
  • v6.d (FAQ) 297
  • v6.x pragma 804
  • Value 392
  • value 442
  • Value type 444
  • values - perlfunc 200
  • VAR (reserved method) 977
  • Variable 445
  • variable $0 1097
  • variable $1 1097
  • variable $1098
  • Variable Interpolation 446
  • variables pragma 824
  • vec - perlfunc 201
  • Vim 281
  • Virtual Machine 447
  • void type (NativeCall) 782
  • wait - perlfunc 202
  • waitpid - perlfunc 203
  • wantarray - perlfunc 204
  • warn - perlfunc 205
  • WAT 448
  • WFM 385
  • WHAT (reserved method) 974
  • whenever 275
  • where clause 1259
  • whitespace 449
  • WHO (reserved method) 975
  • WinCompose 280
  • windows-1251 1212
  • windows-1252 1211
  • windows-932 1213
  • WIP 386
  • with orwith without 475
  • worries pragma 825
  • WP 387
  • write - perlfunc 206
  • ws 532
  • WW 388
  • X (cross metaoperator) 601
  • X operators 721
  • XCompose 278
  • y/// - perlfunc 207
  • Z (zip metaoperator) 602
  • Zen slice (Basics) 33
  • Zen slices 940
  • {{{}}} (macros) 1155
  • « 998
  • «=« 1064
  • «=» 596 1065
  • ¯ 1023
  • ² 1026
  • ³ 1027
  • ¹ 1025
  • » 999
  • »=« 595 1066
  • »=» 1063
  • × 1000
  • ÷ 1001
  • π 1008
  • τ 1009
  • ‘ 1013
  • ’ 1014
  • ‚ 1015
  • “ 1016
  • ” 1017
  • „ 1018
  • … 1012
  • … operators 724
  • …^ operators 725
  • ⁰ 1024
  • ⁴ 1028
  • ⁵ 1029
  • ⁶ 1030
  • ⁷ 1031
  • ⁸ 1032
  • ⁹ 1033
  • ⁺ 1021
  • ⁻ 1022
  • ∅ 453
  • ∈ 1034
  • ∉ 1035
  • ∋ 1036
  • ∌ 1037
  • − 1005
  • ∖ 1050
  • ∘ 1006
  • ∞ 1011
  • ∞ (definition) 1239
  • ∩ 1049
  • ∪ 1048
  • ≅ 1007
  • ≠ 1004
  • ≤ 1002
  • ≥ 1003
  • ≼ 1046
  • ≽ 1047
  • ⊂ 1040
  • ⊃ 1044
  • ⊄ 1041
  • ⊅ 1045
  • ⊆ 1038
  • ⊇ 1042
  • ⊈ 1039
  • ⊉ 1043
  • ⊍ 1052
  • ⊎ 1053
  • ⊖ 1051
  • ⚛ 1055
  • ⚛++ 1060
  • ⚛+= 1056
  • ⚛-- 1062
  • ⚛-= 1057
  • ⚛= 1054
  • ⚛−= 1058
  • 「 1019
  • 」 1020
  • 𝑒 1010