home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Book Home Programming PerlSearch this book

12.5. Class Inheritance

As with the rest of Perl's object system, inheritance of one class by another requires no special syntax to be added to the language. When you invoke a method for which Perl finds no subroutine in the invocant's package, that package's @ISA array[5] is examined. This is how Perl implements inheritance: each element of a given package's @ISA array holds the name of another package, which is searched when methods are missing. For example, the following makes the Horse class a subclass of the Critter class. (We declare @ISA with our because it has to be a package variable, not a lexical declared with my.)

package Horse;
our @ISA = "Critter";
You should now be able to use a Horse class or object everywhere that a Critter was previously used. If your new class passes this empty subclass test, you know that Critter is a proper base class, fit for inheritance.

[5] Pronounced "is a", as in "A horse is a critter."

Suppose you have a Horse object in $steed and invoke a move method on it:

$steed->move(10);
Because $steed is a Horse, Perl's first choice for that method is the Horse::move subroutine. If there isn't one, instead of raising a run-time exception, Perl consults the first element of @Horse::ISA, which directs it to look in the Critter package for Critter::move. If this subroutine isn't found either, and Critter has its own @Critter::ISA array, then that too will be consulted for the name of an ancestral package that might supply a move method, and so on back up the inheritance hierarchy until we come to a package without an @ISA.

The situation we just described is single inheritance, where each class has only one parent. Such inheritance is like a linked list of related packages. Perl also supports multiple inheritance; just add more packages to the class's @ISA. This kind of inheritance works more like a tree data structure, because every package can have more than one immediate parent. Some people find this to be sexier.

When you invoke a method methname on an invocant of type classname, Perl tries six different ways to find a subroutine to use:

  1. First, Perl looks in the invocant's own package for a subroutine named classname::methname. If that fails, inheritance kicks in, and we go to step 2.

  2. Next, Perl checks for methods inherited from base classes by looking in all parent packages listed in @classname::ISA for a parent::methname subroutine. The search is left-to-right, recursive, and depth-first. The recursion assures that grandparent classes, great-grandparent classes, great-great-grandparent classes, and so on, are all searched.

  3. If that fails, Perl looks for a subroutine named UNIVERSAL::methname.

  4. At this point, Perl gives up on methname and starts looking for an AUTOLOAD. First, it looks for a subroutine named classname::AUTOLOAD.

  5. Failing that, Perl searches all parent packages listed in @classname::ISA, for any parent::AUTOLOAD subroutine. The search is again left-to-right, recursive, and depth-first.

  6. Finally, Perl looks for a subroutine named UNIVERSAL::AUTOLOAD.

Perl stops after the first successful attempt and invokes that subroutine. If no subroutine is found, an exception is raised, one that you'll see frequently:

Can't locate object method "methname" via package "classname"
If you've built a debugging version of Perl using the -DDEBUGGING option to your C compiler, by using Perl's -Do switch, you can watch it go through each of these steps when it resolves method invocation.

We will discuss the inheritance mechanism in more detail as we go along.

12.5.1. Inheritance Through @ISA

If @ISA contains more than one package name, the packages are all searched in left-to-right order. The search is depth-first, so if you have a Mule class set up for inheritance this way:

package Mule;
our @ISA = ("Horse", "Donkey");
Perl looks for any methods missing from Mule first in Horse (and any of its ancestors, like Critter) before going on to search through Donkey and its ancestors.

If a missing method is found in a base class, Perl internally caches that location in the current class for efficiency, so the next time it has to find the method, it doesn't have to look as far. Changing @ISA or defining new methods invalidates the cache and causes Perl to perform the lookup again.

When Perl searches for a method, it makes sure that you haven't created a circular inheritance hierarchy. This could happen if two classes inherit from one another, even indirectly through other classes. Trying to be your own great-grandfather is too paradoxical even for Perl, so the attempt raises an exception. However, Perl does not consider it an error to inherit from more than one class sharing a common ancestry, which is rather like cousins marrying. Your inheritance hierarchy just stops looking like a tree and starts to look like a directed acyclic graph. This doesn't bother Perl--so long as the graph really is acyclic.

