Аргумент для строителя подпрограммы в объекте Moose - PullRequest
6 голосов
/ 20 июля 2010

В настоящее время я делегирую метод builder всем объектам, которые расширяют один из моих базовых классов.Проблема, с которой я сталкиваюсь, заключается в том, что мне нужно, чтобы все объекты либо прочитали свой атрибут, либо были переданы в значении.

#  In Role:
has 'const_string' => (
    isa     => 'Str',
    is      => 'ro',
    default => 'test',
);

has 'attr' => (
    isa     => 'Str',
    is      => 'ro',
    builder => '_builder',
);

requires '_builder';


#  In extending object  -  desired 1
sub _builder {
    my ($self) = shift;
    #  $self contains $self->const_string
 }

#  In extending object  -  desired 2
sub _builder {
    my ($arg1, $arg2) = @_;
    #  $args can be passed somehow?
 }

Возможно ли это в настоящее время или мне придется это сделатькаким-то другим способом?

Ответы [ 2 ]

12 голосов
/ 20 июля 2010

Вы не можете передавать аргументы в методы построения атрибутов. Они вызываются автоматически внутренними компонентами Moose и передают только один аргумент - саму ссылку на объект. Построитель должен иметь возможность возвращать свое значение на основе того, что он видит в $self, или чего-либо еще в среде, к которой он имеет доступ.

Какие аргументы вы хотели бы передать строителю? Можно ли вместо этого передать эти значения конструктору объекта и сохранить их в других атрибутах?

# in object #2:
has other_attr_a => (
    is => 'ro', isa => 'Str',
);
has other_attr_b => (
    is => 'ro', isa => 'Str',
);

sub _builder
{
    my $self = shift;
    # calculates something based on other_attr_a and other_attr_b
}

# object #2 is constructed as:
my $obj = Class2->new(other_attr_a => 'value', other_attr_b => 'value');

Также обратите внимание, что если у вас есть атрибуты, которые построены на основе других значений атрибутов, вы должны определить их как lazy, в противном случае компоновщики / значения по умолчанию будут выполняться сразу при построении объекта и в неопределенном порядке. Установка их ленивый задержит их определение, пока они сначала не понадобятся.

0 голосов
/ 22 марта 2016

Вы можете сделать что-то вроде этого:

has 'attr' => (
isa     => 'Str',
is      => 'ro',
builder => '_pre_builder',
);

sub pre_builder {
  _builder(@_, 'your_arg');
}
...