Эта статья в codeproject нашим хостом Jeff Atwood - то, в чем Вы нуждаетесь. Включает код для ловли необработанных исключений и лучших методов для проявления информации о катастрофическом отказе пользователю.
Я думаю, что вполне возможно, что вы усложняете себе задачу, используя неявную мемоизацию атрибутов с ленивым режимом, когда вы могли бы просто сделать мемоизацию явной, делая всю вашу программу более прозрачной
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 не может зависеть от состояния объекта. Таким образом, аргументы должны быть явно переданы в .
Если я понимаю вы правильно, вы можете использовать триггеры для очистки атрибутов, когда он установлен. Вот пример:
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
при следующем доступе.
Будет ли это работать?
#!/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
Я не разбирался во внутренностях Moose и протоколе метаобъектов, но думаю, что сейчас хорошее время для этого.
Вы хотите исправить генерацию кода, чтобы что, когда вы указываете атрибут как
has 'foo' => ();
has 'bar' => (
depends_on => [qw( foo )],
lazy => \&calculate_bar,
);
, на этапе генерации кода создается код для атрибутов foo
и bar
, как вы указали выше.
Как это сделать - это упражнение слева читателю. Если бы у меня была подсказка, я бы попробовал дать вам начало. К сожалению, все, что я могу вам посоветовать, это «Это работа для СС».