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.
|