クラスでは、 の計算値を表す属性を作成するパターンがあります。明白な理由から、計算された値 をキャッシュし、基になる値の1つが変更されたときにキャッシュを無効にする必要があります。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 { ... }
を。
'bar'がそれに依存する属性を監視するためのよりスマートでシンプルな方法はありますか? 対して誰がそれに依存しているのかを知っていますか?また、どのようにハッシュ メンバーアクセスを介してバーを設定するのを避けることができますか?
Hm。 Memoizeを使用してオブジェクトデータをキャッシュするときに問題が発生します。このクラスのすべてのインスタンスが異なる値を持つ場合はどうなりますか? Memoizeは、オブジェクトが破棄されたときにもはやそれらが役に立たないという事実にかかわらず、それらを永久にキャッシュしますか?つまり、永続的なアプリケーションでは(実際にはMooseを使用する唯一の賢明な場所です)、巨大で無駄なキャッシュを潜在的に増やすことになります。いいえ? もちろん、手動で期限切れのものを混乱させることもできます(私は思っています)。しかし、これは上記のムース/怠け者の例よりも複雑です。 – Dan
私は根本的にそれだけではなく、透明性は向上しますが、スピード・ヒットとゲインは予測可能であり、ロジックは他のアクセッサにハッキングされるべきではありません。 Memoize :: Expireをサブクラス化し、ハッシュに書き込む前にキャッシュをクリアするようにSTOREサブを設定するだけです。 –
コードを大幅に簡素化するので、これを答えとして選択しました。これは私が本当に努力していたものでした。 計算結果がオブジェクト自体に格納されていないことは、現在の実装では問題ではありません。 ありがとうEvanCaroll。 – clscott