Rephrase "Perl Home Page" References
[p5sagit/p5-mst-13.2.git] / pod / perltoot.pod
index 698f655..4a212fb 100644 (file)
@@ -1,6 +1,6 @@
 =head1 NAME
 
-perltoot - tchrist's object-oriented perl tutorial (rev 0.4)
+perltoot - Tom's object-oriented tutorial for perl
 
 =head1 DESCRIPTION
 
@@ -33,7 +33,7 @@ Asking a class to do something for you is calling a I<class method>.
 Asking an object to do something for you is calling an I<object method>.
 Asking either a class (usually) or an object (sometimes) to give you
 back an object is calling a I<constructor>, which is just a
-particular kind of method.  
+kind of method.
 
 That's all well and good, but how is an object different from any other
 Perl data type?  Just what is an object I<really>; that is, what's its
@@ -65,7 +65,7 @@ For example, let's make a simple Person class module.  It gets stored in
 the file Person.pm.  If it were called a Happy::Person class, it would
 be stored in the file Happy/Person.pm, and its package would become
 Happy::Person instead of just Person.  (On a personal computer not
-running Unix or Plan 9, but something like MacOS or VMS, the directory
+running Unix or Plan 9, but something like Mac OS or VMS, the directory
 separator may be different, but the principle is the same.)  Do not assume
 any formal relationship between modules based on their directory names.
 This is merely a grouping convenience, and has no effect on inheritance,
@@ -83,15 +83,15 @@ more than that methods may now be called against it.
 While a constructor may be named anything you'd like, most Perl
 programmers seem to like to call theirs new().  However, new() is not
 a reserved word, and a class is under no obligation to supply such.
-Some programmers have also been known to use a function with 
+Some programmers have also been known to use a function with
 the same name as the class as the constructor.
 
 =head2 Object Representation
 
 By far the most common mechanism used in Perl to represent a Pascal
-record, a C struct, or a C++ class an anonymous hash.  That's because a
+record, a C struct, or a C++ class is an anonymous hash.  That's because a
 hash has an arbitrary number of data fields, each conveniently accessed by
-an arbitrary name of your own devising.  
+an arbitrary name of your own devising.
 
 If you were just doing a simple
 struct-like emulation, you would likely go about it something like this:
@@ -111,8 +111,8 @@ by up-casing the hash keys:
         PEERS => [ "Norbert", "Rhys", "Phineas"],
     };
 
-And so you could get at C<$rec-E<gt>{NAME}> to find "Jason", or
-C<@{ $rec-E<gt>{PEERS} }> to get at "Norbert", "Rhys", and "Phineas".
+And so you could get at C<< $rec->{NAME} >> to find "Jason", or
+C<< @{ $rec->{PEERS} } >> to get at "Norbert", "Rhys", and "Phineas".
 (Have you ever noticed how many 23-year-old programmers seem to
 be named "Jason" these days? :-)
 
@@ -131,10 +131,10 @@ but Perl does not.  It relies on you to read the documentation of each
 class.  If you try to call an undefined method on an object, Perl won't
 complain, but the program will trigger an exception while it's running.
 Likewise, if you call a method expecting a prime number as its argument
