📘 Variables in Perl 6: Introspection

Due to the mechanism of introspection, it is easily possible to tell the type of the data living in a variable (a variable in Perl 6 is often referred as a container). To do that, call the predefined WHAT method on a variable. Even if it is a bare scalar, Perl 6 treats it internally as an object; thus, you may call some methods on it.

For scalars, the result depends on the real type of data residing in a variable. Here is an example (parentheses are part of the output):

my $scalar = 42;
my $hello-world = "Hello, World";

say $scalar.WHAT;      # (Int)
say $hello-world.WHAT; # (Str)

For those variables, whose names start with the sigils @ and %, the WHAT method returns the strings (Array) and (Hash).

Try with arrays:

my @list = 10, 20, 30;
my @squares = 0, 1, 4, 9, 16, 25;

say @list.WHAT;    # (Array)
say @squares.WHAT; # (Array)

Now with hashes:

my %hash = 'Language' => 'Perl';
my %capitals = 'France' => 'Paris';

say %hash.WHAT;     # (Hash)
say %capitals.WHAT; # (Hash)

The thing, which is returned after a WHAT call, is a so-called type object. In Perl 6, you should use the === operator to compare these objects.

For instance:

my $value = 42;
say "OK" if $value.WHAT === Int;

There’s an alternative way to check the type of an object residing in a container — the isa method. Call it on an object, passing the type name as an argument, and get the answer:

my $value = 42;
say "OK" if $value.isa(Int);

📘 Int type in Perl 6

The Int type is intended to host integer variables of arbitrary size. For example, no digit is lost in the following assignment:

my Int $x =
say $x;

A special syntax exists for defining integers with an other-than-10 base:

say :16<D0CF11E0>

Also, it is allowable to use the underscore character to separate digits so that big numbers can be read more easily:

my Int $x = 735_817_503_285_431_532;

Of course, when you print the value, all the underscores are gone.

On the Int object, you may call some other handy methods, for example, to convert a number to a character or to check if the integer in hand is prime (yes, is-prime is a built-in method!).

my Int $a = 65;
say $a.chr; # A

my Int $i = 17;
say $i.is-prime; # True

say 42.is-prime; # False

📘 Frequently used special variables in Perl 6

The $_ variable is the one similar to that in Perl 5, which is the default variable containing the current context argument in some cases. Like any other variable, the $_ is an object in Perl 6, even in the simplest use cases. For example, the recent example .say for @*ARGS implicitly contains the $_.say call. The same effect would give $_.say(), .say(), or just .say.

This variable is used as a default variable in other cases, for instance, during the match against regular expressions:

for @*ARGS {
    .say if /\d/;

This short code is equivalent to the following, which uses the smartmatch (~~) operator:

for @*ARGS {
    $_.say if $_ ~~ /\d/;

The result of matching against a regular expression is available in the $/ variable. To get the matched string, you may call the $/.Str method. So as to get the substrings, which were caught during the match, indices are used: $/[2] or, in a simpler form, $2.

"Perl’s Birthday: 18 December 1987" ~~ 
    / (\d+) \s (\D+) \s (\d+) /;
say $/.Str;
say $/[$_] for 0..2;

Here, we are looking for a date. In this case, the date is defined as a sequence of digits \d+, a space \s, the word having no digits \D+, another space \s, and some more digits \d+. If the match succeeded, the $/.Str slot contains the whole date, while the $/[0], $/[1], and $/[2] keep their parts (the small square corner brackets are part of the output to indicate the Match object, see Chapter 6):

18 December 1987

Finally, the $! variable will contain an error message, for example, the one that occurred within a try block, or the one that happened while opening a file:

try {
    say 42/0;
say $! if $!;

If you remove the last line in this programme, nothing will be printed. This is because the try block masks any error output. Remove the try, and the error message reappears (the programme, itself, is terminated).

📘 Array in Perl 6

The Array variables (i.e., all the variables starting with the @ sigil) are equipped with a couple of simple but rather useful methods.

my @a = 1, 2, 3, 5, 7, 11;
say @a.Int; # array length
say @a.Str; # space-separated values

If you print an array, you get its value as a space-separated list in square brackets. Alternatively, you may interpolate it in a string.

my @a = 1, 2, 3, 5, 7, 11;

say @a;                 # [1 2 3 5 7 11]
say "This is @a: @a[]"; # This is @a: 1 2 3 5 7 11

📘 Built-in types in Perl 6

Perl 6 allows using typed variables. To tell the compiler that the variable is typed, you simply need to name the type while declaring the variable.

Some of the types available in Perl 6 are obvious and do not need comments:

Bool, Int, Str
Array, Hash, Complex

Some might require a small comment:

Num, Pair, Rat

The Num type is used to handle floating-point variables, and a Pair is a “key; value” pair. The Rat type introduces rational numbers with numerators and denominators.

📘 Variables in Perl 6: Twigils

In Perl 6, a variable name may be preceded by either a single-character sigil, such as $, @ or %, or with a double character sequence. In the latter case, this is called a twigil. The first character of it means the same thing that a bare sigil does, while the second one extends the description.

For example, the second character of the twigil can describe the scope of the variable. Consider *, which symbolises dynamic scope (more on this in Chapter 3). The following call prints the command line arguments one by one:

.say for @*ARGS;

Here, the @*ARGS array is a global array containing the arguments received from the command line (note that this is called ARGS and not ARGV as in Perl 5). The .say construction is a call of the say method on a loop variable. If you want to make it more verbose, you would write it like this:

for @*ARGS {

Let’s list a few other useful predefined dynamic variables with the star in their twigils. The first element of the twigil denotes the type of a container (thus a scalar, an array, or a hash):

$*PERL contains the Perl version (Perl 6)

$*PID — process identifier

$*PROGRAM-NAME — the name of the file with the currently executing programme (for a one-liner its value is set to -e)

$*EXECUTABLE — the path to the interpreter

$*VM — the name of the virtual machine, which your Perl 6 has been compiled with

$*DISTRO — the name and the version of the operation system distribution

$*KERNEL — similar, but for the kernel

$*CWD — the current working directory

$*TZ — the current timezone

%*ENV — the environment variables

In my case, the variables above took the following values:

Perl 6 (6.c)
moar (2016.11)
macosx (10.10.5)
darwin (14.5.0)
"/Users/ash/Books/Perl 6/code".IO
{Apple_PubSub_Socket_Render => /private/tmp/com.apple., DISPLAY => /private/tmp/com.apple, HISTCONTROL => ignorespace, HOME => /Users/ash, LC_CTYPE => UTF-8, LOGNAME => ash ...

The next group of the predefined variables include those with the ? character as their twigil. These are “constants” or so-called compile-time constants, which contain information about the current position of the programme flow.

$?FILE — the name of the file with a programme (no path included; contains the string -e for one-liners)

$?LINE — the line number (is set to 1 for one-liners)

$?PACKAGE — the name of the current module; on a top level, this is (GLOBAL)

$?TABSTOP — the number of spaces in tabs (might be used in heredocs)