Permalink
Browse files

Applied edits from Matthias Bloch.

  • Loading branch information...
1 parent 21acec4 commit 84a64ea709a078a5634c494120ac8f26a399d132 @chromatic committed Jul 26, 2010
View
@@ -119,3 +119,6 @@ E: ?
N: Andrew Savige
E: asavige@cpan.org
+
+N: Matthias Bloch
+E: matthias.bloch@puffin.ch
View
@@ -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
@@ -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:
@@ -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
@@ -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
@@ -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
@@ -541,6 +541,7 @@ U<http://hop.perl.plover.com/>.
=head3 Recursion
+Z<recursion>
X<recursion>
X<call frame>
X<functions; call frame>
View
@@ -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, >>
@_,
@@ -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
@@ -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
@@ -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
@@ -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
Oops, something went wrong.

0 comments on commit 84a64ea

Please sign in to comment.