Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Edited idioms chapter.

  • Loading branch information...
commit f660f6435365442f814250e27e3e49a59e6cdb0f 1 parent d328880
@chromatic chromatic authored
View
96 sections/autoload.pod
@@ -1,15 +1,13 @@
-=head3 C<AUTOLOAD>
+=head2 C<AUTOLOAD>
Z<autoload>
-In line with Perl's pragmatic approach, you do not have to define every
-function and method anyone will ever call with a time-consuming (and
-potentially buggy) copy-and-paste approach. Perl provides a mechanism by which
-you can intercept calls to functions and methods which do not yet exist. You
-can use this to define only what users of your code actually need or to provide
-interesting error messages and warnings.
+You do not have to define I<every> function and method anyone will ever call.
+Perl provides a mechanism by which you can intercept calls to functions and
+methods which do not yet exist. You can use this to define only those
+functions you need, or to provide interesting error messages and warnings.
-Consider this program:
+Consider the program:
=begin programlisting
@@ -30,7 +28,7 @@ subroutine C<bake_pie()>. Now add a function called C<AUTOLOAD()>:
=end programlisting
-Nothing (obvious) happens. The error has gone away. The presence of a
+Nothing obvious will happen, except that there is no error. The presence of a
function named C<AUTOLOAD()> in a package tells Perl to call that function
whenever normal dispatch for that function or method fails. Change the
C<AUTOLAOD()> to emit a message to demonstrate this:
@@ -41,7 +39,7 @@ C<AUTOLAOD()> to emit a message to demonstrate this:
=end programlisting
-=head4 Basic Features of C<AUTOLOAD>
+=head3 Basic Features of C<AUTOLOAD>
The C<AUTOLOAD()> function receives the arguments passed to the undefined
function in C<@_> directly. You may manipulate these arguments as you like:
@@ -77,8 +75,8 @@ variable C<$AUTOLOAD>:
The C<our> declaration (L<our>) scopes this variable to the body of
C<AUTOLOAD()>. The variable contains the fully-qualified name of the undefined
-function as a string. In this case, the function is C<main::bake_pie>. A
-common idiom is to remove the package name:
+function. In this case, the function is C<main::bake_pie>. A common idiom is
+to remove the package name:
=begin programlisting
@@ -106,7 +104,7 @@ Finally, whatever C<AUTOLOAD()> returns, the original call receives:
So far, these examples have merely intercepted calls to undefined functions.
You have other options.
-=head4 Redispatching Methods in C<AUTOLOAD()>
+=head3 Redispatching Methods in C<AUTOLOAD()>
X<AUTOLOAD; redispatch>
X<AUTOLOAD; delegation>
@@ -145,14 +143,14 @@ it dereferences the proxied object from a blessed scalar reference, extracts
the name of the undefined method, then invokes the method of that name on the
proxied object, passing the given arguments.
-=head4 Generating Code in C<AUTOLOAD()>
+=head3 Generating Code in C<AUTOLOAD()>
X<AUTOLOAD; code installation>
-That double-dispatch trick is useful, but it represents double-dispatch. Every
+That double-dispatch trick is useful, but it is slower than necessary. Every
method call on the proxy must go through normal dispatch and fail, then end up
-in C<AUTOLOAD()>. Fortunately, you can install new methods into the proxy
-class at runtime:
+in C<AUTOLOAD()>. You can instead install new methods into the proxy class as
+the program needs them:
=begin programlisting
@@ -176,23 +174,12 @@ class at runtime:
=end programlisting
-Instead of executing the body of the previous C<AUTOLOAD()> directly, now it
-becomes an anonymous function. The code creates a closure (L<closures>) bound
-over the I<name> of the undefined method. Then it installs that closure in the
-appropriate symbol table so that all subsequent calls to that method will go
-through the closure again as part of normal dispatch, not C<AUTOLOAD()>.
-Finally, it invokes the method directly and returns the result.
-
-=begin sidebar
-
-You can achieve something similar by building a string of code and using
-C<eval()> to compile it directly, but the closure approach is safer and
-simpler--no quoting issues to worry about--and it uses less memory. Perl 5
-compiles the body of closure I<once>, but binds its closed-over lexicals on
-every invocation of C<AUTOLOAD()>. The C<eval()> approach recompiles a new
-closure body for every execution.
-
-=end sidebar
+The body of the previous C<AUTOLOAD()> has become an anonymous function. The
+code creates a closure (L<closures>) bound over the I<name> of the undefined
+method. Then it installs that closure in the appropriate symbol table so that
+all subsequent dispatch to that method will find the created closure and will
+avoid C<AUTOLOAD()>. Finally, it invokes the method directly and returns the
+result.
Though this approach is cleaner and almost always more transparent than
handling the behavior directly in C<AUTOLOAD()>, the code I<called> by
@@ -205,9 +192,9 @@ of I<how> an object provides a method to leak out into the wider world.
X<tailcall>
X<goto; tailcall>
-Another idiom is to use a I<tailcall> to replace the current invocation of
-C<AUTOLOAD()> from C<caller()>'s memory with a call to the destination method.
-The syntax for a tailcall is C<goto &$func_ref>:
+Another idiom is to use a tailcall (L<tail_calls>) to I<replace> the current
+invocation of C<AUTOLOAD()> from C<caller()>'s memory with a call to the
+destination method:
=begin programlisting
@@ -228,7 +215,7 @@ This has the same effect as invoking C<$method> directly, except that
C<AUTOLOAD()> will no longer appear in the list of calls available from
C<caller()>.
-=head4 Drawbacks of C<AUTOLOAD>
+=head3 Drawbacks of C<AUTOLOAD>
Z<autoload_drawbacks>
@@ -239,10 +226,9 @@ X<subs>
X<pragmas; subs>
X<functions; predeclaration>
-Of course, a mechanism this powerful must have some subtleties. C<AUTOLOAD()>
-can be a useful tool in certain circumstances, but it can be difficult to use
-properly. Consider other techniques, such as using helper modules like
-C<Moose> if you need to abstract away boilerplate code.
+C<AUTOLOAD()> can be a useful tool in certain circumstances, but it can be
+difficult to use properly. Consider other techniques, such as C<Moose> and
+other abstractions, instead.
The naI<iuml>ve approach to generating methods at runtime means that the
C<can()> method will not report the right information about the capabilities of
@@ -290,8 +276,8 @@ You can also provide your own C<can()> to generate the appropriate functions:
=end programlisting
Depending on the complexity of your needs, you may find it easier to maintain a
-data structure such as a hash, scoped lexically to the package, which contains
-acceptable names of methods to generate.
+data structure such as a package-scoped hash which contains acceptable names of
+methods to generate.
Be aware that certain methods you do not intend to provide may go through
C<AUTOLOAD()>. A common culprit is C<DESTROY()>, the destructor of objects.
@@ -306,12 +292,6 @@ altogether:
=end programlisting
-=for author
-
-Confirm this.
-
-=end for
-
=begin sidebar
Special methods such as C<import()>, C<unimport()>, and C<VERSION()> never go
@@ -319,7 +299,9 @@ through C<AUTOLOAD()>.
=end sidebar
-If you mix functions and methods in a single namespace which inherits from another package which provides its own C<AUTOLOAD()>, you may get a strange error message:
+If you mix functions and methods in a single namespace which inherits from
+another package which provides its own C<AUTOLOAD()>, you may get a strange
+error message:
=begin screen
@@ -327,9 +309,9 @@ If you mix functions and methods in a single namespace which inherits from anoth
=end screen
-This means that you've tried to call a function, but Perl could not find it and
-had to dispatch to an C<AUTOLOAD()> in a parent class. This is almost never
-what you intend. The problem compounds in several ways: mixing functions and
-methods in a single namespace is often a sign of a design flaw, inheritance and
-C<AUTOLOAD()> get complex very quickly, and reasoning about code when you don't
-know what methods objects can perform is difficult.
+This occurs when you try to call a function which does not exist in a package
+which inherits from a class which contains its own C<AUTOLOAD()>. This is
+almost never what you intend. The problem compounds in several ways: mixing
+functions and methods in a single namespace is often a design flaw, inheritance
+and C<AUTOLOAD()> get complex very quickly, and reasoning about code when you
+don't know what methods objects can perform is difficult.
View
4 sections/chapter_10.pod
@@ -1,7 +1,7 @@
=head1 Perl Idioms
-L<autoload>
+L<idioms>
L<globals>
-L<idioms>
+L<autoload>
View
122 sections/globals.pod
@@ -1,4 +1,4 @@
-=head3 Global Variables
+=head2 Global Variables
Z<globals>
@@ -6,30 +6,29 @@ X<super globals>
X<variables; super global>
Perl 5 provides several I<super global variables> that are truly global, not
-restricted to any specific package. C<perldoc perlvar> contains the exhaustive
-list of such variables. In practice, only a handful are useful with any
-frequency. These super globals have two drawbacks. First, they're global; any
-direct or indirect modifications may have effects on other parts of the
-program. Second, they're terse. Experienced Perl 5 programmers have memorized
-many of them. Few people have memorized all of them.
+restricted to any specific package. These super globals have two drawbacks.
+First, they're global; any direct or indirect modifications may have effects on
+other parts of the program. Second, they're terse. Experienced Perl 5
+programmers have memorized some of them. Few people have memorized all of
+them. Only a handful are ever useful. C<perldoc perlvar> contains the
+exhaustive list of such variables.
-=head4 Managing Super Globals
+=head3 Managing Super Globals
X<super globals; managing>
X<local>
The best approach to managing the global behavior of these super globals is to
-avoid using them. That's not always possible. In those cases, use C<local> in
-the smallest possible scope to constrain any modifications. You are still
-susceptible to any changes code you I<call> makes to those globals, but you
-reduce the likelihood of making surprising changes to code outside of your
-scope.
+avoid using them. When you must use them, use C<local> in the smallest
+possible scope to constrain any modifications. You are still susceptible to
+any changes code you I<call> makes to those globals, but you reduce the
+likelihood of surprising code I<outside> of your scope.
=begin sidebar
Workarounds exist for some of this global behavior, but many of these variables
-have existed since Perl 1 Perl 1 and will continue as part of Perl 5 throughout
-its lifetime. As the easy file slurping idiom (L<easy_file_slurping>)
+have existed since Perl 1 and will continue as part of Perl 5 throughout its
+lifetime. As the easy file slurping idiom (L<easy_file_slurping>)
demonstrates, this is often possible:
=begin programlisting
@@ -46,15 +45,12 @@ change the value of C<$/> within the C<do> block.
Not all cases of using super globals are this easy to guard, but this often
works.
-=for author
-
-Recheck this example.
-
-=end for
+X<eval>
+X<exceptions; catching>
Other times you need to I<read> the value of a super global and hope that no
-other code has modified it. Catching exceptions with C<eval> BLOCK can be
-susceptible to race conditionsN<< So use C<Try::Tiny> instead! >>, in that
+other code has modified it. Catching exceptions with C<eval> block can be
+susceptible to race conditionsN<< Use C<Try::Tiny> instead! >>, in that
C<DESTROY()> methods invoked on lexicals that have gone out of scope may reset
C<$@>:
@@ -68,17 +64,16 @@ C<$@>:
=end programlisting
-Copying the contents of C<$@> I<immediately> help to preserve the information
-you want.
+Copy C<$@> I<immediately> to preserve its contents.
=end sidebar
-=head4 English Names
+=head3 English Names
X<english>
-The core C<English> module provides more verbose names for the
-punctuation-heavy super globals. Import them into a namespace with:
+The core C<English> module provides verbose names for the punctuation-heavy
+super globals. Import them into a namespace with:
=begin programlisting
@@ -86,30 +81,37 @@ punctuation-heavy super globals. Import them into a namespace with:
=end programlisting
-... and subsequently you can use the verbose names documented in C<perldoc
-perlvar> within the scope of this namespace.
+Subsequently you can use the verbose names documented in C<perldoc perlvar>
+within the scope of this namespace.
=begin sidebar
-Three regex-related super globals impose a global performance penalty for
-I<all> regular expressions within a program. If you neglect to provide that
-import flag, your program will suffer the penalty even if you don't explicitly
-read from those variables. This is not the default behavior for
-backwards-compatibility concerns.
+X<$&>
+X<globals; $&>
+X<$`>
+X<globals; $`>
+X<$'>
+X<globals; $'>
+
+Three regex-related super globals (C<$&>, C<$`>, and C<$'>) impose a global
+performance penalty for I<all> regular expressions within a program. If you
+neglect to provide that import flag, your program will suffer the penalty even
+if you don't explicitly read from those variables. This is not the default
+behavior for backwards-compatibility concerns.
Modern Perl programs should use the C<@-> variable as a replacement for the
terrible three.
=end sidebar
-=head4 Useful Super Globals
+=head3 Useful Super Globals
X<super globals; useful>
Most modern Perl 5 programs can get by with using only a couple of the super
globals. Several exist for special circumstances you're unlikely to encounter.
While C<perldoc perlvar> is the canonical documentation for most of these
-variables, some are so useful or ubiquitous that they deserve special mention.
+variables, some deserve special mention.
=begin table Super Globals
@@ -132,10 +134,17 @@ variables, some are so useful or ubiquitous that they deserve special mention.
=cell C<$INPUT_RECORD_SEPARATOR>
=cell A string of zero or more characters which denotes the end of a record
-when reading line-by-line. By default, this is your platform-specific newline
-character sequence. If you undefine this value, Perl will attempt to read the
-entire file into memory. If you set this value to a I<reference> to an
-integer, Perl will try to read that many I<bytes> per record.
+when reading input a line at a time. By default, this is your
+platform-specific newline character sequence. If you undefine this value, Perl
+will attempt to read the entire file into memory. If you set this value to a
+I<reference> to an integer, Perl will try to read that many I<bytes> per
+record.
+
+=for author
+
+... or characters, in a Unicode mode?
+
+=end for
=row
@@ -155,10 +164,9 @@ which it refers.
=cell C<$OUTPUT_AUTOFLUSH>
=cell The boolean value of this variable governs whether Perl will flush
-immediately everything written to the currently selected filehandle or whether
-it will flush only when Perl's buffer is full. Unbuffered output is useful
-when writing to a pipe or socket or something which needs data immediately to
-avoid blocking.
+everything written to the currently selected filehandle immediately or only
+when Perl's buffer is full. Unbuffered output is useful when writing to a pipe
+or socket or terminal which should not block waiting for input.
=row
@@ -181,9 +189,9 @@ returns the appropriate system error string. Localize this variable before
performing a system call (implicitly or explicitly) to avoid overwriting the
appropriate value for other code elsewhere.
-Note that many places within Perl 5 itself make system calls without your
-knowledge, so the value of this variable can change unless you check or copy it
-I<immediately> after making such a call yourself.
+Many places within Perl 5 itself make system calls without your knowledge. The
+value of this variable can change out from under you, so copy it I<immediately>
+after making such a call yourself.
=row
@@ -247,16 +255,16 @@ contain.
=cell (none)
-=cell A hash mapping OS and low-level Perl signals to subroutine references
-used to handle those signals. You can trap the standard Ctrl-C interrupt by
-catching the C<INT> signal, for example. See C<perldoc perlipc> for more
-information about signals and especially safe signals.
+=cell A hash which maps OS and low-level Perl signals to subroutine references
+used to handle those signals. Trap the standard Ctrl-C interrupt by catching
+the C<INT> signal, for example. See C<perldoc perlipc> for more information
+about signals and especially safe signals.
=row
=end table
-=head4 Alternatives to Super Globals
+=head3 Alternatives to Super Globals
X<super globals; alternatives>
@@ -267,8 +275,8 @@ copying the value of C<$!> can help you avoid strange behaviors when Perl makes
implicit system calls.
You can use methods on lexical filehandles (L<lexical_filehandles>) rather than
-IO-related super globals, if you've loaded C<IO::Handle> in your program
-already. In place of C<select>ing a filehandle, then manipulating C<$|>, call
-the C<autoflush()> method on the lexical filehandle directly. Use the
-C<input_line_number()> method to get the equivalent of C<$.> for that specific
-filehandle. See the C<IO::Handle> documentation for other appropriate methods.
+IO-related super globals by C<use>ing C<IO::Handle>. In place of C<select>ing
+a filehandle, then manipulating C<$|>, call the C<autoflush()> method on the
+lexical filehandle directly. Use the C<input_line_number()> method to get the
+equivalent of C<$.> for that specific filehandle. See the C<IO::Handle>
+documentation for other appropriate methods.
View
113 sections/idioms.pod
@@ -20,9 +20,9 @@ X<objects; invocant>
X<methods; invocant>
Perl 5's object system (L<moose>) treats the invocant of a method as a mundane
-parameter. The invocant of a class method (a string containing the name of the
-class) is that method's first parameter. The invocant of an object or instance
-method, the object itself, is that method's first parameter. You are free to
+parameter. The invocant of a class method--a string containing the name of the
+class--is that method's first parameter. The invocant of an object or instance
+method--the object itself--is that method's first parameter. You are free to
use or ignore it as you see fit.
Idiomatic Perl 5 uses C<$class> as the name of the class method and C<$self>
@@ -35,6 +35,8 @@ of the invocant by default.
X<parameters; named>
X<arguments; named>
+X<signatures>
+X<MooseX::MultiMethods>
Without a module such as C<signatures> or C<MooseX::Multimethods>, Perl 5's
argument passing mechanism is simple: all arguments flatten into a single list
@@ -43,10 +45,10 @@ occasionally too simple--named parameters can be very useful at times--it does
not preclude the use of idioms to provide named parameters.
The list context evaluation and assignment of C<@_> allows you to unpack named
-parameters pairwise. Even though this function call is equivalent to passing a
-comma-separated or C<qw//>-created list, arranging the arguments as if they
-were true pairs of keys and values makes the caller-side look like the function
-supports named parameters:
+parameters as pairs in a natural and Perlish fashion. Even though this
+function call is equivalent to passing a comma-separated or C<qw//>-created
+list, arranging the arguments as if they were true pairs of keys and values
+makes the caller-side of the function appear to support named parameters:
=begin programlisting
@@ -76,11 +78,9 @@ if it were the single argument:
=begin sidebar
-I<Perl Best Practices> suggests passing a hash reference instead. This has one
-benefit of performing hash construction checking on the caller side, where it's
-most likely you'll make mistakes and another benefit of minimizing copying and
-memory use. The former benefit is compelling, if somewhat less common in
-practice.
+I<Perl Best Practices> suggests passing a hash reference instead. This allows
+Perl to check that you've constructed a valid hash on the caller side. It also
+uses slightly less memory than the other approach.
=end sidebar
@@ -99,18 +99,15 @@ parameters as you like before slurping the remainder into a hash:
=end programlisting
-Note how this idiom falls naturally out of list assignment; that makes this
-idiom Perlish.
-
=head3 The Schwartzian Transform
Z<schwartzian_transform>
People new to Perl sometimes overlook the importance of lists and list
-processing as a fundamental component of expression evaluationN<People
-explaining its importance in this fashion do not help>. Put more simply, the
-ability for Perl programmers to chain expressions which evaluate to
-variable-length lists gives them countless ways to manipulate data effectively.
+processing as a fundamental component of expression evaluation. Put more
+simply, the ability for Perl programmers to chain expressions which evaluate to
+variable-length lists provides countless opportunities to manipulate data
+effectively.
X<Schwartzian transform>
X<map; Schwartzian transform>
@@ -150,13 +147,11 @@ keys. Sorting the values of the hash in string order is easy:
=end programlisting
-... but that loses the association of names with extensions. The beauty of the
-Schwartzian transform is that it solves this problem almost trivially. All you
-have to do is transform the data before and after sorting it to preserve the
-necessary information. This is most obvious when explained in multiple steps.
-First, convert the hash into a list of data structures which contain the vital
-information in sortable fashion. In this case, converting the hash pairs into
-two-element anonymous arrays will help:
+... but that loses the association of names with extensions. Instead, use the
+Schwartzian transform to transform the data before and after sorting it to
+preserve the necessary information. First, convert the hash into a list of
+data structures which contain the vital information in sortable fashion. In
+this case, convert the hash pairs into two-element anonymous arrays:
=begin programlisting
@@ -166,12 +161,12 @@ two-element anonymous arrays will help:
=begin sidebar
-Reversing the hash I<in place> would work if no one had the same name. In this
-case, that is no problem, but defensive coding anticipates data changes.
+Reversing the hash I<in place> would work if no one had the same name. This
+particular data set presents no such problem, but code defensively.
=end sidebar
-C<sort> gets the list of anonymous arrays and can compare the second elements
+C<sort> takes the list of anonymous arrays and compares their second elements
(the names) with a stringwise comparison:
=begin programlisting
@@ -180,8 +175,8 @@ C<sort> gets the list of anonymous arrays and can compare the second elements
=end programlisting
-Given C<@sorted_pairs>, a second C<map> operation can convert the data
-structure to a more usable form:
+Given C<@sorted_pairs>, a second C<map> operation converts the data structure
+to a more usable form:
=begin programlisting
@@ -214,19 +209,19 @@ the combination:
Read the expression from right to left, in the order of evaluation. For each
key in the extensions hash, make a two-item anonymous array containing the key
and the value from the hash. Sort that list of anonymous arrays by their
-second elements, the values from the hash. Create a nicely formatted string of
-output from those sorted arrays.
+second elements, the values from the hash. Format a string of output from
+those sorted arrays.
The Schwartzian transform is this pipeline of C<map>-C<sort>-C<map> where you
transform a data structure into another form easier for sorting and then
transform it back into your preferred form for modification.
-In this case the transformation is relatively simple. Consider the case where
-calculating the right value to sort is expensive in time or memory, such as
-calculating a cryptographic hash for a large file. In that case, the
-Schwartzian transform is also useful because you can perform those expensive
-operations once (in the rightmost C<map>), compare them repeatedly from a
-de-facto cache in the C<sort>, and then remove them in the leftmost C<map>.
+This transformation is simple. Consider the case where calculating the right
+value to sort is expensive in time or memory, such as calculating a
+cryptographic hash for a large file. In that case, the Schwartzian transform
+is also useful because you can perform those expensive operations once (in the
+rightmost C<map>), compare them repeatedly from a de-facto cache in the
+C<sort>, and then remove them in the leftmost C<map>.
=head3 Easy File Slurping
@@ -235,11 +230,10 @@ Z<easy_file_slurping>
X<local; $/>
X<globals; $/>
-Perl 5's magic global variables are, tragically, truly global in many cases.
-It's all too easy to clobber their values elsewhere, unless you use C<local>
-everywhere. Yet this requirement has allowed the creation of several
-interesting idioms. For example, you can slurp files into a scalar in a single
-expression:
+Perl 5's magic global variables are truly global in many cases. It's all too
+easy to clobber their values elsewhere, unless you use C<local> everywhere.
+Yet this requirement has allowed the creation of several interesting idioms.
+For example, you can slurp files into a scalar in a single expression:
=begin programlisting
@@ -251,7 +245,7 @@ C<$/> is the input record separator. C<local>izing it sets its value to
C<undef>, pending assignment. That C<local>ization takes place I<before> the
assignment. As the value of the separator is undefined, Perl happily reads the
entire contents of the filehandle in one swoop and assigns that value to C<$/>.
-Because a C<do> BLOCK evaluates to the value of the last expression evaluated
+Because a C<do> block evaluates to the value of the last expression evaluated
within the block, this evaluates to the value of the assignment, or the
contents of the file. Even though C<$/> immediately reverts to its previous
state at the end of the block, C<$file> now contains the contents of the file.
@@ -297,7 +291,8 @@ program (with C<perl path/to/Module.pm> instead of C<use Module;>).
=begin sidebar
Checking the eighth element of the list returned from C<caller> in list context
-may be more accurate in most cases, but it's rare. This value is true if the call frame represents C<use> or C<require> and undef otherwise.
+may be more accurate in most cases, but it's rare. This value is true if the
+call frame represents C<use> or C<require> and undef otherwise.
=end sidebar
@@ -347,13 +342,10 @@ Z<postfix_parameter_validation>
Even if you don't use a CPAN module such as C<Params::Validate> or
C<MooseX::Params::Validate> to verify that the parameters your functions
receive are correct, you can still benefit from occasional checks for
-correctness. Though some people suggest to avoid the use of the C<unless>
-control flow modifier (Damian Conway's I<Perl Best Practices> is an oft-cited
-reference), it's an easy and readable way to assert your expectations at the
-beginning of a function.
+correctness. The C<unless> control flow modifier is an easy and readable way
+to assert your expectations at the beginning of a function.
-Suppose your function takes two arguments, no more and no less, and you need to
-verify this because too many people use your code incorrect. You I<could>
+Suppose your function takes two arguments, no more and no less. You I<could>
write:
=begin programlisting
@@ -400,7 +392,7 @@ X<regex; modification>
X<regex; substitution>
Many Perl 5 idioms rely on the language design where expressions evaluate to
-values. This is most obvious with an example:
+values, as in:
=begin programlisting
@@ -426,7 +418,7 @@ easy to do with a regular expression:
... where C<$first_name_rx> is a precompiled regular expression. In list
context, a successful regex match returns a list of all captures, and Perl
-assigns the first one to C<$first_name>. That's straightforward.
+assigns the first one to C<$first_name>.
Now imagine if you want to modify the name, perhaps removing all non-word
characters to create a useful username for a system account. You can write:
@@ -440,9 +432,9 @@ characters to create a useful username for a system account. You can write:
Unlike the previous example, this one reads right to left. First, assign the
value of C<$name> to C<$normalized_name>. Then, perform the transliteration on
C<$normalized_name>N<The parentheses here affect the precedence so that the
-assignment happens first.>. That is to say, the assignment expression
-evaluates to the I<variable> C<$normalized_name>. This technique works on all
-sorts of in-place modification operators:
+assignment happens first.>. The assignment expression evaluates to the
+I<variable> C<$normalized_name>. This technique works on all sorts of in-place
+modification operators:
=begin programlisting
@@ -466,10 +458,11 @@ operator, and Perl will treat both scalars as strings. To add two numbers, use
the addition operator and Perl will treat both scalars as numeric.
Sometimes you have to give Perl a hint about what you mean. Several I<unary
-coercions> exist, by which you can use and abuse Perl 5 operators to force the
-evaluation of a value a specific way.
+coercions> exist, by which you can use Perl 5 operators to force the evaluation
+of a value a specific way.
X<unary conversions; numeric>
+
To ensure that Perl treats a value as numeric, add zero:
=begin programlisting
@@ -479,6 +472,7 @@ To ensure that Perl treats a value as numeric, add zero:
=end programlisting
X<unary conversions; boolean>
+
To ensure that Perl treats a value as boolean, double negate it:
=begin programlisting
@@ -488,6 +482,7 @@ To ensure that Perl treats a value as boolean, double negate it:
=end programlisting
X<unary conversions; string>
+
To ensure that Perl treats a value as a string, concatenate it with the empty
string:
View
1  sections/scoping.pod
@@ -263,6 +263,7 @@ variables used other places in your code.
=head4 Our Scope
+Z<our>
X<our>
X<package scope>
View
2  sections/variables.pod
@@ -22,6 +22,8 @@ leading sigils.
=head3 Variable Scopes
+Z<variable_scopes>
+
X<variables; scope>
X<scope>
Please sign in to comment.
Something went wrong with that request. Please try again.