Consider:
#!/usr/bin/perl
use strict;
use warnings;
package base
{
sub new()
{
my $class = shift( @_ );
my $self = {};
bless( $self, $class );
}
}
package myclass
{
our @ISA = 'base';
}
package main;
my $classname = 'myclass';
print( ( $classname->can( 'new' ) ) ? "can" : "cannot" );
print( "\n" );
print( @myclass::ISA );
I know that having multiple packages in one file isn't exactly "clean Perl". Please let us ignore that issue for the scope of this question.
What I am interested in are the last couple of lines.
my $classname = 'myclass';
print( ( $classname->can( 'new' ) ) ? "can" : "cannot" );
Here, I can use the name of a package, stored in classname
, to "inspect" that package without having instantiated the package / class.
print( @myclass::ISA );
Here I "inspect" a package's ISA
array... but by naming the package directly.
Is there a way to refer to the package's ISA
through $classname
as well?
CodePudding user response:
It's possible without strict refs:
say join ' ', do { no strict 'refs'; @{ "$classname" . '::ISA' } };
Or you can use mro::get_linear_isa to get all the ancestors (i.e. the transitive closure of the @ISA):
use mro;
say join ' ', @{ mro::get_linear_isa($classname) };
But that's not what you usually need. In practice, you want to know whether a class inherited from a given class or not, which is possible using the universal isa
method:
say $classname->isa('base'); # 1
Again, this checks the transitive relation, not just the direct @ISA membership.