[ Team LiB ] Previous Section Next Section

8.4 Calling a Second Method to Simplify Things

You can 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 you call Cow->speak, you get a $class of Cow in speak. This, in turn, selects the Cow->sound method, which returns moooo. 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 you share the definition for speak between the cow and the horse? Yes, with inheritance!

Now let's 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, you can 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.

What happens when you invoke Cow->speak now?

First, Perl constructs the argument list. In this case, it's just Cow. Then Perl looks for Cow::speak. 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. That found, Perl invokes that subroutine with the already frozen argument list, as if you had said:

Animal::speak("Cow");

Inside the Animal::speak subroutine, $class becomes Cow as the first argument is shifted off. When you get to the step of invoking $class->sound while performing the print, it looks for Cow->sound:

print "a $class goes ", $class->sound, "!\n";
# but $class is Cow, so...
print "a Cow goes ", Cow->sound, "!\n";
# which invokes Cow->sound, returning "moooo", so
print "a Cow goes ", "moooo", "!\n";

and you get your desired output.

    [ Team LiB ] Previous Section Next Section