Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Applied edits from Matthias Bloch.

  • Loading branch information...
commit 84a64ea709a078a5634c494120ac8f26a399d132 1 parent 21acec4
@chromatic authored
View
3  CREDITS
@@ -119,3 +119,6 @@ E: ?
N: Andrew Savige
E: asavige@cpan.org
+
+N: Matthias Bloch
+E: matthias.bloch@puffin.ch
View
41 sections/arrays.pod
@@ -85,24 +85,18 @@ replace the C<@> array sigil with the slightly more unwieldy C<$#>:
=end programlisting
That may not read as nicely, however. Most of the time you don't need that
-syntax, for two reasons. First, you can use negative offsets to access an
-array from the end instead of the start. The final element of an array is
-available at the index C<-1>. The penultimate element of the array is
-available at index C<-2>, and so on. For example:
+syntax, as you can use negative offsets to access an array from the end instead
+of the start. The final element of an array is available at the index C<-1>.
+The penultimate element of the array is available at index C<-2>, and so on.
+For example:
=begin programlisting
- my $last_cat = $cats[-1];
+ my $last_cat = $cats[-1];
my $second_to_last_cat = $cats[-2];
=end programlisting
-=for author
-
-What's the second reason you don't need $#?
-
-=end for
-
=head3 Array Assignment
You can assign to individual positions in an array directly by index:
@@ -207,19 +201,22 @@ A slice can contain zero or more elements--including one:
# single-element array slice; function call in I<list> context
@cats[-1] = get_more_cats();
+
+ # single-element array access; function call in I<scalar> context
$cats[-1] = get_more_cats();
=end programlisting
-Be aware that the only syntactic difference between an array slice of one
-element and the scalar access of an array element is the leading sigil. The
-I<semantic> difference is greater: an array slice always enforces list context.
+The only syntactic difference between an array slice of one element and the
+scalar access of an array element is the leading sigil. The I<semantic>
+difference is greater: an array slice always enforces list context. Any array
+slice evaluated in scalar context will produce a warning:
-=begin sidebar
+=begin screen
-This behavior is one reason why Perl 6 uses invariant sigils.
+ Scalar value @cats[1] better written as $cats[1] at...
-=end sidebar
+=end screen
=head3 Array Operations
@@ -365,7 +362,15 @@ this example several years ago>:
# what's in this array again?
{
local $" = ')(';
- say "(@some_values)";
+ say "(@sweet_treats)";
}
=end programlisting
+
+... which produces the result:
+
+=begin screen
+
+ (pie)(cake)(doughnuts)(cookies)(raisin bread)
+
+=end screen
View
15 sections/chapter_00.pod
@@ -37,6 +37,21 @@ program:
=end programlisting
+Other code snippets use testing functions such as C<ok()>, C<like()>, and
+C<is()> (L<testing>). That skeleton program is:
+
+=begin programlisting
+
+ #!/usr/bin/perl
+
+ use Modern::Perl;
+ B<use Test::More 'no_Plan';>
+
+ # example code here
+ ...
+
+=end programlisting
+
If you don't already have a modern version of Perl installed, you can install
it yourself, using:
View
14 sections/context_philosophy.pod
@@ -92,6 +92,20 @@ except that no assignment to the array actually occurs:
=end programlisting
+=begin sidebar
+
+Why is context interesting for functions? Suppose
+C<some_expensive_operation()> calculates all of the tasks you have to do around
+the house, sorted in order of their priority. If you have only time to do one
+task, you can call the function in scalar context to get a useful task--perhaps
+not necessarily the most important, but important enough without having to go
+through your whole task list. In list context, the function can perform all of
+the sorting and searching and comparison and give you an exhaustive list in the
+proper order. If you want all of that work, but only have time for a couple of
+tasks, you can use a one or two-element list.
+
+=end sidebar
+
Evaluating a function or expression--except for assignment--in list context can
produce confusion. Remember that argument lists and lists
themselves--especially lists used in hash initializers--propagate list context
View
43 sections/control_flow.pod
@@ -377,6 +377,10 @@ in numeric context but evaluates to true, thanks to its string contents. Both
the empty list and C<undef> evaluate to false. Empty arrays and hashes return
the number 0 in scalar context, so they evaluate to false in boolean context.
+An array which contains a single element--even C<undef>--evaluates to true in
+boolean context. A hash which contains any elements--even a key and a value of
+C<undef>--evaluates to true in boolean context.
+
=begin sidebar
The C<Want> module available from the CPAN allows you to detect boolean context
@@ -576,8 +580,8 @@ this can be troublesome:
=end programlisting
-To avoid the possibility of this situation, lexicalize the topic variable with
-C<my $_>:
+If you I<must> use C<$_> rather than a named variable, lexicalize the topic
+variable with C<my $_>:
=begin programlisting
@@ -872,7 +876,25 @@ this problem, you may re-open the file inside the C<for> loop (simple to
understand, but not always a good use of system resources), slurp the entire
file into memory (which may not work if the file is large), or C<seek> the
filehandle back to the beginning of the file for each iteration (an often
-overlooked option).
+overlooked option):
+
+=begin programlisting
+
+ use autodie;
+
+ open my $fh, '<', $some_file;
+
+ for my $prefix (@prefixes)
+ {
+ while (<$fh>)
+ {
+ say $prefix, $_;
+ }
+
+ seek $fh, 0, 0;
+ }
+
+=end programlisting
=head3 Loop Control
@@ -929,6 +951,7 @@ implement a silly file parser that joins lines which end with a backslash with:
{
chomp $line;
+ # match backslash at the end of a line
if ($line =~ s{\\$}{})
{
$line .= <$fh>;
@@ -1162,12 +1185,6 @@ Link to smart match.
X<tailcalls>
X<goto>
-=for author
-
-Do I need to explain recursion? I fear so.
-
-=end for
-
A I<tailcall> occurs when the last expression within a function is a call to
another function--the return value of the outer function is the return
value of the inner function:
@@ -1199,10 +1216,10 @@ manually.
=begin sidebar
-Why would you want to do this? Heavily recursive code, especially mutually
-recursive code, can quickly consume a lot of memory. Reducing the memory
-needed for internal bookkeeping of control flow can make otherwise expensive
-algorithms tractable.
+Why would you want to do this? Heavily recursive code (L<recursion>),
+especially mutually recursive code, can quickly consume a lot of memory.
+Reducing the memory needed for internal bookkeeping of control flow can make
+otherwise expensive algorithms tractable.
=end sidebar
View
6 sections/cpan.pod
@@ -100,9 +100,9 @@ reading twice, especially its section on troubleshooting.
Even though the CPAN client is a core module for the Perl 5 distribution, you
may also have to install standard development tools such as a C<make> utility
and possibly a C compiler to install all of the distributions you want.
-Windows users, see Strawberry Perl and Strawberry Perl Professional. Mac OS X
-users need their developer tools installed. Unix and Unix-like users, consult
-your local system administrator.
+Windows users, see Strawberry Perl (U<http://strawberryperl.com/>) and
+Strawberry Perl Professional. Mac OS X users need their developer tools
+installed. Unix and Unix-like users, consult your local system administrator.
=end sidebar
View
1  sections/functions.pod
@@ -541,6 +541,7 @@ U<http://hop.perl.plover.com/>.
=head3 Recursion
+Z<recursion>
X<recursion>
X<call frame>
X<functions; call frame>
View
39 sections/hashes.pod
@@ -234,9 +234,25 @@ contains the given key:
Using C<exists> instead of accessing the hash key directly avoids two problems.
First, it does not check the boolean nature of the hash I<value>; a hash key
-may exist with a value even if that value evaluates to a boolean false (including
-C<undef>). Second, with nested data structures, it avoids autovivifying
-(L<autovivification>) the value.
+may exist with a value even if that value evaluates to a boolean false
+(including C<undef>). Second, with nested data structures, it avoids
+autovivifying (L<autovivification>) the value.
+
+X<defined>
+X<operators; defined>
+
+The corresponding operator for hash values is C<defined>. If a hash key
+exists, its value may be C<undef>. Check that with C<defined>:
+
+=begin programlisting
+
+ $addresses{Leibniz} = undef;
+
+ say "Gottfried lives at $addresses{Leibniz}"
+ if exists $addresses{Leibniz}
+ && defined $addresses{Leibniz};
+
+=end programlisting
=head3 Accessing Hash Keys and Values
@@ -303,13 +319,12 @@ a random factor. With that caveat in mind, the order of items in a hash is the
same for C<keys>, C<values>, and C<each>. Modifying the hash may change the
order, but you can rely on that order if the hash remains the same.
-Beware that each hash has only a single iterator for the C<each> operator. You
-cannot reliably iterate over a hash with C<each> more than once; if you begin a
-new iteration while another is in progress, the former will end prematurely and
-the latter will begin partway through the hash.
+Each hash has only a I<single> iterator for the C<each> operator. You cannot
+reliably iterate over a hash with C<each> more than once; if you begin a new
+iteration while another is in progress, the former will end prematurely and the
+latter will begin partway through the hash.
-You can reset a hash's iterator with the use of C<keys> or C<values> in void
-context:
+Reset a hash's iterator with the use of C<keys> or C<values> in void context:
=begin programlisting
@@ -435,7 +450,9 @@ list contextN<The loop will loop forever, unless the hash is empty.>.
X<hashes; finding uniques>
-Hashes have several uses, such as finding unique elements of lists or arrays:
+Hashes have several uses, such as finding unique elements of lists or arrays.
+Because each key exists only once in a hash, assigning the same key to a hash
+multiple times stores only the most recent key:
=begin programlisting
@@ -560,7 +577,7 @@ You can even set default parameters with this approach:
{
my %parameters =
(
- B<< flavor => 'Vanilla', >>
+ B<< flavor => 'Vanilla', >>
B<< topping => 'fudge', >>
B<< sprinkles => 100, >>
@_,
View
14 sections/implicit_ideas.pod
@@ -77,7 +77,8 @@ Check how many other string functions this includes?
Many of Perl's scalar operators work on the default scalar variable if you do
not provide an alternative.
-Perl's looping constructs also set C<$_>, such as C<for> iterating over a list:
+Perl's looping directives (L<looping_directives>) also set C<$_>, such as
+C<for> iterating over a list:
=begin programlisting
@@ -223,6 +224,17 @@ command-line filter which reverses its input:
=end programlisting
+=begin sidebar
+
+Why C<scalar>? C<say> imposes list context on its operands. C<reverse> passes
+its context on to its operands, treating them as a list in list context and a
+concatenated string in scalar context. If this sounds confusing, it can be: if
+Perl 5 arguably should have had different operators for these different
+operations.
+
+=end sidebar
+
+
If you run it with a list of files:
=begin screen
View
13 sections/nested_data_structures.pod
@@ -149,14 +149,23 @@ autovivification in a lexical scope for specific types of operations; it's
worth your time to consider this in large projects, or projects with multiple
developers.
-=begin programlisting
+=begin sidebar
You can also check for the existence of specific hash keys and the number of
elements in arrays before dereferencing each level of a complex data structure,
but that can produce tedious, lengthy code which many programmers prefer to
avoid.
-=end programlisting
+You may wonder at the contradiction between taking advantage of
+autovivification while enabling C<strictures>. The question is one of balance.
+is it more convenient to catch errors which change the behavior of your program
+at the expense of disabling those error checks for a few well-encapsulated
+symbolic references? Is it more convenient to allow data structures to grow
+rather than specifying their size and allowed keys?
+
+The answer to the latter question depends on your specific project.
+
+=end sidebar
=head3 Debugging Nested Data Structures
View
12 sections/perl_community.pod
@@ -17,15 +17,9 @@ U<http://www.perl6.org/>>, and even Perl 1.
X<Perl Pub>
-=for author
-
-Fix link when appropriate, or remove reference.
-
-=end for
-
-Perl.org also hosts Perl Pub, a website which publishes several articles and
-tutorials about Perl programming every month. Its archives reach back into the
-20th century. See U<http://www.perl.org/pub/>.
+Perl.com publishes several articles and tutorials about Perl programming every
+month. Its archives reach back into the 20th century. See
+U<http://www.perl.com/>.
X<cpan.org>
X<websites; cpan.org>
View
8 sections/references.pod
@@ -228,10 +228,10 @@ Surround a list of values or expressions with square brackets:
=end programlisting
-This array reference behaves the same as named array references. Do note,
-however, that anonymous array references I<always> create a new reference,
-while taking a reference to a named array always refers to the I<same> array
-with regard to scoping. That is to say:
+This array reference behaves the same as named array references, except that
+anonymous array references I<always> create a new reference, while taking a
+reference to a named array always refers to the I<same> array with regard to
+scoping. That is to say:
=begin programlisting
View
19 sections/scalars.pod
@@ -86,8 +86,23 @@ components.
X<stringification>
X<numification>
-Perl 5 stringifies references (L<references>) evaluated in scalar string
-context and numifies references evaluated in scalar numeric context.
+Evaluating a reference (L<references>) in string context produces a string.
+Evaluating a reference in numeric context produces a number. Neither operation
+modifies the reference in place, but you cannot recreate the reference from
+either the string or numeric result:
+
+=begin programlisting
+
+ my $authors = [qw( Pratchett Vinge Conway )];
+ my $stringy_ref = '' . $authors;
+ my $numeric_ref = 0 . $authors;
+
+=end programlisting
+
+C<$authors> is still useful as a reference, but C<$stringy_ref> is a string
+with no connection to the reference and C<$numeric_ref> is a number with no
+connection to the reference.
+
X<Scalar::Util>
X<dualvars>
View
46 sections/values.pod
@@ -29,8 +29,10 @@ contents, and no semantic meaning beyond the fact that it's a string. It could
be your name. It could be the contents of an image file read from your hard
drive. It could be the Perl program itself. A string has no meaning to the
program until you give it meaning. A string is a fixed amount of data
-delineated by quotes of some form. Most strings use either single or double
-quotes:
+delineated by quotes of some form, yet Perl strings can grow or shrink as you
+add to or remove from them.
+
+Most strings use either single or double quotes:
=begin programlisting
@@ -163,7 +165,23 @@ double-quoted interpolation. The C<END_BLURB> itself is an arbitrary
identifier which the Perl 5 parser uses as the ending delimiter.
Be careful; regardless of the indentation of the heredoc declaration itself,
-the ending delimiter must begin in the first column of the program.
+the ending delimiter I<must> begin in the first column of the program:
+
+=begin programlisting
+
+ sub some_function {
+ my $ingredients =<<'END_INGREDIENTS';
+ Two eggs
+ One cup flour
+ Two ounces butter
+ One-quarter teaspoon salt
+ One cup milk
+ One drop vanilla
+ Season to taste
+ END_INGREDIENTS
+ }
+
+=end programlisting
=begin sidebar
@@ -568,10 +586,24 @@ value: C<undef>. Declared but undefined scalar variables contain C<undef>:
X<undef; coercions>
-C<undef> evaluates to false in boolean context. Be aware that an array
-containing a single element which is itself C<undef> evaluates to true in a
-boolean context. Interpolating C<undef> into a string--or evaluating it in a
-string context--produces an C<uninitialized value> warning.
+C<undef> evaluates to false in boolean context. Interpolating C<undef> into a
+string--or evaluating it in a string context--produces an C<uninitialized
+value> warning:
+
+=begin programlisting
+
+ my $undefined;
+ my $defined = $undefined . '... and so forth';
+
+=end programlisting
+
+... produces:
+
+=begin screen
+
+ Use of uninitialized value $undefined in concatenation (.) or string...
+
+=end screen
=head3 The Empty List
View
12 sections/variables.pod
@@ -1,15 +1,15 @@
=head2 Variables
Z<variables>
+X<variable>
A I<variable> in Perl is a storage location for a value (L<values>). You can
work with values directly, but all but the most trivial code works with
-variables. A variable is a level of indirection that allows you to describe an
-operation rather than its effects; it's easier to explain the Pythagorean
-theorem in terms of the variables C<a>, C<b>, and C<c> than with the side
-lengths of every right triangle you can imagine. This may seem basic and
-obvious, but to write robust, well-designed, testable, and composable programs,
-you must identify and exploit points of genericity wherever possible.
+variables. A variable is a level of indirection; it's easier to explain the
+Pythagorean theorem in terms of the variables C<a>, C<b>, and C<c> than with
+the side lengths of every right triangle you can imagine. This may seem basic
+and obvious, but to write robust, well-designed, testable, and composable
+programs, you must identify and exploit points of genericity wherever possible.
=head3 Variable Naming
Please sign in to comment.
Something went wrong with that request. Please try again.