Navigation Menu

Skip to content

Commit

Permalink
Edited chapter. It looks good.
Browse files Browse the repository at this point in the history
  • Loading branch information
chromatic committed Apr 29, 2010
1 parent 971d45f commit 1106aab
Showing 1 changed file with 93 additions and 78 deletions.
171 changes: 93 additions & 78 deletions src/basics.pod
@@ -1,8 +1,8 @@
=head0 The Basics

Perl originated as a programming language intended to gather and summarize
information from text files. Its history demonstrates its strength at those
tasks.
information from text files. It's still strong in text processing, but Perl 5
is a powerful general-purpose programming language. Perl 6 is even better.

Suppose that you host a table tennis tournament. The referees tell you the
results of each game in the format C<Player 1 vs Player 2 | 3:2>, which means
Expand Down Expand Up @@ -66,17 +66,25 @@ The =begin/=end tags here add a bit of semantic markup we can exploit later.

This produces the output:

=begin screen

Ana has won 2 games and 8 sets
Dave has won 2 games and 6 sets
Charlie has won 1 games and 4 sets
Beth has won 1 games and 4 sets

=end screen

X<v6>

Every Perl 6 program should begin with C<use v6;>. This line tells the compiler
which version of Perl the program expects. Should you accidentally run the file
with Perl 5, you'd get a helpful error message.
with Perl 5, you'll get a helpful error message.

X<statement>

A Perl 6 program consists of zero or more statements. A statement ends with a
semicolon or a curly bracket at the end of a line.
A Perl 6 program consists of zero or more statements. A I<statement> ends with
a semicolon or a curly bracket at the end of a line:

=begin programlisting

Expand All @@ -88,34 +96,35 @@ X<lexical>
X<variables; lexical>

C<my> declares a lexical variable. This is a variable that is visible only in
the current block. If there's no enclosing block, it's visible in the
the current block. If there's no enclosing block, it's visible throughout the
remainder of the file.

X<sigil>
X<identifier>

A variable name begins with a I<sigil>, which is a non-word character such as
C<$>, C<@>, C<%>, or C<&> -- or occasionally the double colon C<::>. The
sigils usually restrict the variable to some particular type. After the
sigil comes an identifier, which may consist of letters, digits and the
underscore. Between letters you can also use a dash C<-> or a hyphen C<'>, so
C<isn't> and C<double-click> are valid identifiers.
C<$>, C<@>, C<%>, or C<&>--or occasionally the double colon C<::>. The sigils
usually restrict the variable to some particular type. After the sigil comes an
I<identifier>, which may consist of letters, digits and the underscore. Between
letters you can also use a dash C<-> or a hyphen C<'>, so C<isn't> and
C<double-click> are valid identifiers.

X<files; handle>
X<file handle>
X<assignment>

The built-in function C<open> opens a file, here named
F<scores>, and returns an object describing that file, a I<file handle>. The
equality sign C<=> I<assigns> that file handle to the variable on the left,
which means that C<$file> now stores the file handle.
The built-in function C<open> opens a file, here named F<scores>, and returns
an object representing that file, a I<file handle>. The equality sign C<=>
I<assigns> that file handle to the variable on the left, which means that
C<$file> now stores the file handle.

X<strings; literal>
X<string literal>
X<string>

C<'scores'> is a I<string literal>. A string is a piece of text, a sequence
of characters. In this line, it's an argument provided to C<open>. If you
prefer C-style notation, you could also write C<open('scores')>.
C<'scores'> is a I<string literal>. A string is a piece of text, a sequence of
characters. In this line, it's the argument provided to C<open>. If you prefer
C-style notation, you can write instead C<open('scores')>.

=begin programlisting

Expand All @@ -124,15 +133,18 @@ prefer C-style notation, you could also write C<open('scores')>.
=end programlisting

X<array>

The right-hand side calls a method named C<get> on the file handle stored in
C<$file>. This method reads and returns one line from the file, removing the
line ending. C<split> is also a method, called on the string returned from
C<get>. C<split>'s single argument is a string containing a space character.
C<split> decomposes its invocant string into a list of strings. It turns
C<'Beth Ana Charlie Dave'> into C<'Beth', 'Ana', 'Charlie', 'Dave'>. Finally,
this list gets stored into the array C<@names>. The C<@> sigil marks the
declared variable as an C<Array>. Arrays store ordered lists.
X<method>
X<invocant>

The right-hand side calls a I<method>--a group of behaviors--named C<get> on
the file handle stored in C<$file>. This method reads and returns one line
from the file, removing the line ending. C<split> is also a method, called on
the string returned from C<get>. C<split>'s single argument is a string
containing a space character. C<split> decomposes its I<invocant>--the string
on which it operates--into a list of strings. It turns C<'Beth Ana Charlie
Dave'> into C<'Beth', 'Ana', 'Charlie', 'Dave'>. Finally, this list gets
stored into the array C<@names>. The C<@> sigil marks the declared variable as
an C<Array>. Arrays store ordered lists.

