Сохраните объект Moose, который имеет PDL в качестве атрибута - PullRequest
7 голосов
/ 23 мая 2011

Я новичок в Moose и чувствую себя неплохо, пока не наткнулся на препятствие, используя PDL в качестве свойства.Я хочу иметь возможность записать объект в файл (я использовал use MooseX::Storage; with Storage('io' => 'StorableFile');, и этот объект имеет PDL в качестве атрибута. PDL::IO::Storable предоставляет необходимые методы для использования Storable таким образом, однакоЯ в растерянности относительно того, как это сделать в Moose.

Вот пример, он немного длинный, я знаю, но он настолько минимален, насколько я могу это сделать:

#!/usr/bin/perl

package LinearPDL;
use Moose;

use PDL::Lite;
use PDL::IO::Storable;

use MooseX::Storage; 
with Storage('io' => 'StorableFile');

has 'length' => (is => 'ro', isa => 'Num', required => 1);
has 'divisions' => (is => 'ro', isa => 'Int', required => 1);
has 'linear_pdl' => (is => 'ro', isa => 'PDL', lazy => 1, builder => '_build_pdl');

sub _build_pdl {
  my $self = shift;

  my $pdl = $self->length() / ( $self->divisions() - 1 ) * PDL::Basic::xvals($self->divisions());

  return $pdl;
}

no Moose;
__PACKAGE__->meta->make_immutable;

use strict;
use warnings;

my $linear_pdl = LinearPDL->new('length' => 5, 'divisions' => 10);
print $linear_pdl->linear_pdl;

$linear_pdl->store('file'); # blows up here!

my $loaded_lpdl = load('file');
print $loaded_lpdl->linear_pdl;

Я думаю, что мне, возможно, придется сделать тип PDL или, возможно, даже обернуть PDL во что-то (используя MooseX::NonMoose::InsideOut), но, возможно, кто-то может спасти меня от этого (или указать мне правильный путь, если это так).

Ответы [ 2 ]

7 голосов
/ 24 мая 2011

Вы не говорите, что на самом деле идет не так. Предполагается, что вам нужно указать MooseX :: Storage , как обрабатывать объект PDL с помощью хуков Storable объекта PDL. Документация для этой функции в MooseX :: Storage очень скудная, но MooseX :: Storage :: Engine имеет метод add_custom_type_handler(), который принимает имя типа (PDL в вашем случае) и HashRef обработчиков.

MooseX::Storage::Engine->add_custom_type_handler(
    'PDL' => (
        expand   => sub { my ($data) = @_;   ...  },
        collapse => sub { my ($object) = @_; ...  },
    )
);

Пожалуйста, пройдите мимо #moose на irc.perl.org или в списке рассылки Moose и спросите.

[Редактировать: Обновить с примером, основанным на тестах .]

1 голос
/ 23 июня 2015

Вопрос от Джоэла и ответ Перигрина помогли мне решить проблему с памятью, которая некоторое время находилась у меня в голове. Я публикую здесь рабочий пример. Он не использует PDL, но он связан и может помочь кому-то в будущем.

{
package MVR;
use Moose;
use MooseX::Storage;
use Math::Vector::Real;
use Data::Structure::Util qw (unbless);

with Storage('format' => 'JSON', 'io' => 'File');

MooseX::Storage::Engine->add_custom_type_handler(
  'Math::Vector::Real' => (
      expand    => sub {my $v   = shift; Math::Vector::Real->new(@{$v})},
      collapse  => sub {my $mvr = shift; return (unbless($mvr)) },
  )
);

has 'mvr' => (is => 'rw', isa => 'Math::Vector::Real');

1;
}

use Math::Vector::Real;
my $p = MVR->new(mvr => V(0,1,3));

print $p->dump;
$p->store('my_point.json');

my $p1 = MVR->load('my_point.json');

print $p1->dump; 
...