В наших классах мы имеем шаблон, в котором мы создаем атрибут для представления расчетного значения . По очевидным причинам мы хотим кэшировать вычисленное значение и затем аннулировать кеш при изменении одного из базовых значений.Moose: истекающие кешированные результаты вычислений при изменении значений атрибутов?
Таким образом, мы в настоящее время это:
package FooBar;
use Moose;
has 'foo' => (
accessor => {
'foo' => sub {
my $self = shift;
if (@_ > 0) {
# writer
$self->{foo} = $_[0];
# reset fields that are dependant on me
$self->{bar} = undef;
}
# reader part;
return $self->{foo};
}
}
);
has 'bar' => (
accessor => {
'bar' => sub {
my $self = shift;
if (@_ > 0) {
# writer
$self->{bar} = $_[0];
}
# reader part;
$self->{bar} = calculate_bar($self->foo, $self->baz)
if (not defined($self->{bar}));
return $self->{bar};
}
}
);
sub calculate_bar { ... }
Этот длинный метод рука становится очень утомительным и ошибками при вычислении значения зависит от других расчетных значений.
Есть ли более умный/простой способ для «бара», чтобы контролировать атрибуты, которые он зависит от , и «foo» знает, кто на этом зависит? Также как я могу избежать установки строки через хэш доступ к членству?
Hm. У меня возникают проблемы с использованием Memoize для кэширования данных объекта. Что произойдет, если каждый экземпляр этого класса имеет разные значения? Memoize будет кэшировать их навсегда независимо от того, что они больше не полезны, когда объект уничтожен, правильно? Это означает, что в постоянном приложении (и это действительно единственное разумное место для использования Moose) вы потенциально собираетесь выращивать огромный бесполезный кеш. Нет? Конечно, вы можете беспорядочно уничтожать вещи вручную (я думаю!), Но это намного сложнее, чем выше пример Moose/lazy, для небольшого выигрыша. – Dan
Я принципиально не согласен, это не просто это/меньше/сложно, более прозрачный, но скорость и усиление скорости предсказуемы, и логика заключается в том, где она должна быть, а не взломана в других устройствах доступа. Все, что вам нужно сделать, это подкласс Memoize :: Expire и установить подставку STORE, чтобы очистить кеш, прежде чем писать в хэш. –
Я выбрал это как ответ, поскольку он радикально упрощает код, к чему я действительно стремился. Тот факт, что результат вычисления не хранится в самом объекте, не является проблемой для моей текущей реализации. Thanks EvanCaroll. – clscott