UNIVERSAL::canとは?

いつも忘れるのでメモ。

UNIVERSAL::canは、あるクラスでcan()を定義していた場合にUNIVERSAL::can( $instance, 'foo' )とやっても組み込みの UNIVERSAL::canではなく、そのクラスで定義されたcan()が呼ばれるようにするもの。


具体的には下記のようにmainでUNIVERSAL::can()を読んでも、組み込みのUNIVERSAL::can()ではなく、クラスBのcan()が呼ばれます。

package A;

sub new { bless {}, shift }
sub foo { warn "foo" }

package B;
use base qw(A);

sub can {
    warn "B's can called";
    return;
}

package main;
use UNIVERSAL::can;

my $b = B->new;
unless ( UNIVERSAL::can($b, 'foo') ) {
    warn "B cannot have foo().";
}