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”监控它所依赖的属性 与让“foo”知道谁依赖它?另外我怎样才能避免通过哈希设置栏 会员访问?
In our classes we have a pattern where we create an attribute to represent a
calculated value. For obvious reasons we want to cache the calculated value
and then invalidate the cache when one of the underlying values change.
So we currently have this:
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 { ... }
This long hand method is getting very tedious and error prone when calculated values
depend on other calculated values.
Is there a smarter/simpler way for 'bar' to monitor the attributes it depends on
vs having 'foo' know who is dependent on it? Also how can I avoid setting bar via hash
member access?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果我理解正确,您可以使用 触发器 设置属性后清除属性。这是一个示例:
因此,任何通过
$obj->foo($newvalue)
对foo
的写入都会导致bar
被清除,并且下次访问时重新创建。If I understand you correctly, you can use triggers to clear attributes when one is set. Here's an example:
So, any writes to
foo
via$obj->foo($newvalue)
will causebar
to be cleared, and recreated on next access.我认为你很可能通过使用带有惰性的属性隐式记忆来让自己变得更加困难,而你可以使记忆显式使你的整个程序更加透明
请参阅cpan的Memoize 用于内部缓存的信息和控制,还要记住 Memoized 函数不能依赖于对象的状态。因此参数必须显式传递。
I think it is quite possible that you're making this harder on yourself by using an Attributes implicit memoization with lazy, when you could just make the memoization explicit making your whole program more transparent
See cpan's Memoize for information and control of the internal cache, also remember that a Memoized function can not be dependent on the state of the object. So the arguments must be passed in explicitly.
这行得通吗?
输出:
Would this work?
Output:
我还没有对 Moose 内部结构和元对象协议进行任何研究,但我认为现在是这样做的好时机。
您想要修补代码生成,以便在指定属性作为
代码生成阶段时,为上面指定的
foo
和bar
属性创建代码。如何做到这一点是留给读者的练习。如果我有线索,我会尝试给你一个开始。不幸的是,我只能建议你“这是 MOP 的工作”。
I haven't done any poking around in Moose internals and the meta object protocol, but I think this is a good time to do it.
You want to patch the code generation so that when you specify an attribute as
the code generation phase creates code for the
foo
andbar
attributes as you specified above.How to do this is an exercise left to the reader. If I had a clue, I'd try to give you a start. Unfortunately, all I can advise you with is "This is a job for the MOP".