English 中文(简体)
变式:当属性价值发生变化时,计算结果会急剧上升?
原标题:Moose: Expiring cached results of calculations when attribute values change?
  • 时间:2009-11-21 14:04:52
  •  标签:
  • perl
  • moose

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.

因此,我们现在有:

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?

最佳回答

我认为,如果你能够使整个方案更加透明,那么你就能够利用“阿蒂丁胺”的含蓄的电动,使你更加积极地参与。

has [qw/foo bar baz/] => ( isa =>  Value , is =>  rw  );

use Memoize;
memoize( _memoize_this );

sub old_lazy_attr {
    my $self = shift;
    _memoize_this( $self->attr1, $self->attr2, $self->attr3 );
}

sub _memoize_this {
    my @args = @_;
    # complex stuff
    return $result
}

See cpan s Memoize for information and control of the Internal cache, also记住,改变功能不能取决于物体的状况。 因此,must 的论据可在上通过。

问题回答

这项工作吗?

#!/usr/bin/perl

package Test;

use Modern::Perl;
use Moose;

has a => (is =>  rw , isa =>  Str , trigger => &change_a);
has b => (is =>  rw , isa =>  Str , trigger => &change_b);
has c => (is =>  rw , isa =>  Str );

sub change_a
{
    my $self = shift;
    say  update b ;
    $self->b($self->a .  , bar );
}   

sub change_b
{
    my $self = shift;
    say  update c ;
}   

package main;

my $test = Test->new->a( Foo );

产出:

$ perl test.pl
update b
update c

我在摩罗丝内部和美物议定书中做了任何 p,但我认为这是这样做的良好时机。

你们想要配上法典的一代,这样,当你确定一个归属时,就能够做到。

has  foo  => ();
has  bar  => ( 
    depends_on => [qw( foo )],
    lazy => &calculate_bar,
);

代码生成阶段为<代码>foo和/bar属性(如上所述)。

如何做到这一点,是留给读者的。 如果我有一席之地,我就试图让大家开始。 不幸的是,我能够告诉你,“这是普惠制的一项工作”。





相关问题
Why does my chdir to a filehandle not work in Perl?

When I try a "chdir" with a filehandle as argument, "chdir" returns 0 and a pwd returns still the same directory. Should that be so? I tried this, because in the documentation to chdir I found: "...

How do I use GetOptions to get the default argument?

I ve read the doc for GetOptions but I can t seem to find what I need... (maybe I am blind) What I want to do is to parse command line like this myperlscript.pl -mode [sth] [inputfile] I can use ...

Object-Oriented Perl constructor syntax and named parameters

I m a little confused about what is going on in Perl constructors. I found these two examples perldoc perlbot. package Foo; #In Perl, the constructor is just a subroutine called new. sub new { #I ...

Where can I find object-oriented Perl tutorials? [closed]

A Google search yields a number of results - but which ones are the best? The Perl site appears to contain two - perlboot and perltoot. I m reading these now, but what else is out there? Note: I ve ...

热门标签