2011-05-23 13 views
7

Soy nuevo en Moose y va muy bien hasta que haya con un obstáculo usando un PDL como una propiedad. Quiero ser capaz de escribir un objeto en un archivo (He estado usando use MooseX::Storage; with Storage('io' => 'StorableFile');, y este objeto tiene una PDL como un atributo. PDL::IO::Storable proporciona los métodos necesarios para utilizar Storable de esta manera, sin embargo yo estoy en una pérdida en cuanto a cómo . hacer esto en Moosetienda Moose un objeto que tiene un PDL como un atributo

Aquí es un ejemplo, es un poco largo, lo sé, pero es lo mínimo que puedo hacer:

#!/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; 

creo que voy a tener que hacer una tipo de PDL, o tal vez incluso envolver PDL en algo (usando MooseX::NonMoose::InsideOut), pero tal vez alguien me puede salvar de que (o que me señale en el camino correcto si lo es).

Respuesta

7

No dice qué es lo que realmente falla. Supongo que tendrá que indicar MooseX::Storage cómo manejar el objeto PDL utilizando los ganchos almacenables del objeto PDL. La documentación para esta función en MooseX :: almacenamiento es muy pobre pero MooseX :: :: Motor de almacenamiento tiene un método add_custom_type_handler() que toma un nombre de tipo (PDL en su caso) y un hashref de los manipuladores.

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

favor pivotar pasado #moose en irc.perl.org o la lista de correo alces y preguntar.

[Editar:. Actualización con un ejemplo basado en la tests]

+1

esto parece muy prometedor, ¿puede ampliar un poco más? ¿Creo el objeto '$ engine' en la definición de clase? ¿Cuáles son las entradas y salidas para los subs de expansión y colapso? ¿Hay algún lugar donde se puedan encontrar mejores documentos o tutoriales? ¡Gracias! –

+0

Joel desafortunadamente esta es una parte poco documentada de MooseX :: Storage. Es por eso que sugerí hablar con el canal IRC y/o la lista. Hice un rápido vistazo a través de [la fuente] (http://cpansearch.perl.org/src/BOBTFISH/MooseX-Storage-0.30/lib/MooseX/Storage/Engine.pm) para MooseX :: Almacenamiento anterior porque sabía esta característica existía pero no recordaba cómo/dónde. – perigrin

+1

Y he publicado ese último comentario se dio cuenta de que podía ver el banco de pruebas y se encontró [un ejemplo] (http://cpansearch.perl.org/src/BOBTFISH/MooseX-Storage-0.30/t/006_w_custom_type_handlers.t) de exactamente lo que quieres – perigrin

1

La pregunta por Joel y respuesta de perigrin me ayudó a resolver un problema de almacenamiento que se había sentado en el fondo de mi mente por un tiempo. Estoy publicando un ejemplo de trabajo aquí. No usa PDL pero está relacionado y puede ayudar a alguien en el futuro.

{ 
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; 
Cuestiones relacionadas