When you set @ISA, the assignment normally happens at run time, so unless you take precautions, code in BEGIN, CHECK, or INIT blocks won't be able to use the inheritance hierarchy. One precaution (or convenience) is the use base pragma, which lets you require classes and add them to @ISA at compile time. Here's how you might use it:

package Mule;
use base ("Horse", "Donkey");   # declare superclasses
This is a shorthand for:
package Mule;
BEGIN {
    our @ISA = ("Horse", "Donkey");
    require Horse;
    require Donkey;
}
except that use base also takes into account any use fields declarations.

Sometimes folks are surprised that including a class in @ISA doesn't require the appropriate module for you. That's because Perl's class system is largely orthogonal to its module system. One file can hold many classes (since they're just packages), and one package may be mentioned in many files. But in the most common situation, where one package and one class and one module and one file all end up being pretty interchangeable if you squint enough, the use base pragma offers a declarative syntax that establishes inheritance, loads in module files, and accommodates any declared base class fields. It's one of those convenient diagonals we keep mentioning.

See the descriptions of use base and use fields in Chapter 31, "Pragmatic Modules" for further details.

12.5.2. Accessing Overridden Methods

When a class defines a method, that subroutine overrides methods of the same name in any base classes. Imagine that you've a Mule object (which is derived from class Horse and class Donkey), and you decide to invoke your object's breed method. Although the parent classes have their own breed methods, the designer of the Mule class overrode those by supplying the Mule class with its own breed method. That means the following cross is unlikely to be productive:

$stallion = Horse->new(gender => "male");
$molly = Mule->new(gender => "female");
$colt = $molly->breed($stallion);
Now suppose that through the miracle of genetic engineering, you find some way around a mule's notorious sterility problem, so you want to skip over the nonviable Mule::breed method. You could call your method as an ordinary subroutine, being sure to pass the invocant explicitly:
$colt = Horse::breed($molly, $stallion);
However, this sidesteps inheritance, which is nearly always the wrong thing to do. It's perfectly imaginable that no Horse::breed subroutine exists because both Horses and Donkeys derive that behavior from a common parent class called Equine. If, on the other hand, you want to specify that Perl should start searching for a method in a particular class, just use ordinary method invocation but qualify the method name with the class:
$colt = $molly->Horse::breed($stallion);
Occasionally, you'll want a method in a derived class to act as a wrapper around some method in a base class. The method in the derived class can itself invoke the method in the base class, adding its own actions before or after that invocation. You could use the notation just demonstrated to specify at which class to start the search. But in most cases of overridden methods, you don't want to have to know or specify which parent class's overridden method to execute.

That's where the SUPER pseudoclass comes in handy. It lets you invoke an overridden base class method without having to specify which class defined that method.[6] The following subroutine looks in the current package's @ISA without making you specify particular classes:

package Mule;
our @ISA = qw(Horse Donkey);
sub kick {
    my $self = shift;
    print "The mule kicks!\n";
    $self->SUPER::kick(@_);
}
The SUPER pseudopackage is meaningful only when used inside a method. Although the implementer of a class can employ SUPER in their own code, someone who merely uses a class's objects cannot.

[6] This is not to be confused with the mechanism mentioned in Chapter 11, "Modules" for overriding Perl's built-in functions, which aren't object methods and so aren't overridden by inheritance. You call overridden built-ins via the CORE pseudopackage, not the SUPER pseudopackage.

SUPER does not always work as you might like when multiple inheritance is involved. As you'd expect, it follows @ISA just as the regular inheritance mechanism does: in left-to-right, recursive, depth-first order. If both Horse and Donkey had a speak method, and you preferred the Donkey method, you'd have to name that parent class explicitly:

sub speak {
    my $self = shift;
    print "The mule speaks!\n";
    $self->Donkey::speak(@_);
}
More elaborate approaches to multiple inheritance situations can be crafted using the UNIVERSAL::can method described in the next section. Or you can grab the Class::Multimethods module from CPAN, which provides many elaborate solutions, including finding the closest match instead of leftmost one.

Every bit of code in Perl knows what its current package is, as determined by the last package statement. A SUPER method consults the @ISA only of the package into which the call to SUPER was compiled. It does not care about the class of the invocant, nor about the package of the subroutine that was called. This can cause problems if you try to define methods in another class by merely playing tricks with the method name:

