Package/data sources package rohanType1; sub new { my $self = {}; # Discard the class name shift; $self->{'field11'} = undef; bless ($self); return $self; } return 1; package rohanType2; sub new { my $self = {}; shift; $self->{'field21'} = 0; bless ($self); return $self; } return 1; package rohanType3; sub new { my $self = {}; shift; # Pointer to rohanType1 $self->{'field31'} = undef; # Pointer to rohanType2 $self->{'field32'} = undef; bless ($self); return $self; } return 1; # Now the data structures used globally to store information used by the whole analysis, which holds # data types as defined above package rohanData; sub new { my $self = (); shift; $self->{'rohan1'} = undef; $self->{'rohan2'} = (); bless ($self); return $self; } return 1; ======================= Code my $rohanRoot; my $rohan1; my $rohan2; my $rohan3; my $rohan4; $rohanRoot = rohanData->new(); $rohan1 = rohanType1->new(); $rohan2 = rohanType2->new(); $rohan1->{'field11'} = $rohan2; $rohanRoot->{'rohan1'} = $rohan1; # my debug helper to see if addresses are correct - not part of code push $rohanRoot->{'rohan2'}, $rohan1; # Interpreter/debugger objects to this ... $rohan3 = rohanType1->new(); $rohan4 = rohanType2->new(); $rohan3->{'field11'} = $rohan4; push $rohanRoot->{'rohan2'}, $rohan3; # ... and this