Изменить методы атрибута Moose - PullRequest
2 голосов
/ 02 декабря 2010

Я создаю список атрибутов (более трех, показанных ниже), все из которых имеют общие методы.Можно ли добавить триггер к одному из методов:

# Create a bunch of attributes
for my $attr ( qw( title name address ) ) {
    has $attr => ( is => 'rw', isa => 'Str' );

    around $attr => sub {
        # more stuff here.
    }
}

# Add a trigger
has_another_method 'title' => ( trigger => \&_trigger_title );

Я знаю, что могу получить метаинформацию об атрибутах, но я не нашел ничего, что позволило бы мне изменить методы атрибута (и, возможно, не зря).Возможность сделать это поможет сохранить мой код в чистоте и будет означать, что общие биты определены в одном месте.Если нет, я могу просто создать атрибут отдельно и включить метод триггера.

Обновить

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

# Create a bunch of attributes
for my $attr ( qw( title name address ) ) {

    my %options = ( is => 'rw', isa => 'Str' );

    # Add a trigger to the title attribute.
    $options{ 'trigger' } = \&_trigger_title
        if $attr eq 'title';

    has $attr => ( %options );

    around $attr => sub {
        # more stuff here.
    }
}

Ответы [ 2 ]

2 голосов
/ 02 декабря 2010

Методы атрибутов составляются при их создании, поэтому, как правило, рекомендуется иметь все доступные параметры при его создании с помощью директивы has. Однако , в настоящее время нет ничего особенного, что делается с методами триггера, так что вы можете сделать это, чтобы обойти только для чтения опцию 'trigger':довольно сильно копается во внутренностях лося;если реализация когда-либо изменится, вы можете быть SOL (плюс вы будете нарушать ограничения, которые существуют по определенной причине).Таким образом, было бы намного лучше настроить триггеры как:

has $_ => (
    is => 'rw', isa => 'Str',
    trigger => '_trigger_' . $_,
) for (qw(title name address));

sub _trigger_title {
    # implementation here
}
sub _trigger_name {
    # implementation here
}
sub _trigger_address {
    # implementation here
}
2 голосов
/ 02 декабря 2010

Триггеры - это просто атрибут атрибута, но они определены только для чтения.Вы могли бы find_meta( $attribute )->get_attribute('trigger')->set_value( $attribute, sub { new trigger }), но вы действительно нарушаете инкапсуляцию здесь.

Я бы просто объявил все общие атрибуты в цикле my, а затем объявил бы специальные случаи в других местах.

...