Американский лось: Истекающие кэшируемые результаты вычислений, когда значения атрибута изменяются?

Эта статья в codeproject нашим хостом Jeff Atwood - то, в чем Вы нуждаетесь. Включает код для ловли необработанных исключений и лучших методов для проявления информации о катастрофическом отказе пользователю.

5
задан clscott 21 November 2009 в 14:04
поделиться

4 ответа

Я думаю, что вполне возможно, что вы усложняете себе задачу, используя неявную мемоизацию атрибутов с ленивым режимом, когда вы могли бы просто сделать мемоизацию явной, делая всю вашу программу более прозрачной

has [qw/foo bar baz/] => ( isa => 'Value', is => 'rw' );

use Memoize;
memoize('_memoize_this');

sub old_lazy_attr {
    my $self = shift;
    _memoize_this( $self->attr1, $self->attr2, $self->attr3 );
}

sub _memoize_this {
    my @args = @_;
    # complex stuff
    return $result
}

См. Cpan Memoize для получения информации и управления внутренним кешем. Также помните, что функция Memoized не может зависеть от состояния объекта. Таким образом, аргументы должны быть явно переданы в .

5
ответ дан 18 December 2019 в 10:45
поделиться

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

has 'foo' => (
    is      => 'rw',
    trigger => sub{
        my ($self) = @_;
        $self->clear_bar;
    }
);

has 'bar' => (
    is      => 'rw',
    clearer => 'clear_bar',
    lazy    => 1,
    default => sub{
        my ($self) = @_;
        return calculate_bar( ... );
    }
);

Итак, любая запись в foo через $ obj-> foo ($ newvalue) приведет к очистке и воссозданию bar при следующем доступе.

11
ответ дан 18 December 2019 в 10:45
поделиться

Будет ли это работать?

#!/usr/bin/perl

package Test;

use Modern::Perl;
use Moose;

has a => (is => 'rw', isa => 'Str', trigger => \&change_a);
has b => (is => 'rw', isa => 'Str', trigger => \&change_b);
has c => (is => 'rw', isa => 'Str');

sub change_a
{
    my $self = shift;
    say 'update b';
    $self->b($self->a . ', bar');
}   

sub change_b
{
    my $self = shift;
    say 'update c';
}   

package main;

my $test = Test->new->a('Foo');

Вывод:

$ perl test.pl
update b
update c
0
ответ дан 18 December 2019 в 10:45
поделиться

Я не разбирался во внутренностях Moose и протоколе метаобъектов, но думаю, что сейчас хорошее время для этого.

Вы хотите исправить генерацию кода, чтобы что, когда вы указываете атрибут как

has 'foo' => ();
has 'bar' => ( 
    depends_on => [qw( foo )],
    lazy => \&calculate_bar,
);

, на этапе генерации кода создается код для атрибутов foo и bar , как вы указали выше.

Как это сделать - это упражнение слева читателю. Если бы у меня была подсказка, я бы попробовал дать вам начало. К сожалению, все, что я могу вам посоветовать, это «Это работа для СС».

0
ответ дан 18 December 2019 в 10:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: