In unseren Klassen haben wir ein Muster, wo wir ein Attribut erstellen, um einen berechneten Wert darzustellen. Aus offensichtlichen Gründen möchten wir den berechneten Wert zwischen zwischenspeichern und dann den Cache ungültig machen, wenn sich einer der zugrunde liegenden Werte ändert.Moose: Abgelaufene Ergebnisse von Berechnungen im Cache, wenn sich Attributwerte ändern?
So haben wir zur Zeit die:
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 { ... }
Diese lange Hand-Methode ist immer sehr mühsam und fehleranfällig, wenn Werte berechnet auf anderen berechneten Werten abhängen.
Gibt es eine klügere/einfachere Möglichkeit für 'bar', die Attribute zu überwachen, die davon abhängen, vs 'foo' wissen, wer ist davon abhängig? Wie kann ich auch vermeiden, Bar über Hash Mitglied Zugriff einstellen?
Hm. Ich habe Probleme damit, mit Memoize Objektdaten zwischenzuspeichern. Was passiert, wenn jede Instanz dieser Klasse unterschiedliche Werte hat? Memoize speichert sie für immer, ungeachtet der Tatsache, dass sie nicht länger nützlich sind, wenn das Objekt zerstört wird, oder? Das bedeutet in einer persistenten App (und das ist wirklich der einzig sinnvolle Ort, um Moose zu benutzen), dass Sie möglicherweise einen riesigen, nutzlosen Cache aufbauen. Nein? Natürlich können Sie manuell Dinge ausrangieren (denke ich!), Aber das ist viel mehr Komplexität über das Elch/faul Beispiel oben, für wenig Gewinn .. – Dan
Ich stimme grundsätzlich nicht zu, nicht nur ist/weniger/komplex und transparenter, aber die Geschwindigkeit und der Gewinn sind vorhersehbar und die Logik ist dort, wo sie sein sollte, anstatt in andere Accessoren gehackt zu werden. Alles, was Sie tun müssen, ist die Unterklasse Memoize :: Expire und setzen Sie den STORE-Sub, um den Cache zu löschen, bevor Sie in den Hash schreiben. –
Ich habe dies als Antwort gewählt, da es den Code drastisch vereinfacht, was ich wirklich anstrebte. Die Tatsache, dass das Ergebnis der Berechnung nicht im Objekt selbst gespeichert ist, ist kein Problem für meine aktuelle Implementierung. Danke EvanCaroll. – clscott