This file was automatically generated from http://svn.pugscode.org/pugs/docs/tutorial/ch04_basic_syntax.pod on Sat Aug 1 14:01:20 2009 GMT, revision 27701.
=head0 Basic Syntax
Perl 6 is a work in progress, so the syntax is still changing, but not as fast as it used to be. The next 4 chapters are likely to be slightly outdated by the time you read them. Even so, they provide a good baseline. If you start here, you'll only have to catch up on a few months of changes (starting with the design documents after Apocalypse 12), instead of several years worth.
Pretend for a moment that you don't know anything about Perl. You heard the language has some neat features, so you thought you might check it out. You go to the store and pick up a copy of Programming Perl because you think this Larry Wall guy might know something about it. It's the latest version, put out for the 6.0.1 release of Perl. It's not a delta document describing the changes, it's an introduction, and you dive in with the curiosity of a kid who got a telescope for his birthday. These chapters are a glimpse down that telescope.
There's plenty of time later to analyze each feature and decide which you like and which you don't. For now, take a step back and get a feel for the system as a whole, for what it'll be like to work in it.
The most basic building blocks of a programming language are its
nouns, the chunks of data that get sucked in, pushed around, altered in
various ways, and spat out to some new location. The chunks of data are
values: strings, numbers, etc., or composites of the simpler values.
Variables are just named containers for those values. The three kinds
of variables in Perl 6 are scalars, arrays, and hashes. Each has an
identifying symbol (or sigil) as part of the name of the variable:
$ for scalars, @ for arrays, and % for hashes. The sigils
provide a valuable visual distinction by making it immediately obvious
what kinds of behavior a particular variable is likely to have. But,
fundamentally, there's little difference between the three. Each
variable is essentially a container for a value, whether that value is
single or collective. (This statement is an oversimplification, as
you'll soon see.)
Scalars are all-purpose containers. They can hold strings, integers, floating-point numbers, and all kinds of objects and built-in types. For example:
$string = "Zaphod's just this guy, you know?";
$int = 42;
$float = 3.14159;
$array = [ "Zaphod", "Ford", "Trillian" ];
$hash = { "Zaphod" => 362, "Ford" => 1574, "Trillian" => 28 };
$sub = sub { print $string };
$object = Android.new;
A filehandle is just an ordinary object in an ordinary scalar variable. For example:
$filehandle = open $filename;
Assignment to a scalar parses a single item after the = and stops at
the next unprotected comma.
$foo = 1, $bar = 2; # two scalar assignments
Array variables hold simple ordered collections of scalar values.
Individual values are retrieved from the array by numeric index. The
0 index holds the first value. The @ sigil is part of the name
of the variable and stays the same no matter how the variable is used:
@crew = "Zaphod", "Ford", "Trillian"; $second_member = @crew[1]; # Ford
Unlike scalar assignment, assignment to an array parses everything
after the = as a list, so parentheses are not needed around
the list.
To get the the number of elements in an array use the .elems method.
The .last method returns the index of the last element in an
array--that is, the highest index in an array.
$count_elements = @crew.elems; $last_index = @crew.last;
A Pair holds a single key and a single value. It doesn't have a unique
sigil because pairs rarely appear alone, so they're stored in scalars,
arrays, or hashes. The pair constructor => forms a pair, with the
key on the left and value on the right.
$pair = 'key' => 'value';
The alternate option syntax also constructs a pair, with a colon before the key and parentheses around the value:
$pair = :key('value');
A literal string value occurs often enough that there is a special form using autoquote brackets:
$pair = :key<value>;
The option syntax is useful for subroutine calls, as you'll see in "Named Argument Passing" in Chapter 5.
Hashes are unordered collections of scalar values, stored and retrieved by a key index. The simplest way to build a hash is by passing it a list of anonymous pair objects. For example:
%hash = "Zaphod" => 362, "Ford" => 1574, "Trillian" => 28;
As with arrays, assignment to a hash parses everything after the =
as a list, so parentheses are not needed around the list .
The key for each value may be a string or an object, though there are
some restrictions on object keys. Hashes that use object keys must be
declared as such, for the sake of efficiency. Any object used as a
hash key must have a .WHICH method that returns a unique value for
each unique object to avoid hashing collisions. This method is
provided by default in the universal base class, so you only have to
worry about uniqueness when you define your own .WHICH methods.
$age = %hash{"Zaphod"}; # string
$age = %hash{$name}; # string variable
$age = %hash{$person}; # object
Quotes are required around literal string keys, so you can call a subroutine to retrieve a key and the subroutine name won't act as a string key.
$age = %hash{get_key}; # subroutine call
If you really don't want to type the quotes, substitute auto-quoting brackets for the ordinary curly braces around the key:
$age = %hash<Zaphod>;
In list context, a hash returns a list of key/value pair objects. The
.kv method returns a flattened list of keys and values from a hash.
So the assignment of a hash directly to an array:
@pairs = %hash;
creates an array of pairs that looks like:
(pair1, pair2, pair3, etc...)
While the assignment of the flattened key/value list:
@flat = %hash.kv;
creates an array of alternating keys and values that looks like:
(key1, value1, key2, value2, etc...)
The .keys method returns a list of all the keys in a
hash. The .values method returns a list of all the
values:
@keys = %hash.keys; @values = %hash.values;
Because nearly all entities in Perl 6 are considered first-class objects, references are largely transparent. Instead of treating references as a real data type, we speak directly of various kinds of objects with the assumption that all objects are really represented by references internally. There is a distinction between ordinary objects and containers, but this is minimized as much as possible in actual use, with automatic referencing and dereferencing where appropriate. Creating a reference to an array or hash requires no special syntax, since the array or hash already serves as its own reference. You simply assign the array or hash to a scalar variable:
$array = @array; $hash = %hash;
Objects in scalar containers are implicitly dereferenced, so array indexes and hash keys access individual elements directly from hash and array objects, just like they do with explicit hashes and arrays:
$array = @array;
$array[1] # same as original @array[1]
$hash = %hash;
$hash{"Zaphod"} # same as original %hash{"Zaphod"}
Likewise scalar containers pass method calls on to the contained object. The referent--the underlying data type or object--determines which methods can be used with a particular reference, what those methods do, and whether the reference can support indexed access.
$array.elems $hash.keys
Subroutines may be named as first-class objects by prefixing the name
with the & sigil. A subroutine object can be executed simply by
passing the object an argument list. The list can be empty, but the
parentheses are required when dereferencing a variable containing a subroutine.
$sub = &mysub; $sub($arg);
When it is not clear whether an object should be treated as a single item or as a collection of items, you may use the various sigils to explicitly coerce the value:
@array = @($array); # or @array = @$array;
Ordinarily, a scalar container is always treated as a single item within
a large list, so a scalar assigned to an array would produce an array
with a single scalar element, even if that scalar element happens
to contain an array. To copy the individual elements of $array
to @array you need to put it into @ context to interpolate its
elements into the newly constructed list.
One of the main differences between variables with the $, @, or
% sigils is that they each impose a different context. The $
sigil imposes an item context, @ imposes list context, and %
imposes hashlist context.
Item context expects a single value. Any array or list evaluated in item context returns a single object representing the composite. This means that assigning an array:
@array = "Zaphod", "Ford", "Trillian"; $array = @array;
a list:
$array = "Zaphod", "Ford", "Trillian";
or an explicit anonymous array object:
$array = [ "Zaphod", "Ford", "Trillian" ];
to a scalar variable all produce exactly the same structure: a single array container with three elements.
The comma is the list constructor, even in item context. Parentheses only group. When a single element in parentheses is assigned in item context, it stays a simple scalar value:
$value = (20);
If you want to create an array of one element in item context,
use square brackets ([...]) to explicitly construct an anonymous
array object:
$array = [20];
A hash-like list assigned to a scalar variable creates an ordered array of pairs, following the rule that a list in item context is promoted to an array.
$pair_list = ( "Zaphod" => 362, "Ford" => 1574, "Trillian" => 28 );
You have to use curly braces ({...}) to explicitly construct a hash
object in item context:
$hash = { "Zaphod" => 362, "Ford" => 1574, "Trillian" => 28 };
Variables with the @ sigil impose flattening list context. This
means that if you assign one array to another array, the original
array is flattened--treated as if it were a simple list of
values--and every element from the original array is copied to the new
array. The result is that the two array variables contain
different data structures, each with identical values:
@copy = @original;
Lists also impose flattening list context. Assigning an array to a list flattens the array and assigns each array element to the corresponding element in the list. If the array has more elements than the list, the remaining elements are simply discarded:
($first, $second, $third) = @array;
A single value in list context is a one-element list, so it produces a one-element array on assignment:
@array = (20); @array = 20; # same
The anonymous array composer [...] imposes flattening list
context internally. It doesn't flatten when used in list context,
though, because flattening list context doesn't flatten objects.
In item context, a simple list and an array construct produce the
same result. But in list context, a simple list is treated as a
flattened list, while an array construct is treated as a list of
one element, an array object:
@array = "Zaphod", "Ford", "Trillian"; @array = [ "Zaphod", "Ford", "Trillian" ];
The first example above produces an array with three elements. The second produces an array with one element and that element is a an array object with three elements. This is useful for building up complex data structures.
@array = "Marvin", [ "Zaphod", "Ford", "Trillian" ], "Zarniwoop";
Similarly, in flattening list context a list of array variables are flattened into a single list, while a list of scalar variables are treated as a simple list, even if the scalar variables happen to contain array objects.
@array = @array1, @array2, @array3; # single flattened list @array = $array1, $array1, $array3; # 3-element list
So, the first example above produces an array containing all the elements of the three arrays, while the second produces an array of three arrays.
A lone pair of parentheses is a special token representing an empty list. It produces an array structure with no elements in both scalar and list context:
$array = (); # 0-element array @array = (); # 0-element array
Variables with % sigils impose hashlist context, which expects a
list of pair objects. This is typically simply a list of anonymous
pairs built with the pair constructor (=>):
%hash = "Zaphod" => 362, "Ford" => 1574, "Trillian" => 28;
A list of simple values in hashlist context is treated as a list of pairs. You can substitute two values for a pair object only in hashlist context:
%hash = "Zaphod", 362, "Ford", 1574, "Trillian", 28;
Curly braces {...} are the anonymous hash reference constructor,
but they don't impose hashlist context. This is because an ordinary
structure wrapped in curly braces and assigned to a scalar variable
defines an anonymous subroutine:
# a sub reference that returns a list
$sub = { "Zaphod", 362, "Ford", 1574, "Trillian", 28 };
The hash constructor isn't really {...}, but
{... => ...}, so you can't use commas in place of pair
constructors when assigning a hash reference to a scalar variable. It's
the => that marks the structure as a hash. When there is
ambiguity, you can force the right context by specifying
sub before the block or by use of the hash sigil as a coercion function:
$sub = sub { print "Lost luggage.\n"; }
$hash = %( "Zaphod", 362, "Ford", 1574, "Trillian", 28 );
Properties allow additional information to be attached to variables and values. As Damian likes to explain it, they're much like sticky notes. You can take a note, scribble some important information on it, and slap it onto the refrigerator, your monitor, or the dashboard of your car. When you're done, you peel it off and throw it away.
Some properties are attached at compile time. These are known as
traits. Traits are still properties, just a particular kind of
property. Traits are fixed to the variable when it is declared and
cannot be changed later. Compile-time traits are set with the is
keyword:
my $pi is readonly = 3.14159;
The readonly trait specifies that the value of the variable can't
be changed.
Other properties are attached at run time. They only modify values, not
variables. They can be added and removed at any time during the
execution of the code. Runtime properties are set with the but
keyword:
$true_value = 0 but True;
The True property specifies that the value will evaluate as true in
a boolean context, no matter what the actual value is. This particular
property means the Perl 6 run call can be checked with a simple
conditional. It still returns the same numeric values as its Perl 5
equivalent system did (0 on success and a numeric error code on failure),
but it flags the value with a property as true when the call succeeds and
false when it fails.
Properties and traits can also store a value. Both constant and
true define their own values when they're set. Some properties take
arguments for their value:
my @array is dim(2,5,42); # specify dimensions
Properties have proven to be an incredibly useful and extensible syntax. You'll see them again and again throughout this chapter. They aren't restricted to variables and values, but appear on subroutines, methods, classes, grammars, rules, and in parameter lists.
Perl 6 allows you to specify the types of variables and values much more precisely than Perl 5, but keep in mind that explicit types are completely optional. If you choose to use them, you'll gain some benefits in optimization and interfacing between languages. The biggest benefit, however, is that types enable fine-grained control of multiple dispatch when you want it, or course-grained contol when you don't care.
Perl 6 makes a distinction between the type of a value and the type of
a variable. The value type specifies what kind of values a variable
can hold. Putting an Int value type on a scalar says that the
scalar can only hold an integer value:
my Int $scalar;
Putting an Int value type on an array says that the array holds
integer values:
my Int @array;
And putting an Int value type on a hash says that the hash holds
integer values (but says nothing about the type of the keys):
my Int %hash;
The type of the keys may be declared in a pseudo-subscript. Since the default key type is strings, the preceding declaration is actually short for:
my Int %hash{Str};
To declare a hash that uses any object type for a key and always returns, say, an icon object, say:
my Icon %hash{Any}
The variable type specifies what kind of container the variable is.
This is basically like a tie in Perl 5. Variable types are defined as
traits of the variable, with the is keyword. The sigils provide an
implicit variable type, so a variable with no type is just:
my $scalar is Scalar; my @array is Array; my %hash is Hash;
But you can also define your own classes to implement a variable type:
my $scalar is FileHandle; my @array is Matrix; my %hash is BerkeleyDB;
Hierarchical data structures can have a complex value type. A hash
that holds integer arrays has the value type Array of Int:
my Array of Int %hash;
The type syntax is flexible, so you could also write that as:
my %hash is Hash of Array of Int; # or my %hash of Array of Int;
and get the same data structure. This improves readability, especially in multilevel data structures:
my Array of Hash of Array of Int %hash; my %hash is Hash of Array of Hash of Array of Int;
Operators provide a simple syntax for manipulating values. A few characters take the place of a function call, or even several function calls. On the positive side this makes them incredibly convenient. On the negative side they're also sometimes difficult to learn because they pack so much meaning into a small space. Many of the Perl 6 operators will be familiar, especially to Perl 5 programmers. The new operators either add new features to the language, or move Perl's operator set toward a more consistent system.
The = operator is for ordinary assignment. It creates a copy of
the values on the right-hand side and assigns them to the variables or
data structures on the left-hand side:
$copy = $original; @copies = @originals;
$copy and $original both have the same value, and @copies has
a copy of every element in @originals.
The := operator is for binding assignment. Instead of copying the
value from one variable or structure to the other, it creates an
alias. An alias is an additional entry in the symbol table with a
different name for the one container:
$a := $b; # $a and $b are aliases @c := @d; # @c and @d are aliases
In this example, any change to $a also changes $b and vice
versa, because they're just two separate names for the same container.
Binding assignment requires the same number of elements on both sides,
so both of these would be an error:
# ($a, $b) := ($c); # error # ($a, $b) := ($c, $d, $e); # error
The ::= operator is a variant of the binding operator that binds at
compile time.
The arithmetic operators are
addition (+),
subtraction (-),
multiplication (*),
division (/),
modulus (%), and
exponentiation (**). Each has a
corresponding assignment operator
(+=, -=, *=, /=, %=, **=) that combines the arithmetic
operation with assignment:
$a = 3 + 5; $a += 5; # $a = $a + 5
The unary arithmetic operators are the
prefix and postfix autoincrement (++) and autodecrement (--)
operators. The prefix operators modify their argument before it's
evaluated, and the postfix operators modify it afterward:
$a++; $a--; ++$a; --$a;
The ~ operator concatenates strings. The corresponding ~=
operator concatenates the right-hand side of the assignment to the end
of the string:
$line = "The quick brown " ~ $fox ~ jumps_over() ~ " the lazy " ~ $dog; $line ~= "Belgium"; # appends to the string
The x operator replicates strings. It always returns a string no
matter whether the left side of the operation is a single element or a
list. The following example assigns the string
"LintillaLintillaLintilla":
$triplet = "Lintilla" x 3;
The corresponding x= operator replicates the original string and
assigns it back to the original variable:
$twin = "Lintilla"; $twin x= 2; # "LintillaLintilla"
The xx operator replicates lists. It returns a list no matter
whether it operates on a list of elements or a single element. The
following example assigns a list of three elements to @array, each
with a copy of the value "Lintilla":
@array = "Lintilla" xx 3; # ("Lintilla", "Lintilla", "Lintilla")
The corresponding xx= operator creates a list that contains the
specified number of copies of every element in the original array and
assigns it back to the array variable:
@array = 4, 2; @array xx= 2; # now (4, 2, 4, 2) @array = @array, @array; # equivalent
The range operator .. returns a list of values from a starting
point to an ending point:
@range = 3..7; # 3,4,5,6,7
Ranges evaluate lazily, so a range containing an infinite value won't try to calculate all the values before assigning the list. Instead, it returns a list generator that only generates elements as they're requested.
@range = 3..Inf; # lazy
The * token may be used instead of Inf, which really only makes sense
for numeric types:
@range = 3..*; @range = 'a'..*;
Each comparison operator has two forms, one for numeric comparisons
and one for string comparisons. The comparison operators are
greater-than (>, gt), less-than (<, lt),
greater-than-or-equal (>=, ge), less-than-or-equal
(<=, le), equal (==, eq), and not-equal (!=,
ne). The identity operator (=:=) tests whether the two arguments
are aliases to the same object. Each returns a true value if the
relation is true and a false value otherwise. The generic comparison
operators (<=>, leg) return 0 if the two arguments are
equal, 1 if the first is greater, and -1 if the second is greater.
if $age > 12 {...}
Comparison operators can also be chained. Chained comparisons evaluate each value in the chain only once.
if 24 < $age < 42 {...} # 24 < $age and $age < 42
The binary logical operators test two values and return one value or the other depending on certain truth conditions. They're also known as the short-circuit operators because the right-hand side will never be evaluated if the overall truth value can be determined from the left-hand side. This makes them useful for conditionally assigning values or executing code.
The AND relation has the && operator and the low-precedence and
operator. If the left-hand side evaluates as false, its value is
returned. If the left-hand value is true, the right-hand side is
evaluated and its value is returned:
$splat = $whale && $petunia; $splat = ($whale and $petunia);
The OR relation has the || operator and the low-precedence or
operator. The left-hand value is returned if it is true, otherwise the
right-hand value is evaluated and returned:
$splat = $whale || $petunia; $splat = ($whale or $petunia);
A variant of the OR relation tests for definedness instead of truth.
It uses the // operator and the low-precedence orelse operator. The
left-hand value is returned if it is defined, otherwise the right-hand
side is evaluated and its value returned:
$splat = $whale // $petunia; $splat = ($whale orelse $petunia);
The XOR relation has the ^^ operator and the low-precedence xor
operator. It returns the value of the true operand if any one operand
is true, and a false value if both are true or neither is true. xor
isn't short-circuiting like the others, because it always has to
evaluate both arguments to know if the relation is true:
$splat = $whale ^^ $petunia; $splat = ($whale xor $petunia);
Perl 6 also has boolean variants of the logical operators:
?& (AND),
?| (OR), and
?^ (XOR). These
always return a true or false value.
$whale = 42; $petunia = 24; $value = $whale || $petunia # $value is 42 $truth = $whale ?| $petunia # $truth is 1
The context of an expression specifies the type of value it is expected to produce. An array expects to be assigned multiple values at the same time, so assignment to an array happens in list context. A scalar variable expects to be assigned a single value, so assignment to a scalar happens in scalar context. Perl expressions often adapt to their context, producing values that fit with what's expected.
Contexts have proven to be valuable tools in Perl 5, so Perl 6 has a few more added. Void context still exists. Scalar context is subdivided into boolean, integer, numeric, string, and object contexts. List context is subdivided into flattening list context, non-flattening list context, lazy list context, and hashlist context.
Expects no value.
Expects a single value. A composite value returns a reference to itself in item context.
Expects a true or false value. This includes the traditional
definitions of truth--where 0, undef, and the empty string are
false and all other values are true--and values flagged with the
properties true or false.
Expects an integer value. Strings are treated as numeric and floating-point numbers are truncated.
Expects a number, whether it's an integer or floating-point, and whether it's decimal, binary, octal, hex, or some other base.
Expects a string value. It interprets any information passed to it as a string of characters.
Expects an object, or more specifically, a reference to an object. It may also expect an object of a particular type.
Expects a collection of values. Any single value in list context is treated as a one-element list.
Expects a list. Flattens out arrays and hashes into their component parts.
Expects a list. Treats arrays, hashes, and other composite values as discrete entities.
Expects a list, just like non-flattening list context, but doesn't require all the elements at once.
Expects a list of pairs. A simple list in hashlist context pairs up alternating elements.
The unary context operators force a particular context when it wouldn't otherwise be imposed. Generally the default context is the right one, but at times you might want a little more control.
The unary ? operator and its low-precedence equivalent true force
boolean context. Assignment of a scalar to a scalar only imposes generic
item context, so the value of $number is simply copied. With the
? operator, you can force boolean context and assign the truth value
of the variable instead of the numeric value:
$value = $number; $truth = ?$number;
The unary ! operator and the low-precedence not also force
boolean context, but they negate the value at the same time. They're
often used in a boolean context, where only the negating effect is
visible.
$untruth = !$number;
The unary + operator forces numeric context, and - forces
numeric context and negates the number at the same time:
$number = +$string; $negnum = -$string;
The unary ~ operator forces string context:
$string = ~$number;
You can also create a scalar, list, or hashlist context with $(...),
@(...), and %(...).
Perl 6 has two sets of bitwise operators, one for integers and one for
strings. The integer bitwise operators
combine the AND, OR, and XOR relation symbols with the general numeric
symbol + (the unary numeric context operator). These are the binary
+&, +|, and +^ and the unary +^ for bitwise negation (ones
complement). The default integer type in Perl 6 is a signed int, so the
results are equivalent to working with the use integer pragma turned
on in Perl 5.
$number = 42 +& 18; # $number is 2 $number = 42 +| 18; # $number is 58 $number = 42 +^ 18; # $number is 56 $number = +^ 42; # $number is -43
The numeric bitwise shift operators shift the value of the left
operand by the number of bits in the right operand, either to the left
(<<) or to the right (>>).
$number = 4 << 1; # $number is 8 $number = 4 >> 1; # $number is 2
The string bitwise operators combine the AND, OR, and XOR relation
symbols with the general string symbol ~ (the same symbol as string
concatenation and the unary string context operator). These are
~&, ~|, and ~^.
$string = 'jj' ~& 'gg'; # $string is 'bb' $string = 'aa' ~| 'bb'; # $string is 'cc' $string = "GG" ~^ "**"; # $string is 'mm'
Each of the binary bitwise operators has an assignment counterpart
+&=, +|=, +^=, <<=, >>=, ~&=,
~|=, and ~^=.
The ternary ??!! operator evaluates either its second or third
operand, depending on whether the first operand evaluates as true or
false. It's basically an if-then-else statement acting as an
expression:
$form = $heads == 2 ?? "Zaphod" !! "ape-descended lifeform";
The hyper operators are designed to work with lists. They're simply
modified versions of the standard scalar operators. Every operator has
a hyper version, even user-defined operators. They have the same
basic forms as their scalar counterparts, but are marked with the
bracketing characters » and «, or their plain-text equivalents >>
and <<. For example, the hyper addition operator is
>>+<<.
Hyper operators impose list context on their operands and distribute their operations across all the operands' elements. Hyper addition takes each element from the first list and adds it to the corresponding element in the second list:
@sums = @first >>+<< @second;
The resulting array contains the sums of each pair of elements, as if each pair were added with the scalar operator:
@sums = @first[0] + @second[0], @first[1] + @second[1], etc...;
If one side of a hyper operation is a simple scalar, you can point the small end of the angles at it to indicate that you know that side is "undersized". Then that value is distributed across the list as if it were a list of identical elements:
@sums = @numbers >>+>> 5; @sums = @numbers[0] + 5, @numbers[1] + 5, etc...;
Unary operators may also take a one-sided hyper on the side of their single operand:
@less = @numbers>>--; @nums = +<<@strings;
The Latin-1 characters « and » may also be used.
At the simplest level, junction operators are no more than AND, OR,
XOR, and NOT for values instead of expressions. The binary junction
operators are & (AND), | (OR), and ^ (XOR). There isn't an
operator for junctive NOT, but there is a function, as you'll see
shortly. So while || is a logical operation on two expressions:
if $value == 1 || $value == 2 { ... }
| is the same logical relation between two values:
if $value == 1 | 2 { ... }
In fact, those two examples have exactly the same result: they return
true when $value is 1 or 2 and false otherwise. In the common
case that's all you'll ever need to know.
But junctions are a good deal more powerful than that, once you learn their secrets. A junctive operation doesn't return an ordinary single value, it returns a composite value containing all of its operands. This return value is a junction, and it can be used anywhere a junction operation is used:
$junc = 1 | 2;
if $value == $junc { ... }
Here, the variable $junc is used in place of 1 | 2, and has
exactly the same effect as the earlier example.
A junction is basically just an unordered set with a logical relation defined between its elements. Any operation on the junction is an operation on the entire set. Table 4-1 shows the way the four different types of junctions interact with other operators.
The simplest possible example is the result of evaluating a junction
in boolean context. The operation on the set is just "is it true?"
This operation on an all junction is true if all the values are
true:
true( $a & $b ) true( all($a,$b) )
So, if both $a and $b are true, the result is true.
On an any junction, it's true if any one value is true:
true( $a | $b ) true( any($a,$b) )
So, if $a or $b is true or if both are true, the result is true.
On a one junction, it's true only if exactly one value is true:
true( $a ^ $b ) true( one($a,$b) )
So, if either $a or $b is true, the result is true. But, if
$a and $b are both true or neither is true, the result is false.
On a none junction, it's true only when none of the values are
true--that is, when all the values are false.
true( none($a,$b) )
So, if $a and $b are both false, the result is true.
Ordinary arithmetic operators interact with junctions much like vector operators on arrays. A junction distributes the operation across all of its elements:
$junc = any(1, 2); $junc += 5; # $junc is now any(6, 7)
Junctions can be combined to produce compact and powerful logical comparisons. If you want to test that two sets have no intersection, you might do something like:
if all($a, $b) == none($c, $d) { ... }
which tests that all of the elements of the first set are equal to none of the elements of the second set. Translated to ordinary logical operators that's:
if $a != $c && $a != $d && $b != $c && $b != $d { ... }
If you want to get back a flat list of values from a junction, use the
.values method:
$junc = all(1, 2, 3); # create a junction $sums = $junc + 3; # add 3 @set = $sums.values(); # (4, 5, 6)
The .dump method returns a string that shows the structure of a
junction:
$string = $sums.dump(); # "all(4,5,6)"
The .pick method selects one value from an any junction or a
one junction that has exactly one value, and returns it as an
ordinary scalar:
$junc = any(1, 2, 3); $single = $junc.pick(); # may be 1, 2, or 3
On an all junction, a none junction, or a one junction with
more than one value, .pick returns undef. (With some levels of
error strictness, it may raise an exception.)
The binary ~~ operator makes a smart match between its two terms.
It returns a true value if the match is successful and a false value
if the match fails. The negated smart match operator !~ does the exact
opposite: it returns true if the match fails and false if it is
successful. The kind of match a smart match does is determined by the
kind of arguments it matches. If the types of the two arguments can't
be determined at compile time, the kind of match is determined at
run time. Smart match is usually a symmetric operator, so you can
reverse A ~~ B to B ~~ A and it will have the same truth value.
Any scalar value (or any code that results in a scalar value) matched
against a string tests for string equality. The following match is
true if $string has the value "Ford":
$string ~~ "Ford"
Any scalar value matched against a numeric value tests for numeric
equality. The following is true if $number has the numeric value
42, or the string value "42":
$number ~~ 42
An expression that results in the value 42 is also true:
( (5 * 8) + 2 ) ~~ 42
Any scalar value matched against an undefined value checks for
definedness. The following matches are true if $value is an
undefined value and false if $value is any defined value:
$value ~~ undef $value ~~ $undefined_value
Any scalar value matched against a rule (regex) does a pattern match.
The following match is true if the sequence "towel" can be found
anywhere within $string:
$string ~~ /towel/
Any scalar value matched against a substitution attempts that
substitution on the value. This means the value has to be modifiable.
The following match is true if the substitution succeeds on $string
and false if it fails:
$string ~~ s/weapon/towel/
Any scalar value matched against a boolean value simply takes the truth value of the boolean. The following match will always be true, because the boolean on the right is always true:
$value ~~ (1 == 1)
The boolean value on the right must be an actual boolean: the result
of a boolean comparison or operation, the return value of a not or
true function, or a value forced into boolean context by ! or
?. The boolean value also must be on the right; a boolean on the
left is treated as an ordinary scalar value.
Any scalar value matched against a list compares each element in
sequence. The match is true if at least one element of the list would
match in a simple expression-to-expression match. The following match
is true if $value is the same as any of the three strings on the
right:
$value ~~ ( "Zaphod", "Ford", "Trillian" )
This match is short-circuiting: it stops after the first successful
match. It has the same truth value as a series of or-ed matches:
($value ~~ "Zaphod") or ($value ~~ "Ford") or ($value ~~ "Trillian")
A smart-matched list can contain any combination of elements: scalar values, rules, boolean expressions, arrays, hashes, etc.:
$value ~~ ( "Zaphod", 5, /petunias/ )
A match of a list against another list sequentially compares each element in the first list to the corresponding element in the second list. The match is true if every element of the first list matches the corresponding element in the second list. The following match is true, because the two lists are identical:
( "Zaphod", "Ford", "Trillian" ) ~~ ( "Zaphod", "Ford", "Trillian" )
The two lists don't have to be identical, as long as they're the same length and their corresponding elements match:
( $zaphod, $ford, $trillian ) ~~ ( "Zaphod", /Ford/, /^T/ )
The list-to-list match is also short-circuiting. It stops after the
first failed match. This has the same truth value as a series of
single-element smart matches linked by and:
($zaphod ~~ "Zaphod") and ($ford ~~ /Ford/) and ($trillian ~~ /^T/)
A nonnumeric expression matched against an array sequentially searches
for that value in the array. The match is true if the value is found.
If @array contains the values "Zaphod", "Ford", and "Trillian", the
following match is true when $value matches any of those three
strings:
$value ~~ @array
An integer value matched against an array tests the truth of the value
at that numeric index. The following match is true if the element
@array[2] exists and has a true value:
2 ~~ @array
An integer value matched against an array reference also does an index lookup:
2 ~~ [ "Zaphod", "Ford", "Trillian" ]
This match is true, because the third element of the array reference is a true value.
An array matches just like a list of scalar values if it's flattened
with the * operator (See "Referencing (or Not)"
later in this chapter). So, the following example searches the array
for an element with the value 2, instead of doing an index lookup:
2 ~~ *@array
An array matched against a rule does a pattern match against every
element of the array. The match is true if any element matches the
rule. If "Trillian", "Milliways", or "million" is an element of
@array, the following match is true, no matter what the other
elements are:
@array ~~ /illi/
A match of an array against an array sequentially compares each element in the first array to the corresponding element in the second array:
@humans ~~ @vogons
This match is true if the two arrays are the same length and
@humans[0] matches @vogons[0], @humans[1] matches
@vogons[1], etc.
A hash matched against any scalar value tests the truth value of the hash entry with that key:
$key ~~ %hash
This match is true if the element %hash{$key} exists and has a true
value.
A hash matched against a rule does a pattern match on the hash keys:
%hash ~~ /blue/
This match is true if at least one key in %hash matches the string "blue".
A hash matched against a hash checks for intersection between the keys of the two hashes:
%vogons ~~ %humans
So, this match is true if at least one key from %vogons is also a
key of %humans. If you want to see that two hashes have exactly the
same keys, match their lists of keys:
%vogons.keys.sort ~~ %humans.keys.sort
A hash matched against an array checks a slice of a hash to see if its values are true. The match is true if any element of the array is a key in the hash and the hash value for that key is true:
%hash ~~ @array
If @array has one element 'blue' and %hash has a corresponding
key 'blue', the match is true if %hash{'blue'} has a true value,
but false if %hash{'blue'} has a false value.
An expression matched against an any junction is a recursive
disjunction. The match is true if at least one of the elements of the
list would match in a simple expression-to-expression match:
$value ~~ any("Zaphod", "Ford", "Trillian")
This example matches if $value is the same as any of the three
strings on the right. The effect of this comparison is the same as a
simple comparison to a list, except that it isn't guaranteed to
compare in any particular order.
A smart match of an all junction is only true when the expression
matches every value in the junction:
/illi/ ~~ all("Gillian", "million", "Trillian") # match succeeds
/illi/ ~~ all("Zaphod", "Ford", "Trillian") # match fails
A smart match of a one junction is only true when the expression
matches exactly one value in the junction:
/illi/ ~~ one("Zaphod", "Ford", "Trillian") # match succeeds
/illi/ ~~ one("Gillian", "million", "Trillian") # match fails
A smart match of a none junction is true when it doesn't match any
values in the junction:
/illi/ ~~ none("Zaphod", "Ford", "Marvin") # match succeeds
/illi/ ~~ none("Zaphod", "Ford", "Trillian") # match fails
An any junction matched against another any junction is a
recursive disjunction of every value in the first junction to every
value in the second junction. The match is true if at least one value
of the first junction matches at least one value in the second
junction:
any("Ford", "Trillian") ~~ any("Trillian", "Arthur")
This match is true, because "Trillian" is in both junctions.
An object matched against a class name is true if the object belongs
to that class or inherits from that class. It's essentially the same
as calling the .isa method on the object:
$ship ~~ Vogon::Constructor # $ship.isa(Vogon::Constructor)
Any expression matched against a subroutine tests the return value of the subroutine. If the subroutine takes no arguments it is treated as a simple boolean:
$value ~~ my_true
If the subroutine has a one argument signature and it is compatible with the variable type of the expression, the subroutine is called with the expression as its argument:
$value ~~ &value_test # value_test($value) @array ~~ &array_test # array_test(@array) %hash ~~ &hash_test # hash_test(%hash)
The return value of the subroutine determines the truth of the match.
A block matches as an anonymous subroutine. The return value of the
block determines the truth of the match. It's treated as a simple
boolean if it takes no arguments, or passed the value on the left side
if it uses $_ or placeholder variables inside the block (see
"Placeholder Variables" in Chapter 5).
$value ~~ { $_ + 5; } # $_ is $value
%hash ~~ { $_.keys; } # $_ is \%hash
@array ~~ { @^a.elems; } # @^a is @array
The unary \ operator returns a capture of its operand, which you
can think of as a kind of reference, except that a capture can
hold an entire set of arguments together. The
capture operator isn't needed very often, since item context
automatically generates arrays, hashes, and functions,
but it is still needed in other contexts that need to defer binding.
@array_of_captures = \@a, \@b, \@c;
Ordinarily, an array assigned a list of arrays would flatten the elements of all the arrays into a single array. With the referencing operator, @array_of_captures is assigned a list of three array captures.
The unary | operator (known as the insertion operator) flattens a capture
into a context where it would usually be taken as an item. On an
rvalue, | causes the array's elements to be treated as a simple argument
list:
@combo = \@array, \%hash; @a := @combo; # @a is @combo (@b, %c) := |@combo; # @b is @array, %c is %hash
Since the @combo array contains an array and a hash, an
ordinary binding assignment of @combo to @a treats @combo as
a single element and binds it to @a. With the insertion operator,
the @combo array is treated as a simple list, so each of its
elements are bound to a separate element on the left-hand side. @b
is bound to the original @array and %c is bound to the original
%hash.
On an lvalue, * tells the array to slurp all available arguments.
An ordinary binding of two arrays to two arrays simply binds the first
element on the right-hand side to the first element on the left-hand
side, and the second to the second. So, @a is bound to @c, and
@b is bound to @d:
(@a, @b) := @c, @d; # @a is @c, @b is @d
With the * operator, the first element on the left-hand side
flattens all the elements on the right-hand side into a list before
the binding assignment. So, @a contains all the elements from
@c and @d:
*@a := @c, @d; # @a contains @c and @d
One common use for * is in defining subroutine and method
signatures, as you will see in "Variadic Parameters"
in Chapter 5.
The Z operator takes two or more lists (arrays, hash keys, etc.)
and returns a single list with alternating elements from each of the
original lists. This allows loops and other iterative structures to
iterate through the elements of several lists at the same time:
@a = 1, 2, 3; @b = 4, 5, 6; @c = @a Z @b; # @c is 1, 4, 2, 5, 3, 6
The zip operator is described in "The for loop" later in this chapter.
The simplest flow of control is linear--one statement follows the next in a straight line to the end of the program. Since this is far too limiting for most development tasks, languages provide ways to alter the control flow.
Selection executes one set of actions out of many possible sets. The
selection control structures are if, unless, and
given/when.
The if statement checks a condition and executes its associated
block only if that condition is true. The condition can be any
expression that evaluates to a truth value. Parentheses around the
condition are optional:
if $blue {
print "True Blue.";
}
The if statement can also have an unlimited number of elsif
statements that check additional conditions when the preceding
conditions are false. The final else statement executes if all
preceding if and elsif conditions are false:
if $blue {
print "True Blue.";
} elsif $green {
print "Green, green, green they say...";
} else {
print "Colorless green ideas sleep furiously.";
}
The unless statement is the logical opposite of if. Its block
executes only when the tested condition is false:
unless $fire {
print "All's well.";
}
There is no elsunless statement, though else works with
unless.
The switch statement selects an action by comparing a given
expression (the switch) to a series of when statements (the
cases). When a case matches the switch, its block is executed:
given $bugblatter {
when Beast::Trall { close_eyes(); }
when 'ravenous' { toss('steak'); }
when .feeding { sneak_past(); }
when /grrr+/ { cover_ears(); }
when 2 { run_between(); }
when (3..10) { run_away(); }
}
If these comparisons are starting to look familiar, they should. The
set of possible relationships between a given and a when are
exactly the same as the left and right side of a smart match operator
(~~). The given aliases its argument to $_. $_ is always
the current topic (think "topic of conversation"), so the process of
aliasing a variable to $_ is known as topicalization. The
when is a defaulting construct that does an implicit smart match on
$_. The result is the same as if you typed:
given $bugblatter {
when $_ ~~ Beast::Trall { close_eyes(); }
when $_ ~~ 'ravenous' { toss('steak'); }
when $_ ~~ .feeding { sneak_past(); }
when $_ ~~ /grrr+/ { cover_ears(); }
when $_ ~~ 2 { run_between(); }
when $_ ~~ (3..10) { run_away(); }
}
but more convenient. In general, only one case is ever executed. Each
when statement has an implicit break at the end. It is possible
to fall through a case and continue comparing, but since falling
through is less common, it has to be explicitly specified with a
continue:
given $bugblatter {
when Beast::Trall { close_eyes(); continue; }
when 'ravenous' { toss('steak'); continue; }
when 'attacking' { hurl($spear, $bugblatter); continue; }
when 'retreating' { toss('towel'); }
}
The default case executes its block when all other cases fail:
given $bugblatter {
when Beast::Trall { close_eyes(); }
when 'ravenous' { toss('steak'); }
default { run('away'); }
}
Any code within a given will execute, but a successful when
skips all remaining code within the given, not just the when
statements:
given $bugblatter {
print "Slowly I turn...";
when Beast::Trall { close_eyes(); }
print "Step by step...";
when 'ravenous' { toss('steak'); }
print "Inch by inch...";
}
This means the default case isn't really necessary, because any
code after the final when just acts like a default. But an
explicit default case makes the intention of the code clearer in
the pure switch. The difference is also significant when trapping
exceptions. More on that in "Exceptions" later in
this chapter.>
A when statement can also appear outside a given. When they do,
they simply smart match against $_. when statements also have a
statement modifier form that doesn't have an implicit break:
print "Zaphod" when 'two heads'; # if $_ ~~ 'two heads'
Iteration constructs allow you to execute a set of statements multiple
times. Perl 6's loop constructs are while, until, loop, and
for.
A while loop iterates as long as a condition is true. The condition
may be complex, but the result is always a single boolean value
because while imposes boolean context on its condition:
while $improbability > 1 {
print "$improbability to 1 against and falling.";
$improbability = drive_status('power_down');
}
until is like while but continues looping as long as the
condition is false:
until $improbability <= 1 {
print "$improbability to 1 against and falling.";
$improbability = drive_status('power_down');
}
In its simplest form, the loop construct is infinite. It will
iterate until a statement within the loop explicitly terminates it:
loop {
print "One more of that Ol' Janx.";
last if enough();
}
loop is also the counter iterator. Like while, it tests a
condition before executing its block each time, but it has added
expression slots for initialization and execution between iterations
that make it ideal for counter loops:
loop ($counter = 1; $counter < 20; $counter++) {
print "Try to count electric sheep...";
}
The parentheses around the loop condition are optional.
The for loop is the list iterator, so it imposes lazy list context.
It takes a list or array, or any expression that produces a list, and
loops through the list's elements one at a time. On each iteration,
for aliases $_ to the current loop element. This means all the
constructs that default to $_, like print and when, can
default to the loop variable:
for @useful_things {
.print; # prints $_, the current loop variable
print " You're one hoopy frood." when 'towel';
}
The arrow operator, ->, makes a named alias to the current
element, in addition to the $_ alias.
All aliases are lexically scoped to the block.
for %people.keys -> $name {
print; # prints $_ (same as $name)
print ":", %people{$name}{'age'};
}
The arrow operator also makes it possible to iterate over multiple loop elements at the same time:
for %ages.kv -> $name, $age {
print "$name is now $age";
}
You can combine the arrow operator with the zip function or zip
operator to loop over several lists, taking some specified number of
elements from each list on every iteration, as in the following code.
# one from each array
for zip(@people,@places,@things) -> $person, $place, $thing {
print "Are you a $person, $place, or $thing?";
}
This example iterates over three arrays, taking one element from each array on each iteration and creating named aliases for the three elements.
# two from each array
for zip( @animals, @things, :by(2) )
-> $animal1, $animal2, $thing1, $thing2 {
print "The animals, they came, they came in by twosies, twosies: ";
print "$animal1 and $animal2";
print "Two things. And I call them, $thing1 and $thing2.";
}
This example iterates over two arrays, taking two elements from each array on each iteration and creating named aliases for them.
# two from the first array and one from the second
for zip(@colors=>2, @textures=>1) -> $color1, $color2, $texture {
$mix = blend($color1, $color2);
draw_circle($mix, $texture);
}
This example iterates over two arrays, taking two elements from the first array and one element from the second array on each iteration and creating named aliases for them.
If zip is called with arrays or lists of different lengths, it will
fill in undef values for the named aliases pulled from the shorter
lists.
The next, redo and last keywords allow you to interrupt the
control flow of a loop. next skips the remaining code in the loop
and starts the next iteration. redo skips the remaining code in the
loop and restarts the same iteration over again without incrementing
counters or re-evaluating loop conditions. last skips the remaining
code in the loop and terminates the loop.
for @useful_things -> $item {
next when 'towel';
redo when .try_again;
last when 'bomb';
print "Are you sure you need your $item?";
}
In Perl 6, every block is a closure, so you get consistent behavior throughout the language, whether the block is a control structure, an argument passed to a subroutine, an anonymous subroutine reference, or the definition of a named element such as a subroutine, method, or class. What is a closure? Closures are chunks of code that are tied to the lexical scope in which they're defined. When they're stored and later executed at some point far removed from their definition, they execute using the variables in their original scope, even if those variables are no longer accessible any other way. It's almost as if they package up their lexical scope to make it portable. This example creates a closure that prints a lexical variable. When the closure is executed (from some other lexical scope), it prints the variable from the scope where it was defined, not the scope where it's executed:
my $person = "Zaphod";
$closure = { print $person; }
...
my $person = "Trillian";
$closure(); # prints "Zaphod"
The fact that all blocks are closures has some implications. Every
block can take arguments. This is how for creates a $_ alias for
the iterator variable. Every block defines a lexical scope. Every
block has the potential to be stored and executed later. Whether a
block is stored or executed immediately depends on the structure that
uses it. The control structures we've discussed so far all execute
their blocks where they're defined. A bare block executes immediately
when it's alone, but is stored when it's in an assignment context or
passed as a parameter:
# executed immediately
{
print "Zaphod";
}
# stored
$closure = {
print "Trillian";
}
my and our are different ways of declaring variables. my
declares a variable in the current lexical scratchpad, while our
declares a lexical alias to a variable in the package symbol table.
my $lexical_var; our $package_var;
state declares a lexical variable similar to my, but instead of
reinitializing the value every time the block is executed it preserves
the previous value.
state $static_var;
temp and let are not declarations; they are run-time commands to
store the current value of a variable so it can be restored later.
temp variables always restore their previous value on exiting the
lexical scope of the temp, while let variables keep the
temporary value, unless the lexical scope of the let is exited
under an error condition (an undef or empty-list return value, or
an exception).
temp $throwaway; let $hypothetical;
temp and let don't change the value of the variable, they only
store it.
Every block may have a series of control flow handlers attached to it. These are called property blocks because they are themselves blocks (i.e., closures), attached as properties on the block that contains them. Property blocks are defined within the block they modify by an uppercase keyword followed by a block (they're also sometimes called NAMED blocks):
NEXT {
print "Coming around again."
}
Property blocks aren't executed in sequential order with the other
code in the enclosing block--they are stored at compile time and
executed at the appropriate point in the control flow. NEXT
executes between each iteration of a loop, LAST executes at the end
of the final iteration (or simply at the end of an ordinary block).
PRE executes before everything else--before all other properties
and code in an ordinary block and before the first iteration of a
loop. POST executes after everything else--after all code and
properties in an ordinary block and after the last iteration of a
loop. PRE and POST are intended for assertion checking and
cannot have any side effects. CATCH, KEEP, and UNDO are
related to exception handling. KEEP and UNDO are variants of
LAST and execute after CATCH. KEEP executes when the block
exits with no exceptions, or when all exceptions have been trapped and
handled; UNDO executes when the block exits with untrapped
exceptions. There can be only one CATCH in a block, but there's no
limit on the other types of property blocks.
This example prints out its loop variable in the body of the block:
for 1..4 {
NEXT { print " potato, "; }
LAST { print "." }
print;
}
Between each iteration, the NEXT block executes, printing "potato".
At the end of the final iteration, the LAST block prints a period.
So the final result is:
Property blocks are lexically scoped within their enclosing block, so they have access to lexical variables defined there.
for 5..7 -> $count {
my $potato = "$count potato, ";
NEXT {
print $potato;
}
LAST {
print $potato, "more.";
}
}
In this example, the lexical variable $potato is redefined on every
iteration and then printed from within the NEXT or LAST block. So
the final result is:
There are two types of exceptions: error exceptions and control flow
exceptions. All exceptions are stored in the error object $!.
All exception classes inherit from the Exception class.
Error exceptions are thrown by die or (under use fatal) fail.
Any block can be an error exception handler--all it needs is a CATCH
block. CATCH blocks always topicalize $!, so the simplest way to
test for a particular exception is to compare it to a class name using a
when statement.
CATCH {
when Err::Danger { warn "fly away home"; }
}
The $! object will also stringify to its text message if you match
it against a pattern.
CATCH {
when /:w I'm sorry Dave/ { warn "HAL is in the house."; }
}
If the CATCH block is exited by an explicit break statement, or
by an implicit break in a when or default case, it marks the
exception as clean. A when case with a continue statement leaves
the exception unhandled, since continue skips the implicit
break. If the exception isn't marked clean by the end of the
CATCH block, CATCH rethrows the exception so an outer block can
catch it.
Once an exception is thrown, execution skips straight to the CATCH
block and the remaining code in the block is skipped. If the block has
POST, KEEP, or UNDO property blocks, they will execute after
the CATCH block.
If you want to limit the effects of an error exception, you can wrap
the error throwing code in a try block. A try block without a
CATCH block provides a default CATCH that catches all exceptions
and, marks them as clean, and causes the try to return undef when
any exception was caught. A try block is also a handy bit of
self-documentation.
try {
may_throw_exception();
CATCH {
when Error::Moof { warn "Caught a Moof error."; }
}
}
Control flow exceptions handle alterations in the flow of control that
aren't errors. When you call next to skip the remaining code in the
loop and go on to the next iteration, you're actually throwing a
control exception. These exceptions are caught by the relevant control
structure: next and last exceptions are caught by loops, a
return exception is caught by a subroutine or method, etc.