Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

810 lines (511 sloc) 19.694 kB

Operators are very short names for often used routines. They have a special calling syntax, and can manipulate each other.

Consider the table tennis example from the previous chapter. Suppose you want to plot the number of sets that each player won in a tournament. This example makes a very simple text output by printing X characters to represent horizontal bars:

This program produces the output:

The line:

... already contains three different operators: =, =>, and ,.

The = operator is the assignment operator--it takes the values from the right-hand side, and stores them in the variable on the left-hand side, here @scores.

The => operator (the fat arrow) constructs Pair objects. A Pair stores a key and a value; the key is on the left-hand side of the => operator, the value on the right. This operator also has a special feature: it causes the parser to interpret any bare identifier on the left-hand side as a string. You could also write the example line as:

Finally, the , operator constructs a Parcel, which is a sequence of objects. In this case the objects are pairs.

All of the three operators above are infix operators, which means they stand between two terms. A term can be a literal like 8 or 'Dave', or a combination of other terms and operators.

The previous chapter already used other types of operators. It contained the statement %matches{$p1}++;. The postcircumfix operator {...} occurs after (post) a term, and consists of two symbols (an opening and a closing curly bracket) which enclose (circumfix) another term. After this postcircumfix operator is an ordinary postfix operator with name ++, which increments the value it qualifies. You may not use whitespace between a term and its postfix or postcircumfix operators.

Another operator type is the prefix operator, which occurs before a term. An example is the - operator, which negates the following numeric value, as in my $x = -4.

The - operator can also mean subtraction, so say 5 - 4 will print a 1. To distinguish the prefix operator - from the infix operator -, the Perl 6 parser always keeps track of whether it expects an infix operator or a term. A term can have zero or more prefix operators, so you can actually write say 4 + -5. After the + (an infix operator), the compiler expects a term, so as to interpret the - as a prefix operator to the term 5.

The next line containing new features is:

It begins harmlessly with a variable declaration my $label-area-width and an assignment. Next comes a simple numeric addition, 1 + .... The right side of the + operator is more complicated.

The infix max operator returns the greater of two values, so 2 max 3 returns 3. Square brackets around an infix operator cause Perl to apply the operator to a list element by element. [max] 1, 5, 3, 7 is the same as 1 max 5 max 3 max 7 and evaluates to 7. You might know this as as reduce from other programming languages.

Likewise, you can write [+] to get the sum of a list of values, [*] for the product, and [<=] to check if a list is ordered by ascending values.

Next comes the expression @scores».key».chars. Just like @variable.method calls a method on @variable, @array».method calls a method for each item in @array and returns the list of the return values.

» is a hyper operator. It is also a Unicode character. If your operating systemUbuntu 10.4: In System/Preferences/Keyboard/Layouts/Options/Compose Key position select one of the keys to be the "Compose" key. Then press Compose-key and the "greater than" key twice. or text editorEmacs users can type C-x 8 Enter 00bb Enter, vim users can type C-k >>. does not make it easy to write it you can also write it using two angle brackets (>>). @scores».key is a list of all the keys of the pair objects in @scores, and @scores».key».chars is a list of the length of all keys in @scores.

The expression [max] @scores».key».chars gives the largest of these values. It is the same as:

These circumfix square brackets are the reduction meta operator, which transforms the enclosed infix operator into an operator that expects a list (a listop), and carries out the operation between each two consecutive list items.

For plotting the names of the players and bar charts, the program needs to know how much space to allocate for the player names. Adding 1 to it leaves space for a single blank space between the name of the longest player and the left edge of the bars.

The program next determines the maximum score:

The drawing area has the width $screen-width - $label-area-width, so for each score, it should print:

... amount of X characters. This expression uses the infix operators - and / for numerical calculations.

Now all the necessary informations are in place, and the chart can print:

These lines loop over the items in @scores, binding them to the special variable $_ one at a time. For each item, the program uses the printf built-in function to print both the name of the player and a bar. This function is similar to printf in C and Perl 5. It takes a format string, which specifies how to print the following parameters. If $label-area-width is 8, the format string is "%- 8s%s\n", which means a string ('s') filled to 8 spaces (' 8') and left-justified ('-'), followed by another string and a newline.

The first string is the name of the player and the second is the bar.

The infix x operator, or repetition operator, generates this bar. It takes a string on the left-hand side and a number on the right-hand side, and sticks the strings together as many times as the number specifies, so 'ab' x 3 returns the string 'ababab'. .value returns the value of the current pair, ($unit * .value) multiplies that values with $unit, and 'X' x ($unit * .value) returns as that many X characters.

A Word on Precedence

The explanations of this example have one implication which is not entirely obvious. In the line:

