NAME 

perlboot - Beginner's Object-Oriented Tutorial

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 perlobj, a basic reference in using objects, and 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 (perlsub), references (perlref et. seq.), and packages (perlmod), so become familiar with those first if you haven't already.

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 "no strict subs" 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?

Introducing the method invocation arrow 

For now, let's say that "Class->method" invokes subroutine "method" in package "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 "use strict refs" is enabled.

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 "speak" routines has a similar structure: a "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 "says" instead of "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.

The extra parameter of method invocation 

The invocation of:
    Class->method(@args)

attempts to invoke subroutine "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 "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, $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.

Calling a second method to simplify things 

Let's call out from "speak" to a helper method called "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 "Cow->speak", we get a $class of "Cow" in "speak". This in turn selects the "Cow->sound" method, which returns "moooo". But how different would this be for the "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 "speak" between the Cow and the Horse? Yes, with inheritance!

Inheriting the windpipes 

We'll define a common subroutine package called "Animal", with the definition for "speak":
    { package Animal;
      sub speak {
        my $class = shift;
        print "a $class goes ", $class->sound, "!\n"
      }
    }

Then, for each animal, we say it ``inherits'' from "Animal", along with the animal-specific sound:

    { package Cow;
      @ISA = qw(Animal);
      sub sound { "moooo" }
    }

Note the added @ISA array. We'll get to that in a minute.

But what happens when we invoke "Cow->speak" now?

First, Perl constructs the argument list. In this case, it's just "Cow". Then Perl looks for "Cow::speak". But that's not there, so Perl checks for the inheritance array @Cow::ISA. It's there, and contains the single name "Animal".

Perl next checks for "speak" inside "Animal" instead, as in "Animal::speak". And that's found, so Perl invokes that subroutine with the already frozen argument list.

Inside the "Animal::speak" subroutine, $class becomes "Cow" (the first argument). So when we get to the step of invoking "$class->sound", it'll be looking for "Cow->sound", which gets it on the first try without looking at @ISA. Success!