irishBatman has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I am trying to serialise and reload a Moose object structure. I would like to build my object structure, dump this out to a JSON, then load a JSON that may have some of the values modified and have these changes propagated through my object structure.

I tried do this with MooseX::Storage, however when I load the modified JSON the changed value is not reflected in the Moose object

In the example below it looks like the incoming json is being ignored. Have I missed something or misunderstood how load works?
#!/usr/bin/perl -w #------------------------------------------------ package myDevice; use strict; use Moose; use MooseX::Storage; with Storage( 'format' => 'JSON', 'io' => 'File' ); #with Storage( 'format' => [ JSONpm => { json_opts => { pretty => 1 } +} ], 'io' => 'File' ); has 'instruments' => ( isa => 'HashRef', is => 'rw', default => sub { +{} } ); sub BUILD { my $self = shift; my $noOfInstruments = keys(%{$self->instruments}) . "\n"; if ( $noOfInstruments > 0 ) { print "The object seems to exist already\n"; } else { $self->instruments->{batt1} = readBatteryVoltage->new(); $self->instruments->{batt2} = readBatteryVoltage->new(); $self->instruments->{batt3} = readBatteryVoltage->new(); } return $self; } 1; #------------------------------------------------ package readBatteryVoltage; use strict; use Moose; use MooseX::Storage; with Storage( 'format' => 'JSON', 'io' => 'File' ); #with Storage( 'format' => [ JSONpm => { json_opts => { pretty => 1 } +} ], 'io' => 'File' ); has 'randomNumber' => ( is => 'rw', default => 1234567, ); has 'var2' => ( is => 'rw', default => 1999, ); has 'str1' => ( is => 'rw', default => "I am a string", ); 1; #------------------------------------------------ my $aNewDevice = myDevice->new(); # create our device print "+++++++++++++++Initial object we create\n"; print $aNewDevice->freeze() . "\n"; # look at the output # Its should look as below #{"__CLASS__":"myDevice","instruments":{"batt":{"__CLASS__":"readBatte +ryVoltage","randomNumber":1234567}}} $aNewDevice->store('file1.json'); # save our object # Lets quickly modify the value system 'perl -p -i -e \'s/1234567/987654321/\' file1.json'; system 'perl -p -i -e \'s/1234567/10293847/\' file1.json'; # remove a value to have a partial JSON system 'perl -p -i -e \'s/,\"var2\":1999//g\' file1.json'; # Change this also system 'perl -p -i -e \'s/am a string/am a number/\' file1.json'; system 'perl -p -i -e \'s/am a string/am a modified variable/\' file1. +json'; print "+++++++++++++++++File after modification\n"; system 'more file1.json'; # Its should look as below #{"__CLASS__":"myDevice","instruments":{"batt":{"__CLASS__":"readBatte +ryVoltage","randomNumber":987654321}}} my $anotherNewDevice = myDevice->load('file1.json'); use Data::Dumper; print "+++++++++++++++++Using Dumper\n"; print Dumper($anotherNewDevice); print "+++++++++++++++++Our new device\n"; print $anotherNewDevice->freeze() . "\n"; # Why is randomNumber not taking the vaue 987654321? #{"__CLASS__":"myDevice","instruments":{"batt":{"__CLASS__":"readBatte +ryVoltage","randomNumber":1234567}}}

Replies are listed 'Best First'.
Re: MooseX::Storage JSON load not functioning as expected
by Loops (Curate) on Jul 07, 2013 at 20:09 UTC

    The problem is that you've hard coded the creation of a new "batt" instrument in the BUILD method. The object is loaded properly from file1.json and then the BUILD method unceremoniously overwrites it with a newly constructed object with the default value

      Thanks, I have modified the code to check if the hash elements have been created yet and create them if not. This seems to work.

      I am wondering if there is a cleaner way of creating my object structure in the first place?