From 6d5d18826d8cafbf43df15d3871dea7bab033c12 Mon Sep 17 00:00:00 2001 From: chromatic Date: Thu, 7 Oct 2010 22:49:01 -0700 Subject: [PATCH] Applied edits from John Bokma. --- CREDITS | 3 + sections/advanced_oo.pod | 19 +++-- sections/barewords.pod | 9 ++- sections/blessed_references.pod | 8 +- sections/handling_warnings.pod | 3 +- sections/hashes.pod | 3 +- sections/missing_defaults.pod | 8 ++ sections/moose.pod | 125 +++++++++++++++++++------------- sections/reflection.pod | 9 ++- 9 files changed, 114 insertions(+), 73 deletions(-) diff --git a/CREDITS b/CREDITS index 3967e8af..976de29a 100644 --- a/CREDITS +++ b/CREDITS @@ -200,3 +200,6 @@ E: spazm@cpan.org N: Mark Hindess E: soft-cpan@temporalanomaly.com + +N: John Bokma +E: contact@johnbokma.com diff --git a/sections/advanced_oo.pod b/sections/advanced_oo.pod index af703b19..f396ff24 100644 --- a/sections/advanced_oo.pod +++ b/sections/advanced_oo.pod @@ -10,17 +10,22 @@ several principles can guide you. =head2 Favor Composition Over Inheritance -Novice OO designs often overuse inheritance. It's common to see class -hierarchies which try to model all of the behavior for entities within the -system in a single class. This adds a conceptual overhead to understanding the -system, because you have to understand the hierarchy, and it adds technical -weight to every class, because conflicting responsibilities and methods may get -in the way of necessary behaviors or future modifications. +Novice OO designs often overuse inheritance for two reasons: to reuse as much +code as possible and to exploit as much polymorphism as possible. It's common +to see class hierarchies which try to model all of the behavior for entities +within the system in a single class. This adds a conceptual overhead to +understanding the system, because you have to understand the hierarchy. It +adds technical weight to every class, because conflicting responsibilities and +methods may obstruct necessary behaviors or future modifications. + +X +X The encapsulation provided by classes offers better ways to organize code. You don't have to inherit from superclasses to provide behavior to users of objects. A C object does not have to inherit from a C -object; it can contain several C objects as instance attributes. +object (an I); it can contain 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/barewords.pod b/sections/barewords.pod index 4f947512..04fa2d16 100644 --- a/sections/barewords.pod +++ b/sections/barewords.pod @@ -27,12 +27,15 @@ Even so, barewords are permissible in several places in Perl 5 for good reason. X X +X; unary operator> Hash keys in Perl 5 are barewords. These are usually not ambiguous because their use as keys is sufficient for the parser to identify them as the equivalent of single-quoted strings. Yet be aware that attempting to evaluate -a function call or a built-in operator (such as C) to I a hash -key may not do what you expect, unless you disambiguate. +a function call or a builtin operator (such as C) to I a hash +key may not do what you expect, unless you disambiguate by providing arguments, +using function argument parentheses, or prepending unary plus to force the +evaluation of the builtin rather than its interpretation as a string: =begin programlisting @@ -42,7 +45,7 @@ key may not do what you expect, unless you disambiguate. # the value produced by shift is the key my $value = $items{B} - # unary plus is also sufficient to disambiguate + # unary plus uses the keyword shift my $value = $items{B<+>shift}; =end programlisting diff --git a/sections/blessed_references.pod b/sections/blessed_references.pod index c3426872..05e8123b 100644 --- a/sections/blessed_references.pod +++ b/sections/blessed_references.pod @@ -27,8 +27,8 @@ resolution. That sounds more complicated than it is. Though these rules explain Perl 5's underlying object system, they are somewhat more minimal in practice than may be practical, especially for larger projects. -In particular, they offer few facilities for metaprogramming (using APIs to -manipulate the program itself). +In particular, they offer few facilities for metaprogramming +(L). Moose (L) is a better choice for serious, modern Perl programs larger than a couple of hundred lines, but you will likely encounter bare-bones Perl 5 @@ -209,8 +209,8 @@ X =begin sidebar -Perl 5.10 added C to supersede the C pragma added in Perl -5.004_4. If you can't use Moose, use C. +Perl 5.10 added C to supersede the C pragma. If you can't use +Moose, use C. =end sidebar diff --git a/sections/handling_warnings.pod b/sections/handling_warnings.pod index 6edc0be0..edea45e4 100644 --- a/sections/handling_warnings.pod +++ b/sections/handling_warnings.pod @@ -66,7 +66,8 @@ C's verbose mode throughout the entire program: =end programlisting This changes all C (and C--L) calls to -include a backtrace. +include a backtrace. When you organize your code into modules (L), +use Carp instead of C or C to save debugging time. =head2 Enabling and Disabling Warnings diff --git a/sections/hashes.pod b/sections/hashes.pod index e589f80e..3eeba55a 100644 --- a/sections/hashes.pod +++ b/sections/hashes.pod @@ -108,8 +108,7 @@ function: =end programlisting The key of the hash will be C and not C. If you intend to call -the function to get the key, disambiguate your intent by making the call -explicit: +the function to get the key, make the function call explicit: =begin programlisting diff --git a/sections/missing_defaults.pod b/sections/missing_defaults.pod index e8776e86..217174f7 100644 --- a/sections/missing_defaults.pod +++ b/sections/missing_defaults.pod @@ -10,6 +10,14 @@ clean, maintainable, powerful, and succinct Perl 5 code is very different from Perl 5.000. The default behaviors sometimes get in the way; fortunately, better behaviors are available. +X + +The CPAN (L) contains many modules and pragmas designed to make your work +simpler, more correct, and more enjoyableN to start.>. As +you improve as a Perl programmer, you will have many opportunities to use (and +even to create) such code in the right circumstances. For now, use these +pragmas and modules regularly in your own code. + =head2 The strict Pragma X diff --git a/sections/moose.pod b/sections/moose.pod index 82005201..15b7016f 100644 --- a/sections/moose.pod +++ b/sections/moose.pod @@ -3,13 +3,12 @@ Z X -Moose is a more complete object system for Perl 5. It builds on the existing -Perl 5 system, and provides simpler defaults, better integration, and advanced -features from several other languages, including Smalltalk, Common Lisp, and -Perl 6. It's still worth learning the default Perl 5 object system, if only to -write very simple programs where Moose is inappropriate or to maintain legacy -code, but Moose is currently the best way to write object-oriented code in -modern Perl 5. +Moose is a powerful and complete object system for Perl 5. It builds on the +existing Perl 5 system to provide simpler defaults, better integration, and +advanced features from languages such as Smalltalk, Common Lisp, and Perl 6. +It's still worth learning the default Perl 5 object system--especially when you +have existing code to maintain--but Moose is the best way to write object +oriented code in modern Perl 5. X X @@ -18,10 +17,10 @@ X X X -I, or I, is a way of managing -programs by categorizing their components into discrete, unique entities. -These are I. In Moose terms, each object is an instance of a -I, which serves as a template to describe any data the object contains +I (OO), or I (OOP), is a way +of managing programs by categorizing their components into discrete, unique +entities. These are I. In Moose terms, each object is an instance of +a I, which serves as a template to describe any data the object contains as well as its specific behaviors. =head2 Classes @@ -29,8 +28,8 @@ as well as its specific behaviors. X X -A class in Perl 5 stores class data. It may have a name. By default, Perl 5 -classes use packages to provide namespaces: +A class in Perl 5 stores class data. By default, Perl 5 classes use packages +to provide namespaces: =begin programlisting @@ -67,12 +66,14 @@ X A I is a function associated with a class. It resembles a fully-qualified function call in a superficial sense, but it differs in two important ways. First, a method call always has an I on which the -method operates. In the case of creating the two C objects, the name of -the class (C) is the invocant: +method operates. When you create an object, the I of the class is the +invocant. When you call a method on an instance, that instance is the +invocant: =begin programlisting my $fuzzy = B->new(); + B<$fuzzy>->sleep_on_keyboard(); =end programlisting @@ -115,14 +116,17 @@ eaten yet: =end programlisting +X +X X X -By convention, invocants in Perl methods are lexical variables named C<$self>, -but this is merely pervasive convention. The example implementation of -C does not use the invocant, so it's irrelevant once method dispatch -has completed. In that sense, C is like C; you can safely use -the name of the class (C) as its invocant. This is a I: +By pervasive convention, methods store their invocants in lexical variables +named C<$self>. Methods which access invocant data are I, +because they depend on the presence of an appropriate invocant to work +correctly. Methods (such as C) which do not access instance data are +I, as you can use the name of the class as an invocant. +Constructors are also class methods. For example: =begin programlisting @@ -130,6 +134,11 @@ the name of the class (C) as its invocant. This is a I: =end programlisting +Class methods can help you organize your code into namespaces without requiring +you to import (L) functions, but a design which relies heavily on +class methods for anything other than constructors may be the sign of muddled +thinking. + =head2 Attributes X @@ -327,9 +336,9 @@ available if you really need it, but the declarative approach can actually improve your programs. In this way, Moose encourages I: hiding the internal details of an object from external users of that object. -Consider a change to the age of a C; instead of requesting that directly -from the constructor, calculate the age of a C based on the year of its -birth: +Consider how you might change the way C handles ages. Instead of +requiring a static value for an age passed to the constructor, pass in the year +of the cat's birth and calculate the age as needed: =begin programlisting @@ -409,11 +418,12 @@ for each object, including a hash or array reference. =head3 Polymorphism A program which deals with one type of data and one type of behavior on that -data benefits little from the use of objects. A well-designed object-oriented -program should be capable of managing many types of data. When well designed -classes encapsulate specific details of objects into the appropriate places, -something curious happens to the rest of the program: it has the opportunity to -become I specific. +data receives few benefits from the use of object. Encapsulation is useful, to +be sure--but the real power of object orientation is not solely in +encapsulation. A well designed OO program can manage many types of data. When +well designed classes encapsulate specific details of objects into the +appropriate places, something curious happens to the rest of the program: it +has the opportunity to become I specific. In other words, moving the specifics of the details of what the program knows about individual Cs (the attributes) and what the program knows that @@ -502,11 +512,14 @@ Sometimes it's useful to know I an object does. In other words, you need Z -A I is a named collection of behavior and state. A class is like a role, -with the vital difference that you can instantiate a class, but not a role. -While a class is primarily a mechanism for organizing behaviors and state into -a template for objects, a role is primarily a mechanism for organizing -behaviors and state into a named collection. +A I is a named collection of behavior and stateN and research on +traits in Smalltalk at U for copious +details.>. A class is like a role, with the vital difference that you can +instantiate a class, but not a role. While a class is primarily a mechanism +for organizing behaviors and state into a template for objects, a role is +primarily a mechanism for organizing behaviors and state into a named +collection. A role is something a class does. @@ -640,6 +653,14 @@ flexibility in your design by naming specific collections of behaviors so that you can test the capabilities of objects and classes and not their implementations. +=begin sidebar + +For details about roles versus other design techniques such as mixins, multiple +inheritance, and monkeypatching, see +U. + +=end sidebar + =head3 Roles and DOES() X @@ -742,19 +763,18 @@ X The C syntax takes a list of class names to use as parents of the current class. The C<+> at the start of the C attribute name -indicates that the current class extends the declaration of the attribute. In -this case, the super candle overrides the default value of the light source, so -any new C created has a light value of 100 candles. The other -attribute and both methods are available on C instances; when you -invoke C or C on such an instance, Perl will look in -C for the method, then in the list of parents of the -class. Ultimately it finds them in C. +indicates that the current class extends or overrides the declaration of the +attribute. In this case, the super candle overrides the default value of the +light source, so any new C created has a light value of 100 +candles. The other attribute and both methods are available on C +instances; when you invoke C or C on such an instance, Perl +will look in C for the method, then in the list of +parents of the class. Ultimately it finds them in C. X -Attribute inheritance works in a similar fashion, except that the act of -I the instance makes all of the appropriate attributes available -in the proper fashion (see C). +Attribute inheritance works in a similar way (see C for +details). X X @@ -762,11 +782,12 @@ X X X X +X -I (sometimes written I) is easy -to understand in the case of single-parent inheritance. When a class has -multiple parents (I), dispatch is less obvious. By -default, Perl 5 provides a depth-first strategy of method resolution. It +I (sometimes written I or +I) is easy to understand in the case of single-parent inheritance. When a +class has multiple parents (I), dispatch is less obvious. +By default, Perl 5 provides a depth-first strategy of method resolution. It searches the class of the I named parent and all of its parents recursively before searching the classes of the subsequent named parents. This behavior is often confusing; avoid using multiple inheritance until you @@ -799,9 +820,9 @@ nothing. Perl's method dispatch system will find this method and will not look for any methods of this name in any of the parent classes. Sometimes an overridden method needs behavior from its parent as well. The -C command tells Moose that the subclass deliberately overrides the -named method. The C function is available to dispatch from the -overriding method to the overridden method: +C command tells Moose (and everyone else reading the code) that the +subclass deliberately overrides the named method. The C function is +available to dispatch from the overriding method to the overridden method: =begin programlisting @@ -961,8 +982,8 @@ shift;> line at the start of the C method. =begin sidebar -The Perl 5 core provides support for C as of Perl 5.12, but the -module is not a core module. +As of Perl 5.12, the Perl 5 core explicitly supports C, but the +module is not a core module and it works with earlier versions of Perl 5. =end sidebar diff --git a/sections/reflection.pod b/sections/reflection.pod index 14cbaf38..bd9054bd 100644 --- a/sections/reflection.pod +++ b/sections/reflection.pod @@ -13,8 +13,9 @@ in the system. C (L) simplifies many reflection tasks for object systems, but many useful programs do not use objects pervasively, and many -useful programs do not use C. Several idioms (L) exist for -using reflection effectively in the absence of such a formal system. +useful programs do not use C. Several idioms exist for using +reflection effectively in the absence of such a formal system. These are the +most common. =head2 Checking that a Package Exists @@ -81,8 +82,8 @@ within C<%INC>: Nothing prevents other code from manipulating C<%INC> itself. Depending on your paranoia level, you may check the path and the expected contents of the -package yourself, but modules with good reasons for manipulating this variable -(such as C or C) may do so. Code which +package yourself. Some modules (such as C or +C) manipulate C<%INC> for good reasons. Code which manipulates C<%INC> for poor reasons deserves replacing. =head2 Checking the Version of a Module