Perl isa Operator

When I started learning Perl, back in the days of version 5.4 or so, I learnt about the @ISA array used to implement class inheritance.
Then it was time for UNIVERSAL::isa, a kind of catch-all method to test if a given reference is an object of the specified type.
Since Perl 5.31.6, a new infix operator isa is available, and since version 5.36 such operator is transparently available, meaning that you don’t have to enable any feature. The operator does the same, and even more, than the UNIVERSAL::isa method, and the following piece of code demonstrate its usage:

use v5.38;

package Person;
use Moo;

has name => ( is => 'ro' );

package Student;
use Moo;
extends 'Person';


package Professor;
use Moo;
extends 'Person';


package main;

my $prof = Professor->new( name => 'Luca' );
my $stud = Student->new( name => 'Emanuela' );

for my $who ( $prof, $stud ) {
    say $who->name . " is a " . ref $who;

    say "\t (infix isa) Professor ? " . ( $who isa Professor  ? 'Yes' : 'No' );
    say "\t (infix isa) Student   ? " . ( $who isa Student    ? 'Yes' : 'No' );
    say "\t (infix isa) Person    ? " . ( $who isa Person     ? 'Yes' : 'No' );

    say "\t (method isa) Professor ? " . ( $who->isa( 'Professor' ) ? 'Yes' : 'No' );
    say "\t (method isa) Student   ? " . ( $who->isa( 'Student' )   ? 'Yes' : 'No' );
    say "\t (method isa) Person    ? " . ( $who->isa( 'Person' )    ? 'Yes' : 'No' );

}



The above program is very simple: it creates a Person class, from which Student and Professor inherit. Then, the program creates two instances of objects, and checks both trhu the infix operator and the method if the reference is of a particular class type. Clearly, the end result is the same without any regard to the specific isa used:

% perl test.pl
Luca is a Professor
         (infix isa) Professor ? Yes
         (infix isa) Student   ? No
         (infix isa) Person    ? Yes
         (method isa) Professor ? Yes
         (method isa) Student   ? No
         (method isa) Person    ? Yes
Emanuela is a Student
         (infix isa) Professor ? No
         (infix isa) Student   ? Yes
         (infix isa) Person    ? Yes
         (method isa) Professor ? No
         (method isa) Student   ? Yes
         (method isa) Person    ? Yes



If you come from the Java world, this infix isa works pretty much the same as instanceof, but it is clearly shorter (and smarter, as you will understand later).
There is an important difference between the isa infix operator and the method: the isa infix operator accepts as right argument both a string or a package name, and if the right operand is a bareword it is automatically considred as a package (class) name. On the other hand, the isa method does not accept a bareword, and in fact in the above program the method accepts a quoted string. In order to use the method with a bareword, a package separator must be used, so the above program must be rewritten as:

for my $who ( $prof, $stud ) {
    say $who->name . " is a " . ref $who;
    say "\t (infix isa) Professor ? " . ( $who isa Professor  ? 'Yes' : 'No' );
    say "\t (infix isa) Student   ? " . ( $who isa Student    ? 'Yes' : 'No' );
    say "\t (infix isa) Person    ? " . ( $who isa Person     ? 'Yes' : 'No' );

    say "\t (method isa) Professor ? " . ( $who->isa( Professor:: ) ? 'Yes' : 'No' );
    say "\t (method isa) Student   ? " . ( $who->isa( Student:: )   ? 'Yes' : 'No' );
    say "\t (method isa) Person    ? " . ( $who->isa( Person:: )    ? 'Yes' : 'No' );

}



Conclusions

I tend to prefer the method way of using isa just because I like using object oriented programming everywhere. However, having the infix operator within the language could be very useful in general.

The article Perl isa Operator has been posted by Luca Ferrari on September 23, 2023

Tags: perl