Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

[Solved] : Perl Serialization + Moose Object. Will the code get serialized?

by sam_bakki (Pilgrim)
on May 24, 2015 at 13:24 UTC ( #1127586=perlquestion: print w/replies, xml ) Need Help??

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

Hi Monks,

I am confused in the Perl object serialization (or serialization in general) topic. Please shed some light and enlighten me.

I understand that perl serialization (using Storable module for example) can perfectly do the object / variables-value serialization. This means that, if I serialize a Moose class (ofcourse object), all the properties / variable values will be saved in a file and I can get them later to reconstruct the Moose object.

I also understand that, the code part (Subs) can not be / will not be by default serialized. When we talk about Object Oriented Programming, The object contains two parts

  1. Data
  2. Procedure / function to operate on the Data


I thought only Data part will be serialized. But I am wrong, To illustrate my confusion, Please see my example code below,

package MooseClass; #MooseClass.pm file use strict; use warnings; use Moose; use namespace::autoclean; #--------ONLY for Eclipse ---- #Just for the Perl Eclipse IDE to auto complete $self variable #$self = MooseClass->new(); #--------ONLY for Eclipse ---- # Members has 'name',is=>'rw',isa=>'Str',required=>1; has 'age',is=>'rw',isa=>'Int',required=>1; has 'gender', is=>'rw', isa=>'Str', required=>0; sub BUILD { my $self = shift @_; my $constArgsHashRef = shift @_; # Hash ref of arguments passed to + constructor at the time of object creation return 1; } sub increaseAge { my $self = shift @_; $self->age($self->age()+1); print "\n ", $self->name(), " is now ",$self->age()," old. "; return 1; } sub getAgeIterator { my $self = shift @_; my $iter = sub { print "\n iterate to next age", " AgeNow: ",$ +self->age(); return $self->age($self->age()+1); }; return $iter; } #Do it for all classes so Moose will create fast object creation, so a +pplication runs faster __PACKAGE__->meta->make_immutable(); no Moose; 1;


#serialize.pl use strict; use warnings; use Storable; use MooseClass; use Data::Dumper; my $obj = MooseClass->new(name=>'Eva',age=>'20',gender=>'girl'); print "\n Class dump \n", Dumper($obj); $obj->increaseAge(); print "\n Class dump 2\n", Dumper($obj); my $nextage = $obj->getAgeIterator(); $nextage->(); $nextage->(); print "\n Class dump 3\n", Dumper($obj); #Lets serailize the $obj store ($obj,'serialize.bin'); #Lets deserialize the object #--------ONLY for Eclipse ---- #Just for the Perl Eclipse IDE to auto complete $self variable #$newObj = MooseClass->new(); #--------ONLY for Eclipse ---- my $newObj = retrieve ('serialize.bin'); print "\n \n New Class dump1 \n", Dumper($newObj); $newObj->increaseAge(); print "\n \n New Class dump2 \n", Dumper($newObj); my $newnextAge = $newObj->getAgeIterator(); $newnextAge->(); $newnextAge->(); print "\n \n New Class dump3 \n", Dumper($newObj);


#Output Class dump $VAR1 = bless( { 'name' => 'Eva', 'age' => '20', 'gender' => 'girl' }, 'MooseClass' ); Eva is now 21 old. Class dump 2 $VAR1 = bless( { 'name' => 'Eva', 'age' => 21, 'gender' => 'girl' }, 'MooseClass' ); iterate to next age AgeNow: 21 iterate to next age AgeNow: 22 Class dump 3 $VAR1 = bless( { 'name' => 'Eva', 'age' => 23, 'gender' => 'girl' }, 'MooseClass' ); New Class dump1 $VAR1 = bless( { 'gender' => 'girl', 'age' => 23, 'name' => 'Eva' }, 'MooseClass' ); Eva is now 24 old. New Class dump2 $VAR1 = bless( { 'gender' => 'girl', 'age' => 24, 'name' => 'Eva' }, 'MooseClass' ); iterate to next age AgeNow: 24 iterate to next age AgeNow: 25 New Class dump3 $VAR1 = bless( { 'gender' => 'girl', 'age' => 26, 'name' => 'Eva' }, 'MooseClass' );


I thought $newObj (which is de-serialized), Can not call the class methods (Closure also working !). How its possible? This means, I can send this object to some other perl script / process which does not "use" the MooseClass and can it operate on the class member functions? So the serialization by default embeds the moose class member function code as well?

forgive me, If I miss the obvious.

Thanks & Regards,
Bakkiaraj M
My Perl Gtk2 technology demo project - http://code.google.com/p/saaral-soft-search-spider/ , contributions are welcome.

Replies are listed 'Best First'.
Re: Perl Serialization + Moose Object. Will the code get serialized?
by choroba (Archbishop) on May 24, 2015 at 14:49 UTC
    The code is not retrieved from the dump, it exists because you loaded the class. I created a new script which doesn't use MooseClass:
    #serialize.pl use strict; use warnings; use Storable; use Data::Dumper; my $no_class = retrieve('serialize.bin'); print Dumper $no_class; $no_class->increaseAge();

    The output shows what was retrieved and what was missing:

    $VAR1 = bless( { 'age' => 23, 'gender' => 'girl', 'name' => 'Eva' }, 'MooseClass' ); Can't locate object method "increaseAge" via package "MooseClass" at 1 +.pl line 46.
    لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      Hi choroba

      Thanks for the clarification :). So looks like the "bless" information alone is serialized. So when deserialized , if the class is already loaded, it can work. I will mark this thread as solved.

      Thanks & Regards,
      Bakkiaraj M
      My Perl Gtk2 technology demo project - http://code.google.com/p/saaral-soft-search-spider/ , contributions are welcome.

Re: [Solved] : Perl Serialization + Moose Object. Will the code get serialized?
by sundialsvc4 (Abbot) on May 25, 2015 at 12:42 UTC

    So far as I know, in any object-oriented language (or approximation thereof), serialization only addresses the properties of the object, not the methods.

    Also, I suggest that you should not expect that any “setters” (methods that are to be called when you store a value into some property) will be called, nor that “private” things which may be used by such getters/setters will be populated.

    The problem here is that “a serializer” can be counted on only to serialize/unserialize a data structure.   But, an object is more than a data-structure.   An object, so to speak, moves.   When you push-and-prod an object, lights may flash and bells may ring.   Serializers can’t know anything about such things.   Even if they precisely restore the memory-areas corresponding to the object, they do not know what the object does.   Thus, they might not restore the true internal/external state of the object.

    In practice, many object-oriented programs which I have encountered (not necessarily in Perl ...), which need to reliably serialize objects, do so, at least in part, using methods which are created for the purpose.   The object, itself, provides “a serialized representation of itself,” and, within another method, consumes it.   Anything which needs to be executed as part of the process of doing either of these things becomes, as it should be, the opaque responsibility of the object itself.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1127586]
Approved by Laurent_R
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (3)
As of 2020-11-28 05:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?