В ожидании разъяснения относительно вопроса, я подумал, что вы в каком-то учебном заведении получаете задания, связанные с Perl, я решил, что нет лучшего времени, чтобы познакомить вас с Moose и CPAN, вещами, которыми вы действительно должны быть используя в реальном мире.
Он и его различные расширения сделают вашу жизнь проще и сделают объектно-ориентированный дизайн более простым и понятным.
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use Moose::Autobox;
use 5.010;
sub Moose::Autobox::SCALAR::sprintf {
my $self = shift;
sprintf( $self, @_ );
}
{
package Son;
use Moose;
use MooseX::Types::Moose qw( :all );
use MooseX::ClassAttribute;
use MooseX::Has::Sugar 0.0300;
use Moose::Autobox;
class_has 'Ancestry' => ( isa => HashRef, rw, default => sub { {} } );
class_has 'People' => ( isa => HashRef, rw, default => sub { {} } );
has 'name' => ( isa => Str, rw, required );
has 'father' => ( isa => Str, rw, required );
sub BUILD {
my $self = shift;
$self->Ancestry->{ $self->name } //= {};
$self->Ancestry->{ $self->father } //= {};
$self->People->{ $self->name } //= $self;
$self->Ancestry->{ $self->father }->{ $self->name } = $self->Ancestry->{ $self->name };
}
sub children {
my $self = shift;
$self->subtree->keys;
}
sub subtree {
my $self = shift;
$self->Ancestry->{ $self->name };
}
sub find_person {
my ( $self, $name ) = @_;
return $self->People->{$name};
}
sub visualise {
my $self = shift;
'<ul><li class="person">%s</li></ul>'->sprintf( $self->visualise_t );
}
sub visualise_t {
my $self = shift;
'%s <ul>%s</ul>'->sprintf(
$self->name,
$self->children->map(
sub {
'<li class="person">%s</li>'->sprintf( $self->find_person($_)->visualise_t );
}
)->join('')
);
}
__PACKAGE__->meta->make_immutable;
}
my @rows = ( [ "bill", "sam" ], [ "bob", "" ], [ "jack", "sam" ], [ "jone", "mike" ], [ "mike", "bob" ], [ "sam", "bob" ], );
for (@rows) {
Son->new(
father => $_->at(1),
name => $_->at(0),
);
}
<<'EOX'->sprintf( Son->find_person('bob')->visualise )->say;
<html>
<head>
<style>
li.person {
border: 1px solid #000;
padding: 4px;
margin: 3px;
background-color: rgba(0,0,0,0.05);
}
</style>
</head>
<body>
%s
</body>
</html>
EOX