-with an even one instead, you can't expect the compiler to catch this.
+with a non-prime one instead, you can't expect the compiler to catch this.
 (Well, you can expect it all you like, but it's not going to happen.)
 
-Let's suppose you have a well-educated user of you Person class,
+Let's suppose you have a well-educated user of your Person class,
 someone who has read the docs that explain the prescribed
 interface.  Here's how they might use the Person class:
 
@@ -224,23 +224,8 @@ The second argument is the class into which the referent will be blessed.
 By not assuming our own class as the default second argument and instead
 using the class passed into us, we make our constructor inheritable.
 
-While we're at it, let's make our constructor a bit more flexible.
-Rather than being uniquely a class method, we'll set it up so that
-it can be called as either a class method I<or> an object
-method.  That way you can say:
-
-    $me  = Person->new();
-    $him = $me->new();
-
-To do this, all we have to do is check whether what was passed in
-was a reference or not.  If so, we were invoked as an object method,
-and we need to extract the package (class) using the ref() function.
-If not, we just use the string passed in as the package name
-for blessing our referent.
-
     sub new {
-        my $proto = shift;
-        my $class = ref($proto) || $proto;
+        my $class = shift;
         my $self  = {};
         $self->{NAME}   = undef;
         $self->{AGE}    = undef;
@@ -267,8 +252,11 @@ Because while a constructor is explicitly called, a destructor is not.
 Destruction happens automatically via Perl's garbage collection (GC)
 system, which is a quick but somewhat lazy reference-based GC system.
 To know what to call, Perl insists that the destructor be named DESTROY.
+Perl's notion of the right time to call a destructor is not well-defined
+currently, which is why your destructors should not rely on when they are
+called.
 
-Why is DESTROY in all caps?  Perl on occasion uses purely upper-case
+Why is DESTROY in all caps?  Perl on occasion uses purely uppercase
 function names as a convention to indicate that the function will
 be automatically called by Perl in some way.  Others that are called
 implicitly include BEGIN, END, AUTOLOAD, plus all methods used by
@@ -295,7 +283,7 @@ your program not to leak memory.  While admittedly error-prone, this is
 the best we can do right now.  Nonetheless, rest assured that when your
 program is finished, its objects' destructors are all duly called.
 So you are guaranteed that an object I<eventually> gets properly
-destructed, except in the unique case of a program that never exits.
+destroyed, except in the unique case of a program that never exits.
 (If you're running Perl embedded in another application, this full GC
 pass happens a bit more frequently--whenever a thread shuts down.)
 
@@ -311,8 +299,8 @@ be made through methods.
 
 Perl doesn't impose restrictions on who gets to use which methods.
 The public-versus-private distinction is by convention, not syntax.
-(Well, unless you use the Alias module described below in L</"Data Members
-as Variables">.)  Occasionally you'll see method names beginning or ending
+(Well, unless you use the Alias module described below in
+L<Data Members as Variables>.)  Occasionally you'll see method names beginning or ending
 with an underscore or two.  This marking is a convention indicating
 that the methods are private to that class alone and sometimes to its
 closest acquaintances, its immediate subclasses.  But this distinction
@@ -321,12 +309,12 @@ is not enforced by Perl itself.  It's up to the programmer to behave.
 There's no reason to limit methods to those that simply access data.
 Methods can do anything at all.  The key point is that they're invoked
 against an object or a class.  Let's say we'd like object methods that
-do more than fetch or set one particular field .
+do more than fetch or set one particular field.
 
     sub exclaim {
         my $self = shift;
         return sprintf "Hi, I'm %s, age %d, working with %s",
-            $self->{NAME}, $self->{AGE}, join(", ", $self->{PEERS});
+            $self->{NAME}, $self->{AGE}, join(", ", @{$self->{PEERS}});
     }
 
 Or maybe even one like this:
@@ -350,7 +338,7 @@ Some might argue that one should go at these this way:
     }
 
 But since these methods are all executing in the class itself, this
-may not be critical.  There are trade-offs to be made.  Using direct
+may not be critical.  There are tradeoffs to be made.  Using direct
 hash access is faster (about an order of magnitude faster, in fact), and
 it's more convenient when you want to interpolate in strings.  But using
 methods (the external interface) internally shields not just the users of
@@ -398,8 +386,7 @@ it instead a file-scoped lexical, you should make these
 changes to your Person::new() constructor:
 
     sub new {
-        my $proto = shift;
-        my $class = ref($proto) || $proto;
+        my $class = shift;
         my $self  = {};
         $Census++;
         $self->{NAME}   = undef;
@@ -422,6 +409,10 @@ this could be done:
 Notice how there's no memory to deallocate in the destructor?  That's
 something that Perl takes care of for you all by itself.
 
+Alternatively, you could use the Class::Data::Inheritable module from
+CPAN.
+
+
 =head2 Accessing Class Data
 
 It turns out that this is not really a good way to go about handling
@@ -437,7 +428,7 @@ to inheritance.
 
 Got that?  Maybe not.  Ok, let's say that some other class "borrowed"
 (well, inherited) the DESTROY method as it was defined above.  When those
-objects are destructed, the original $Census variable will be altered,
+objects are destroyed, the original $Census variable will be altered,
 not the one in the new class's package namespace.  Perhaps this is what
 you want, but probably it isn't.
 
@@ -448,11 +439,10 @@ of magicalness to a C programmer.  It's really just a mnemonic device
 to remind ourselves that this field is special and not to be used as
 a public data member in the same way that NAME, AGE, and PEERS are.
 (Because we've been developing this code under the strict pragma, prior
-to 5.004 we'll have to quote the field name.)
+to perl version 5.004 we'll have to quote the field name.)
 
     sub new {
-        my $proto = shift;
-        my $class = ref($proto) || $proto;
+        my $class = shift;
         my $self  = {};
         $self->{NAME}     = undef;
         $self->{AGE}      = undef;
@@ -538,9 +528,13 @@ and DESTROY methods as follows:
         -- ${ $self->{"_CENSUS"} };
     }
 
+What happens if a derived class (which we'll call Employee) inherits
+methods from this Person base class?  Then C<< Employee->debug() >>, when called
+as a class method, manipulates $Person::Debugging not $Employee::Debugging.
+
 =head2 Class Destructors
 
-The object destructor handles for each particular object.  But sometimes
+The object destructor handles the death of each distinct object.  But sometimes
 you want a bit of cleanup when the entire class is shut down, which
 currently only happens when the program exits.  To make such a
 I<class destructor>, create a function in that class's package named
@@ -639,8 +633,7 @@ Ok.  To do this, we'll change Person::new() so that it supports
 a full name field this way:
 
     sub new {
-        my $proto = shift;
-        my $class = ref($proto) || $proto;
+        my $class = shift;
         my $self  = {};
         $self->{FULLNAME} = Fullname->new();
         $self->{AGE}      = undef;
@@ -672,8 +665,7 @@ by the appropriate name to access them:
     use strict;
 
     sub new {
-        my $proto = shift;
-        my $class = ref($proto) || $proto;
+        my $class = shift;
         my $self  = {
             TITLE       => undef,
             CHRISTIAN   => undef,
@@ -742,7 +734,7 @@ Finally, here's the test program:
     $him->fullname->title("St");
     $him->age(1);
 
-    printf "%s is really %s.\n", $him->name, $him->fullname;
+    printf "%s is really %s.\n", $him->name, $him->fullname->as_string;
     printf "%s's age: %d.\n", $him->name, $him->age;
     $him->happy_birthday;
     printf "%s's age: %d.\n", $him->name, $him->age;
@@ -792,7 +784,7 @@ base class.  If the original base class has been designed properly,
 then the new derived class can be used as a drop-in replacement for the
 old one.  This means you should be able to write a program like this:
 
-    use Employee
+    use Employee;
     my $empl = Employee->new();
     $empl->name("Jason");
     $empl->age(23);
@@ -806,10 +798,10 @@ but the reference to this is stored on the object itself and all other
 methods access package data via that reference, so we should be ok.
 
 What do we mean by the Person::new() function -- isn't that actually
-method.  Well, in principle, yes.  A method is just a function that
+a method?  Well, in principle, yes.  A method is just a function that
 expects as its first argument a class name (package) or object
-(bless reference).   Person::new() is the function that both the
-C<Person-E<gt>new()> method and the C<Employee-E<gt>new()> method end
+(blessed reference).   Person::new() is the function that both the
+C<< Person->new() >> method and the C<< Employee->new() >> method end
 up calling.  Understand that while a method call looks a lot like a
 function call, they aren't really quite the same, and if you treat them
 as the same, you'll very soon be left with nothing but broken programs.
@@ -825,7 +817,7 @@ but methods do.
 So don't use function calls when you mean to call a method.
 
 If an employee is just a Person, that's not all too very interesting.
-So let's add some other methods.  We'll give our employee 
+So let's add some other methods.  We'll give our employee
 data fields to access their salary, their employee ID, and their
 start date.
 
@@ -876,13 +868,13 @@ To do this, merely add this definition into the Employee.pm file:
     }
 
 There, we've just demonstrated the high-falutin' concept known in certain
-circles as I<polymorphism>.  We've taken on the form and behavior of
+circles as I<polymorphism>.  We've taken on the form and behaviour of
 an existing object, and then we've altered it to suit our own purposes.
 This is a form of Laziness.  (Getting polymorphed is also what happens
 when the wizard decides you'd look better as a frog.)
 
 Every now and then you'll want to have a method call trigger both its
-derived class (also know as "subclass") version as well as its base class
+derived class (also known as "subclass") version as well as its base class
 (also known as "superclass") version.  In practice, constructors and
 destructors are likely to want to do this, and it probably also makes
 sense in the debug() method we showed previously.
@@ -924,12 +916,13 @@ superclass's name.  This in particular is bad if you change which classes
 you inherit from, or add others.  Fortunately, the pseudoclass SUPER
 comes to the rescue here.
 
-    $class->SUPER::debug($Debugging);
+    $self->SUPER::debug($Debugging);
 
 This way it starts looking in my class's @ISA.  This only makes sense
 from I<within> a method call, though.  Don't try to access anything
 in SUPER:: from anywhere else, because it doesn't exist outside
-an overridden method call.
+an overridden method call. Note that C<SUPER> refers to the superclass of
+the current package, I<not> to the superclass of C<$self>.
 
 Things are getting a bit complicated here.  Have we done anything
 we shouldn't?  As before, one way to test whether we're designing
@@ -958,33 +951,35 @@ And here's the test program:
     $boss->age(47);
     $boss->peers("Frank", "Felipe", "Faust");
 
-    printf "%s is age %d.\n", $boss->fullname, $boss->age;
+    printf "%s is age %d.\n", $boss->fullname->as_string, $boss->age;
     printf "His peers are: %s\n", join(", ", $boss->peers);
 
 Running it, we see that we're still ok.  If you'd like to dump out your
-object in a nice format, the way the 'x' command does in the debugger,
-you could use these undocumented calls the debugger employs (until
-its author changes them).
+object in a nice format, somewhat like the way the 'x' command works in
+the debugger, you could use the Data::Dumper module from CPAN this way:
 
-    require 'dumpvar.pl';
+    use Data::Dumper;
     print "Here's the boss:\n";
-    dumpValue($boss);
+    print Dumper($boss);
 
 Which shows us something like this:
 
-    Boss=HASH(0x8104084)
-       '_CENSUS' => SCALAR(0x80c949c)
-          -> 1
-       'AGE' => 47
-       'FULLNAME' => Fullname=HASH(0x81040d8)
-          'CHRISTIAN' => 'Federico Miguel'
-          'NICK' => 'Fred'
-          'SURNAME' => 'Pichon Alvarez'
-          'TITLE' => 'Don'
-       'PEERS' => ARRAY(0x80ebb3c)
-          0  'Frank'
-          1  'Felipe'
-          2  'Faust'
+    Here's the boss:
+    $VAR1 = bless( {
+        _CENSUS => \1,
+        FULLNAME => bless( {
+                             TITLE => 'Don',
+                             SURNAME => 'Pichon Alvarez',
+                             NICK => 'Fred',
+                             CHRISTIAN => 'Federico Jesus'
+                           }, 'Fullname' ),
+        AGE => 47,
+        PEERS => [
+                   'Frank',
+                   'Felipe',
+                   'Faust'
+                 ]
+       }, 'Boss' );
 
 Hm.... something's missing there.  What about the salary, start date,
 and ID fields?  Well, we never set them to anything, even undef, so they
@@ -995,8 +990,7 @@ know about its immediate superclass, but never vice-versa.)  So let's
 fix up Employee::new() this way:
 
     sub new {
-        my $proto = shift;
-        my $class = ref($proto) || $proto;
+        my $class = shift;
         my $self  = $class->SUPER::new();
         $self->{SALARY}        = undef;
         $self->{ID}            = undef;
@@ -1046,10 +1040,10 @@ it I<was> one.
 
 However, there is one particular area where MI in Perl is rampant:
 borrowing another class's class methods.  This is rather common,
-particularly with some bundled "objectless" classes,
+especially with some bundled "objectless" classes,
 like Exporter, DynaLoader, AutoLoader, and SelfLoader.  These classes
 do not provide constructors; they exist only so you may inherit their
-class methods.  (It's not entirey clear why inheritance was done
+class methods.  (It's not entirely clear why inheritance was done
 here rather than traditional module importation.)
 
 For example, here is the POSIX module's @ISA:
@@ -1064,7 +1058,7 @@ classes' behaviours to POSIX.
 Why don't people use MI for object methods much?  One reason is that
 it can have complicated side-effects.  For one thing, your inheritance
 graph (no longer a tree) might converge back to the same base class.
-Although Perl guards against recursive inheritance, but having parents
+Although Perl guards against recursive inheritance, merely having parents
 who are related to each other via a common ancestor, incestuous though
 it sounds, is not forbidden.  What if in our Third class shown above we
 wanted its new() method to also call both overridden constructors in its
@@ -1081,11 +1075,11 @@ base class?  That way you could give every object common methods without
 having to go and add it to each and every @ISA.  Well, it turns out that
 you can.  You don't see it, but Perl tacitly and irrevocably assumes
 that there's an extra element at the end of @ISA: the class UNIVERSAL.
-In 5.003, there were no predefined methods there, but you could put
+In version 5.003, there were no predefined methods there, but you could put
 whatever you felt like into it.
 
-However, as of 5.004 (or some subversive releases, like 5.003_08),
-UNIVERSAL has some methods in it already.  These are built-in to your Perl
+However, as of version 5.004 (or some subversive releases, like 5.003_08),
+UNIVERSAL has some methods in it already.  These are builtin to your Perl
 binary, so they don't take any extra time to load.  Predefined methods
 include isa(), can(), and VERSION().  isa() tells you whether an object or
 class "is" another one without having to traverse the hierarchy yourself:
@@ -1106,21 +1100,20 @@ class) has a package global called $VERSION that's high enough, as in:
     $his_vers = $ob->VERSION();
 
 However, we don't usually call VERSION ourselves.  (Remember that an all
-upper-case function name is a Perl convention that indicates that the
+uppercase function name is a Perl convention that indicates that the
 function will be automatically used by Perl in some way.)  In this case,
 it happens when you say
 
     use Some_Module 3.0;
 
-If you wanted to add versioning to your Person class explained
+If you wanted to add version checking to your Person class explained
 above, just add this to Person.pm:
 
-    use vars qw($VERSION);
-    $VERSION = '1.1';
+    our $VERSION = '1.1';
 
-and then in Employee.pm could you can say
+and then in Employee.pm you can say
 
-    use Employee 1.1;
+    use Person 1.1;
 
 And it would make sure that you have at least that version number or
 higher available.   This is not the same as loading in that exact version
@@ -1157,7 +1150,7 @@ instead of a hash reference to represent the object.
     sub new {
         my $self = [];
         $self->[$NAME]   = undef;  # this is unnecessary
-        $self->[$AGE]    = undef;  # as it this
+        $self->[$AGE]    = undef;  # as is this
         $self->[$PEERS]  = [];     # but this isn't, really
         bless($self);
         return $self;
@@ -1183,15 +1176,15 @@ instead of a hash reference to represent the object.
 
     1;  # so the require or use succeeds
 
-You might guess that the array access will be a lot faster than the
-hash access, but they're actually comparable.  The array is a little
+You might guess that the array access would be a lot faster than the
+hash access, but they're actually comparable.  The array is a I<little>
 bit faster, but not more than ten or fifteen percent, even when you
 replace the variables above like $AGE with literal numbers, like 1.
 A bigger difference between the two approaches can be found in memory use.
 A hash representation takes up more memory than an array representation
-because you have to allocation memory for the keys as well as the values.
-However, it really isn't that bad, especially since as of 5.004,
-memory is only allocated one for a given hash key, no matter how many
+because you have to allocate memory for the keys as well as for the values.
+However, it really isn't that bad, especially since as of version 5.004,
+memory is only allocated once for a given hash key, no matter how many
 hashes have that key.  It's expected that sometime in the future, even
 these differences will fade into obscurity as more efficient underlying
 representations are devised.
@@ -1211,7 +1204,7 @@ alone in all the world can see the object's data.  This is because we
 put the data into an anonymous hash that's lexically visible only to
 the closure we create, bless, and return as the object.  This object's
 methods turn around and call the closure as a regular subroutine call,
-passing it as a particular argument the field we want to affect.  (Yes,
+passing it the field we want to affect.  (Yes,
 the double-function call is slow, but if you wanted fast, you wouldn't
 be using objects at all, eh? :-)
 
@@ -1231,8 +1224,7 @@ different:
     package Person;
 
     sub new {
-        my $that  = shift;
-        my $class = ref($that) || $that;
+        my $class  = shift;
         my $self = {
            NAME  => undef,
            AGE   => undef,
@@ -1256,16 +1248,16 @@ different:
 Because this object is hidden behind a code reference, it's probably a bit
 mysterious to those whose background is more firmly rooted in standard
 procedural or object-based programming languages than in functional
-procedural programming languages whence closures derive.  The object
+programming languages whence closures derive.  The object
 created and returned by the new() method is itself not a data reference
 as we've seen before.  It's an anonymous code reference that has within
-it access to a particular version (lexical binding and instantiation)
+it access to a specific version (lexical binding and instantiation)
 of the object's data, which are stored in the private variable $self.
 Although this is the same function each time, it contains a different
 version of $self.
 
-When a method like C<$him-E<gt>name("Jason") is called, its implicit
-zeroth argument is as the invoking object just as it is with all method
+When a method like C<$him-E<gt>name("Jason")> is called, its implicit
+zeroth argument is the invoking object--just as it is with all method
 calls.  But in this case, it's our code reference (something like a
 function pointer in C++, but with deep binding of lexical variables).
 There's not a lot to be done with a code reference beyond calling it, so
@@ -1312,7 +1304,7 @@ have the autoloaded method itself directly provide the
 requested service.  When used in this way, you may think
 of autoloaded methods as "proxy" methods.
 
-When Perl tries to call an undefined function is a particular package
+When Perl tries to call an undefined function in a particular package
 and that function is not defined, it looks for a function in
 that same package called AUTOLOAD.  If one exists, it's called
 with the same arguments as the original function would have had.
@@ -1345,7 +1337,7 @@ Instead of writing a new function every time we want a new data field,
 we'll use the autoload mechanism to generate (actually, mimic) methods on
 the fly.  To verify that we're accessing a valid member, we will check
 against an C<_permitted> (pronounced "under-permitted") field, which
-is a reference to a file-static hash of permitted fields in this record
+is a reference to a file-scoped lexical (like a C file static) hash of permitted fields in this record
 called %fields.  Why the underscore?  For the same reason as the _CENSUS
 field we once used: as a marker that means "for internal use only".
 
@@ -1354,7 +1346,7 @@ constructor will look like when taking this approach:
 
     package Person;
     use Carp;
-    use vars qw($AUTOLOAD);  # it's a package global
+    our $AUTOLOAD;  # it's a package global
 
     my %fields = (
        name        => undef,
@@ -1363,8 +1355,7 @@ constructor will look like when taking this approach:
     );
 
     sub new {
-       my $that  = shift;
-       my $class = ref($that) || $that;
+       my $class = shift;
        my $self  = {
            _permitted => \%fields,
            %fields,
@@ -1409,6 +1400,11 @@ a user directly.
 Pretty nifty, eh?  All we have to do to add new data fields
 is modify %fields.  No new functions need be written.
 
+I could have avoided the C<_permitted> field entirely, but I
+wanted to demonstrate how to store a reference to class data on the
+object so you wouldn't have to access that class data
+directly from an object method.
+
 =head2 Inherited Autoloaded Data Methods
 
 But what about inheritance?  Can we define our Employee
@@ -1419,8 +1415,7 @@ Here's how to be careful:
     package Employee;
     use Person;
     use strict;
-    use vars qw(@ISA);
-    @ISA = qw(Person);
+    our @ISA = qw(Person);
 
     my %fields = (
        id          => undef,
@@ -1428,9 +1423,8 @@ Here's how to be careful:
     );
 
     sub new {
-       my $that  = shift;
-       my $class = ref($that) || $that;
-       my $self = bless $that->SUPER::new(), $class;
+       my $class = shift;
+       my $self  = $class->SUPER::new();
        my($element);
        foreach $element (keys %fields) {
            $self->{_permitted}->{$element} = $fields{$element};
@@ -1444,7 +1438,7 @@ AUTOLOAD function in the Employee package, because
 we'll grab Person's version of that via inheritance,
 and it will all work out just fine.
 
-=head1 Metaclass Tools
+=head1 Metaclassical Tools
 
 Even though proxy methods can provide a more convenient approach to making
 more struct-like classes than tediously coding up data methods as
@@ -1455,31 +1449,35 @@ as detailed above.
 
 Perl programmers have responded to this by creating several different
 class construction classes.  These metaclasses are classes
-that create other classes.  Three worth looking at are
-Class::Template, Class::MethodMaker, and Alias.  All can be
+that create other classes.  A couple worth looking at are
+Class::Struct and Alias.  These and other related metaclasses can be
 found in the modules directory on CPAN.
 
-=head2 Class::Template
+=head2 Class::Struct
 
-One of the older ones is Class::Template.  In fact, its syntax and
+One of the older ones is Class::Struct.  In fact, its syntax and
 interface were sketched out long before perl5 even solidified into a
-real thing.  What it does is provide you a way to "declare"
-a class as having objects whose fields are of a particular type.
-The function that does this is called, not surprisingly
-enough, struct().
+real thing.  What it does is provide you a way to "declare" a class
+as having objects whose fields are of a specific type.  The function
+that does this is called, not surprisingly enough, struct().  Because
+structures or records are not base types in Perl, each time you want to
+create a class to provide a record-like data object, you yourself have
+to define a new() method, plus separate data-access methods for each of
+that record's fields.  You'll quickly become bored with this process.
+The Class::Struct::struct() function alleviates this tedium.
 
 Here's a simple example of using it:
 
-    use Class::Template qw(struct);
+    use Class::Struct qw(struct);
     use Jobbie;  # user-defined; see below
 
     struct 'Fred' => {
         one        => '$',
         many       => '@',
-        profession => Jobbie,  # calls Jobbie->new()
+        profession => 'Jobbie',  # does not call Jobbie->new()
     };
 
-    $ob = Fred->new;
+    $ob = Fred->new(profession => Jobbie->new());
     $ob->one("hmmmm");
 
     $ob->many(0, "here");
@@ -1493,11 +1491,15 @@ You can declare types in the struct to be basic Perl types, or
 user-defined types (classes).  User types will be initialized by calling
 that class's new() method.
 
+Take care that the C<Jobbie> object is not created automatically by the
+C<Fred> class's new() method, so you should specify a C<Jobbie> object
+when you create an instance of C<Fred>.
+
 Here's a real-world example of using struct generation.  Let's say you
 wanted to override Perl's idea of gethostbyname() and gethostbyaddr() so
 that they would return objects that acted like C structures.  We don't
 care about high-falutin' OO gunk.  All we want is for these objects to
-act like structs in the C sense.   
+act like structs in the C sense.
 
     use Socket;
     use Net::hostent;
@@ -1505,10 +1507,10 @@ act like structs in the C sense.
     printf "perl.com's real name is %s, address %s\n",
        $h->name, inet_ntoa($h->addr);
 
-Here's how to do this using the Class::Template module.
-They crux is going to be this call:
+Here's how to do this using the Class::Struct module.
+The crux is going to be this call:
 
-    struct 'Net::hostent' => [
+    struct 'Net::hostent' => [         # note bracket
        name       => '$',
        aliases    => '@',
        addrtype   => '$',
@@ -1521,7 +1523,7 @@ It even creates a new() method for us.
 
 We could also have implemented our object this way:
 
-    struct 'Net::hostent' => {
+    struct 'Net::hostent' => {         # note brace
        name       => '$',
        aliases    => '@',
        addrtype   => '$',
@@ -1529,11 +1531,11 @@ We could also have implemented our object this way:
        addr_list  => '@',
      };
 
-and then Class::Template would have used an anonymous hash as the object
+and then Class::Struct would have used an anonymous hash as the object
 type, instead of an anonymous array.  The array is faster and smaller,
 but the hash works out better if you eventually want to do inheritance.
 Since for this struct-like object we aren't planning on inheritance,
-we'll go for better speed and size over better flexibility.  
+this time we'll opt for better speed and size over better flexibility.
 
 Here's the whole implementation:
 
@@ -1542,19 +1544,20 @@ Here's the whole implementation:
 
     BEGIN {
        use Exporter   ();
-       use vars       qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
-       @ISA         = qw(Exporter);
-       @EXPORT      = qw(gethostbyname gethostbyaddr gethost);
-       @EXPORT_OK   = qw(
-                          $h_name         @h_aliases
-                          $h_addrtype     $h_length
-                          @h_addr_list    $h_addr
-                      );
-       %EXPORT_TAGS = ( FIELDS => [ @EXPORT_OK, @EXPORT ] );
+       our @EXPORT      = qw(gethostbyname gethostbyaddr gethost);
+       our @EXPORT_OK   = qw(
+                              $h_name         @h_aliases
+                              $h_addrtype     $h_length
+                              @h_addr_list    $h_addr
+                          );
+       our %EXPORT_TAGS = ( FIELDS => [ @EXPORT_OK, @EXPORT ] );
     }
-    use vars      @EXPORT_OK;
+    our @EXPORT_OK;
 
-    use Class::Template qw(struct);
+    # Class::Struct forbids use of @ISA
+    sub import { goto &Exporter::import }
+
+    use Class::Struct qw(struct);
     struct 'Net::hostent' => [
        name        => '$',
        aliases     => '@',
@@ -1567,7 +1570,7 @@ Here's the whole implementation:
 
     sub populate (@) {
        return unless @_;
-       my $hob = new();  # Class::Template made this!
+       my $hob = new();  # Class::Struct made this!
        $h_name     =    $hob->[0]              = $_[0];
        @h_aliases  = @{ $hob->[1] } = split ' ', $_[1];
        $h_addrtype =    $hob->[2]              = $_[2];
@@ -1600,17 +1603,18 @@ Here's the whole implementation:
 
 We've snuck in quite a fair bit of other concepts besides just dynamic
 class creation, like overriding core functions, import/export bits,
-function prototyping, and short-cut function call via C<&whatever>.
-These all mostly make sense from the perspective of a traditional module,
-but as you can see, we can also use them in an object module.
+function prototyping, short-cut function call via C<&whatever>, and
+function replacement with C<goto &whatever>.  These all mostly make
+sense from the perspective of a traditional module, but as you can see,
+we can also use them in an object module.
 
 You can look at other object-based, struct-like overrides of core
 functions in the 5.004 release of Perl in File::stat, Net::hostent,
 Net::netent, Net::protoent, Net::servent, Time::gmtime, Time::localtime,
 User::grent, and User::pwent.  These modules have a final component
-that's all lower-case, by convention reserved for compiler pragmas,
-because they affect the compilation and change a built-in function.
-They also have the type name that a C programmer would most expect.  
+that's all lowercase, by convention reserved for compiler pragmas,
+because they affect the compilation and change a builtin function.
+They also have the type names that a C programmer would most expect.
 
 =head2 Data Members as Variables
 
@@ -1628,8 +1632,7 @@ update value fields in the hash.  Convenient, eh?
 
     # this is the same as before...
     sub new {
-        my $that  = shift;
-        my $class = ref($that) || $that;
+        my $class = shift;
         my $self = {
            NAME  => undef,
            AGE   => undef,
@@ -1640,7 +1643,7 @@ update value fields in the hash.  Convenient, eh?
     }
 
     use Alias qw(attr);
-    use vars qw($NAME $AGE $PEERS);
+    our ($NAME, $AGE, $PEERS);
 
     sub name {
        my $self = attr shift;
@@ -1671,18 +1674,18 @@ update value fields in the hash.  Convenient, eh?
         return ++$AGE;
     }
 
-The need for the C<use vars> declaration is because what Alias does
+The need for the C<our> declaration is because what Alias does
 is play with package globals with the same name as the fields.  To use
-globals while C<use strict> is in effect, you have to pre-declare them.
+globals while C<use strict> is in effect, you have to predeclare them.
 These package variables are localized to the block enclosing the attr()
 call just as if you'd used a local() on them.  However, that means that
 they're still considered global variables with temporary values, just
 as with any other local().
 
 It would be nice to combine Alias with
-something like Class::Template or Class::MethodMaker.
+something like Class::Struct or Class::MethodMaker.
 
-=head2 NOTES
+=head1 NOTES
 
 =head2 Object Terminology
 
@@ -1694,50 +1697,35 @@ get at the same concepts in Perl.
 
 For example, it's common to call an object an I<instance> of a class
 and to call those objects' methods I<instance methods>.  Data fields
-particular to each object are often called I<instance data> or <object
+peculiar to each object are often called I<instance data> or I<object
 attributes>, and data fields common to all members of that class are
 I<class data>, I<class attributes>, or I<static data members>.
 
-Also, I<base class>, I<generic class>, and I<subclass> all describe
+Also, I<base class>, I<generic class>, and I<superclass> all describe
 the same notion, whereas I<derived class>, I<specific class>, and
-I<superclass> describe the other related one.
+I<subclass> describe the other related one.
 
 C++ programmers have I<static methods> and I<virtual methods>,
-but Perl only has I<class methods> and I<object methods>.  
+but Perl only has I<class methods> and I<object methods>.
 Actually, Perl only has methods.  Whether a method gets used
 as a class or object method is by usage only.  You could accidentally
-call a class method (one expecting a string argument) on an 
+call a class method (one expecting a string argument) on an
 object (one expecting a reference), or vice versa.
 
->From the C++ perspective, all methods in Perl are virtual.
+From the C++ perspective, all methods in Perl are virtual.
 This, by the way, is why they are never checked for function
-prototypes in the argument list as regular built-in and user-defined
+prototypes in the argument list as regular builtin and user-defined
 functions can be.
 
 Because a class is itself something of an object, Perl's classes can be
 taken as describing both a "class as meta-object" (also called I<object
 factory>) philosophy and the "class as type definition" (I<declaring>
-behavior, not I<defining> mechanism) idea.  C++ supports the latter
+behaviour, not I<defining> mechanism) idea.  C++ supports the latter
 notion, but not the former.
 
-=head2 Programming with Style
-
-Remember the underscores we used on "start_date" and "START_DATE"?
-While some programmers might be tempted to leave them out, please don't.
-Otherwise it's hard for some people to read.   Also, you'd have to make
-up a new rule for identifiers that you've rendered in all capitals,
-like START_DATE.  Plus you get people wondering whether it's "startdate",
-"Startdate", "startDate", "StartDate", or some other crazy variation.
-And adding another word, like "employee_start_date", just racks up the
-confusion.  Nobody but a compiler wants to parse "employeestartdate" or
-even "EmployeeStartDate".  So (almost) always use underscores to separate
-words in identifiers.  See also L<perlstyle> and either L<perlmod> or the
-list of registered modules posted periodically to comp.lang.perl.modules
-or found on CPAN in the http://www.perl.com/CPAN/modules/ directory.
-
 =head1 SEE ALSO
 
-The following man pages will doubtless provide more
+The following manpages will doubtless provide more
 background for this one:
 L<perlmod>,
 L<perlref>,
@@ -1747,30 +1735,41 @@ L<perltie>,
 and
 L<overload>.
 
-=head1 COPYRIGHT
+L<perlboot> is a kinder, gentler introduction to object-oriented
+programming.
+
+L<perltooc> provides more detail on class data.
+
+Some modules which might prove interesting are Class::Accessor,
+Class::Class, Class::Contract, Class::Data::Inheritable,
+Class::MethodMaker and Tie::SecureHash
 
-I I<really> hate to have to say this, but recent unpleasant
-experiences have mandated its inclusion:
-
-    Copyright 1996 Tom Christiansen.  All Rights Reserved.
-
-This work derives in part from the second edition of I<Programming Perl>.
-Although destined for release as a man page with the standard Perl
-distribution, it is not public domain (nor is any of Perl and its docset:
-publishers beware).  It's expected to someday make its way into a revision
-of the Camel Book.  While it is copyright by me with all rights reserved,
-permission is granted to freely distribute verbatim copies of this
-document provided that no modifications outside of formatting be made,
-and that this notice remain intact.  You are permitted and encouraged to
-use its code and derivatives thereof in your own source code for fun or
-for profit as you see fit.  But so help me, if in six months I find some
-book out there with a hacked-up version of this material in it claiming to
-be written by someone else, I'll tell all the world that you're a jerk.
-Furthermore, your lawyer will meet my lawyer (or O'Reilly's) over lunch
-to arrange for you to receive your just deserts.  Count on it.
+
+=head1 AUTHOR AND COPYRIGHT
+
+Copyright (c) 1997, 1998 Tom Christiansen 
+All rights reserved.
+
+This documentation is free; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+Irrespective of its distribution, all code examples in this file
+are hereby placed into the public domain.  You are permitted and
+encouraged to use this code in your own programs for fun
+or for profit as you see fit.  A simple comment in the code giving
+credit would be courteous but is not required.
+
+=head1 COPYRIGHT
 
 =head2 Acknowledgments
 
-Thanks to Brad Appleton, Raphael Manfredi, Dean Roehrich, Gurusamy
-Sarathy, and many others from the perl porters list for their helpful
-comments.
+Thanks to
+Larry Wall,
+Roderick Schertler,
+Gurusamy Sarathy,
+Dean Roehrich,
+Raphael Manfredi,
+Brent Halsey,
+Greg Bacon,
+Brad Appleton,
+and many others for their helpful comments.