This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
infnan: comment tweaks
[perl5.git] / pod / perlboot.pod
index 64ad4e7..8259998 100644 (file)
+=encoding utf8
+
 =head1 NAME
 
-perlboot - Beginner's Object-Oriented Tutorial
+perlboot - Links to information on object-oriented programming in Perl
 
 =head1 DESCRIPTION
 
-If you're not familiar with objects from other languages, some of the
-other Perl object documentation may be a little daunting, such as
-L<perlobj>, a basic reference in using objects, and L<perltoot>, which
-introduces readers to the peculiarities of Perl's object system in a
-tutorial way.
-
-So, let's take a different approach, presuming no prior object
-experience. It helps if you know about subroutines (L<perlsub>),
-references (L<perlref> et. seq.), and packages (L<perlmod>), so become
-familiar with those first if you haven't already.
-
-=head2 If we could talk to the animals...
-
-Let's let the animals talk for a moment:
-
-    sub Cow::speak {
-      print "a Cow goes moooo!\n";
-    }
-    sub Horse::speak {
-      print "a Horse goes neigh!\n";
-    }
-    sub Sheep::speak {
-      print "a Sheep goes baaaah!\n";
-    }
-
-    Cow::speak;
-    Horse::speak;
-    Sheep::speak;
-
-This results in:
-
-    a Cow goes moooo!
-    a Horse goes neigh!
-    a Sheep goes baaaah!
-
-Nothing spectacular here.  Simple subroutines, albeit from separate
-packages, and called using the full package name.  So let's create
-an entire pasture:
-
-    # Cow::speak, Horse::speak, Sheep::speak as before
-    @pasture = qw(Cow Cow Horse Sheep Sheep);
-    foreach $animal (@pasture) {
-      &{$animal."::speak"};
-    }
-
-This results in:
-
-    a Cow goes moooo!
-    a Cow goes moooo!
-    a Horse goes neigh!
-    a Sheep goes baaaah!
-    a Sheep goes baaaah!
-
-Wow.  That symbolic coderef de-referencing there is pretty nasty.
-We're counting on C<no strict refs> mode, certainly not recommended
-for larger programs.  And why was that necessary?  Because the name of
-the package seems to be inseparable from the name of the subroutine we
-want to invoke within that package.
-
-Or is it?
-
-=head2 Introducing the method invocation arrow
-
-For now, let's say that C<< Class->method >> invokes subroutine
-C<method> in package C<Class>.  (Here, "Class" is used in its
-"category" meaning, not its "scholastic" meaning.) That's not
-completely accurate, but we'll do this one step at a time.  Now let's
-use it like so:
-
-    # Cow::speak, Horse::speak, Sheep::speak as before
-    Cow->speak;
-    Horse->speak;
-    Sheep->speak;
-
-And once again, this results in:
-
-    a Cow goes moooo!
-    a Horse goes neigh!
-    a Sheep goes baaaah!
-
-That's not fun yet.  Same number of characters, all constant, no
-variables.  But yet, the parts are separable now.  Watch:
-
-    $a = "Cow";
-    $a->speak; # invokes Cow->speak
-
-Ahh!  Now that the package name has been parted from the subroutine
-name, we can use a variable package name.  And this time, we've got
-something that works even when C<use strict refs> is enabled.
-
-=head2 Invoking a barnyard
-
-Let's take that new arrow invocation and put it back in the barnyard
-example:
-
-    sub Cow::speak {
-      print "a Cow goes moooo!\n";
-    }
-    sub Horse::speak {
-      print "a Horse goes neigh!\n";
-    }
-    sub Sheep::speak {
-      print "a Sheep goes baaaah!\n";
-    }
-
-    @pasture = qw(Cow Cow Horse Sheep Sheep);
-    foreach $animal (@pasture) {
-      $animal->speak;
-    }
-
-There!  Now we have the animals all talking, and safely at that,
-without the use of symbolic coderefs.
-
-But look at all that common code.  Each of the C<speak> routines has a
-similar structure: a C<print> operator and a string that contains
-common text, except for two of the words.  It'd be nice if we could
-factor out the commonality, in case we decide later to change it all
-to C<says> instead of C<goes>.
-
-And we actually have a way of doing that without much fuss, but we
-have to hear a bit more about what the method invocation arrow is
-actually doing for us.
-
-=head2 The extra parameter of method invocation
-
-The invocation of:
-
-    Class->method(@args)
-
-attempts to invoke subroutine C<Class::method> as:
-
-    Class::method("Class", @args);
-
-(If the subroutine can't be found, "inheritance" kicks in, but we'll
-get to that later.)  This means that we get the class name as the
-first parameter (the only parameter, if no arguments are given).  So
-we can rewrite the C<Sheep> speaking subroutine as:
-
-    sub Sheep::speak {
-      my $class = shift;
-      print "a $class goes baaaah!\n";
-    }
-
-And the other two animals come out similarly:
-
-    sub Cow::speak {
-      my $class = shift;
-      print "a $class goes moooo!\n";
-    }
-    sub Horse::speak {
-      my $class = shift;
-      print "a $class goes neigh!\n";
-    }
-
-In each case, C<$class> will get the value appropriate for that
-subroutine.  But once again, we have a lot of similar structure.  Can
-we factor that out even further?  Yes, by calling another method in
-the same class.
-
-=head2 Calling a second method to simplify things
-
-Let's call out from C<speak> to a helper method called C<sound>.
-This method provides the constant text for the sound itself.
-
-    { package Cow;
-      sub sound { "moooo" }
-      sub speak {
-       my $class = shift;
-       print "a $class goes ", $class->sound, "!\n";
-      }
-    }
-
-Now, when we call C<< Cow->speak >>, we get a C<$class> of C<Cow> in
-C<speak>.  This in turn selects the C<< Cow->sound >> method, which
-returns C<moooo>.  But how different would this be for the C<Horse>?
-
-    { package Horse;
-      sub sound { "neigh" }
-      sub speak {
-       my $class = shift;
-       print "a $class goes ", $class->sound, "!\n";
-      }
-    }
-
-Only the name of the package and the specific sound change.  So can we
-somehow share the definition for C<speak> between the Cow and the
-Horse?  Yes, with inheritance!
-
-=head2 Inheriting the windpipes
-
-We'll define a common subroutine package called C<Animal>, with the
-definition for C<speak>:
-
-    { package Animal;
-      sub speak {
-       my $class = shift;
-       print "a $class goes ", $class->sound, "!\n";
-      }
-    }
-
-Then, for each animal, we say it "inherits" from C<Animal>, along
-with the animal-specific sound:
-
-    { package Cow;
-      @ISA = qw(Animal);
-      sub sound { "moooo" }
-    }
-
-Note the added C<@ISA> array (pronounced "is a").  We'll get to that in a minute.
-
-But what happens when we invoke C<< Cow->speak >> now?
-
-First, Perl constructs the argument list.  In this case, it's just
-C<Cow>.  Then Perl looks for C<Cow::speak>.  But that's not there, so
-Perl checks for the inheritance array C<@Cow::ISA>.  It's there,
-and contains the single name C<Animal>.
-
-Perl next checks for C<speak> inside C<Animal> instead, as in
-C<Animal::speak>.  And that's found, so Perl invokes that subroutine
-with the already frozen argument list.
-
-Inside the C<Animal::speak> subroutine, C<$class> becomes C<Cow> (the
-first argument).  So when we get to the step of invoking
-C<< $class->sound >>, it'll be looking for C<< Cow->sound >>, which
-gets it on the first try without looking at C<@ISA>.  Success!
-
-=head2 A few notes about @ISA
-
-This magical C<@ISA> variable has declared that C<Cow> "is a" C<Animal>.
-Note that it's an array, not a simple single value, because on rare
-occasions, it makes sense to have more than one parent class searched
-for the missing methods.
-
-If C<Animal> also had an C<@ISA>, then we'd check there too.  The
-search is recursive, depth-first, left-to-right in each C<@ISA> by
-default (see L<mro> for alternatives).  Typically, each C<@ISA> has
-only one element (multiple elements means multiple inheritance and
-multiple headaches), so we get a nice tree of inheritance.
-
-When we turn on C<use strict>, we'll get complaints on C<@ISA>, since
-it's not a variable containing an explicit package name, nor is it a
-lexical ("my") variable.  We can't make it a lexical variable though
-(it has to belong to the package to be found by the inheritance mechanism),
-so there's a couple of straightforward ways to handle that.
-
-The easiest is to just spell the package name out:
-
-    @Cow::ISA = qw(Animal);
-
-Or declare it as package global variable:
-
-    package Cow;
-    our @ISA = qw(Animal);
-
-Or allow it as an implicitly named package variable:
-
-    package Cow;
-    use vars qw(@ISA);
-    @ISA = qw(Animal);
-
-If you're bringing in the class from outside, via an object-oriented
-module, you change:
-
-    package Cow;
-    use Animal;
-    use vars qw(@ISA);
-    @ISA = qw(Animal);
-
-into just:
-
-    package Cow;
-    use base qw(Animal);
-
-And that's pretty darn compact.
-
-=head2 Overriding the methods
-
-Let's add a mouse, which can barely be heard:
-
-    # Animal package from before
-    { package Mouse;
-      @ISA = qw(Animal);
-      sub sound { "squeak" }
-      sub speak {
-        my $class = shift;
-       print "a $class goes ", $class->sound, "!\n";
-       print "[but you can barely hear it!]\n";
-      }
-    }
-
-    Mouse->speak;
-
-which results in:
-
-    a Mouse goes squeak!
-    [but you can barely hear it!]
-
-Here, C<Mouse> has its own speaking routine, so C<< Mouse->speak >>
-doesn't immediately invoke C<< Animal->speak >>.  This is known as
-"overriding".  In fact, we didn't even need to say that a C<Mouse> was
-an C<Animal> at all, since all of the methods needed for C<speak> are
-completely defined with C<Mouse>.
-
-But we've now duplicated some of the code from C<< Animal->speak >>,
-and this can once again be a maintenance headache.  So, can we avoid
-that?  Can we say somehow that a C<Mouse> does everything any other
-C<Animal> does, but add in the extra comment?  Sure!
-
-First, we can invoke the C<Animal::speak> method directly:
-
-    # Animal package from before
-    { package Mouse;
-      @ISA = qw(Animal);
-      sub sound { "squeak" }
-      sub speak {
-        my $class = shift;
-        Animal::speak($class);
-       print "[but you can barely hear it!]\n";
-      }
-    }
-
-Note that we have to include the C<$class> parameter (almost surely
-the value of C<"Mouse">) as the first parameter to C<Animal::speak>,
-since we've stopped using the method arrow.  Why did we stop?  Well,
-if we invoke C<< Animal->speak >> there, the first parameter to the
-method will be C<"Animal"> not C<"Mouse">, and when time comes for it
-to call for the C<sound>, it won't have the right class to come back
-to this package.
-
-Invoking C<Animal::speak> directly is a mess, however.  What if
-C<Animal::speak> didn't exist before, and was being inherited from a
-class mentioned in C<@Animal::ISA>?  Because we are no longer using
-the method arrow, we get one and only one chance to hit the right
-subroutine.
-
-Also note that the C<Animal> classname is now hardwired into the
-subroutine selection.  This is a mess if someone maintains the code,
-changing C<@ISA> for C<Mouse> and didn't notice C<Animal> there in
-C<speak>.  So, this is probably not the right way to go.
-
-=head2 Starting the search from a different place
-
-A better solution is to tell Perl to search from a higher place
-in the inheritance chain:
-
-    # same Animal as before
-    { package Mouse;
-      # same @ISA, &sound as before
-      sub speak {
-        my $class = shift;
-        $class->Animal::speak;
-        print "[but you can barely hear it!]\n";
-      }
-    }
-
-Ahh.  This works.  Using this syntax, we start with C<Animal> to find
-C<speak>, and use all of C<Animal>'s inheritance chain if not found
-immediately.  And yet the first parameter will be C<$class>, so the
-found C<speak> method will get C<Mouse> as its first entry, and
-eventually work its way back to C<Mouse::sound> for the details.
-
-But this isn't the best solution.  We still have to keep the C<@ISA>
-and the initial search package coordinated.  Worse, if C<Mouse> had
-multiple entries in C<@ISA>, we wouldn't necessarily know which one
-had actually defined C<speak>.  So, is there an even better way?
-
-=head2 The SUPER way of doing things
-
-By changing the C<Animal> class to the C<SUPER> class in that
-invocation, we get a search of all of our super classes (classes
-listed in C<@ISA>) automatically:
-
-    # same Animal as before
-    { package Mouse;
-      # same @ISA, &sound as before
-      sub speak {
-        my $class = shift;
-        $class->SUPER::speak;
-        print "[but you can barely hear it!]\n";
-      }
-    }
-
-So, C<SUPER::speak> means look in the current package's C<@ISA> for
-C<speak>, invoking the first one found. Note that it does I<not> look in
-the C<@ISA> of C<$class>.
-
-=head2 Where we're at so far...
-
-So far, we've seen the method arrow syntax:
-
-  Class->method(@args);
-
-or the equivalent:
-
-  $a = "Class";
-  $a->method(@args);
-
-which constructs an argument list of:
-
-  ("Class", @args)
-
-and attempts to invoke
-
-  Class::method("Class", @Args);
-
-However, if C<Class::method> is not found, then C<@Class::ISA> is examined
-(recursively) to locate a package that does indeed contain C<method>,
-and that subroutine is invoked instead.
-
-Using this simple syntax, we have class methods, (multiple)
-inheritance, overriding, and extending.  Using just what we've seen so
-far, we've been able to factor out common code, and provide a nice way
-to reuse implementations with variations.  This is at the core of what
-objects provide, but objects also provide instance data, which we
-haven't even begun to cover.
-
-=head2 A horse is a horse, of course of course -- or is it?
-
-Let's start with the code for the C<Animal> class
-and the C<Horse> class:
-
-  { package Animal;
-    sub speak {
-      my $class = shift;
-      print "a $class goes ", $class->sound, "!\n";
-    }
-  }
-  { package Horse;
-    @ISA = qw(Animal);
-    sub sound { "neigh" }
-  }
-
-This lets us invoke C<< Horse->speak >> to ripple upward to
-C<Animal::speak>, calling back to C<Horse::sound> to get the specific
-sound, and the output of:
-
-  a Horse goes neigh!
-
-But all of our Horse objects would have to be absolutely identical.
-If I add a subroutine, all horses automatically share it.  That's
-great for making horses the same, but how do we capture the
-distinctions about an individual horse?  For example, suppose I want
-to give my first horse a name.  There's got to be a way to keep its
-name separate from the other horses.
-
-We can do that by drawing a new distinction, called an "instance".
-An "instance" is generally created by a class.  In Perl, any reference
-can be an instance, so let's start with the simplest reference
-that can hold a horse's name: a scalar reference.
-
-  my $name = "Mr. Ed";
-  my $talking = \$name;
-
-So now C<$talking> is a reference to what will be the instance-specific
-data (the name).  The final step in turning this into a real instance
-is with a special operator called C<bless>:
-
-  bless $talking, Horse;
-
-This operator stores information about the package named C<Horse> into
-the thing pointed at by the reference.  At this point, we say
-C<$talking> is an instance of C<Horse>.  That is, it's a specific
-horse.  The reference is otherwise unchanged, and can still be used
-with traditional dereferencing operators.
-
-=head2 Invoking an instance method
-
-The method arrow can be used on instances, as well as names of
-packages (classes).  So, let's get the sound that C<$talking> makes:
-
-  my $noise = $talking->sound;
-
-To invoke C<sound>, Perl first notes that C<$talking> is a blessed
-reference (and thus an instance).  It then constructs an argument
-list, in this case from just C<($talking)>.  (Later we'll see that
-arguments will take their place following the instance variable,
-just like with classes.)
-
-Now for the fun part: Perl takes the class in which the instance was
-blessed, in this case C<Horse>, and uses that to locate the subroutine
-to invoke the method.  In this case, C<Horse::sound> is found directly
-(without using inheritance), yielding the final subroutine invocation:
-
-  Horse::sound($talking)
-
-Note that the first parameter here is still the instance, not the name
-of the class as before.  We'll get C<neigh> as the return value, and
-that'll end up as the C<$noise> variable above.
-
-If Horse::sound had not been found, we'd be wandering up the
-C<@Horse::ISA> list to try to find the method in one of the
-superclasses, just as for a class method.  The only difference between
-a class method and an instance method is whether the first parameter
-is an instance (a blessed reference) or a class name (a string).
-
-=head2 Accessing the instance data
-
-Because we get the instance as the first parameter, we can now access
-the instance-specific data.  In this case, let's add a way to get at
-the name:
-
-  { package Horse;
-    @ISA = qw(Animal);
-    sub sound { "neigh" }
-    sub name {
-      my $self = shift;
-      $$self;
-    }
-  }
-
-Now we call for the name:
-
-  print $talking->name, " says ", $talking->sound, "\n";
-
-Inside C<Horse::name>, the C<@_> array contains just C<$talking>,
-which the C<shift> stores into C<$self>.  (It's traditional to shift
-the first parameter off into a variable named C<$self> for instance
-methods, so stay with that unless you have strong reasons otherwise.)
-Then, C<$self> gets de-referenced as a scalar ref, yielding C<Mr. Ed>,
-and we're done with that.  The result is:
-
-  Mr. Ed says neigh.
-
-=head2 How to build a horse
-
-Of course, if we constructed all of our horses by hand, we'd most
-likely make mistakes from time to time.  We're also violating one of
-the properties of object-oriented programming, in that the "inside
-guts" of a Horse are visible.  That's good if you're a veterinarian,
-but not if you just like to own horses.  So, let's let the Horse class
-build a new horse:
-
-  { package Horse;
-    @ISA = qw(Animal);
-    sub sound { "neigh" }
-    sub name {
-      my $self = shift;
-      $$self;
-    }
-    sub named {
-      my $class = shift;
-      my $name = shift;
-      bless \$name, $class;
-    }
-  }
-
-Now with the new C<named> method, we can build a horse:
-
-  my $talking = Horse->named("Mr. Ed");
-
-Notice we're back to a class method, so the two arguments to
-C<Horse::named> are C<Horse> and C<Mr. Ed>.  The C<bless> operator
-not only blesses C<$name>, it also returns the reference to C<$name>,
-so that's fine as a return value.  And that's how to build a horse.
-
-We've called the constructor C<named> here, so that it quickly denotes
-the constructor's argument as the name for this particular C<Horse>.
-You can use different constructors with different names for different
-ways of "giving birth" to the object (like maybe recording its
-pedigree or date of birth).  However, you'll find that most people
-coming to Perl from more limited languages use a single constructor
-named C<new>, with various ways of interpreting the arguments to
-C<new>.  Either style is fine, as long as you document your particular
-way of giving birth to an object.  (And you I<were> going to do that,
-right?)
-
-=head2 Inheriting the constructor
-
-But was there anything specific to C<Horse> in that method?  No.  Therefore,
-it's also the same recipe for building anything else that inherited from
-C<Animal>, so let's put it there:
-
-  { package Animal;
-    sub speak {
-      my $class = shift;
-      print "a $class goes ", $class->sound, "!\n";
-    }
-    sub name {
-      my $self = shift;
-      $$self;
-    }
-    sub named {
-      my $class = shift;
-      my $name = shift;
-      bless \$name, $class;
-    }
-  }
-  { package Horse;
-    @ISA = qw(Animal);
-    sub sound { "neigh" }
-  }
-
-Ahh, but what happens if we invoke C<speak> on an instance?
-
-  my $talking = Horse->named("Mr. Ed");
-  $talking->speak;
-
-We get a debugging value:
-
-  a Horse=SCALAR(0xaca42ac) goes neigh!
-
-Why?  Because the C<Animal::speak> routine is expecting a classname as
-its first parameter, not an instance.  When the instance is passed in,
-we'll end up using a blessed scalar reference as a string, and that
-shows up as we saw it just now.
-
-=head2 Making a method work with either classes or instances
-
-All we need is for a method to detect if it is being called on a class
-or called on an instance.  The most straightforward way is with the
-C<ref> operator.  This returns a string (the classname) when used on a
-blessed reference, and an empty string when used on a string (like a
-classname).  Let's modify the C<name> method first to notice the change:
-
-  sub name {
-    my $either = shift;
-    ref $either
-      ? $$either # it's an instance, return name
-      : "an unnamed $either"; # it's a class, return generic
-  }
-
-Here, the C<?:> operator comes in handy to select either the
-dereference or a derived string.  Now we can use this with either an
-instance or a class.  Note that I've changed the first parameter
-holder to C<$either> to show that this is intended:
-
-  my $talking = Horse->named("Mr. Ed");
-  print Horse->name, "\n"; # prints "an unnamed Horse\n"
-  print $talking->name, "\n"; # prints "Mr Ed.\n"
-
-and now we'll fix C<speak> to use this:
-
-  sub speak {
-    my $either = shift;
-    print $either->name, " goes ", $either->sound, "\n";
-  }
-
-And since C<sound> already worked with either a class or an instance,
-we're done!
-
-=head2 Adding parameters to a method
-
-Let's train our animals to eat:
-
-  { package Animal;
-    sub named {
-      my $class = shift;
-      my $name = shift;
-      bless \$name, $class;
-    }
-    sub name {
-      my $either = shift;
-      ref $either
-       ? $$either # it's an instance, return name
-       : "an unnamed $either"; # it's a class, return generic
-    }
-    sub speak {
-      my $either = shift;
-      print $either->name, " goes ", $either->sound, "\n";
-    }
-    sub eat {
-      my $either = shift;
-      my $food = shift;
-      print $either->name, " eats $food.\n";
-    }
-  }
-  { package Horse;
-    @ISA = qw(Animal);
-    sub sound { "neigh" }
-  }
-  { package Sheep;
-    @ISA = qw(Animal);
-    sub sound { "baaaah" }
-  }
-
-And now try it out:
-
-  my $talking = Horse->named("Mr. Ed");
-  $talking->eat("hay");
-  Sheep->eat("grass");
-
-which prints:
-
-  Mr. Ed eats hay.
-  an unnamed Sheep eats grass.
-
-An instance method with parameters gets invoked with the instance,
-and then the list of parameters.  So that first invocation is like:
-
-  Animal::eat($talking, "hay");
-
-=head2 More interesting instances
-
-What if an instance needs more data?  Most interesting instances are
-made of many items, each of which can in turn be a reference or even
-another object.  The easiest way to store these is often in a hash.
-The keys of the hash serve as the names of parts of the object (often
-called "instance variables" or "member variables"), and the
-corresponding values are, well, the values.
-
-But how do we turn the horse into a hash?  Recall that an object was
-any blessed reference.  We can just as easily make it a blessed hash
-reference as a blessed scalar reference, as long as everything that
-looks at the reference is changed accordingly.
-
-Let's make a sheep that has a name and a color:
-
-  my $bad = bless { Name => "Evil", Color => "black" }, Sheep;
-
-so C<< $bad->{Name} >> has C<Evil>, and C<< $bad->{Color} >> has
-C<black>.  But we want to make C<< $bad->name >> access the name, and
-that's now messed up because it's expecting a scalar reference.  Not
-to worry, because that's pretty easy to fix up:
-
-  ## in Animal
-  sub name {
-    my $either = shift;
-    ref $either ?
-      $either->{Name} :
-      "an unnamed $either";
-  }
-
-And of course C<named> still builds a scalar sheep, so let's fix that
-as well:
-
-  ## in Animal
-  sub named {
-    my $class = shift;
-    my $name = shift;
-    my $self = { Name => $name, Color => $class->default_color };
-    bless $self, $class;
-  }
-
-What's this C<default_color>?  Well, if C<named> has only the name,
-we still need to set a color, so we'll have a class-specific initial color.
-For a sheep, we might define it as white:
-
-  ## in Sheep
-  sub default_color { "white" }
-
-And then to keep from having to define one for each additional class,
-we'll define a "backstop" method that serves as the "default default",
-directly in C<Animal>:
-
-  ## in Animal
-  sub default_color { "brown" }
-
-Now, because C<name> and C<named> were the only methods that
-referenced the "structure" of the object, the rest of the methods can
-remain the same, so C<speak> still works as before.
-
-=head2 A horse of a different color
-
-But having all our horses be brown would be boring.  So let's add a
-method or two to get and set the color.
-
-  ## in Animal
-  sub color {
-    $_[0]->{Color}
-  }
-  sub set_color {
-    $_[0]->{Color} = $_[1];
-  }
-
-Note the alternate way of accessing the arguments: C<$_[0]> is used
-in-place, rather than with a C<shift>.  (This saves us a bit of time
-for something that may be invoked frequently.)  And now we can fix
-that color for Mr. Ed:
-
-  my $talking = Horse->named("Mr. Ed");
-  $talking->set_color("black-and-white");
-  print $talking->name, " is colored ", $talking->color, "\n";
-
-which results in:
-
-  Mr. Ed is colored black-and-white
-
-=head2 Summary
-
-So, now we have class methods, constructors, instance methods,
-instance data, and even accessors.  But that's still just the
-beginning of what Perl has to offer.  We haven't even begun to talk
-about accessors that double as getters and setters, destructors,
-indirect object notation, subclasses that add instance data, per-class
-data, overloading, "isa" and "can" tests, C<UNIVERSAL> class, and so
-on.  That's for the rest of the Perl documentation to cover.
-Hopefully, this gets you started, though.
-
-=head1 SEE ALSO
-
-For more information, see L<perlobj> (for all the gritty details about
-Perl objects, now that you've seen the basics), L<perltoot> (the
-tutorial for those who already know objects), L<perltooc> (dealing
-with class data), L<perlbot> (for some more tricks), and books such as
-Damian Conway's excellent I<Object Oriented Perl>.
-
-Some modules which might prove interesting are Class::Accessor,
-Class::Class, Class::Contract, Class::Data::Inheritable,
-Class::MethodMaker and Tie::SecureHash
-
-=head1 COPYRIGHT
-
-Copyright (c) 1999, 2000 by Randal L. Schwartz and Stonehenge
-Consulting Services, Inc.  Permission is hereby granted to distribute
-this document intact with the Perl distribution, and in accordance
-with the licenses of the Perl distribution; derived documents must
-include this copyright notice intact.
+For information on OO programming with Perl, please see L<perlootut>
+and L<perlobj>.
 
-Portions of this text have been derived from Perl Training materials
-originally appearing in the I<Packages, References, Objects, and
-Modules> course taught by instructors for Stonehenge Consulting
-Services, Inc. and used with permission.
+(The above documents supersede the tutorial that was formerly here in
+perlboot.)
 
-Portions of this text have been derived from materials originally
-appearing in I<Linux Magazine> and used with permission.
+=cut