Можно ли использовать Attribute :: Handlers для реализации логики повторов? - PullRequest
2 голосов
/ 20 января 2012

Можно ли использовать Attribute::Handlers для реализации логики повторов

У меня почти 50+ подпрограмм, как verifyXXXX. Мне нужно реализовать логику повтора для всех этих подпрограмм. Я хочу написать эту логику повторных попыток, где на самом деле реализована подпрограмма. Если возвращаемое значение sub - false / undef, то оно повторится снова.

подпрограммы будут вызываться обычным способом, так что вызывающая сторона не будет знать о логике повторения, что-то вроде.

verify_am_i_doing_good()
    or die('sorry you are not doing as expected.');

verify_am_i_fine()
    or die ('sorry you are not find.');

: :

фактическая реализация этих функций в пакете выглядит примерно так:

use Attribute::Handlers;

use constant RETRY_LIMIT => 4;
use constant RETRY_DELAY => 2;

sub verify_am_i_doing_good : __retry
{
    return 1 if ($x == $y);
    return;
}

sub __retry : ATTR(CODE) {
    my ($pkg, $sym, $code) = @_;

    my $name = *{ $sym }{NAME};
    no warnings 'redefine';

    *{ $sym } = sub
    {
        my $self = $_[0];
        my $result;

        logMsg (INFO, "Executing subroutine $name with retry limit " . RETRY_LIMIT);
        for (my $retryCount = 1; $retryCount <= RETRY_LIMIT; $retryCount++)
        {
            logMsg (INFO, "Executing subroutine $name with retry count $retryCount");
            my $result = $code->( @_ );
            if ($result)
            {
                logMsg (INFO, "Expected result observed in retry count $retryCount");
                return wantarray ? @$result : $result;
            }
            else
            {
                logMsg (INFO, "Expected result is NOT observed in retry count $retryCount");
                logMsg (INFO, "Retrying again by updating uixml");

                sleep RETRY_DELAY;
                $self->updateState();
            }
        }
        logMsg (WARN, "Failed to verify expected result for subroutine $name with retry limit " . RETRY_LIMIT);
        return;
    };
}

Причина использования Attribute :: Handlers вместо Attribute :: Attempts заключается в том, что в случае сбоя мне нужно вызвать другую подпрограмму updateState() перед повторной попыткой (повторным выполнением) подпрограммы.

Мне пришла идея написать логику повторов из следующего поста http://www.perl.com/pub/2007/04/12/lightning-four.html

Моя главная проблема заключается в том, что, поскольку я использую этот атрибут __retry для почти 50+ подпрограмм. Это хорошая практика, или я могу сделать что-нибудь простое?

Ваша помощь будет высоко оценена.

1 Ответ

2 голосов
/ 21 января 2012

Вам не нужны атрибуты для создания вложенной оболочки. Было Memoize задолго до того, как было Memoize::Attrs (или Attribute::Memoize в этом отношении). Вы можете просто взглянуть на то, как Memoize справляется с этим.

Совсем недавно я писал Perl для функций, вызываемых в другом интерфейсе. Все аргументы, передаваемые функции Perl из этого интерфейса, будут передаваться в необычном, но универсальном формате, используемом моим подразделением. Вместо того, чтобы разбираться с этим повсюду, я написал логическую оболочку примерно так:

sub external (@) {
    my ( $subname, $code ) = @_;
    ...
    my $wrapped 
        = sub { 
            my $count = 5;
            while ( --$count and not my @results = &$code ) { 
                adjust_stuff();
            }
            return @results;
        };
    {   no strict 'refs'; # my special "no-block"
        *$subname = $wrapped;
    }
    return;
}

И использовал это так (некоторым людям не нравится это использование "жирной запятой")

external something_I_want_to_do => sub {
    my @regular_old_perl_args = @_;
    ...
};

Прототип (@) помогает подчиненному действию в качестве оператора и не всегда должен вызываться с круглыми скобками.

Но во что бы то ни стало, если вам нравятся атрибуты метода, и он работает, и вы можете заставить его не кусать вас, использовать их . Но ты не обязан. Вы должны, вероятно, прочитать об оговорках, хотя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...