The normal technique would be to write Class1
in such a way that its constructor keeps a (presumably weak) reference to each object that is constructed in an array or hash somewhere. If you're using Moose, there's an extension called MooseX::InstanceTracking that makes that very easy to do:
package Class1 {
use Moose;
use MooseX::InstanceTracking;
# ... methods, etc here.
}
package Class2 {
use Moose;
extends 'Class1';
}
my $foo = Class1->new;
my $bar = Class1->new;
my $baz = Class2->new;
my @all = Class1->meta->get_all_instances;
If you're not using Moose; then it's still pretty easy:
package Class1 {
use Scalar::Util qw( weaken refaddr );
my %all;
sub new {
my $class = shift;
my $self = bless {}, $class;
# ... initialization stuff here
weaken( $all{refaddr $self} = $self );
return $self;
}
sub get_all_instances {
values %all;
}
sub DESTROY {
my $self = shift;
delete( $all{refaddr $self} );
}
# ... methods, etc here.
}
package Class2 {
our @ISA = 'Class1';
}
my $foo = Class1->new;
my $bar = Class1->new;
my $baz = Class2->new;
my @all = Class1->get_all_instances;