Home > Mobile >  Refer to package by name
Refer to package by name

Time:10-01

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.

  • Related