=begin programlisting

Expand All @@ -148,13 +160,13 @@ collection of pairs of keys and values. Other programming languages call that a
I<hash table>, I<dictionary>, or I<map>. You can query a hash table for the
value that corresponds to a certain C<$key> with C<%hash{$key}>.

Here in the score counting program, C<%games> stores the number of games each
player has won and C<%sets> the number of sets each player has won.
In the score counting program, C<%games> stores the number of games each player
has won. C<%sets> stores the number of sets each player has won.

C<Array>s and C<Hash>es are central enough to each have their own sigil in
Perl. The C<$> sigil, however, confers no restriction on the type of the
value it contains. You can store numbers, strings or more complex objects
in C<$>-sigil variables. (You can even put an C<Array> or a C<Hash> in there,
Perl. The C<$> sigil, however, confers no restriction on the type of the value
it contains. You can store numbers, strings, or more complex objects in
C<$>-sigil variables. (You can even put an C<Array> or a C<Hash> in there,
should you wish.)

=begin programlisting
Expand All @@ -166,28 +178,29 @@ should you wish.)
=end programlisting

X<for>
X<block>

C<for> produces a loop that runs the block indicated by C<...> once for each
item of the list, setting the variable C<$line> to the current value of each
iteration. C<$file.lines> produces a list of the lines read from the file
C<scores>.
C<for> produces a loop that runs the I<block> delimited by curly brackets and
containing C<...> once for each item of the list, setting the variable C<$line>
to the current value of each iteration. C<$file.lines> produces a list of the
lines read from the file F<scores>.

During the first iteration, C<$line> contains the string C<Ana vs Dave | 3:0>.
During the second, C<Charlie vs Beth | 3:1>, and so on.
During the first iteration, C<$line> will contain the string C<Ana vs Dave |
3:0>. During the second, C<Charlie vs Beth | 3:1>, and so on.

=begin programlisting

my ($pairing, $result) = $line.split(' | ');

=end programlisting

Again, C<my> declares variables, this time a list of two at once. The right-hand
side of the assignment is again a call to C<split>, this time splitting on a
vertical bar surrounded by spaces. C<$pairing> gets the first item of the
returned list, and C<$result> the second.
C<my> can declare multiple variables simultaneously. The right-hand side of the
assignment is again a call to C<split>, this time splitting on a vertical bar
surrounded by spaces. C<$pairing> gets the first item of the returned list, and
C<$result> the second.

While processing the first line, C<$pairing> holds the string C<Ana vs Dave>
and C<$result> is set to C<3:0>.
After processing the first line, C<$pairing> will hold the string C<Ana vs
Dave> and C<$result> C<3:0>.

The next two lines follow the same pattern:

Expand Down Expand Up @@ -260,7 +273,7 @@ After processing the first line of the file, the variables contain the values:

=end table

The program then counts the number of sets won:
The program then counts the number of sets each player has won:

=begin programlisting

Expand All @@ -269,7 +282,7 @@ The program then counts the number of sets won:

=end programlisting

This is a shortcut for
This is a shortcut for:

=begin programlisting

Expand All @@ -282,14 +295,15 @@ X<Any>
X<+=>
X<operators; +=>

C<+= $r1> means I<increase the value in the variable the left by $r1>. In the
first iteration C<%sets{$p1}> is not yet set, so it defaults to a special value
called C<Any>. The addition and incrementing operators treat C<Any> as a
C<+= $r1> means I<increase the value in the variable on the left by $r1>. In
the first iteration C<%sets{$p1}> is not yet set, so it defaults to a special
value called C<Any>. The addition and incrementing operators treat C<Any> as a
number with the value of zero.

X<fat arrow>
X<< => >>
X<pair>
X<autovivification>

Before these two lines execute, C<%sets> is empty. Adding to an entry not in
the hash will cause that entry to spring into existence just-in-time, with a
Expand All @@ -309,19 +323,19 @@ lines have run for the first time, C<%sets> contains C<< 'Ana' => 3, 'Dave' =>

If C<$r1> has a larger value than C<$r2>, C<%games{$p1}> increments by one. If
C<$r1> is not larger than C<$r2>, C<%games{$p2}> increments. Just as in the
case of C<+=> above, if either hash value did not exist previously, it is
case of C<+=>, if either hash value did not exist previously, it is
autovivified by the increment operation.

X<postincrement>
X<operators; postincrement>
X<preincrement>
X<operators; preincrement>

C<$thing++> is short for C<$thing += 1> or
C<$thing = $thing + 1>, with the small exception that the return value of the
expression is C<$thing>, not the incremented value. Just like in the C
programming language, you can also use C<++> as a prefix, in which case it
returns the incremented value; C<my $x = 1; say ++$x> prints C<2>.
C<$thing++> is short for C<$thing += 1> or C<$thing = $thing + 1>, with the
small exception that the return value of the expression is C<$thing>, not the
incremented value. If, as you can do in many other programming languages, you
can use C<++> as a prefix, it returns the incremented value; C<my $x = 1; say
++$x> prints C<2>.

