perlbuildmoose

Moose: Loading object from file in the BUILD method


I have to read a file in the BUILD method and I want to use the load method of the MooseX::Storage package.
But this load method create a new object and so when I instatiate the object this isn’t the object read from file. In the code below I create an object $m1 with state 2 to write the file, I create $m2 with no parameter to read the file but $m2 doesn’t contain the right value. The package:

package mia;
use Moose;
use MooseX::Storage;

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

has 'nome'  => ( is     => 'rw', isa    => 'Str', default =>'',);
has 'stato' => ( is     => 'rw', isa    => 'Int', default =>1,);

sub BUILD { 
    my $self=shift;
    if ($self->stato==1){
        $self=mia->load("mia.dat");
    }
    if ($self->stato==2){
        $self->stato(0);
        $self->nome("prova");
        $self->store("mia.dat");    
    }
}

sub stampa(){
    my $self=shift;
    print $self->nome." ".$self->stato;
}

the main program

use mia;
my $m;

$m1=mia->new(stato=>2); 
$m2=mia->new();
print "\nm1 \n";
$m1->stampa();
print "\nm2 \n";
$m2->stampa();

Solution

  • Your code seems to be acting as if BUILD is a constructor, which it isn't -- it's more like a post-construction hook where you can perform other things like read values from a DB. You should instead either:

    Here is an example of the first case, separating the MooseX::Storage object from the object that controls it:

    package miaController;
    use Moose;
    use mia;
    
    has 'nome'  => ( is     => 'rw', isa    => 'Str', default =>'',);
    has 'stato' => ( is     => 'rw', isa    => 'Int', default =>1,);
    has 'mia'   => ( is     => 'rw', isa    => 'mia', lazy => 1);
    
    sub BUILD
    {
        my $self = shift;
        if ($self->stato == 1)
        {
            $self->mia(mia->load("mia.dat"));
        }
        elsif ($self->stato == 2)
        {
            $self->stato(0);
            $self->nome("prova");
            $self->mia->store("mia.dat");
        }
    }
    sub stampa
    {
        my $self = shift;
        print $self->nome." ".$self->stato;
    }
    
    package mia;
    use Moose;
    use MooseX::Storage;
    with Storage(format => 'JSON', io => 'File');
    
    package main:
    use miaController;
    
    my $m1=miaController->new(stato=>2);
    my $m2=miaController->new();
    print "\nm1 \n";
    $m1->stampa();
    print "\nm2 \n";
    $m2->stampa();