From 46dbab75ebee06a9d55b69623b3390a59399643c Mon Sep 17 00:00:00 2001 From: chromatic Date: Tue, 17 Jan 2012 13:37:43 -0800 Subject: [PATCH] Final page- and linebreaking changes. --- build/latex/copyright.tex | 1 - sections/advanced_oo.pod | 7 +- sections/anonymous_functions.pod | 26 ++-- sections/arrays.pod | 178 ++++++++++++---------------- sections/attributes.pod | 8 +- sections/autoload.pod | 43 +++---- sections/chapter_01.pod | 4 +- sections/closures.pod | 21 ++-- sections/code_generation.pod | 5 +- sections/context_philosophy.pod | 32 +++-- sections/control_flow.pod | 41 +++---- sections/distributions.pod | 7 +- sections/expressivity.pod | 12 +- sections/files.pod | 67 ++++++----- sections/functions.pod | 17 +-- sections/hashes.pod | 27 ++--- sections/idioms.pod | 28 ++--- sections/implicit_ideas.pod | 38 +++--- sections/modules.pod | 38 +++--- sections/nested_data_structures.pod | 40 ++----- sections/overloading.pod | 61 +++++----- sections/packages.pod | 13 +- sections/pragmas.pod | 49 ++++---- sections/references.pod | 52 +++----- sections/regular_expressions.pod | 57 ++++----- sections/scope.pod | 15 +-- sections/smart_match.pod | 81 ++++--------- sections/state.pod | 20 ++-- sections/testing.pod | 27 +++-- sections/universal.pod | 16 ++- sections/values.pod | 7 +- 31 files changed, 440 insertions(+), 598 deletions(-) diff --git a/build/latex/copyright.tex b/build/latex/copyright.tex index a6f5afe3..722631c4 100644 --- a/build/latex/copyright.tex +++ b/build/latex/copyright.tex @@ -1,4 +1,3 @@ -\chapter*{} \thispagestyle{empty} \huge{\booktitle} diff --git a/sections/advanced_oo.pod b/sections/advanced_oo.pod index c8583e4c..3c5a90e7 100644 --- a/sections/advanced_oo.pod +++ b/sections/advanced_oo.pod @@ -21,10 +21,9 @@ with code declared elsewhere? X X -Inheritance is but one of many tools. Although C may extend -C (an I), it's likely better for C to -I contain several C objects as instance attributes (a I). +Inheritance is but one of many tools. A C may extend C +(an I), but C may better I several C +objects as instance attributes (a I). Decomposing complex classes into smaller, focused entities (whether classes or roles) improves encapsulation and reduces the possibility that any one class or diff --git a/sections/anonymous_functions.pod b/sections/anonymous_functions.pod index eae037a5..5069984c 100644 --- a/sections/anonymous_functions.pod +++ b/sections/anonymous_functions.pod @@ -99,8 +99,11 @@ You may also see anonymous functions passed as function arguments: X +X> + Given a reference to a function, you can determine whether the function is -named or anonymous with introspection: +named or anonymous with introspectionN<... or C from the CPAN module +C.>: =begin programlisting @@ -123,15 +126,6 @@ named or anonymous with introspection: =end programlisting -=begin tip Who Are You? - -X> - -The CPAN module C's C function simplifies this -introspection. - -=end tip - The result may be surprising: Called from ShowCaller::B
@@ -183,7 +177,10 @@ Perl 5 allows the declaration of anonymous functions implicitly through the use of prototypes (L). Though this feature exists nominally to enable programmers to write their own syntax such as that for C and C, an interesting example is the use of I functions that don't look like -functions. Consider the CPAN module C: +functions. + +Consider the CPAN module C, which takes an anonymous function as +the first argument to its C function: =begin programlisting @@ -200,8 +197,7 @@ functions. Consider the CPAN module C: =end programlisting -The function C takes an anonymous function as its first argument. -These calls are equivalent to: +You might rewrite this more verbosely as: =begin programlisting @@ -210,9 +206,7 @@ These calls are equivalent to: =end programlisting -... but are easier to read. - -This syntax allows you to pass named functions by reference as well: +... or to pass named functions by reference: =begin programlisting diff --git a/sections/arrays.pod b/sections/arrays.pod index d5832602..bf3b78cf 100644 --- a/sections/arrays.pod +++ b/sections/arrays.pod @@ -1,17 +1,15 @@ =head1 Arrays Z + X +X sigil> +X> Perl 5 I are I data structures--the language supports them as a built-in data type--which store zero or more scalars. You can access individual members of the array by integer indexes, and you can add or remove -elements at will. - -X sigil> -X> - -The C<@> sigil denotes an array. To declare an array: +elements at will. The C<@> sigil denotes an array. To declare an array: =begin programlisting @@ -58,37 +56,27 @@ addition, or boolean context) evaluates to the number of elements in the array: =end programlisting -To get the I of the final element of an array, subtract one from the -number of elements of the array (remember that array indexes start at 0): - -=begin programlisting - - my $first_index = 0; - my $last_index = @cats - 1; - - say "My first cat has an index of $first_index, " - . "and my last cat has an index of $last_index." - -=end programlisting - X; sigil> X> -The less wieldy syntax C<$#cats> also evaluates to the last index of the array: +To get the I of the final element of an array, subtract one from the +number of elements of the array (remember that array indexes start at 0) or use the unwieldy C<$#cats> syntax: =begin programlisting my $first_index = 0; - B + my $last_index = @cats - 1; + # or + # my $last_index = $#cats; say "My first cat has an index of $first_index, " . "and my last cat has an index of $last_index." =end programlisting -... though it's often clearer to use negative array indices instead. The last -element of an array is available at the index C<-1>. The second to last element -of the array is available at index C<-2>, and so on: +When the index matters less than the position of an element, use negative array +indices instead. The last element of an array is available at the index C<-1>. +The second to last element of the array is available at index C<-2>, and so on: =begin programlisting @@ -166,68 +154,6 @@ freshly-declared arrays start out empty. =end tip -=head2 Array Slices - -Z - -X -X -X; sigil> -X> - -The I construct allows you to access elements of an array in list -context. Unlike scalar access of an array element, this indexing operation -takes a list of zero or more indices and uses the array sigil (C<@>): - -=begin programlisting - - my @youngest_cats = @cats[-1, -2]; - my @oldest_cats = @cats[0 .. 2]; - my @selected_cats = @cats[ @indexes ]; - -=end programlisting - -Array slices are useful for assignment: - -=begin programlisting - - @users[ @replace_indices ] = @replace_users; - -=end programlisting - -A slice can contain zero or more elements--including one: - -=begin programlisting - - # single-element array slice; function call in I context - @cats[-1] = get_more_cats(); - - # single-element array access; function call in I context - $cats[-1] = get_more_cats(); - -=end programlisting - -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 -difference is greater: an array slice always imposes list context. An array -slice evaluated in scalar context will produce a warning: - -=begin screen - - Scalar value @cats[1] better written as $cats[1]... - -=end screen - -An array slice imposes list context (L) on the expression -used as its index: - -=begin programlisting - - # function called in list context - my @hungry_cats = @cats[ get_cat_indices() ]; - -=end programlisting - =head2 Array Operations Sometimes an array is more convenient as an ordered, mutable collection of @@ -326,6 +252,67 @@ As of Perl 5.12, C can iterate over an array by index and value: =end programlisting +=head2 Array Slices + +Z + +X +X +X; sigil> +X> + +The I construct allows you to access elements of an array in list +context. Unlike scalar access of an array element, this indexing operation +takes a list of zero or more indices and uses the array sigil (C<@>): + +=begin programlisting + + my @youngest_cats = @cats[-1, -2]; + my @oldest_cats = @cats[0 .. 2]; + my @selected_cats = @cats[ @indexes ]; + +=end programlisting + +Array slices are useful for assignment: + +=begin programlisting + + @users[ @replace_indices ] = @replace_users; + +=end programlisting + +A slice can contain zero or more elements--including one: + +=begin programlisting + + # single-element array slice; I context + @cats[-1] = get_more_cats(); + + # single-element array access; I context + $cats[-1] = get_more_cats(); + +=end programlisting + +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 +difference is greater: an array slice always imposes list context. An array +slice evaluated in scalar context will produce a warning: + +=begin screen + + Scalar value @cats[1] better written as $cats[1]... + +=end screen + +An array slice imposes list context on the expression used as its index: + +=begin programlisting + + # function called in list context + my @hungry_cats = @cats[ get_cat_indices() ]; + +=end programlisting + =head2 Arrays and Context X @@ -400,24 +387,13 @@ C<$LIST_SEPARATOR>. Thus: =end programlisting -Temporarily localizing and assigning another value to C<$"> for debugging -purposes is very handyN: +Localize C<$"> with a delimiter to ease your debuggingN: =begin programlisting # what's in this array again? - { - local $" = ')('; - say "(@sweet_treats)"; - } + local $" = ')('; + say "(@sweet_treats)"; + B<(pie)(cake)(doughnuts)(cookies)(raisin bread)> =end programlisting - -... which produces the result: - -=begin screen - - (pie)(cake)(doughnuts)(cookies)(raisin bread) - -=end screen diff --git a/sections/attributes.pod b/sections/attributes.pod index 7c738790..9f57fac8 100644 --- a/sections/attributes.pod +++ b/sections/attributes.pod @@ -36,11 +36,9 @@ CPAN uses such parametric arguments to good effect: =begin programlisting - sub setup_tests :Test(setup) { ... } - - sub test_monkey_creation :Test(10) { ... } - - sub shutdown_tests :Test(teardown) { ... } + sub setup_tests :Test(setup) { ... } + sub test_monkey_creation :Test(10) { ... } + sub shutdown_tests :Test(teardown) { ... } =end programlisting diff --git a/sections/autoload.pod b/sections/autoload.pod index 8649b038..3f7e0b36 100644 --- a/sections/autoload.pod +++ b/sections/autoload.pod @@ -8,8 +8,6 @@ program: =begin programlisting - #!/usr/bin/perl - use Modern::Perl; bake_pie( filling => 'apple' ); @@ -17,7 +15,9 @@ program: =end programlisting When you run it, Perl will throw an exception due to the call to the undefined -function C. Now add a function called C: +function C. + +Now add a function called C: =begin programlisting @@ -25,9 +25,9 @@ function C. Now add a function called C: =end programlisting -When you run the program now, nothing will happen. Perl will call a function -named C in a package--if it exists-- whenever normal dispatch. -Change the C to emit a message: +When you run the program now, nothing obvious will happen. Perl will call a +function named C in a package--if it exists--whenever normal +dispatch fails. Change the C to emit a message: =begin programlisting @@ -35,26 +35,16 @@ Change the C to emit a message: =end programlisting -=head2 Basic Features of AUTOLOAD - -The C function receives the arguments passed to the undefined -function in C<@_> directly. Manipulate these arguments as you like: - -=begin programlisting - - sub AUTOLOAD - { - # pretty-print the arguments - B - B - } +... to demonstrate that it gets called. -=end programlisting +=head2 Basic Features of AUTOLOAD X> -The I of the undefined function is available in the pseudo-global -variable C<$AUTOLOAD>: +The C function receives the arguments passed to the undefined +function in C<@_> directly and the I of the undefined function is +available in the package global C<$AUTOLOAD>. Manipulate these arguments as you +like: =begin programlisting @@ -69,10 +59,10 @@ variable C<$AUTOLOAD>: =end programlisting -The C declaration (L) scopes this variable to the body of -C. The variable contains the fully-qualified name of the undefined -function (in this case, C). Remove the package name with a -regular expression (L): +The C declaration (L) scopes C<$AUTOLOAD> to the function body. The +variable contains the fully-qualified name of the undefined function (in this +case, C). Remove the package name with a regular expression +(L): =begin programlisting @@ -193,7 +183,6 @@ of C with a call to the destination method: sub AUTOLOAD { B - my $method = sub { ... } no strict 'refs'; diff --git a/sections/chapter_01.pod b/sections/chapter_01.pod index 089d7167..30265c3d 100644 --- a/sections/chapter_01.pod +++ b/sections/chapter_01.pod @@ -4,8 +4,8 @@ Perl gets things done--it's flexible, forgiving, and malleable. Capable programmers use it every day for everything from one-liners and one-off automations to multi-year, multi-programmer projects. -Perl is pragmatic. You're in charge. You decide how best to solve your problems -and Perl will mold itself to do what you mean, with little frustration and no +Perl is pragmatic. You're in charge. You decide how to solve your problems and +Perl will mold itself to do what you mean, with little frustration and no ceremony. Perl will grow with you. In the next hour, you'll learn enough to write real, diff --git a/sections/closures.pod b/sections/closures.pod index 458d753d..f98004b7 100644 --- a/sections/closures.pod +++ b/sections/closures.pod @@ -145,18 +145,13 @@ elements you need: =end programlisting Every call to the function returned by C takes one argument, the -Ith element of the Fibonacci series. The function generates all preceding +Ith element of the Fibonacci series. The function generates all preceding values in the series as necessary, caches them, and returns the requested -element. It delays computation until absolutely necessary. - -Perhaps this is too much work to calculate a simple numeric series, but the -function C is itself amazing. It initializes an array as a cache, -executes some custom code to populate arbitrary elements of the cache, and -returns the calculated or cached value. If you extract the behavior specific to -Fibonacci values, this code can provide any arbitrary code with a -lazily-iterated cache. - -Extracting the function C produces: +element--even delaying computation until absolutely necessary. Yet there's a +pattern specific to caching intertwined with the numeric series. What happens +if you extract the cache-specific code (initialize a cache, execute custom code +to populate cache elements, and return the calculated or cached value) to a +function C? =begin programlisting @@ -179,8 +174,8 @@ Extracting the function C produces: =begin tip Fold, Apply, and Filter -In one sense, the builtins C, C, and C are themselves -higher-order functions. Compare them to C. +The builtins C, C, and C are themselves higher-order +functions. =end tip diff --git a/sections/code_generation.pod b/sections/code_generation.pod index ad229b37..721b000d 100644 --- a/sections/code_generation.pod +++ b/sections/code_generation.pod @@ -326,8 +326,6 @@ Add attributes and methods to this class when you create it: =begin programlisting - use Class::MOP; - my $class = Class::MOP::Class->create( 'Monkey::Wrench' => ( @@ -346,8 +344,7 @@ Add attributes and methods to this class when you create it: =end programlisting -... or add them to the I (the object which represents that class) -after you've created it: +... or to the metaclass (the object which represents that class) once created: =begin programlisting diff --git a/sections/context_philosophy.pod b/sections/context_philosophy.pod index 3d9d25b0..c48ecb1d 100644 --- a/sections/context_philosophy.pod +++ b/sections/context_philosophy.pod @@ -126,13 +126,11 @@ contain. Both of these calls to C occur in list context: =end programlisting -The latter example often surprises novice programmers who expect scalar context -for the function call. Initializing a hash (L) with a list of values -imposes list context on C. - X> -Use the C operator to impose scalar context: +The latter example often surprises novice programmers, as initializing a hash +(L) with a list of values imposes list context on C. Use +the C operator to impose scalar context: =begin programlisting @@ -145,10 +143,9 @@ Use the C operator to impose scalar context: =end programlisting Why does context matter? A context-aware function can examine its calling -context and decide how much work it needs to do before returning its results. -In void context, C may legitimately do nothing. In scalar -context, it can find only the most important task. In list context, it must -sort and return the entire list. +context and decide how much work it must do. In void context, C +may legitimately do nothing. In scalar context, it can find only the most +important task. In list context, it must sort and return the entire list. =head2 Numeric, String, and Boolean Context @@ -166,11 +163,9 @@ contexts provide hints that tell the compiler how to treat data. X> -Perl will do its best to coerce values to the proper type (L), -depending on the operators you use. Be sure to use the proper operator for the -type of context you want. Suppose you want to compare the contents of two -strings. The C operator tells you if the strings contain the same -information I: +Perl will coerce values to specific proper types (L), depending on +the operators you use. For example, the C operator tests that strings +contain the same information I: =begin programlisting @@ -197,7 +192,8 @@ X> The C operator treats its operands as strings by enforcing I on them. The C<==> operator imposes I. In numeric -context, both strings evaluate to C<0> (L). +context, both strings evaluate to C<0> (L). Be sure to use +the proper operator for the type of context you want. X X @@ -221,6 +217,6 @@ string. To force a boolean context, double the negation operator: =end programlisting -Type contexts are less difficult to identify than amount contexts. Once you -understand that they exist and know which operators provide which contexts -(L), you'll rarely make mistakes with them. +Type contexts are easier to identify than amount contexts. Once you know which +operators provide which contexts (L), you'll rarely make +mistakes. diff --git a/sections/control_flow.pod b/sections/control_flow.pod index 6a108c71..9f22fecc 100644 --- a/sections/control_flow.pod +++ b/sections/control_flow.pod @@ -104,10 +104,7 @@ validation in functions (L): { return unless @_; - for my $chant (@_) - { - ... - } + for my $chant (@_) { ... } } =end programlisting @@ -833,10 +830,7 @@ You may nest loops within other loops: for my $suit (@suits) { - for my $values (@card_values) - { - ... - } + for my $values (@card_values) { ... } } =end programlisting @@ -1065,10 +1059,10 @@ C also lexicalizes the topic variable: X> X -C is most useful when combined with C. C I a -value within a block so that multiple C statements can match the topic -against expressions using I semantics. To write the Rock, Paper, -Scissors game: +C is most useful when combined with C (L). C +I a value within a block so that multiple C statements can +match the topic against expressions using I semantics. To write +the Rock, Paper, Scissors game: =begin programlisting @@ -1135,18 +1129,14 @@ this code. =end tip -The C construct is even more powerful; it can match (L) -against many other types of expressions including scalars, aggregates, -references, arbitrary comparison expressions, and even code references. - =head2 Tailcalls Z X A I 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: +another function--the outer function's return value is the inner function's +return value: =begin programlisting @@ -1160,18 +1150,17 @@ value of the inner function: =end programlisting -Here returning from C directly to the caller of -C is more efficient than returning to -C and immediately returning I -C. Returning directly from C to the -caller of C is a I. +Returning from C directly to the caller of +C is more efficient than returning I +C and immediately I C. +Returning directly I C to the caller of +C is a I. Heavily recursive code (L), especially mutually recursive code, can consume a lot of memory. Tailcalls reduce the memory needed for internal bookkeeping of control flow and can make expensive algorithms tractable. -Unfortunately, Perl 5 will not detect cases where it could apply this -optimization automatically. If this happens in your code, use a manual tailcall -optimization. +Unfortunately, Perl 5 does not automatically perform this optimization; you +have to do it yourself when it's necessary. X> diff --git a/sections/distributions.pod b/sections/distributions.pod index 4c4dafb0..8672d51d 100644 --- a/sections/distributions.pod +++ b/sections/distributions.pod @@ -20,7 +20,8 @@ of its uploading, with errors reported automatically to authors--all without human intervention. You may choose never to release any of your code as public CPAN distributions, -but you can reuse CPAN tools and conventions. +but you can use CPAN tools and conventions to manage even private code. The +Perl community has built amazing infrastructure; why not take advantage of it? =head2 Attributes of a Distribution @@ -55,7 +56,9 @@ A well-formed distribution must contain a unique name and single version number (often taken from its primary module). Any distribution you download from the public CPAN should conform to these standards. The public CPANTS service (U) evaluates each uploaded distribution against -packaging guidelines and conventions and recommends improvements. +packaging guidelines and conventions and recommends improvements. Following the +CPANTS guidelines doesn't mean the code works, but it does mean that the CPAN +packaging tools should understand the distribution. =head2 CPAN Tools for Managing Distributions diff --git a/sections/expressivity.pod b/sections/expressivity.pod index d23de761..f29d221d 100644 --- a/sections/expressivity.pod +++ b/sections/expressivity.pod @@ -62,8 +62,7 @@ the sense that most everyone wants to help babies learn to communicate well. Everyone begins as a novice. Through practice and learning from more experienced programmers, you will understand and adopt more powerful idioms and techniques. -For example, an experienced Perl hacker might triple a list of numbers by -writing: +For example, an experienced Perl hacker might triple a list of numbers with: =begin programlisting @@ -84,22 +83,21 @@ writing: =end programlisting -... while a novice might start with: +... while a novice might try: =begin programlisting my @tripled; - my $count = @numbers; - for (my $i = 0; $i < $count; $i++) + for (my $i = 0; $i < scalar @numbers; $i++) { $tripled[$i] = $numbers[$i] * 3; } =end programlisting -All three approaches accomplish the same thing, but each takes advantage of -Perl in a different way. +All three approaches accomplish the same thing, but each uses Perl in a +different way. Experience writing Perl will help you to focus on I you want to do rather than I to do it. Even so, Perl will happily run simple programs. You can diff --git a/sections/files.pod b/sections/files.pod index 0a73df44..a3712abc 100644 --- a/sections/files.pod +++ b/sections/files.pod @@ -36,14 +36,6 @@ Use the C builtin to get a filehandle. To open a file for reading: =end programlisting -=begin tip Remember C? - -Assume all examples in this section have C enabled. If you choose -not to do this, remember to add error checking yourself. - -=end tip - - The first operand is a lexical which will contain the resulting filehandle. The second operand is the I, which determines the type of the filehandle operation. The final operand is the name of the file. If the C fails, the @@ -91,6 +83,18 @@ file otherwise. =cell Open for both reading and writing. +=row + +=cell C<< -| >> + +=cell Open a pipe to an external process for reading. + +=row + +=cell C<< |- >> + +=cell Open a pipe to an external process for writing. + =end table You can even create filehandles which read from or write to plain Perl scalars, using any existing file mode: @@ -104,6 +108,15 @@ You can even create filehandles which read from or write to plain Perl scalars, =end programlisting +=begin tip Remember C? + +All examples in this section have C enabled, and so can safely +elide error handling. If you choose not to use C, that's fine--but +remember to check the return values of all system calls to handle errors +appropriately. + +=end tip + X> C offers far more details about more exotic uses of @@ -111,21 +124,6 @@ C, including its ability to launch and control other processes, as well as the use of C for finer-grained control over input and output. C includes working code for many common IO tasks. -=begin tip The Many Names of C - -X> -X> -X> - -The special package global C filehandle represents the current file. When -Perl finishes compiling the file, it leaves C open at the end of the -compilation unit I the file has a C<__DATA__> or C<__END__> section. Any -text which occurs after that token is available for reading from C. This -is useful for short, self-contained programs. See C for more -details. - -=end tip - =head3 Two-argument C Older code often uses the two-argument form of C, which jams the file @@ -146,6 +144,21 @@ could change how your program behaves. The three-argument C is a safer replacement for this code. +=begin tip The Many Names of C + +X> +X> +X> + +The special package global C filehandle represents the current file. When +Perl finishes compiling the file, it leaves C open at the end of the +compilation unit I the file has a C<__DATA__> or C<__END__> section. Any +text which occurs after that token is available for reading from C. This +is useful for short, self-contained programs. See C for more +details. + +=end tip + =head3 Reading from Files X> @@ -376,10 +389,10 @@ X; C> X> X; C> -C provides several methods, including C and -C methods to access C<$.> and C<$/>, as well as -C. See C, C, and C for more information. +C's C and C methods +allow per-filehandle access to that for which you'd normally have to use the +superglobals C<$.> and C<$/>. See the documentation for C, +C, and C for more information. =head2 Directories and Paths diff --git a/sections/functions.pod b/sections/functions.pod index 7c4173ab..c40a8418 100644 --- a/sections/functions.pod +++ b/sections/functions.pod @@ -475,7 +475,7 @@ function is correct: sub add_numbers { - croak 'Expected two numbers, but received: ' . @_ + croak 'Expected two numbers, received: ' . @_ unless @_ == 2; ... @@ -700,12 +700,11 @@ X> X> X> -Unfortunately, Perl 5 does not eliminate tail calls automatically. You can do -so manually with a special form of the C builtin. Unlike the form which -can often lead to spaghetti code, the C function form replaces the -current function call with a call to another function. You may use a function -by name or by reference. You must always set C<@_> yourself manually, if you -want to pass different arguments: +Unfortunately, Perl 5 does not eliminate tail calls automatically. Do so +manually with a special form of the C builtin. Unlike the form which +often produces spaghetti code, the C function form replaces the current +function call with a call to another function. You may use a function by name +or by reference. To pass different arguments, assign to C<@_> directly: =begin programlisting @@ -730,10 +729,6 @@ Sometimes optimizations are ugly. =head1 Pitfalls and Misfeatures X - -Some Perl features look good, but have substantial drawbacks. In particular, -prototypes (L) rarely do what novices mean. - X X X; sigil> diff --git a/sections/hashes.pod b/sections/hashes.pod index dec3572d..e07ae675 100644 --- a/sections/hashes.pod +++ b/sections/hashes.pod @@ -413,7 +413,7 @@ both would themselves evaluate to false values in a boolean context. use Test::More; my %empty; - ok( ! %empty, 'empty hash should evaluate to false' ); + ok( ! %empty, 'empty hash should evaluate false' ); my %false_key = ( 0 => 'true value' ); ok( %false_key, 'hash containing false key @@ -449,16 +449,7 @@ the loop will never terminate: You I loop over the list of keys and values with a C loop, but the iterator variable will get a key on one iteration and its value on the next, because Perl will flatten the hash into a single list of interleaved keys and -values: - -=begin programlisting - - for (%hash) - { - ... - } - -=end programlisting +values. =head2 Hash Idioms @@ -541,10 +532,8 @@ Perl 5.10 introduced the defined-or and defined-or assignment operators. Prior to 5.10, most code used the boolean-or assignment operator (C<||=>) for this purpose. Unfortunately, some valid values evaluate to a false value in boolean context, so evaluating the I of values is almost always more -accurate. - -This lazy orcish maneuver tests for the definedness of the cached value, not -truthiness. +accurate. This lazy orcish maneuver tests for the definedness of the cached +value, not truthiness. X @@ -571,7 +560,7 @@ This approach allows you to set default values: sub make_sundae { - my %parameters = @_; + my %parameters = @_; B<$parameters{flavor} //= 'Vanilla';> B<$parameters{topping} //= 'fudge';> B<$parameters{sprinkles} //= 100;> @@ -580,7 +569,8 @@ This approach allows you to set default values: =end programlisting -... or include them in the initial declaration and assignment itself: +... or include them in the hash initialization, as latter assignments take +precedence over earlier assignments: =begin programlisting @@ -598,9 +588,6 @@ This approach allows you to set default values: =end programlisting -... as subsequent declarations of the same key with a different value will -overwrite previous values. - =head2 Locking Hashes Z diff --git a/sections/idioms.pod b/sections/idioms.pod index 2cd3fc62..a8d7f105 100644 --- a/sections/idioms.pod +++ b/sections/idioms.pod @@ -61,9 +61,9 @@ if it were a single argument: sub make_ice_cream_sundae { - B - + B my $dessert = get_ice_cream( $args{ice_cream} ); + ... } @@ -130,8 +130,8 @@ their phone extensions: =end programlisting -If you want to sort this list by names alphabetically, you must sort the hash -by its values, not its keys. Getting the values sorted correctly is easy: +To sort this list by name alphabetically, you must sort the hash by its values, +not its keys. Getting the values sorted correctly is easy: =begin programlisting @@ -140,9 +140,9 @@ by its values, not its keys. Getting the values sorted correctly is easy: =end programlisting ... but you need an extra step to preserve the association of names and -extensions, unless you use the Schwartzian transform. First, convert the hash -into a list of data structures which contain the vital information in sortable -fashion--in this case, two-element anonymous arrays: +extensions, hence the Schwartzian transform. First, convert the hash into a +list of data structures which is easy to sort--in this case, two-element +anonymous arrays: =begin programlisting @@ -151,13 +151,6 @@ fashion--in this case, two-element anonymous arrays: =end programlisting -=begin tip Know Your Data - -Reversing the hash I would work if no one had the same name. This -particular data set presents no such problem, but code defensively. - -=end tip - C takes the list of anonymous arrays and compares their second elements (the names) as strings: @@ -181,6 +174,13 @@ block must return -1. If both values are sufficiently equal in the sorting terms, the block must return 0. Finally, if C<$a> should come after C<$b> in the results, the block should return 1. Any other return values are errors. +=begin tip Know Your Data + +Reversing the hash I would work if no one had the same name. This +particular data set presents no such problem, but code defensively. + +=end tip + X> X<< operators; C<< <=> >> >> diff --git a/sections/implicit_ideas.pod b/sections/implicit_ideas.pod index fb8c79ec..d1a30dca 100644 --- a/sections/implicit_ideas.pod +++ b/sections/implicit_ideas.pod @@ -22,21 +22,31 @@ contents of C<$_> in the absence of an explicit variable. You can still use C<$_> as the variable, but it's often unnecessary. X> +X> +X> +X> +X> +X> +X> -For example, the C builtin removes any trailing newline sequence from -the given stringN and C<$/> for more precise details of its behavior.>: +Many of Perl's scalar operators (including C, C, C, C, +C, and C) work on the default scalar variable if you do not +provide an alternative. For example, the C builtin removes any trailing +newline sequence from its operandN and C<$/> for more +precise details of its behavior.>: =begin programlisting my $uncle = "Bob\n"; - say "'$uncle'"; chomp $uncle; say "'$uncle'"; =end programlisting -Without an explicit variable, C removes the trailing newline sequence -from C<$_>. These two lines of code are equivalent: +C<$_> has the same function in Perl as the pronoun I in English. Without an +explicit variable, C removes the trailing newline sequence from C<$_>. +Perl understands what you mean when you say "C"; Perl will always chomp +I, so these two lines of code are equivalent: =begin programlisting @@ -45,10 +55,6 @@ from C<$_>. These two lines of code are equivalent: =end programlisting -C<$_> has the same function in Perl as the pronoun I in English. Read the -first line as "C I" and the second as "C". Perl understands -what you mean when you say "C"; Perl will always chomp I. - X> X> @@ -58,8 +64,7 @@ arguments: =begin programlisting print; # prints $_ to the current filehandle - say; # prints $_ to the current filehandle, - # with a trailing newline + say; # prints "$_\n" to the current filehandle =end programlisting @@ -82,17 +87,6 @@ substitute, and transliterate: =end programlisting -X> -X> -X> -X> -X> -X> - -Many of Perl's scalar operators (including C, C, C, C, -C, and C) work on the default scalar variable if you do not -provide an alternative. - X> Perl's looping directives (L) default to using C<$_> as the diff --git a/sections/modules.pod b/sections/modules.pod index ab34df7e..c9a31836 100644 --- a/sections/modules.pod +++ b/sections/modules.pod @@ -55,7 +55,12 @@ X pragma> X> When you load a module with C, Perl loads it from disk, then calls its -C method, passing any arguments you provided: +C method, passing any arguments you provided. By convention, a +module's C method takes a list of names and exports functions and +other symbols into the calling namespace. This is merely convention; a module +may decline to provide an C, or its C may perform other +behaviors. Pragmas (L) such as C use arguments to change the +behavior of the calling lexical scope instead of exporting symbols: =begin programlisting @@ -70,13 +75,6 @@ C method, passing any arguments you provided: =end programlisting -By convention, a module's C method takes a list of names and exports -functions and other symbols into the calling namespace. This is merely -convention; a module may decline to provide an C, or its C -may perform other behaviors. Pragmas (L) such as C use -arguments to change the behavior of the calling lexical scope instead of -exporting symbols. - X> X @@ -86,21 +84,19 @@ through C: =begin programlisting - # no symbolic references - # variable declaration required - # no barewords use strict; + # no symbolic references or barewords + # variable declaration required { - # symbolic references allowed - # variable declaration still required - # barewords still prohibited no strict 'refs'; + # symbolic references allowed + # strict 'subs' and 'vars' still in effect } =end programlisting -Both C and C take effect during compilation: +Both C and C take effect during compilation, such that: =begin programlisting @@ -142,10 +138,6 @@ Similarly: ... including the C of the module. -You I call C and C directly, though outside of a -C block it makes little sense to do so; after compilation has completed, -the effects of C or C may have little effect. - =begin tip Missing Methods Never Missed If C or C does not exist in the module, Perl will not @@ -153,6 +145,10 @@ give an error message. They are truly optional. =end tip +You I call C and C directly, though outside of a +C block it makes little sense to do so; after compilation has completed, +the effects of C or C may have little effect. + X X @@ -193,12 +189,10 @@ functions usable throughout the system: use Exporter 'import'; - our @EXPORT_OK = qw( round_number translate screech ); + our @EXPORT_OK = qw( round translate screech ); ... - 1; - =end programlisting Any other code now can use this module and, optionally, import any or all of diff --git a/sections/nested_data_structures.pod b/sections/nested_data_structures.pod index 020d0ef7..9416601e 100644 --- a/sections/nested_data_structures.pod +++ b/sections/nested_data_structures.pod @@ -10,28 +10,24 @@ you to access aggregate data types through special scalars. Nested data structures in Perl, such as an array of arrays or a hash of hashes, are possible through the use of references. -=head2 Declaring Nested Data Structures - Use the anonymous reference declaration syntax to declare a nested data structure: =begin programlisting - my @famous_triplets = - ( + my @famous_triplets = ( [qw( eenie miney moe )], [qw( huey dewey louie )], [qw( duck duck goose )], ); - my %meals = - ( + my %meals = ( breakfast => { entree => 'eggs', side => 'hash browns' }, lunch => { entree => 'panini', - side => 'apple' }, + side => 'apple' }, dinner => { entree => 'steak', - side => 'avocado salad' }, + side => 'avocado salad' }, ); =end programlisting @@ -43,8 +39,6 @@ elements to the list. =end tip -=head2 Accessing Nested Data Structures - Use Perl's reference syntax to access elements in nested data structures. The sigil denotes the amount of data to retrieve, and the dereferencing arrow indicates that the value of one portion of the data structure is a reference: @@ -57,22 +51,17 @@ indicates that the value of one portion of the data structure is a reference: =end programlisting The only way to nest a multi-level data structure is through references, so the -arrow is superfluous. You may omit it for clarity: +arrow is superfluous. You may omit it for clarity, except for invoking function +references: =begin programlisting - my $last_nephew = $famous_triplets[1][2]; - my $breaky_side = $meals{breakfast}{side}; + my $nephew = $famous_triplets[1][2]; + my $meal = $meals{breakfast}{side}; + $actions{financial}{buy_food}->( $nephew, $meal ); =end programlisting -=begin tip Save Your Arrows for Functions - -The arrow invocation syntax is clearest only in the case of invoking a function -reference stored in a nested data structure. - -=end tip - Use disambiguation blocks to access components of nested data structures as if they were first-class arrays or hashes: @@ -114,8 +103,6 @@ intermediate reference: =end programlisting -... though always keep clarity in mind. - C, the data structures cookbook, gives copious examples of how to use Perl's various data structures. @@ -124,9 +111,8 @@ to use Perl's various data structures. Z X -Perl's expressivity extends to nested data structures. When you attempt to -write to a component of a nested data structure, Perl will create the path -through the data structure to the destination as necessary: +When you attempt to write to a component of a nested data structure, Perl will +create the path through the data structure to the destination as necessary: =begin programlisting @@ -139,12 +125,12 @@ After the second line of code, this array of arrays of arrays of arrays contains an array reference in an array reference in an array reference in an array reference. Each array reference contains one element. Similarly, treating an undefined value as if it were a hash reference in a nested data structure -will create intermediary hashes: +will make it so: =begin programlisting my %hohoh; - $hohoh{Robot}{Santa}{Claus} = 'mostly harmful'; + $hohoh{Robot}{Santa} = 'mostly harmful'; =end programlisting diff --git a/sections/overloading.pod b/sections/overloading.pod index c6ed7b71..b923d3a5 100644 --- a/sections/overloading.pod +++ b/sections/overloading.pod @@ -29,33 +29,32 @@ X pragma> X> The C pragma allows you to associate a function with an operation you -can overload. A C class which overloads boolean evaluation might -resemble: +can overload by passing argument pairs, where the key names the type of +overload and the value is a function reference to call for that operation. A +C class which overloads boolean evaluation so that it always evaluates to +a false value might resemble: =begin programlisting - package Null; + package Null + { + use overload 'bool' => sub { 0 }; - use overload 'bool' => sub { 0 }; + ... + } =end programlisting -In all boolean contexts, every instance of this class will evaluate to a false -value. - -The arguments to the C pragma are pairs where the key describes the -type of overload and the value is a function reference to call in place of -Perl's default behavior for that object. - It's easy to add a stringification: =begin programlisting - package Null; - - use overload - 'bool' => sub { 0 }, - B<< '""' => sub { '(null)' }; >> + package Null + { + use overload + 'bool' => sub { 0 }, + B<< '""' => sub { '(null)' }; >> + } =end programlisting @@ -72,13 +71,14 @@ use the provided overloads as fallbacks where possible: =begin programlisting - package Null; - - use overload - 'bool' => sub { 0 }, - '""' => sub { '(null)' }, - B<< '0+' => sub { 0 }, >> - B<< fallback => 1; >> + package Null + { + use overload + 'bool' => sub { 0 }, + '""' => sub { '(null)' }, + B<< '0+' => sub { 0 }, >> + B<< fallback => 1; >> + } =end programlisting @@ -105,13 +105,14 @@ hard-coding a function reference: =begin programlisting - package Null; - - use overload - 'bool' => 'get_bool', - '""' => 'get_string', - '0+' => 'get_num', - fallback => 1; + package Null + { + use overload + 'bool' => 'get_bool', + '""' => 'get_string', + '0+' => 'get_num', + fallback => 1; + } =end programlisting diff --git a/sections/packages.pod b/sections/packages.pod index 53b0621c..48e8880b 100644 --- a/sections/packages.pod +++ b/sections/packages.pod @@ -59,13 +59,12 @@ programs, and even F<.pm> files. X X> -Besides a name, a package has a version and three implicit methods, -C, C (L), and C. - -C returns the package's version number. This number is a series of -numbers contained in a package global named C<$VERSION>. By rough convention, -versions tend to be a series of integers separated by dots, as in C<1.23> or -C<1.1.10>, where each segment is an integer. +Besides a name, a package has a version and three implicit methods, C +(L), C, and C. C returns the +package's version number. This number is a series of numbers contained in a +package global named C<$VERSION>. By rough convention, versions tend to be a +series of integers separated by dots, as in C<1.23> or C<1.1.10>, where each +segment is an integer. X diff --git a/sections/pragmas.pod b/sections/pragmas.pod index 19d54adc..22e60d21 100644 --- a/sections/pragmas.pod +++ b/sections/pragmas.pod @@ -69,38 +69,42 @@ behavior: X X> -Pragmas have lexical effects, and sometimes you need to I all or part -of those effects within a further nested lexical scope. The C builtin -performs an unimport (L), which with well-behaved pragmas undoes -their effects. - -For example, to disable the protection of C when you need to do -something symbolic: +Sometimes you need to I all or part of those effects within a further +nested lexical scope. The C builtin performs an unimport (L), +which undoes the effects of well-behaved pragmas. For example, to disable the +protection of C when you need to do something symbolic: =begin programlisting - use strict; + use Modern::Perl; + # or use strict; { - # get ready to manipulate the symbol table no strict 'refs'; - ... + # manipulate the symbol table here } =end programlisting -=head2 Useful Core Pragmas +=head2 Useful Pragmas + +X> +X + +Perl 5.10.0 added the ability to write your own lexical pragmas in pure Perl +code. C explains how to do so, while the explanation of +C<$^H> in C explains how the feature works. X -Perl 5 includes several useful core pragmas: +Even before 5.10, Perl 5 included several useful core pragmas. X> =over 4 =item * the C pragma enables compiler checking of symbolic references, -bareword use, and variable declaration +bareword use, and variable declaration. X> @@ -110,22 +114,22 @@ unintended, and awkward behaviors. X> =item * the C pragma forces the parser to interpret the source code with -UTF-8 encoding +UTF-8 encoding. X> =item * the C pragma enables automatic error checking of system calls -and builtins +and builtins. X> =item * the C pragma allows you to create compile-time constant -values (see the CPAN's C for an alternative) +values (see the CPAN's C for an alternative). X> =item * the C pragma allows you to declare package global variables, such -as C<$VERSION> or C<@ISA> (L) +as C<$VERSION> or C<@ISA> (L). X> @@ -135,16 +139,13 @@ features of Perl 5 individually. Where C enables all of the Perl This pragma is more useful to I individual features in a lexical scope. -=back +X> -X> -X +=item * the C pragma demonstrates how to write a pragma. -Perl 5.10.0 added the ability to write your own lexical pragmas in pure Perl -code. C explains how to do so, while the explanation of -C<$^H> in C explains how the feature works. +=back -The CPAN has begun to gather useful pragmas. Some of the most useful are: +The CPAN has begun to gather non-core pragmas: X> X> diff --git a/sections/references.pod b/sections/references.pod index 2ab2a3ea..67facc79 100644 --- a/sections/references.pod +++ b/sections/references.pod @@ -300,7 +300,7 @@ sigil C<%>: =end programlisting Access individual values of the hash (to store, delete, check the existence of, -or retrieve) by using the dereferencing arrow: +or retrieve) by using the dereferencing arrow or double sigils: =begin programlisting @@ -308,17 +308,11 @@ or retrieve) by using the dereferencing arrow: { my $color = shift; return B<< $colors_ref->{$color} >>; + # or return B<< $$colors_ref{$color} >>; } =end programlisting -=begin tip Doubling Sigils Redux - -As with array references, you may eschew the dereferencing arrow for another -prefixed scalar sigil, such as C<$$colors_ref{$color}>. - -=end tip - Use the array sigil (C<@>) and disambiguation braces to slice a hash reference: =begin programlisting @@ -504,32 +498,25 @@ simple as: =end programlisting -In 5.12, you must write C before this will work. Before 5.12, -these objects were instances of C, so you had to C that -instead. - -You may see old code which takes references to typeglobs, such as: +You must C in 5.12 to enable this and C in 5.10 +and earlier. Even older code may take references to typeglobs: =begin programlisting - my $fh = do - { - local *FH; - open FH, "> $file" - or die "Can't write to '$file': $!\n"; - B<\*FH>; - }; + local *FH; + open FH, "> $file" or die "Can't write '$file': $!"; + my $fh = B<\*FH>; =end programlisting -This idiom predates lexical filehandles, introduced as part of Perl 5.6.0 in -March 2000. You may still use the reference operator on typeglobs to take -references to package-global filehandles such as C, C, -C, or C--but these are all global names anyhow. +This idiom predates lexical filehandles (introduced with Perl 5.6.0 in March +2000). You may still use the reference operator on typeglobs to take references +to package-global filehandles such as C, C, C, or +C--but these are all global names anyhow. Prefer lexical filehandles when possible. With the benefit of explicit scoping, lexical filehandles allow you to manage the lifespan of filehandles as a -feature of how Perl 5 manages memory. +feature of Perl 5's memory management. =head2 Reference Counts @@ -549,18 +536,15 @@ does Perl know when it's safe to close the file opened in this inner scope: =begin programlisting - sub show_off_scope - { - say 'file not open'; - - { - open my $fh, '>', 'inner_scope.txt'; - $fh->say( 'file open here' ); - } + say 'file not open'; - say 'file closed here'; + { + open my $fh, '>', 'inner_scope.txt'; + $fh->say( 'file open here' ); } + say 'file closed here'; + =end programlisting Within the inner block in the example, there's one C<$fh>. (Multiple lines in diff --git a/sections/regular_expressions.pod b/sections/regular_expressions.pod index a95642ac..5b68d5dd 100644 --- a/sections/regular_expressions.pod +++ b/sections/regular_expressions.pod @@ -358,7 +358,8 @@ X Perl interprets several characters in regular expressions as I, characters represent something other than their literal interpretation. -Metacharacters give regex wielders power far beyond mere substring matches. +Metacharacters give regex wielders power far beyond mere substring matches. The +regex engine treats all metacharacters as atoms. X> X; anything but newline regex metacharacter> @@ -427,12 +428,14 @@ X; non-digit regex metacharacter> X; non-whitespace regex metacharacter> X; non-alphanumeric regex metacharacter> +=begin tip Negated Metacharacters + These metacharacters have negated forms. Use C<\W> to match any character I a word character. Use C<\D> to match a non-digit character. Use C<\S> to match anything but whitespace. Use C<\B> to match anywhere except a word boundary. -The regex engine treats all metacharacters as atoms. +=end tip =head1 Character Classes @@ -560,11 +563,12 @@ X> Parentheses enclose the capture. The C<< ?< name > >> construct names this particular capture and must immediately follow the left parenthesis. The -remainder of the capture is a regular expression. When a match against the -enclosing pattern succeeds, Perl stores the portion of the string which matches -the enclosed pattern in the magic variable C<%+>. In this hash, the key is the -name of the capture and the value is the appropriate portion of the matched -string. +remainder of the capture is a regular expression. + +When a match against the enclosing pattern succeeds, Perl stores the portion of +the string which matches the enclosed pattern in the magic variable C<%+>. In +this hash, the key is the name of the capture and the value is the appropriate +portion of the matched string. =head2 Numbered Captures @@ -597,17 +601,11 @@ second into C<$2>, and so on. While the syntax for named captures is longer than for numbered captures, it provides additional clarity. Counting left parentheses is tedious work, and combining regexes which each contain numbered captures is far too difficult. -Named captures improve regex maintainability. - -=begin tip Safer Capture Composition +Named captures improve regex maintainability--though name collisions are +possible, they're relatively infrequent. Minimize the risk by using named +captures only in top-level regexes. -Named captures I produce name collisions, though far less frequent than -number collisions. To avoid this, use named captures only in top-level regexes. - -=end tip - -In list context, a regex match against a string returns a list of all captured -substrings: +In list context, a regex match returns a list of captured substrings: =begin programlisting @@ -1002,22 +1000,17 @@ whitespace and comments. The results are often much more readable: my $attr_re = qr{ \A # start of line - # miscellany (?: [;\n\s]* # spaces and semicolons (?:/\*.*?\*/)? # C comments )* - # attribute marker ATTR - # type \s+ ( U?INTVAL | FLOATVAL | STRING\s+\* - | PMC\s+\* - | \w* ) }x; @@ -1072,22 +1065,20 @@ X The C modifier allows you to write arbitrary Perl 5 code on the right side of a substitution operation. If the match succeeds, the regex engine will run the code, using its return value as the substitution value. The earlier global -substitution example could be more robust about replacing some or all of an -unfortunate protagonist's name with: +substitution example could be simpler with code like: =begin programlisting # appease the Mitchell estate - my $contents = slurp( $file ); - $contents =~ s{Scarlett( O'Hara)?} - { - 'Mauve' . defined $1 - ? ' Midway' - : '' - }ge; + $sequel =~ s{Scarlett( O'Hara)?} + { + 'Mauve' . defined $1 + ? ' Midway' + : '' + }ge; =end programlisting Each additional occurrence of the C modifier will cause another evaluation -of the result of the expression, though only Perl golfers tend to use C or -anything more complex. +of the result of the expression, though only Perl golfers use anything beyond +C. diff --git a/sections/scope.pod b/sections/scope.pod index 79ad72e6..bd385c83 100644 --- a/sections/scope.pod +++ b/sections/scope.pod @@ -70,7 +70,8 @@ X X Declaring a lexical in an inner scope with the same name as a lexical in an -outer scope hides, or I, the outer lexical: +outer scope hides, or I, the outer lexical within the inner scope. +This is often what you want: =begin programlisting @@ -85,11 +86,6 @@ outer scope hides, or I, the outer lexical: =end programlisting -This program prints C and then CN, even though redeclaring a lexical variable with the same name and -type I produces a warning message. Shadowing a -lexical is a feature of encapsulation. - =begin tip Name Collisions Lexical shadowing can happen by accident. Limit the scope of variables and the @@ -97,6 +93,11 @@ nesting of scopes to lessen your risk. =end tip +This program prints C and then CN, even though redeclaring a lexical variable with the same name and +type I produces a warning message. Shadowing a +lexical is a feature of encapsulation. + Some lexical declarations have subtleties, such as a lexical variable used as the iterator variable of a C loop. Its declaration comes outside of the block, but its scope is that I the loop block: @@ -139,7 +140,7 @@ within its block: Functions--named and anonymous--provide lexical scoping to their bodies. This facilitates closures (L). -=head3 Our Scope +=head2 Our Scope Z X> diff --git a/sections/smart_match.pod b/sections/smart_match.pod index f99a4f00..ca90ef23 100644 --- a/sections/smart_match.pod +++ b/sections/smart_match.pod @@ -9,9 +9,9 @@ X> X> The smart match operator, C<~~>, compares two operands and returns a true value -if they match each other. The fuzziness of the definition demonstrates the -smartness of the operator: the type of comparison depends on the type of both -operands. C (L) performs an implicit smart match. +if they match. The fuzziness of the definition demonstrates the smartness of +the operator: the type of comparison depends on the type of both operands. +C (L) performs an implicit smart match. X> X; smart match operator> @@ -30,83 +30,54 @@ with a numeric component, the comparison will use numeric equality. If the right operand is a regex, the comparison will use a grep or a pattern match. If the right operand is an array, the comparison will perform a grep or a recursive smart match. If the right operand is a hash, the comparison will -check the existence of one or more keys. +check the existence of one or more keys. A large and intimidating chart in +C gives far more details about all the comparisons smart match +can perform. -For example: +A serious proposal for 5.16 suggests simplifying smart match substantially. The +more complex your operands, the more likely you are to receive confusing +results. Avoid comparing objects and stick to simple operations between two +scalars or one scalar and one aggregate for the best results. + +With that said, smart match can be useful: =begin programlisting - # scalar numeric comparison - my $x = 10; - my $y = 20; + my ($x, $y) = (10, 20); say 'Not equal numerically' unless $x ~~ $y; - # scalar numeric-ish comparison - my $x = 10; - my $y = '10 little endians'; - say 'Equal numeric-ishally' if $x ~~ $y; - -=end programlisting + my $z = '10 little endians'; + say 'Equal numeric-ishally' if $x ~~ $z; -... or: - -=begin programlisting + # regular expression match + my $needle = qr/needle/; - my $needlepat = qr/needle/; + say 'Pattern match' if 'needle' ~~ $needle; - say 'Pattern match' - if $needle ~~ $needlepat; + say 'Grep through array' if @haystack ~~ $needle; - say 'Grep through array' - if @haystack ~~ $needlepat; + say 'Grep through hash keys' if %hayhash ~~ $needle; - say 'Grep through hash keys' - if %hayhash ~~ $needlepat; - -=end programlisting - -... or: - -=begin programlisting - - say 'Grep through array' - if $needlepat ~~ @haystack; + say 'Grep through array' if $needle ~~ @haystack; say 'Array elements exist as hash keys' if %hayhash ~~ @haystack; - say 'Array elements smart match' - if @strawstack ~~ @haystack; - -=end programlisting - -.... or: - -=begin programlisting + say 'Smart match elements' if @straw ~~ @haystack; - say 'Grep through hash keys' - if $needlepat ~~ %hayhash; + say 'Grep through hash keys' if $needle ~~ %hayhash; say 'Array elements exist as hash keys' - if @haystack ~~ %hayhach; + if @haystack ~~ %hayhash; - say 'Hash keys identical' - if %hayhash ~~ %haymap; + say 'Hash keys identical' if %hayhash ~~ %haymap; =end programlisting -These comparisons work correctly if one operand is a I to the given -data type. For example: +Smart match works even if one operand is a I to the given data type: =begin programlisting say 'Hash keys identical' if %hayhash ~~ \%hayhash; =end programlisting - -A large and intimidating chart in C gives far more details -about all the comparisons smart match can perform. A serious proposal for 5.16 -suggests simplifying smart match substantially. The more complex your operands, -the more likely the results will confuse the readers of your program. If you -avoid comparing objects and stick to simple operations with scalars or one -scalar and one aggregate, you will have better results. diff --git a/sections/state.pod b/sections/state.pod index 12941f31..9d089062 100644 --- a/sections/state.pod +++ b/sections/state.pod @@ -29,25 +29,21 @@ This idiom works well for cases where external code should be able to change internal state, but it's clunkier when only one function needs to manage that state. -Suppose that you want to count the number of customers at your ice cream -parlor. Every hundredth person gets free sprinkles: +Suppose every hundredth person at your ice cream parlor gets free sprinkles: =begin programlisting - { - my $cust_count = 0; + my $cust_count = 0; - sub serve_customer - { - $cust_count++; + sub serve_customer + { + $cust_count++; - my $order = shift; + my $order = shift; - add_sprinkles($order) - if ($cust_count % 100 == 0); + add_sprinkles($order) if $cust_count % 100 == 0; - ... - } + ... } =end programlisting diff --git a/sections/testing.pod b/sections/testing.pod index 86a95291..b2988d69 100644 --- a/sections/testing.pod +++ b/sections/testing.pod @@ -25,7 +25,7 @@ describes the test's purpose: =begin programlisting ok( 1, 'the number one should be true' ); - ok( 0, '... and the number zero should not' ); + ok( 0, '... and zero should not' ); ok( '', 'the empty string should be false' ); ok( '!', '... and a non-empty string should not' ); @@ -64,7 +64,7 @@ individual assertions you plan to run: use Test::More tests => 4; ok( 1, 'the number one should be true' ); - ok( 0, '... and the number zero should not' ); + ok( 0, '... and zero should not' ); ok( '', 'the empty string should be false' ); ok( '!', '... and a non-empty string should not' ); @@ -86,8 +86,8 @@ output: =begin screen ok 1 - the number one should be true - not ok 2 - ... and the number zero should not - # Failed test '... and the number zero should not' + not ok 2 - ... and zero should not + # Failed test '... and zero should not' # at truth_values.t line 4. not ok 3 - the empty string should be false # Failed test 'the empty string should be false' @@ -120,7 +120,7 @@ and displays only the most pertinent information: $ B truth_values.t .. 1/? - # Failed test '... and the number zero should not' + # Failed test '... and zero should not' # at truth_values.t line 4. # Failed test 'the empty string should be false' @@ -144,8 +144,8 @@ boolean coercion (L): =begin programlisting - ok( B 0, '... and the number zero should not' ); - ok( B '', 'the empty string should be false' ); + ok( B 0, '... and zero should not' ); + ok( B '', 'the empty string should be false' ); =end programlisting @@ -377,9 +377,10 @@ exceptions appropriately. You may also encounter C. =item * C and C allow you to test difficult interfaces by I (emulating but producing different results). -=item * C allows you to test web applications. Both -C, C, and C can do -so without requiring the use of a live web server. +=item * C helps test web applications, while +C, C, and the subclass +C can do so without using an external live web +server. =item * C provides functions to test the use and abuse of databases. C helps test schemas built with C. @@ -387,9 +388,9 @@ databases. C helps test schemas built with C. =item * C offers an alternate mechanism for organizing test suites. It allows you to create classes in which specific methods group tests. You can inherit from test classes just as your code classes inherit from each -other. This is an excellent way to reduce duplication in test suites. See the -C series written by Curtis Poe at -U. +other. This is an excellent way to reduce duplication in test suites. See +Curtis Poe's excellent C +seriesN>. The newer C distribution offers similar possibilities through the use of Moose (L). diff --git a/sections/universal.pod b/sections/universal.pod index bf5731ba..3f0dc46c 100644 --- a/sections/universal.pod +++ b/sections/universal.pod @@ -92,10 +92,7 @@ reference to the method with: X> X> -In an application which uses plugins, use C to test if a package -implements a specific function. - -X> +Use C to test if a package implements a specific function or method: =begin programlisting @@ -104,7 +101,7 @@ X> die "Couldn't load $module!" unless load_class( $module ); - if (my $register = $module->can( 'register' ) + if (my $register = $module->can( 'register' )) { $register->(); } @@ -113,15 +110,16 @@ X> =begin tip C +X> X> -The CPAN module C is a great way to manage plugins. +While the CPAN module C simplifies the work of loading classes by +name--rather than doing the C dance--C takes most +of the work out of building and managing plugin systems. Get to know both +distributions. =end tip -Override C in your own code if you use C -(L). - =head2 The VERSION() Method X> diff --git a/sections/values.pod b/sections/values.pod index 6bb0b73c..76f1c50f 100644 --- a/sections/values.pod +++ b/sections/values.pod @@ -798,10 +798,7 @@ a single element) or list context (for a slice): my @array_slice = @list_slice[context()]; my $array_index = $array_slice[context()]; - # say imposes list context - say context(); - - # void context is obvious - context(); + say context(); # list context + context(); # void context =end programlisting