if (Horse->isa("Animal")) { # does Horse inherit from Animal?
print "A Horse is an Animal.\n";
}
my $tv_horse = Horse->named("Mr. Ed");
if ($tv_horse->isa("Animal")) { # is it an Animal?
print $tv_horse->name, " is an Animal.\n";
if ($tv_horse->isa("Horse")) { # is it a Horse?
print "In fact, ", $tv_horse->name, " is a Horse.\n";
} else {
print "...but it's not a Horse.\n";
}
}
This is handy when you have a heterogeneous mix of objects in a data
structure and want to distinguish particular categories of objects:
my @horses = grep $_->isa("Horse"), @all_animals;
The result will be only the horses (or race horses) from the array.
Compare that with:
my @horses_only = ref $_ eq "Horse", @all_animals;
which picks out just the horses because a
RaceHorse won't return
Horse for ref.
In general, you shouldn't use:
ref($some_object) eq "SomeClass"
in your programs because it prevents future users from subclassing
that class. Use the isa construct as given
earlier.
if (UNIVERSAL::isa($unknown_thing, "Animal")) {
... it's an Animal! ...
}
This works regardless of what $unknown_thing
contains.
As in the case of isa, you can test for acceptable
behaviors with the can method. For example:
if ($tv_horse->can("eat")) {
$tv_horse->eat("hay");
}
If the result of can is true, then somewhere in
the inheritance hierarchy, a class has defined an
eat method. Again, the caveats about
$tv_horse being only either a blessed reference or
a class name as a scalar still apply, so the robust solution when you
might deal with nearly anything looks like:
if (UNIVERSAL::can($tv_horse, "eat")) { ... }