Determining Subclass Membership (Perl Cookbook, 2nd Edition)

## 13.9. Determining Subclass Membership

### 13.9.1. Problem

You want to know whether an object is an instance of a particular class or that class's subclasses. Perhaps you want to decide whether a particular method should be invoked on an arbitrary object.

### 13.9.2. Solution

Use methods from the special UNIVERSAL class:

>     $obj->isa("HTTP::Message");                  # as object method
>     HTTP::Response->isa("HTTP::Message");        # as class method

>     if ($obj->can("method_name")) { .... }       # check method validity

### 13.9.3. Discussion

Wouldn't it be convenient if all objects were rooted at some ultimate base class? That way you could give every object common methods without having to add to each `@ISA`. Well, you can. You don't see it, but Perl pretends there's an extra element at the end of `@ISA`—the package named UNIVERSAL.

UNIVERSAL has only a few predefined methods, although you are free to add your own. These are built right into your Perl binary, so they don't take extra time to load. Predefined methods include `isa`, `can`, and `VERSION`. All three may be used for both sorts of invocants: classes and objects.

The `isa` method reports whether its invocant inherits the class name directly or indirectly from the class name supplied as the argument. This saves having to traverse the hierarchy yourself, and is much better than testing with an exact check against the string returned by the `ref` built-in. You may even supply a basic type that `ref` might return as an argument, such as SCALAR, ARRAY, HASH, or GLOB.

>     $has_io = $fd->isa("IO::Handle") || $fd->isa("GLOB");
>     $itza_handle = IO::Socket->isa("IO::Handle");

Type checks like this are sometimes frowned upon as being too constraining. If you just want to know if a certain method can be invoked against something, it might be better to just try to invoke the method you're hoping will be there instead of checking for the class.

Another possibility is to use another UNIVERSAL method, `can`. The `can` method reports whether its string argument is a valid method for its invocant. In fact, it even returns a function reference for that method:

>     $his_print_method = $obj->can('as_string');

Finally, the `VERSION` method checks whether the invocant class has a package global called `$VERSION` that's high enough, as in:

>     Some_Module->VERSION(3.0);
>     $his_vers = $obj->VERSION( );

However, we don't usually invoke `VERSION` ourselves. Remember, in Perl an all-uppercase function name means that the function will be automatically called by Perl in some way. In this case, it happens when you say:

>     use Some_Module 3.0;

If you wanted to add version checking to your Person class explained earlier, add this to Person.pm:

>     our $VERSION = "1.01";

Then, in the user code say `use` `Person` `1.01;` to make sure that you have at least that version number or higher available. This is not the same as loading in that exact version number; it just has to be at least that high. Lamentably, no mechanism for concurrent installation of multiple versions of a module yet exists.

### 13.9.4. See Also

The documentation for the standard UNIVERSAL module; the `use` keyword in perlfunc(1) and in Chapter 11 of Programming Perl

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