Variables
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 base type subscripts required 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.
An item assignment copies a single value from the right-hand side into a Scalar
variable on the left. An assignment to anything other than a simple Scalar
variable is parsed as a list assignment. A list assignment leaves the choice of
what the assignment operation entails to the variable on the left. For example,
Array variables (@
sigil) empty themselves on list assignment,
and then iteratively copy all values from the right-hand side into themselves as
elements.
The two types of assignment both use the equal sign =
as their operator and
are both right associative, but differ in operator precedence: item assignment
has a higher precedence level (level: Item assignment) than list assignment
(level: List prefix). In situations in which a comma-separated list of elements
is assigned, these precedences should in particular be contrasted with that of
the comma operator ,
which sits in between. So without any list-delimiting
parentheses (or other construct to hold the list's elements together), item
assignment will only assign the first element of the specified list, and not the
full list.
In an assignment expression the context of the left-hand side determines whether
an =
means item or list assignment. As mentioned, item assignment is
restricted to simple Scalar variables. Accordingly, assignment to a Scalar
container (scalar-context) triggers item assignment, unless the Scalar is
explicitly put in list-context by surrounding parentheses ( )
:
my $a;
$a = 1,2,3; # item assignment to Scalar
say $a; # OUTPUT: «1» ( '=' has higher precedence than ',' )
my $b = 1,2,3; # item assignment to Scalar (same as preceding example)
say $b; # OUTPUT: «1»
my $c;
($c) = 4,5,6; # list assignment to Scalar; '( )' is list-contextualizer
say $c; # OUTPUT: «(4,5,6)»
(my $d) = 4,5,6; # list assignment to Scalar (same as preceding example)
say $d; # OUTPUT: «(4,5,6)»
Assignment to a List container (list-context) always triggers list assignment:
my @e;
@e = 7,8,9; # list assignment to Array
say @e; # OUTPUT: «[7,8,9]»
my $f;
($f,) = 7,8,9; # list assignment to List with one element
say $f; # OUTPUT: «7»
say ( ($f,) ).VAR.^name; # OUTPUT: «List»
# ATTENTION: special declaration syntax!
my ($g) = 7,8,9; # list assignment to List with one element
say $g; # OUTPUT: «7»
say ( ($g) ).VAR.^name # OUTPUT: «List»
The last two examples above are simple destructuring assignments that select the first item of the right-hand side list. See for a more elaborate discussion of destructuring assignments in the context of variable declarations the section on declaring a list of variables with lexical or package scope.
Chained assignments are parsed having regard to the precedence of the assignment
operators and, where applicable, their right associativity. For instance, in the
example below there is one chained assignment statement comprising two
assignment operators. The assignment to @array
is a list assignment having a
lower precedence than the item assignment to the Scalar variable $num
. The
assignment expression involving the item assignment to the Scalar variable
$num
is thus evaluated first. It returns the assigned value 42
, which in
turn forms part of the List (42, "str")
constructed by the comma operator
that also has a higher precedence than the list assignment. Finally, the
List (42, "str")
is list-assigned to @array
:
my @array;
@array = my $num = 42, "str"; # parsed as @array = ( (my $num = 42), "str )
say @array.raku; # OUTPUT: «[42, "str"]» (an Array)
say $num.raku; # OUTPUT: «42» (a Num)
Here's a variant:
my ( @foo, $bar );
@foo = ($bar) = 42, "str"; # parsed as @foo = ( $bar = (42, "str") )
say $bar.raku; # OUTPUT: «$(42, "str")» (a List)#
say @foo.raku; # OUTPUT: «[(42, "str"),]» (an Array)
In this case, the list contextualizer ( )
puts $bar
in a list context, and
thus triggers a list assignment to the Scalar variable $bar
. This means that
there are two chained list assignments, both having a lower precedence than the
comma operator ,
that constructs the List (42, "str")
. Due to their right
associativity, the list assignment expression that is evaluated first is the
assignment to $bar
, which returns the assigned value $(42, "str")
, i.e. a
Scalar containing a two-element List. This value is in turn list-assigned to
@array
, such that it becomes an Array with a single element, namely a List.
See operators for more details on precedence and associativity.
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.raku);
my \result = f(|args);
# ^^^^^^^ not enforcing any context here
say(&f.name ~ ' returned ' ~ result.raku);
return |result;
}
Sigilless variables can also be used for binding. See Binding for more information.
Twigils
We use the term twigils, a word play with sigil, that indicates it uses two symbols in front of an identifier; the second symbol will be placed between the sigil and the identifier, and it will be related to the scoping of a variable, that is, where that variable is defined and can be changed.
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.[1]
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.raku: 23"
# if this is the line 23 of a
# file named "hello.raku"
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 Raku all attributes are
private and can be directly accessed within the class by using
$!attribute-name
. Raku 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.
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 Perl-isms).
The ^
twigil can be combined with any sigil to create a placeholder variable
with that sigil. The sigil will have its normal semantic effects, as described
in the Sigils table. Thus @^array
, %^hash
, and &^fun
are all
valid placeholder variables.
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). For instance:
say { $:add ?? $^a + $^b !! $^a - $^b }( 4, 5 ) :!add
# OUTPUT: «-1»
See ^ for more details about placeholder variables.
A note on ^
and :
Unlike other twigils, ^
and :
declare variables, which can then be
referred to without that twigil. Thus, the previous example could be written as:
say { $:add ?? $^a + $^b !! $a - $b }( 4, 5 ) :!add # OUTPUT: «-1»
That is, once you have used $^a
to declare $a
, you can refer to that variable
in the same scope with either $^a
or $a
. The same is true for :
: after
declaring $:add
, you are free to refer to that declared variable with $add
if
you prefer.
In some instances, this is just a convenience – but it can be much more significant when dealing with nested blocks. For example:
{ say $^a; with "inner" { say $^a } }("outer"); # OUTPUT: «outerinner»
{ say $^a; with "inner" { say $a } }("outer"); # OUTPUT: «outerouter»
The first line declares two formal positional parameters, while the second declares
only one (but refers to it twice). This can be especially significant with constructs
such as with
, for
, and if
that are often used without much consideration of
the fact that they create blocks.
Just like the ^
twigil, the :
twigil can be combined with any sigil; using
:
with a sigil will create a formal named parameter with that sigil (applying
the semantics of that sigil). Thus @:array
, %:hash
, and
&:fun
are all valid, and each creates a formal named parameter with the
specified sigil.
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 Foo
...
=end Foo
# after that, $=Foo gives you all Foo-Pod-blocks
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., Raku 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 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 three 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 are created in the scope of the surrounding package. They also create
an alias in the lexical scope, therefore they can be used like my
variables as well.
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|Language,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].raku;
# 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.raku;
# 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].raku;
# 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 ) );
# OUTPUT: «True»
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: «12»
foo; # OUTPUT: «12»
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: {$_(), $_()}; # OUTPUT: «121212»
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: «1234435»
# OUTPUT: «21345»
# 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.
raku -ne 'say ++$ ~ " $_"' example.txt
Each reference to $
within a lexical scope is in effect a separate
variable.
raku -e '{ say ++$; say $++ } for ^5'
# OUTPUT: «1021324354»
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: «135»
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: «012»
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 methods, but not attributes, 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).
For a better, and safer example, this is a practical
way to create a class module to extend IO::Path by
adding a currently missing method to yield the part of the basename
left after the extension
is removed. (Note there
is no clear developer consensus about what to call that
part or even how it should be constructed.)
unit class IO::Barename is IO::Path;
method new(|c) {
return self.IO::Path::new(|c);
}
use MONKEY-TYPING;
augment class IO::Path {
method barename {
self.extension("").basename;
}
}
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 the value it tags 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. Since Raku modules are precompiled automatically, constants defined in modules are not re-evaluated when the program is run. 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.
Special variables
Raku 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 four special variables that are always available:
Variable | Meaning Scope | |
$_ | topic variable | every block |
$/ | regex match | every sub / method |
$! | exceptions | every sub / method |
$¢ | last match (similar to $/) | inside current regex |
Note that while you can access $¢
without error anywhere, it will
contain Nil if accessed outside of a regex.
The $_
variable
$_
is the topic variable. A fresh one is created in every block.
It's also 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 $_ } # binds $_ to 'a', 'b' and 'c' in turn
say $_ for <a b c>; # same, even though it's not a block
given 'a' { say $_ } # binds $_ to 'a'
say $_ given 'a'; # same, even though it's not a block
Because $_
is bound to the value of the iteration, you can also
assign to $_
if it is bound to something assignable.
my @numbers = ^5; # 0 through 4
$_++ for @numbers; # increment all elements of @numbers
say @numbers;
# OUTPUT: «1 2 3 4 5»
CATCH
blocks bind $_
to the exception that was caught. The ~~
smartmatch operator binds $_
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. A fresh one is created in every routine.
It is set to 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|Variables,$0;Variables,$1
$/
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|Variables,$<named>
$/
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.
Thread-safety issues
Because $/
is only defined per routine, you are in fact
re-using the same $/
when you do matching in a loop. In a single
threaded program, this is not an issue. However, if you're going to
use hyper
or race
to have multiple threads do matching in
parallel, the sharing of the "outer" $/
becomes an issue, because
then it is being shared between threads! Fortunately, the solution
is very simple: define your own $/
inside the scope where you are
doing the matching. For example, taking a source of text, running
a regex on it, and map that to a hash using parallel execution:
my %mapped = @source.race.map: {
my $/; # need one in this block to prevent racing issues
m/foo (.*?) bar (.*)/; # matches on $_, stores in $/
$0 => $1 # short for $/[0] / $/[1]
}
The $!
variable
$!
is the error variable. A fresh one is created in every routine.
If a try
block or statement prefix catches an exception, that exception
is stored in $!
. If no exception was caught, $!
is set to Nil.
Note that CATCH
blocks do not set $!
. Rather, they set $_
inside
the block to the caught exception.
Also note that the same thread-safety issues apply to the use of $!
as
they do to $/
.
The $¢
variable
See the description in Match.
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.
%?RESOURCES
|Variables,%?RESOURCES
%?RESOURCES
is a compile-time variable available to the code of a
Distribution.
It contains a hash that provides compile and runtime access to files associated with the Distribution of the current compilation unit. This hash is used to access a special storage for Distribution-wide static files (such as examples of configuration files, templates or data files).
Files available via this variable need to be placed under the Distribution's resources
directory:
Module-Foo/
├── lib
│ └── Module
│ └── Foo.rakumod
├── META6.json
├── README.md
└── resources
└── images
└── foo.jpg
Additionally, a relative path (starting from the root resources directory of a
distribution) to a file may be specified under the "resources"
field in the
META6.json
file:
"resources": [
"images/foo.jpg"
]
Every resource file is added to an installed Distribution and is
accessible using a Hash-like access to %?RESOURCES
, returning a
Distribution::Resources
object:
my $foo-IO = %?RESOURCES<images/foo.jpg>; # gets an object you can slurp
my $foo-IO = %?RESOURCES<images/foo.jpg>.absolute; # gets an absolute path to a file
my $foo-IO = %?RESOURCES<images/foo.jpg>.open; # gets an opened IO::Handle to work with
Note that paths and names of resource files can be mangled in an
installed distribution, so do not rely on their values in any other
case besides using them as keys for the %?RESOURCES
variable.
The %?RESOURCES
variable is not implemented as a plain Hash, but as an
instance of the Distribution::Resources type, so do not expect to see
all available resource files in a distribution by printing or by using other
ways to inspect its value. Instead, use the API described above to
access particular files.
The %?RESOURCES
variable is only accessible inside of modules.
If you want to access %?RESOURCES
outside of a module, you'll need
to expose that API yourself. One way to do that is to create a
routine in the lib
directory to return its value:
unit module MyLib;
sub my-resources is export {
%?RESOURCES
}
Then create a test file, say, t/resources.t
, with contents:
use Test;
use MyLib;
my $resources = my-resources;
isa-ok $resources, Hash;
The contents of the compile-time hash are thus exposed to the runtime code.
Introspection compile-time variables
The following compile time variables allow for a deeper introspection:
$?PACKAGE Which package am I in? |
$?MODULE, ::?MODULE Which module am I in? It contains the type of the module. |
$?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.
Rakudo-specific compile-time variables
These variables are Rakudo specific, with all the corresponding caveats:
$?BITS | Number of data-path bits of the platform the program is being compiled upon. |
&?ROUTINE
The compile time variable &?ROUTINE
provides introspection about which
routine the program is actually within. It returns an instance of
Routine 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 Routine:
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;
Note that, in a multi,
&?ROUTINE
refers to the current candidate, not the multi
as a whole.
Thus, the following recursive definition does not work:
multi broken-fibonacci($n where * ≤ 1) { $n }
multi broken-fibonacci($n where * > 0) {
&?ROUTINE($n - 1) + &?ROUTINE($n - 2)
}
If called, &?ROUTINE
would always refer to the second
multi candidate and would never dispatch to the first. If
you want to use self-recursion for the whole proto
, either
use the function name or samewith.
&?BLOCK
The special compile variable &?BLOCK
behaves similarly to
&?ROUTINE
but it allows to introspect a single block of code.
It holds a Block 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>; # OUTPUT: «0.0.1»
}
The .meta
method currently has hash keys of ver
, auth
, and api
,
The .content
method provides access to files in the distribution
when provided with the relative path from the distribution's top-level
directory.
sub module-source {
say "MyFoo source code:";
say $?DISTRIBUTION.content('lib/MyFoo.rakumod');
# OUTPUT: «IO::Handle<"lib/MyFoo.rakumod".IO>(closed)»
}
Note the output for the content
example is a closed filehandle.
To actually use the file's content, the user can extract it as a string
in another routine in the same module:
sub get-file-content {
say $?DISTRIBUTION.content('lib/MyFoo.rakumod').open.slurp;
# OUTPUT: «unit module MyFoo;»
}
Dynamic variables
All dynamically scoped variables have the *
twigil, and their name is
(conventionally) written in uppercase.
Argument related variables
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.
$*IN
Standard input filehandle, AKA STDIN.$*OUT
Standard output filehandle, AKA STDOUT.$*ERR
Standard error filehandle, AKA STDERR.
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
is a dynamic variable intended to contain an object with information
about the system's local timezone. It should numify to the number of
seconds from GMT.
If not set explicitly, it contains just an integer value without any
further information, set the first time $*TZ
is accessed. Any
daylight saving time changes occurring during the duration of the
process will not be seen in that case.
$*CWD
It contains the C
urrent W
orking D
irectory.
$*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.raku;
# 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 Raku environment.
$*RAKU
This object of the Raku class contains information on the current implementation of the Raku language:
say $*RAKU.compiler.version; # OUTPUT: «v2020.01»
but its gist includes the name of the language, followed by the major version of the compiler:
say $*RAKU; # OUTPUT: «Raku (6.d)»
It stringifies to Raku
:
$*RAKU.put; # OUTPUT: «Raku»
Note: Before Rakudo version 2020.1, this information was only
available through the $*PERL
variable. Since Rakudo version 2020.1,
it is available through both the $*RAKU
and the $*PERL
variables.
$*PERL
For the foreseeable future, the same as $*RAKU
. Will be deprecated at
some point.
$*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 raku was invoked with the -e flag.
$*PROGRAM
Contains the location (in the form of an IO::Path object) of the Raku 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
Raku is embedded in another language runtime (such as Inline::Perl6 in Perl).
$*EXIT
Using $*EXIT
usually only makes sense in an END
block. It contains the currently known exit() value: 1
if an exception occurred, 0 if no exception occurred, N when an
exit(N)
was executed.
Support for $*EXIT
was added in Rakudo compiler version 2023.02.
$*EXCEPTION
Using $*EXCEPTION
usually only makes sense in an END
block. It contains an instantiated Exception object if the program is
ending because of an exception having been thrown. Will contain the Exception
type object otherwise.
Support for $*EXCEPTION
was added in Rakudo compiler version 2023.02.
$*EXECUTABLE
Contains an IO::Path absolute path of the raku executable that is currently running.
$*EXECUTABLE-NAME
Contains the name of the Raku executable that is currently running. (e.g.
raku-p, raku-m). Favor $*EXECUTABLE
over this one, since it's not
guaranteed that the raku executable is in PATH
.
$*USAGE
This is an object of type Str containing the default usage message
generated from the signatures of MAIN
subs available from inside
sub MAIN
and sub USAGE
. The variable is read-only.
sub MAIN($a, :$b, UInt :$ehehe) {
say $*USAGE; # OUTPUT: «Usage: my-script.raku [-a=<Int>] [-b=<Str>] [--<opts>=...]»
}
It is accessible only inside of MAIN sub.
$*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 %*ENHOME if set.
On Windows, uses %*ENHOMEDRIVE ~ %*ENHOMEPATH. 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 raku 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.
Runtime variables
These variables affect the behavior of certain functions, and in some cases its value can be changed during runtime.
$*DEFAULT-READ-ELEMS
Affects the number of bytes read by default by IO::Handle.read. Its default value is 65536.
$*COLLATION
This is a Collation object that can be used to configure Unicode collation levels.
$*RAT-OVERFLOW
Available as of release 2022.02 of the Rakudo compiler.
Using Rats by itself is fine, until you run out of precision. The $*RAT-OVERFLOW dynamic variable specifies the behavior that should be executed when a Rat overflows its precision. By default, it is set to Num, meaning it will revert to using (lossy) floating point.
You can also set it to FatRat, which will cause automatic upgrade to FatRat as soon as a Rat runs out of precision. You can also specify Failure (to have it fail), Exception (to have it throw an exception) or CX::Warn (to have it warn on downgrading to Num).
To activate this globally to upgrade to FatRat:
INIT $*RAT-OVERFLOW = FatRat;
To activate this only for a lexical scope:
my $*RAT-OVERFLOW = FatRat;
How does that work? The $*RAT-OVERFLOW variable is supposed to contain
a class or instance on which the UPGRADE-RAT
method will be called
when a Rat overflows. So you can introduce your own behavior by
creating a class with an UPGRADE-RAT
method in it.
Such a method should accept two integer values: one for the numerator
and one for the denominator. For example (not entirely serious) would
be to convert the resulting value to Inf
if really great, or 0
if really small:
class ZeroOrInf {
method UPGRADE-RAT(Int $nu, Int $de) {
$nu > $de ?? Inf !! 0
}
}
$*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
.
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.
Subs and methods from the built-ins library try to have single-word names when a good one could be found. In cases where there are two or more words making up a name, they are separated by a "-".
Compounds are treated as a single word, thus
substr
,subbuf
, anddeepmap
(just like we write "starfish", not "star fish" in English).Subs and methods that are automatically called for you at special times are written in uppercase. This includes the
MAIN
sub, theAT-POS
and related methods for implementing container types, along withBUILD
andDESTROY
.Type names are camel case, except for native types, which are lowercase. For the exception, you can remember it by: they are stored in a more compact way, so they names look smaller too.
Built-in dynamic variables and compile-time variables are always uppercase, such like
$*OUT
,$?FILE
.Methods from the MOP and other internals use "_" to separate multiple words, such like
add_method
.