En nuestras clases tenemos un patrón donde creamos un atributo para representar un valor calculado . Por razones obvias, queremos almacenar en caché el valor calculado y luego invalidar la caché cuando cambia uno de los valores subyacentes.Moose: ¿Caducan los resultados en caché de los cálculos cuando cambian los valores de los atributos?
Así que actualmente tienen la siguiente:
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 { ... }
Este método de la mano larga se está volviendo muy tedioso y propenso a errores cuando se calculan los valores dependen de otros valores calculados.
¿Existe alguna manera más inteligente/más simple para que 'bar' controle los atributos, depende de y de que 'foo' sepa quién depende de ello? ¿También cómo puedo evitar establecer la barra a través del acceso de miembro hash ?
Hm. Tengo problemas para usar Memoize para almacenar en caché los datos del objeto. ¿Qué pasa si cada instancia de esta clase tiene valores diferentes? Memoize los almacenará en caché para siempre, independientemente de que ya no sean útiles cuando se destruya el objeto, ¿verdad? Lo que significa que en una aplicación persistente (y ese es realmente el único lugar sensato para usar Moose) es posible que crezca un caché enorme e inútil. ¿No? Por supuesto, puedes cometer un error al expirar cosas manualmente (¡creo!), Pero eso es mucho más complejo que el ejemplo anterior de Moose/perezoso, con poca ganancia ... – Dan
Estoy en desacuerdo fundamentalmente, no solo es/menos/complejo y más transparente, pero el golpe y la ganancia de velocidad son predecibles y la lógica es donde debería estar, en lugar de piratearse, en otros accesores. Todo lo que necesita hacer es la subclase Memoize :: Expire y establecer el sub STORE para borrar el caché, antes de escribir en el hash. –
Elegí esto como la respuesta, ya que simplifica drásticamente el código, que era lo que realmente estaba buscando. El hecho de que el resultado del cálculo no se almacena en el objeto en sí no es un problema para mi implementación actual. Gracias EvanCaroll. – clscott