... the right-hand side of the assignment produces a list (because of the , operator) that is made of pairs (because of =>), and the result is then assigned to the array variable. You could think of other ways for Perl 6 to interpret this program. Perl 5 will interpret it as:

... so that @scores will contain only one item. The rest of the expression is merely a list of constants evaluated, then discarded.

Precedence rules govern how a parser will parse this line. Perl 6's precedence rules state that the infix => operator binds its arguments more tightly than the infix , operator, which in turn binds more tightly than the = assignment operator.

right-hand or left-hand?

Perl 6's precedence rules allow you to express many common operations naturally, without thinking about precedence at all. If you want to force a different parsing precedence, surround an expression with parentheses, so that this new group has the tightest possible precedence:

But beware that parenthesis directly after an identifier -- without any whitespace between -- are always parsed as the argument list, so

prints out only the result of 5 - 7.

Comparisons and Smart Matching

There are several ways to compare objects in Perl. You can test for value equivalence using the === infix operator. For immutable objectsObjects whose values can not be changed; literal values. For instance, the literal 7 will always and forever be just a 7., this is an ordinary value comparison. "hello" === "hello" is true because both strings are immutable and have the same value.

For mutable objects, === compares their identities. Two objects only share the same identity if, in fact, they are the same object. Even if the two arrays @a and @b contain the same values, if their containers are two separate array objects, they will have different identities and will not be equivalent when compared with ===:

The eqv operator returns True only if two objects are of the same type and the same structure. With @a and @b as defined in the previous example, @a eqv @b is true because @a and @b contain the same values each. On the other hand '2' eqv 2 returns False, because one argument is a string, the other an integer and so they are not of the same type.

clarify "same structure"

Numeric Comparisons

You can ask if two objects have the same numeric value with the == infix operator. If one of the objects is not numeric, Perl will do its best to make it numeric before doing the comparison. If there is no good way to convert an object to a number, Perl will use the default of 0.

maybe explain the failure in 3 == '3b' more thoroughly?

The operators <, <=, >=, and > compare the relative size of numbers. != returns True if the two objects differ in their numerical value.

When you use an array or list as a number, it evaluates to the number of items in that list.

String Comparisons

Just like == converts its arguments to numbers before comparing, eq as an infix operator compares for string equality, converting its arguments to strings as necessary:

Other operators compare strings lexicographically.

For example, 'a' lt 'b' is true, and likewise 'a' lt 'aa'.

!= is really just a convenience for !==, which in turn is really the ! meta operator added to the infix == operator. An equivalent explanation applies to ne and !eq.

Three-way Comparison

The three-way comparison operators take two operands, and return Order::Increase if the left is smaller, Order::Same when both are equal, and Order::Decrease if the right operand is smallerOrder::Increase, Order::Same, and Order::Decrease are enumerations (enums); see sec:subtypes . For numbers, the comparison operator is <=> and for strings it's leg (from lesser, equal, greater). The infix cmp operator is a type sensitive three-way comparison operator which compares numbers like <=>, strings like leg, and (for example) pairs first by key, and then by value if the keys are identical:

A typical use case for three-way comparison is sorting. The .sort method in lists can take a block or function that takes two values, compares them, and returns a value less than, equal to or, greater than 0. The sort method then orders the values according to that return value:

The default comparison is case sensitive; by comparing not the values, but their upper case variant, this example sorts case insensitively.

Smart Matching

The various comparison operators all coerce their arguments to certain types before comparing them. This is useful if you wish to be very specific about what kind of comparison you want and are unsure of the types of the values you are comparing. Perl 6 provides another operator that allows you to perform comparisons that Do The Right Thing with ~~, the smart match operator.

The smart match operator always decides what kind of comparison to do based upon the type of the value on the right hand side. In the previous examples, the comparisons are numeric, string, and range, respectively. While this chapter has demonstrated the numeric and string comparison operators --== and eq--there is no operator for comparing ranges. This is part of the power of smart matching: more complex types can define interesting and useful ways to compare themselves to other things.

POD ERRORS

Hey! The above document had some coding errors, which are explained below:

Around line 1:

Unknown directive: =head0

Around line 3:

A non-empty Z<>

Around line 155:

Deleting unknown formatting code N<>

Deleting unknown formatting code N<>

Around line 282:

=end for without matching =begin. (Stack: [empty])

Around line 506:

Deleting unknown formatting code N<>

Around line 551:

=end for without matching =begin. (Stack: [empty])

Around line 573:

=end for without matching =begin. (Stack: [empty])

Around line 716:

Deleting unknown formatting code N<>

Deleting unknown formatting code A<>

Around line 805:

=end for doesn't match =begin sidebar. (Stack: =begin sidebar)

Jump to Line
Something went wrong with that request. Please try again.