2011-05-23 18 views
7

olarak depolayın Moose'da yeniyim ve bir PDL özelliğini özellik olarak kullanarak bir takıma varana kadar oldukça iyiyim. Bir nesneyi bir dosyaya yazabilmek istiyorum (use MooseX::Storage; with Storage('io' => 'StorableFile'); kullanıyorum ve bu nesne bir PDL özniteliğine sahiptir. PDL::IO::Storable bu şekilde Storable kullanmak için gerekli yöntemleri sağlar, ancak nasıl bir kayıp olduğunu . Moose bunu İşte Bir PDL olan bir Moose nesnesini

bir örnektir, biraz uzun, biliyorum, ama bunu yapabilirsiniz olduğunca minimal:

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

Ben yapmanız gerekebilir düşünüyorum PDL türü veya belki de bir şey içine PDL sarın (MooseX::NonMoose::InsideOut kullanarak), ama belki de birileri beni bundan koruyabilir (veya eğer doğruysa bana doğru yolu işaret et).

cevap

7

Aslında neyin yanlış gittiğini söylemiyorsunuz. Bir tahminde, PDL nesnesinin Storable kancalarını kullanarak PDL nesnesinin nasıl ele alınacağını MooseX::Storage anlatmanız gerekir. MooseX :: Storage'deki bu özelliğin belgeleri çok zayıftır ancak MooseX :: Storage :: Engine, bir typename (sizin durumunuzda PDL) ve bir HashRef işleyicisini alan bir add_custom_type_handler() yöntemine sahiptir.

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

irc.perl.org veya Moose posta listesinde geçen #moose salıncak ve isteyiniz.

[Düzenleme:. tests dayalı bir örnekle Güncelleme]

+1

Bu çok umut verici görünüyor, biraz daha genişleyebilir misiniz? Sınıf tanımında '$ engine' nesnesini oluşturuyor muyum? Genişletme ve daraltma birimleri için girdi ve çıktılar nelerdir? Daha iyi belgelerin veya öğreticilerin bulunabileceği bir yer var mı? Teşekkürler! –

+0

Joel, maalesef bu MooseX :: Storage'ın belgelenmemiş bir parçasıdır. Bu yüzden irc kanalı ve/veya listesiyle konuşmayı önerdim. Daha önce MooseX :: Storage için [kaynak] (http://cpansearch.perl.org/src/BOBTFISH/MooseX-Storage-0.30/lib/MooseX/Storage/Engine.pm) aracılığıyla hızlı bir bakışta bulundum çünkü Bu özellik var ama nasıl/nerede olduğunu hatırlayamadım. – perigrin

+1

Ve ben bu son yorumu yayınladıktan sonra test paketine bakabileceğimi fark ettim ve [bir örnek] buldum (http://cpansearch.perl.org/src/BOBTFISH/MooseX-Storage-0.30/t/006_w_custom_type_handlers.t) tam olarak ne istersen. – perigrin

1

Joel tarafından soru perigrin gelen yanıt beni bir süre kafamın arkasına oturan olmuştu bir depolama sorunu çözmek yardımcı oldu. Burada çalışan bir örnek gönderiyorum. PDL'yi kullanmaz, ancak ilişkilidir ve gelecekte birisine yardımcı olabilir.

{ 
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; 
İlgili konular