package Bird;
use Dragonfly;
sub Dragonfly::divebomb { shift->SUPER::divebomb(@_) }

Unfortunately, this invokes Bird's superclass, not Dragonfly's. To do what you're trying to do, you need to explicitly switch into the appropriate package for the compilation of SUPER as well:

package Bird;
use Dragonfly;
{
    package Dragonfly;
    sub divebomb { shift->SUPER::divebomb(@_) }
}
As this example illustrates, you never need to edit a module file just to add methods to an existing class. Since a class is just a package, and a method just a subroutine, all you have to do is define a function in that package as we've done here, and the class suddenly has a new method. No inheritance required. Only the package matters, and since packages are global, any package can be accessed from anywhere in the program. (Did we mention we're going to install a jacuzzi in your living room next week?)

12.5.3. UNIVERSAL: The Ultimate Ancestor Class

If no method definition with the right name is found after searching the invocant's class and all its ancestor classes recursively, one more check for a method of that name is made in the special predefined class called UNIVERSAL. This package never appears in an @ISA, but is always consulted when an @ISA check fails. You can think of UNIVERSAL as the ultimate ancestor from which all classes implicitly derive.

The following predefined methods are available in class UNIVERSAL, and thus in all classes. These all work regardless of whether they are invoked as class methods or object methods.

INVOCANT->isa(CLASS)

The isa method returns true if INVOCANT's class is CLASS or any class inheriting from CLASS. Instead of a package name, CLASS may also be one of the built-in types, such as "HASH" or "ARRAY". (Checking for an exact type does not bode well for encapsulation or polymorphism, though. You should be relying on method dispatch to give you the right method.)

use FileHandle;
if (FileHandle->isa("Exporter")) {
    print "FileHandle is an Exporter.\n";
}

$fh = FileHandle->new();
if ($fh->isa("IO::Handle")) {
    print "\$fh is some sort of IOish object.\n";
}
if ($fh->isa("GLOB")) {
    print "\$fh is really a GLOB reference.\n";
}

INVOCANT->can(METHOD)

The can method returns a reference to the subroutine that would be called if METHOD were applied to INVOCANT. If no such subroutine is found, can returns undef.

if ($invocant->can("copy")) {
    print "Our invocant can copy.\n";
}
This could be used to conditionally invoke a method only if one exists:
$obj->snarl if $obj->can("snarl");
Under multiple inheritance, this allows a method to invoke all overridden base class methods, not just the leftmost one:
sub snarl {
    my $self = shift;
    print "Snarling: @_\n";
    my %seen;
    for my $parent (@ISA) {
        if (my $code = $parent->can("snarl")) {
            $self->$code(@_) unless $seen{$code}++;
        }
    }
}
We use the %seen hash to keep track of which subroutines we've already called, so we can avoid calling the same subroutine more than once. This could happen if several parent classes shared a common ancestor.

Methods that would trigger an AUTOLOAD (described in the next section) will not be accurately reported unless the package has declared (but not defined) the subroutines it wishes to have autoloaded.

INVOCANT->VERSION(NEED)

The VERSION method returns the version number of INVOCANT's class, as stored in the package's $VERSION variable. If the NEED argument is provided, it verifies that the current version isn't less than NEED and raises an exception if it is. This is the method that use invokes to determine whether a module is sufficiently recent.

use Thread 1.0;   # calls Thread->VERSION(1.0)
print "Running version ", Thread->VERSION, " of Thread.\n";
You may supply your own VERSION method to override the method in UNIVERSAL. However, this will cause any classes derived from your class to use the overridden method, too. If you don't want that to happen, you should design your method to delegate other classes' version requests back up to UNIVERSAL.

The methods in UNIVERSAL are built-in Perl subroutines, which you may call if you fully qualify them and pass two arguments, as in UNIVERSAL::isa($formobj, "HASH"). (This is not recommended, though, because can usually has the answer you're really looking for.)

You're free to add your own methods to class UNIVERSAL. (You should be careful, of course; you could really mess someone up who is expecting not to find the method name you're defining, perhaps so that they can autoload it from somewhere else.) Here we create a copy method that objects of all classes can use if they've not defined their own. (We fail spectacularly if invoked on a class instead of an object.)

