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 usingisa
just because I like using object oriented programming everywhere. However, having the infix operator within the language could be very useful in general.