如何使用MooseX::Storage来存储一个大的HashRef?

How to use MooseX::Storage for storing one big HashRef?

想要使用 MooseX::Storage using the MooseX::Storage::IO::CHI 存储以下内容:

has 'packages' => (is => 'ro', isa => 'HashRef', ...);

它存储了对象,但我无法从缓存中检索它。

我的演示代码如下...

# the Entry objects are the values in the Some->packages HasrRef
package Entry {
    use Moose;
    use warnings;
    use MooseX::Storage;
    with Storage(io => [ 'CHI' => { key_attr => 'id', key_prefix => 'id-' }]);
    has 'id' => (is => 'ro', isa => 'Int', default => 0);
    has 'names' => (is => 'ro', isa => 'ArrayRef[Str]', default => sub{ [] } );
}

# want store THIS object into the cache,
# because the computation of the '_build_packages' is expensive
package Some {
    use Moose;
    use warnings;
    use MooseX::Storage;
    with Storage(io => [ 'CHI' => { key_attr => 'packages', key_prefix => 'package-' }]);

    has 'packages' => (is => 'ro', isa => 'HashRef', builder => '_build_packages');
    sub _build_packages {
        my $hr;
        # building the demo 2-element hash here - otherwise very time-expensive code...
        # each value in the hash an object ISA: Entry 
        $hr->{$_} = Entry->new(id => $_, names => ["some", "names $_"]) for (1..2);
        return $hr;
    }
}

use 5.014;
use warnings;
use Data::Dumper;
use CHI;

my $cachedir = './testcache';
my $cache = CHI->new(driver => 'File', root_dir => $cachedir);

my $some = Some->new();             # OK
say Dumper $some;
my $cached = $some->store(cache => $cache); # also OK
say Dumper $cached;

# doesn't loads the 'packages'...
my $some2 = Some->load('packages', cache => $cache);    #returns undef :(
say Dumper $some2;

以上代码转储以下内容:

$VAR1 = bless( {
                 'packages' => {
                                 '1' => bless( {
                                                 'names' => [
                                                              'some',
                                                              'names 1'
                                                            ],
                                                 'id' => 1
                                               }, 'Entry' ),
                                 '2' => bless( {
                                                 'id' => 2,
                                                 'names' => [
                                                              'some',
                                                              'names 2'
                                                            ]
                                               }, 'Entry' )
                               }
               }, 'Some' );

$VAR1 = {
          '__CLASS__' => 'Some',
          'packages' => {
                          '2' => {
                                   '__CLASS__' => 'Entry',
                                   'names' => [
                                                'some',
                                                'names 2'
                                              ],
                                   'id' => 2
                                 },
                          '1' => {
                                   'id' => 1,
                                   '__CLASS__' => 'Entry',
                                   'names' => [
                                                'some',
                                                'names 1'
                                              ]
                                 }
                        }
        };

$VAR1 = undef;

因此,看起来 packages 已存储在缓存中。但是最新的undef显示,比

my $some2 = Some->load('packages', cache => $cache);

没有像我预期的那样工作。

有人能帮忙吗?

load() 需要 key_attr 的实际值,而不仅仅是名称。

所以我相信这样的事情会奏效。

# the Entry objects are the values in the Some->packages HasrRef
package Entry {
    use Moose;
    use warnings;
    use MooseX::Storage;
    with Storage(io => [ 'CHI' => { key_attr => 'id', key_prefix => 'id-' }]);
    has 'id' => (is => 'ro', isa => 'Int', default => 0);
    has 'names' => (is => 'ro', isa => 'ArrayRef[Str]', default => sub{ [] } );
}

# want store THIS object into the cache,
# because the computation of the '_build_packages' is expensive
package Some {
    use Moose;
    use warnings;
    use MooseX::Storage;
    with Storage(io => [ 'CHI' => { key_attr => 'some_id', key_prefix => 'some_id-' }]);

    has 'some_id' => (is => 'ro', isa => 'Int');
    has 'packages' => (is => 'ro', isa => 'HashRef', builder => '_build_packages');
    sub _build_packages {
        my $hr;
        # building the demo 2-element hash here - otherwise very time-expensive code...
        # each value in the hash an object ISA: Entry 
        $hr->{$_} = Entry->new(id => $_, names => ["some", "names $_"]) for (1..2);
        return $hr;
    }
}

use 5.014;
use warnings;
use Data::Dumper;
use CHI;

my $cachedir = './testcache';
my $cache = CHI->new(driver => 'File', root_dir => $cachedir);

my $some = Some->new(some_id => 100);             # OK
say Dumper $some;
my $cached = $some->store(cache => $cache); # also OK
say Dumper $cached;

my $some2 = Some->load(100, cache => $cache);
say Dumper $some2->packages;