UNIVERSAL::can

UNIVERSALは全てのクラス共通の祖先ですが、それを利用して UNIVERSAL クラスに定義されている便利なメソッドを、どんなオブジェクトからでも呼び出す事ができます。
UNIVERSAL::can は、指定したメソッドのリファレンスを得る事ができます。もしメソッドが存在しない場合は undef を返すので、「オブジェクトはこのメソッドを実行できるか」を調べたい時に便利です。
使ってみました。

package Dog;
sub new  { bless {}, shift }
sub bark { return "Bow-wow!" }
 
package Cat;
sub new  { bless {}, shift }
sub meow { return "Meow, meow..." }
 
package main;
$pochi = Dog->new();
$tama  = Cat->new();
 
if ($pochi->can("bark")) {
    print "Pochi barks: ", $pochi->bark(), "\n";
} else {
    print "Pochi can't bark.\n";
}
if ($pochi->can("meow")) {
    print "Pochi meows: ", $pochi->meow(), "\n";
} else {
    print "Pochi can't meow.\n";
}
 
if ($tama->can("bark")) {
    print "Tama barks: ", $tama->bark(), "\n";
} else {
    print "Tama can't bark.\n";
}
if ($tama->can("meow")) {
    print "Tama meows: ", $tama->meow(), "\n";
} else {
    print "Tama can't meow.\n";
}

Dog クラスは bark メソッドを、Cat クラスは meow メソッドをそれぞれ持っています。
Dog オブジェクトである $pochi と、Cat オブジェクトである $tama が、それぞれ bark と meow を持っているか can で確かめています。
以下が実行結果です。

Pochi barks: Bow-wow!
Pochi can't meow.
Tama can't bark.
Tama meows: Meow, meow...

ちゃんと判別できていますね。
継承したメソッドの場合はどうなるのでしょうか。

package Animal;
sub new {
    my ($class, $name) = @_;
    bless \$name, $class;
}
sub sleep {
    my $self = shift;
    print "$$self is sleeping.\n";
}
sub eat {
    my ($self, $food) = @_;
    print "$$self is eating $food.\n";
}
 
package Human;
@ISA = qw(Animal);
 
sub sleep {
    my $self = shift;
    print "$$self is sleeping ... zzz ZZZ\n";
}
 
package main;
$palmo = Human->new("Palmo");
 
if ($palmo->can("sleep")) {
    $palmo->sleep();
} else {
    print "Palmo can't sleep.\n";
}
 
if ($palmo->can("eat")) {
    $palmo->eat("Spaghetti");
} else {
    print "Palmo can't eat.\n";
}
 
if ($palmo->can("fly")) {
    $palmo->fly();
} else {
    print "Palmo can't fly.\n";
}

Human クラスは Animal クラスを継承しています。sleep メソッドはオーバーライドしています。
Human オブジェクトを生成して $palmo に代入し、sleep、eat、fly メソッドが実行できるか確かめています。
以下が実行結果です。

Palmo is sleeping ... zzz ZZZ
Palmo is eating Spaghetti.
Palmo can't fly.

継承したメソッド eat も can で検出できるようですね。(^_^)