Search code examples
perlserializationyamlmoosecoderef

Which recommended Perl modules can serialize Moose objects?


I was usually using Storable with nstore, but now I have a module that has CODE and apparently Storable doesn't like that.

I found YAML (and YAML::XS which I can't really get to work). I also experimented a bit with MooseX::Storage without much success.

Are there other alternatives? What would you recommend?


Solution

  • You can dump a coderef with Data::Dumper after setting $Data::Dumper::Deparse to a true value, but this is only intended for debugging purposes, not for serialization.

    I would suggest you go back to looking at why MooseX::Storage isn't working out for you, as the authors tried really hard to present a well-abstracted and robust solution for Moose object serialization.


    Update: it looks like you are running into issues serializing the _offset_sub attribute, as described in this question. Since that attribute has a builder, and its construction is fairly trivial (it just looks at the current value of another attribute), you shouldn't need to serialize it at all -- when you deserialize your object and want to use it again, the builder will be invoked the first time you call $this->offset. Consequently, you should just be able to mark it as "do not serialize":

    use MooseX::Storage;
    
    has '_offset_sub' => (
        is       => 'ro',
        isa      => 'CodeRef',
        traits   => [ 'DoNotSerialize' ],
        lazy     => 1,
        builder  => '_build_offset_sub',
        init_arg => undef,
    );
    

    Lastly, this is somewhat orthogonal, but you can fold the offset and _offset_sub attributes together by using the native attribute 'Code' trait:

    has offset => (
        is          => 'bare',
        isa         => 'CodeRef',
        traits      => [ qw(Code DoNotSerialize) ],
        lazy        => 1,
        builder     => '_build_offset',
        init_arg    => undef,
        handles     => {
            offset  => 'execute_method',
        },
    );
    
    sub _build_offset {
        my ($self) = @_;
    
        # same as previous _build_offset_sub...
    }