11.4. Calling a Second Method to Simplify Things
We 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 we call Cow->speak, we 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 we share the definition for speak between the cow and the horse? Yes, with inheritance
!
Now let's define a common method 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 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 we 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 method with the already frozen argument list, as if we had said:
Animal::speak('Cow');
Inside the Animal::speak method, $class becomes Cow as the first argument is shifted off. When we 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 we get our desired output.
|