Использование подпрограммы в методе new() с использованием perl Moo

Мой вопрос заключается в следующем: я хочу использовать подпрограмму для создания массива, когда я вызываю метод new() для создания объекта с использованием perl Moo. Пожалуйста, смотрите следующий пример.

package Customer;
use DBI;
use 5.010;
use Data::Dumper;
use Moo;
use FindBin qw/$Bin/;
use lib "$Bin/../../../lib";
use lib '/home/fm/lib';
use TT::SQL;

has id => (
  is=>'ro',
  required=>1,
);

has type => (
  is=>'ro',
);

has emails => (
  is=>'rw',
  isa => sub {getEmails() },
);

sub getEmails
{
                #connecting into de DB
                my $self=shift;
                my $db2 = TT::SQL::get_handler("xxxxxx","xxxxx");
                my $fmuser=$self->id;
                my $type=$self->type;
                my $query;
                #checking the customer type to perform the query
                if ($type eq "xxxxxxxxxx")
                {
                $query=xxxxxxxxxxxxxx;
                }
                else
                {
                $query=xxxxxxxxxxxxxx;
                }
                my $ref = $db2->execute($query,$fmuser);
                my @emails;
                #retrieving emails
                while ( my $row = $ref->fetchrow_hashref  ) {
                       @emails=(@emails,"$row->{email}\n");
                  }
                return @emails;
}

1;

По сути, я пытаюсь получить некоторые электронные письма из базы данных, и не беспокоиться о запросах и доступе к БД, потому что, когда я выполняю следующее:

my $cc= Customer->new(id=>92,type=>'xxxxxxx');
@emails=$cc->getEmails();

Результат в @emails - ожидаемый. Тем не менее, когда я выполняю:

my $cc= Customer->new(id=>92,type=>'xxxxxxx');
@emails=$cc->emails;

У меня даже нет результата.

Буду очень признателен, если получу ответ на этот вопрос. Заранее спасибо, ребята.

1 ответ

Решение

Вы хотите использовать либо метод компоновщика, либо метод по умолчанию, isa для применения ограничений типа:

дефолт:

has emails => (
  is      => 'rw',
  default => sub { 
     my ($self) = @_;
     return $self->getEmails();
  },
);

строитель:

has emails => (
  is      => 'rw',
  builder => '_build_emails',
);

sub build_emails {
    my ($self) = @_;

    return $self->getEmails();
}

Если getEmails() подпрограмма требует дополнительного времени запуска (например, получение дескриптора к базе данных), я бы также предложил добавить lazy => 1 аргумент вашего атрибута электронной почты. Это только инициализирует это, если это вызвало.

Другие вопросы по тегам