use Data::Dumper;   
use Carp;
sub UNIVERSAL::copy {
    my $self = shift;
    if (ref $self) {
        return eval Dumper($self);  # no CODE refs
    } else {
        confess "UNIVERSAL::copy can't copy class $self";
    }
}
This Data::Dumper strategy doesn't work if the object contains any references to subroutines, because they cannot be properly reproduced. Even if the source were available, the lexical bindings would be lost.

12.5.4. Method Autoloading

Normally, when you call an undefined subroutine in a package that defines an AUTOLOAD subroutine, the AUTOLOAD subroutine is called in lieu of raising an exception (see the section Section 12.2, "Autoloading" in Chapter 10, "Packages"). With methods, this works a little differently. If the regular method search (through the class, its ancestors, and finally UNIVERSAL) fails to find a match, the same sequence is run again, this time looking for an AUTOLOAD subroutine. If found, this subroutine is called as a method, with the package's $AUTOLOAD variable set to the fully qualified name of the subroutine on whose behalf AUTOLOAD was called.

You need to be a bit cautious when autoloading methods. First, the AUTOLOAD subroutine should return immediately if it's being called on behalf of a method named DESTROY, unless your goal was to simulate DESTROY, which has a special meaning to Perl described in the section Section 12.6, "Instance Destructors" later in this chapter.

sub AUTOLOAD {
    return if our $AUTOLOAD =~ /::DESTROY$/;
    ...
}
Second, if the class is providing an AUTOLOAD safety net, you won't be able to use UNIVERAL::can on a method name to check whether it's safe to invoke. You have to check for AUTOLOAD separately:
if ($obj->can("methname") || $obj->can("AUTOLOAD")) {
    $obj->methname();
}
Finally, under multiple inheritance, if a class inherits from two or more classes each of which has an AUTOLOAD, only the leftmost will ever be triggered, since Perl stops as soon as it finds the first AUTOLOAD.

The last two quirks are easily circumvented by declaring the subroutines in the package whose AUTOLOAD is supposed to manage those methods. You can do this either with individual declarations:

package Goblin;
sub kick;
sub bite;
sub scratch;
or with the use subs pragma, which is more convenient if you have many methods to declare:
package Goblin;
use subs qw(kick bite scratch);
Even though you've only declared these subroutines and not defined them, this is enough for the system to think they're real. They show up in a UNIVERAL::can check, and, more importantly, they show up in step 2 of the search for a method, which will never progress to step 3, let alone step 4.

"But, but," you exclaim, "they invoke AUTOLOAD, don't they?" Well, yes, they do eventually, but the mechanism is different. Having found the method stub via step 2, Perl tries to call it. When it is discovered that the method isn't all it was cracked up to be, the AUTOLOAD method search kicks in again, but this time, it starts its search in the class containing the stub, which restricts the method search to that class and its ancestors (and UNIVERSAL). That's how Perl finds the correct AUTOLOAD to run and knows to ignore AUTOLOADs from the wrong part of the original inheritance tree.

12.5.5. Private Methods

There is one way to invoke a method so that Perl ignores inheritance altogether. If instead of a literal method name, you specify a simple scalar variable containing a reference to a subroutine, then the subroutine is called immediately. In the description of UNIVERSAL->can in the previous section, the last example invokes all overridden methods using the subroutine's reference, not its name.

An intriguing aspect of this behavior is that it can be used to implement private method calls. If you put your class in a module, you can make use of the file's lexical scope for privacy. First, store an anonymous subroutine in a file-scoped lexical:

# declare private method
my $secret_door = sub {
    my $self = shift;
    ...
};
Later on in the file, you can use that variable as though it held a method name. The closure will be called directly, without regard to inheritance. As with any other method, the invocant is passed as an extra argument.
sub knock {
    my $self = shift;
    if ($self->{knocked}++ > 5) {
        $self->$secret_door();
    }
}
This enables the file's own subroutines (the class methods) to invoke a method that code outside that lexical scope cannot access.



Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.