Raku by Example: Variables

Most variable declarations in Raku are done by using my keyword which created lexically scoped names.

# creating a new lexical scope with a block
    my $a = 2;
    say $a;
# say $a; # Error: Variable '$a' is not declared
$ perl6 my.p6

Variables and sigils

They're four type of sigils:

  • The scalar-sigil $ associated with scalar variables. A scalar variable stores a single value or reference.
my $hyp    = 5;
my $name   = 'Pythagoras';
my $height = 5.9;

say 'Hypotenuse: ', $hyp;
say "Name: $name";     
say "Height: $height"; # Double quotes cause interpolation of scalar variables
$ perl6 scalars.p6
Hypotenuse: 5
Name: Pythagoras
Height: 5.9
  • The positional-sigil @ associated with array variables. An array variable stores multiple values.
my @mars-moons  = 'Phobos', 'Deimos';
my @earth-moons = 'Moon';

say @mars-moons[0];   # accessing an element through its index
say "Array's name: @mars-moons";
say "@earth-moons[]"; # append a [] to interpolate inside double quotes 
$ perl6 array.p6
Array's name: @mars-moons
  • The associative-sigil % associated with hash variables. A hash variable stores a set of key-value pairs.
my %chem-elems = 'H' => 1, 'He' => 2, 'C' => 6, 'O' => 8, 'Ca' => 20;
%chem-elems = :H(1), :He(2), :C(6), :O(8), :Ca(20); # using colon syntax

say %chem-elems{'H'}; # accesing a value through its key
say %chem-elems<He>;  # similar if key doesn't contain spaces
say %chem-elems{'C'};
say "%chem-elems{}";  # append a {} to interpolate inside double quotes
$ perl6 hash.p6
C	6
Ca	20
H	1
He	2
O	8
  • The callable-sigil & associated with callable variables. A callable variable stores functions/subroutines.
my &greet = sub { say "Gretting!!!" }

&greet(); # parens are needed to call a code variable.
          # Otherwise, the variable is a reference to the funtion/sub.
$ perl6 code.p6

Binding vs assignment

Binding is done with the := operator. By binding to a variable, we make the bound value the variable's literal value. In this sense, such variable is just a named value. Thus a bound variable is just a literal constant (or immutable value) within the scope of its declaration. An attempt to re-assign to it will produce an error similar to the error produced by trying to assign to a literal value (i.e., 5 = 10, 'b' = 'z', etc).

my $var := 25;
say $var;
$var = 99; # Here we're trying to assign `99` to `25` (`$var`) which 
say $var;  # is not possible so an exception will occur.
$ perl6 binding.p6
Cannot assign to an immutable value

Instead of creating a bound variable with a value, we can assign it a regular variable.

my $a = 1;
my $b := $a;

say $a.WHERE; # OUTPUT: 93930814379696
say $b.WHERE; # OUTPUT: 93930814379696

$b = 21;
say $a;       # OUTPUT: 21

In this case, both $a and $b are just different names for the same object.

Assignment is performed with the = operator and interfaced by what's known as a container (specifically, a Scalar container). Instead of binding a value directly to a variable, a container is bound in its place to the variable and then the value is stored in the container. From here on, operations (including assignments) are performed on the container. Although the Scalar container is invisible in most operations, it underlies the process of every assignment in Raku.

my $var = 35;
$var = 56;       # assignment works just fine
say $var;
$var = $var * 2; # same as above
say $var;
$ perl6 assignment.p6

Here both variables contain the same value (1) but they represent different objects.

my $a = 1;
my $b = $a;

$b = 21;
say $a;       # OUTPUT: 1

For a more thorough explanation of this, read Elizabeth Mattijsen's Containers in Perl 6.

More variable declarators

The our keyword is similar to my but variables declared with it also introduce an alias into the symbol table:

module Mod {
    our $value = 'Moon';

say $Mod::value;
$ perl6 our.p6

The has keyword has scope for attribute names for classes and roles. For examples, go .

class Person {
    has $.name;

my $p = Person.new(name => 'Hercules);
say "Person: ", $p.name;
$ perl6 has.p6
Person: Hercules

The anon declarator prevents a symbol from getting installed in the lexical scope, the method table and everywhere else:

# creating an anonymous subroutine from a regular sub. However, 
# the sub cannot be called by its name.

my $f = anon sub hello { say "Hello!" }

# hello(); # Error: undeclared subroutine
$ perl6 anon.p6

There are additional declarators (state, augment, supersed) and prefixes (temp, let, constant) that resemble declarators but act on predefined variables.

To learn more about variables, go to https://docs.perl6.org/language/variables.

Back to main