=begin programlisting

Expand All @@ -334,21 +348,20 @@ X<topic>
X<variables; $_>

This might look a bit scary at first, but it consists of three individually
simple steps. An array knows how to return a sorted version of itself with the
C<sort> method. However, the default sort on an array sorts by its contents.
To print the players names in winner-first order, the code must sort the array
by the scores of the players, not their names. The C<sort> method can take an
simple steps. An array's C<sort> method returns a sorted version of the array's
contents. However, the default sort on an array sorts by its contents. To
print the players names in winner-first order, the code must sort the array by
the I<scores> of the players, not their names. The C<sort> method can take an
argument, a I<block> used to transform the array elements (the names of
players) to the thing you want to sort by. The array items are passed in
players) to the data by which you wish to sort. The array items are passed in
through the I<topic variable> C<$_>.

X<block>

You have seen blocks before: The C<for> loop worked on a block
C<< -> $line { ... } >>, the C<if> statement worked on the blocks
C<{ %games{$p1}++ }> and C<{ %games{$p1} }>. A block is a self-contained
piece of Perl 6 code, optionally with a signature (the C<< -> $line >> part).
More about that in the next chapter. (TODO: write that)
You have seen blocks before: both the C<for> loop C<< -> $line { ... } >> and
the C<if> statement worked on blocks. A block is a self-contained piece of
Perl 6 code, optionally with a signature (the C<< -> $line >> part). See
L<signatures> for more information.

The simplest way to sort the players by score would be C<@names.sort({
%games{$_} })>, which sorts by number of games won. However Ana and Dave have
Expand All @@ -359,7 +372,7 @@ X<stable sort>
X<sort; stable>

When two array items have the same value, C<sort> leaves them in the same order
as they came in. Computer scientists call this a I<stable> sort. The program
as it found them. Computer scientists call this a I<stable sort>. The program
takes advantage of this property of Perl 6's C<sort> to achieve the goal by
sorting twice: first by the number of sets won (the secondary criterion), then
by the number of games won.
Expand Down Expand Up @@ -388,16 +401,19 @@ X<operators; print>
X<operators; say>

To print out the players and their scores, the code loops over C<@sorted>,
setting C<$n> to the name of each player in turn. C<say> prints its arguments
to the standard output (the screen, normally), followed by a newline. (Use
C<print> if you don't want the newline at the end.)
setting C<$n> to the name of each player in turn. Read this code as "For each
element of sorted, set C<$n> to the element, then execute the contents of the
following block." C<say> prints its arguments to the standard output (the
screen, normally), followed by a newline. (Use C<print> if you don't want the
newline at the end.)

X<interpolation>

When you try out the program, you'll find that it doesn't literally print
C<$n> each time, but the name that is stored in C<$n>. This automatic
substitution is called M<interpolation>. Perl 6 quotes can interpolate
variables with the dollar sigil as well as blocks of code in curly braces.
When you run the program, you'll see that C<say> doesn't print the contents of
that string verbatim. For example, in place of C<$n> it prints the names of
players stored in C<$n>--the contents of C<$n>. This automatic substitution is
I<interpolation>. Perl 6 quotes can interpolate variables with the dollar
sigil as well as blocks of code in curly braces.

X<double-quoted strings>
X<strings; double-quoted>
Expand Down Expand Up @@ -430,28 +446,27 @@ in the subsequent rows.
How can you change the program if the first input line is omitted?
Hint: C<%hash.keys> returns a list of all keys stored in C<%hash>.

B<Answer:> Remove the line C<my @names = $file.get.split(' ');>, and change
B<Answer:> Remove the line C<my @names = $file.get.split(' ');>, and change:

=begin programlisting

my @sorted = @names.sort({ %sets{$_} }).sort({ %games{$_} }).reverse;

=end programlisting

into
... into:

=begin programlisting

my @sorted = B<%sets.keys>.sort({ %sets{$_} }).sort({ %games{$_} }).reverse;

=end programlisting


B<2.> Instead of removing the redundancy, you can also use it to warn if a
player appears that wasn't mentioned in the first line, for example due to a
typo. How would you modify your program to achieve that?

B<Answer:> introduce another hash with the names of the legitimate players as
B<Answer:> Introduce another hash with the names of the legitimate players as
keys, and look in this hash when the name of a player is read:

=begin programlisting
Expand All @@ -462,7 +477,7 @@ keys, and look in this hash when the name of a player is read:
B<for @names ->>B< $n {>
B< %legitimate-players{$n} = 1;>
B<}>

...

for $file.lines -> $line {
Expand Down

0 comments on commit 1106aab

Please sign in to comment.