Приглашаем посетить
Ахматова (ahmatova.niv.ru)

Section 11.4.  Calling a Second Method to Simplify Things

Previous
Table of Contents
Next

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.


Previous
Table of Contents
Next